From c1ae0b10ab3791c635116a70a4de335936b7c83d Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Thu, 17 Feb 2022 12:15:57 -0800 Subject: [PATCH 001/364] initial commit --- .clang-format | 7 + .github/workflows/github-ci.yml | 68 ++++ .gitignore | 22 ++ .pre-commit-config.yaml | 56 +++ .typos.toml | 5 + CMakeLists.txt | 135 +++++++ README.md | 85 +++++ benchmark/CMakeLists.txt | 20 ++ benchmark/bench_cryptography.cpp | 293 +++++++++++++++ benchmark/bench_ops.cpp | 545 ++++++++++++++++++++++++++++ benchmark/main.cpp | 10 + cmake/gbenchmark.cmake | 37 ++ cmake/gtest.cmake | 27 ++ cmake/ipcl/IPCLConfig.cmake.in | 21 ++ cmake/ipcl/ipcl-util.cmake | 112 ++++++ cmake/ippcrypto.cmake | 63 ++++ docs/CMakeLists.txt | 23 ++ docs/Doxyfile.in | 29 ++ docs/index.html | 2 + docs/index.rst | 10 + ipcl/CMakeLists.txt | 109 ++++++ ipcl/bignum.cpp | 499 ++++++++++++++++++++++++++ ipcl/include/ipcl/bignum.h | 136 +++++++ ipcl/include/ipcl/key_pair.hpp | 32 ++ ipcl/include/ipcl/paillier_ops.hpp | 133 +++++++ ipcl/include/ipcl/pri_key.hpp | 125 +++++++ ipcl/include/ipcl/pub_key.hpp | 141 ++++++++ ipcl/key_pair.cpp | 103 ++++++ ipcl/paillier_ops.cpp | 150 ++++++++ ipcl/paillier_pri.cpp | 189 ++++++++++ ipcl/paillier_pub.cpp | 267 ++++++++++++++ test/CMakeLists.txt | 15 + test/test.cpp | 404 +++++++++++++++++++++ test/test_omp.cpp | 549 +++++++++++++++++++++++++++++ 34 files changed, 4422 insertions(+) create mode 100644 .clang-format create mode 100644 .github/workflows/github-ci.yml create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 .typos.toml create mode 100644 CMakeLists.txt create mode 100644 README.md create mode 100644 benchmark/CMakeLists.txt create mode 100644 benchmark/bench_cryptography.cpp create mode 100644 benchmark/bench_ops.cpp create mode 100644 benchmark/main.cpp create mode 100644 cmake/gbenchmark.cmake create mode 100644 cmake/gtest.cmake create mode 100644 cmake/ipcl/IPCLConfig.cmake.in create mode 100644 cmake/ipcl/ipcl-util.cmake create mode 100644 cmake/ippcrypto.cmake create mode 100644 docs/CMakeLists.txt create mode 100644 docs/Doxyfile.in create mode 100644 docs/index.html create mode 100644 docs/index.rst create mode 100644 ipcl/CMakeLists.txt create mode 100644 ipcl/bignum.cpp create mode 100644 ipcl/include/ipcl/bignum.h create mode 100644 ipcl/include/ipcl/key_pair.hpp create mode 100644 ipcl/include/ipcl/paillier_ops.hpp create mode 100644 ipcl/include/ipcl/pri_key.hpp create mode 100644 ipcl/include/ipcl/pub_key.hpp create mode 100644 ipcl/key_pair.cpp create mode 100644 ipcl/paillier_ops.cpp create mode 100644 ipcl/paillier_pri.cpp create mode 100644 ipcl/paillier_pub.cpp create mode 100644 test/CMakeLists.txt create mode 100644 test/test.cpp create mode 100644 test/test_omp.cpp diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..6ee397d --- /dev/null +++ b/.clang-format @@ -0,0 +1,7 @@ +# Copyright (C) 2020-2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +BasedOnStyle: Google +Language: Cpp +DerivePointerAlignment: false +PointerAlignment: Left diff --git a/.github/workflows/github-ci.yml b/.github/workflows/github-ci.yml new file mode 100644 index 0000000..bc6a98b --- /dev/null +++ b/.github/workflows/github-ci.yml @@ -0,0 +1,68 @@ +# Copyright (C) 2021 Intel Corporation + +name: project_phe +on: + # By default this will run when the activity type is "opened", "synchronize", + # or "reopened". + pull_request: + branches: + - main + - development + push: + branches: + - main + - development + + # Manually run this workflow on any specified branch. + workflow_dispatch: + +############## +# IceLake CI # +############## +jobs: + format: + name: Format check + runs-on: [self-hosted, linux, x64, icx] + # Use environment protection (require review) + environment: intel_workflow + steps: + - uses: actions/checkout@v2 + # Add local bin for cpplint + - name: Setup + run: echo "$HOME/.local/bin" >> $GITHUB_PATH + - name: pre-commit + run: pre-commit run --all-files + + build-and-test: + name: Build, test and run kernels + needs: [format] + runs-on: [self-hosted, linux, x64, icx] + # Use environment protection (require review) + environment: intel_workflow + defaults: + run: + shell: bash + working-directory: . + steps: + - uses: actions/checkout@v2 + - name: Validate paths + run: | + whoami + echo $HOME + echo $GITHUB_WORKSPACE + echo "Testing from branch:" + echo $GITHUB_REF + pwd + + # Build library + - name: Build the repository + run: | + cmake -S . -B build -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=Release + cmake --build build --target all -j + + # Unit tests and examples + - name: Run the unit tests + run: ./build/test/unit-test + + - name: Run the unit tests - OpenMP + run: ./build/test/unit-test_omp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..914bd42 --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +.vscode/ +.vs/ +build*/ + + +.DS_Store + +# Generated files +docs/doxygen/ +*.log +Doxyfile +cmake/ipcl-*.*.*/IPCLConfig.cmake + +# Python files +venv/ +__pycache__/ +.ipynb_checkpoints/ +.mypy_cache/ +.env + +# vim +**.swp diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..d4dd2af --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,56 @@ +exclude: 'docs/doxygen/' +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.0.1 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-merge-conflict + - id: mixed-line-ending + - id: check-byte-order-marker + - id: check-yaml + - repo: https://github.com/crate-ci/typos + rev: typos-v0.8.2 + hooks: + - id: typos + - repo: local + hooks: + - id: clang-format-10 + name: clang-format-10 + entry: clang-format-10 + language: system + files: \.(c|cc|cxx|cpp|h|hpp|hxx|js|proto)$ + args: + - -i + - id: shfmt + name: shfmt + entry: shfmt + language: system + files: \.sh$ + args: + - -d + - -i + - '2' + - -ci + - -sr + - -bn + - -w + - id: cpplint + name: cpplint + entry: cpplint + language: system + files: \.(c|cc|cxx|cpp|h|hpp|hxx)$ + exclude: ipcl/bignum.cpp|ipcl/include/ipcl/bignum.h + args: + - --recursive + - --filter=-runtime/references,-whitespace/comments,-whitespace/indent + - id: shellcheck + name: shellcheck + entry: shellcheck + language: system + files: \.sh$ + args: + - -s + - bash + - -e + - SC1091 diff --git a/.typos.toml b/.typos.toml new file mode 100644 index 0000000..50006f5 --- /dev/null +++ b/.typos.toml @@ -0,0 +1,5 @@ +[default.extend-identifiers] + +[default.extend-words] +# variation of params +parms = "parms" diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..97f7087 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,135 @@ +# Copyright (C) 2021-2022 Intel Corporation +cmake_minimum_required(VERSION 3.15.1) + +project(IPCL VERSION 1.0.0 LANGUAGES C CXX) + +include(CMakePackageConfigHelpers) +include(CheckCCompilerFlag) +include(CheckCXXCompilerFlag) + +if(CMAKE_BUILD_TYPE) + set(RELEASE_TYPES + Debug + Release + RelWithDebInfo + MinSizeRel) + list(FIND RELEASE_TYPES ${CMAKE_BUILD_TYPE} INDEX_FOUND) + if(${INDEX_FOUND} EQUAL -1) + message( + FATAL_ERROR + "CMAKE_BUILD_TYPE must be one of Debug, Release, RelWithDebInfo, or MinSizeRel" + ) + endif() +else() + set(CMAKE_BUILD_TYPE Release) +endif() + +# TODO(skmono): Assess if C++17 is necessary +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +# Create compilation database compile_commands.json +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +set(CMAKE_POSITION_INDEPENDENT_CODE ON) +set(CMAKE_INSTALL_MESSAGE LAZY) +set(CMAKE_INSTALL_RPATH "\$ORIGIN") + +set(CMAKE_C_FLAGS "-O2") +set(CMAKE_CXX_FLAGS "-O2 -fpermissive") + +if(NOT CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}) +endif() + +include(GNUInstallDirs) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) + +#--------------------------------------------------- +option(IPCL_TEST "Enable testing" ON) +option(IPCL_BENCHMARK "Enable benchmark" ON) +option(IPCL_TEST_OMP "Enable OpenMP testing" ON) +option(IPCL_DOCS "Enable document building" OFF) +# TODO(skmono): Fix static library build +option(IPCL_SHARED "Build shared library" ON) + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(IPCL_DEBUG ON) +else() + set(IPCL_DEBUG OFF) +endif() + +set(IPCL_CMAKE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/ipcl") + +message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") +message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}") +message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}") +message(STATUS "IPCL_TEST: ${IPCL_TEST}") +message(STATUS "IPCL_TEST_OMP: ${IPCL_TEST_OMP}") +message(STATUS "IPCL_BENCHMARK: ${IPCL_BENCHMARK}") +message(STATUS "IPCL_DOCS: ${IPCL_DOCS}") +message(STATUS "IPCL_SHARED: ${IPCL_SHARED}") +message(STATUS "CMAKE_INSTALL_LIBDIR: ${CMAKE_INSTALL_LIBDIR}") +message(STATUS "CMAKE_INSTALL_INCLUDEDIR: ${CMAKE_INSTALL_INCLUDEDIR}") +message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") + +set(IPCL_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(IPCL_SRC_DIR ${IPCL_ROOT_DIR}/ipcl) +set(IPCL_INC_DIR ${IPCL_SRC_DIR}/include) + +set(IPCL_FORWARD_CMAKE_ARGS + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} + -DCMAKE_CXX_STANDARD_REQUIRED=${CMAKE_CXX_STANDARD_REQUIRED} + -DCMAKE_CXX_EXTENSIONS=${CMAKE_CXX_EXTENSIONS} + -DCMAKE_EXPORT_COMPILE_COMMANDS=${CMAKE_EXPORT_COMPILE_COMMANDS} + -DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE} + -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} +) + +# find package for OpenSSL and Threads +set(OPENSSL_USE_STATIC_LIBS TRUE) +find_package(Threads REQUIRED) +find_package(OpenSSL REQUIRED) +message(STATUS "OpenSSL Found: ${OPENSSL_FOUND}") +# External dependencies +set(CMAKE_THREAD_PREFER_PTHREAD ON) +set(THREADS_PREFER_PTHREAD_FLAG ON) + +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ipcl) +include(ipcl-util) + +include(cmake/ippcrypto.cmake) + +if(IPCL_TEST OR IPCL_OMP_TEST) + include(cmake/gtest.cmake) +endif() +if(IPCL_BENCHMARK) + include(cmake/gbenchmark.cmake) +endif() + +add_subdirectory(ipcl) + +if(IPCL_TEST) + add_subdirectory(test) + add_custom_target(unittest COMMAND $ DEPENDS unit-test) + if(IPCL_TEST_OMP) + add_custom_target(unittest_omp COMMAND $ DEPENDS unit-test_omp) + endif() +endif() +unset(IPCL_TEST CACHE) + +if(IPCL_BENCHMARK) + add_subdirectory(benchmark) + add_custom_target(benchmark COMMAND $ DEPENDS bench_ipcl) +endif() + +if(IPCL_DOCS) + add_subdirectory(docs) +endif() + +unset(IPCL_BENCHMARK CACHE) diff --git a/README.md b/README.md new file mode 100644 index 0000000..8688533 --- /dev/null +++ b/README.md @@ -0,0 +1,85 @@ +# Intel Paillier Cryptosystem Library +Intel Paillier Cryptosystem Library is an open-source library which provides accelerated performance of a partial homomorphic encryption (HE), named Paillier cryptosystem, by utilizing IntelĀ® [IPP-Crypto](https://github.com/intel/ipp-crypto) technologies on Intel CPUs supporting the AVX512IFMA instructions. The library is written in modern standard C++ and provides the essential API for the Paillier cryptosystem scheme. + +## Contents +- [Paillier Homomorphic Encryption library with Intel ipp-crypto](#paillier-homomorphic-encryption-library-with-intel-ipp-crypto) + - [Contents](#content) + - [Introduction](#introduction) + - [Building the Library](#building-the-library) + - [Dependencies](#dependencies) + - [Instructions](#instructions) + - [Testing and Benchmarking](#testing-and-benchmarking) +- [Contributors](#contributors) + +## Introduction +adding intro + +## Building the Library +### Dependencies +The library has been tested on Ubuntu 18.04 and 20.04 + +Must have dependencies include: +``` +cmake >=3.15.1 +git +pthread +g++ >= 7.0 or clang >= 10.0 +python >= 3.8 +``` + +The following libraries are also required, +``` +nasm>=2.15 +OpenSSL +``` +which can be installed by: +```bash +sudo apt update +sudo apt install libssl-dev +``` +For ```nasm```, please refer to the [Netwide Assembler webpage](https://nasm.us/) for installation details. + +### Instructions +The library can be built using the following commands: +```bash +export IPCL_DIR=$(pwd) +cmake -S . -B build -DCMAKE_BUILD_TYPE=Release +cmake --build build -j +``` + +It is possible to pass additional options to enable more features. The following table contains the current CMake options, default values are in bold. + +| CMake options | Values | Default | Comments | +|-------------------------|-----------|---------|------------------------------| +|`IPCL_TEST` | ON/OFF | ON | unit-test | +|`IPCL_TEST_OMP` | ON/OFF | ON | unit-test w/ OpenMP | +|`IPCL_BENCHMARK` | ON/OFF | ON | benchmark | +|`IPCL_DOCS` | ON/OFF | OFF | build doxygen documentation | +|`IPCL_SHARED` | ON/OFF | ON | build shared library | + +## Testing and Benchmarking +To run a set of unit tests via [Googletest](https://github.com/google/googletest), configure and build library with `-DIPCL_TEST=ON` (see [Instructions](#instructions)). +Then, run +```bash +cmake --build build --target unittest +``` +For OpenMP testing, configure and build with `-DIPCL_TEST_OMP=ON`, and run +```bash +cmake --build build --target unittest_omp +``` + +For running benchmark via [Google Benchmark](https://github.com/google/benchmark), configure and build library with `-DIPCL_BENCHMARK=ON` (see [Instructions](#instructions)). +Then, run +```bash +cmake --build build --target benchmark +``` +OpenMP benchmarks will automatically be applied if `-DIPCL_TEST_OMP=ON` is set. + +The unit-test executable itself is located at `build/test/unit-test`, `build/test/unit-test_omp` and `build/benchmark/bench_ipp_paillier`. + +# Contributors +Main contributors to this project, sorted by alphabetical order of last name are: + - [Xiaoran Fang](https://github.com/fangxiaoran) + - [Hamish Hunt](https://github.com/hamishun) + - [Sejun Kim](https://github.com/skmono) (lead) + - [Bin Wang](https://github.com/bwang30) diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt new file mode 100644 index 0000000..fc96711 --- /dev/null +++ b/benchmark/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright (C) 2021-2022 Intel Corporation +set(SRC main.cpp + bench_cryptography.cpp + bench_ops.cpp) + +add_executable(bench_ipcl ${SRC}) +target_include_directories(bench_ipcl PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${IPP_PAILLIER_INC_DIR} +) + +target_link_libraries(bench_ipcl PRIVATE + ipcl libgbenchmark Threads::Threads +) + +if(IPP_PAILLIER_TEST_OMP) + find_package(OpenMP REQUIRED) + add_compile_definitions(BENCHMARK_OMP) + target_link_libraries(bench_ipcl PRIVATE OpenMP::OpenMP_CXX) +endif() diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp new file mode 100644 index 0000000..5adb7ed --- /dev/null +++ b/benchmark/bench_cryptography.cpp @@ -0,0 +1,293 @@ +// Copyright (C) 2021-2022 Intel Corporation + +#include + +#include +#ifdef BENCHMARK_OMP +#include +#endif + +#include "ipcl/key_pair.hpp" + +static void BM_KeyGen(benchmark::State& state) { + int64_t n_length = state.range(0); + for (auto _ : state) { + keyPair key = generateKeypair(n_length, true); + } +} +BENCHMARK(BM_KeyGen)->Unit(benchmark::kMicrosecond)->Args({1024})->Args({2048}); + +static void BM_Encrypt(benchmark::State& state) { + size_t dsize = state.range(0); + keyPair key = generateKeypair(2048, true); + + BigNumber** pt = new BigNumber*[dsize]; + BigNumber** ct = new BigNumber*[dsize]; + + for (size_t i = 0; i < dsize; ++i) { + pt[i] = new BigNumber[8]; + ct[i] = new BigNumber[8]; + pt[i][0] = BigNumber((unsigned int)i); + } + + for (auto _ : state) { + for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); + } + + for (size_t i = 0; i < dsize; ++i) { + delete[] pt[i]; + delete[] ct[i]; + } + + delete[] pt; + delete[] ct; +} + +BENCHMARK(BM_Encrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); + +static void BM_Encrypt_buff8(benchmark::State& state) { + size_t dsize = state.range(0); + keyPair key = generateKeypair(2048, true); + + BigNumber** pt = new BigNumber*[dsize / 8]; + BigNumber** ct = new BigNumber*[dsize / 8]; + + for (size_t i = 0; i < dsize / 8; ++i) { + pt[i] = new BigNumber[8]; + ct[i] = new BigNumber[8]; + for (size_t j = 0; j < 8; ++j) + pt[i][j] = BigNumber((unsigned int)(i * 8 + j)); + } + + for (auto _ : state) { + for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); + } + + for (size_t i = 0; i < dsize / 8; ++i) { + delete[] pt[i]; + delete[] ct[i]; + } + delete[] pt; + delete[] ct; +} + +BENCHMARK(BM_Encrypt_buff8) + ->Unit(benchmark::kMicrosecond) + ->Args({16}) + ->Args({64}); + +static void BM_Decrypt(benchmark::State& state) { + size_t dsize = state.range(0); + keyPair key = generateKeypair(2048, true); + + BigNumber** pt = new BigNumber*[dsize]; + BigNumber** ct = new BigNumber*[dsize]; + BigNumber** de_ct = new BigNumber*[dsize]; + for (size_t i = 0; i < dsize; ++i) { + pt[i] = new BigNumber[8]; + ct[i] = new BigNumber[8]; + de_ct[i] = new BigNumber[8]; + pt[i][0] = BigNumber((unsigned int)i); + } + + for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); + + for (auto _ : state) { + for (size_t i = 0; i < dsize; ++i) { + key.priv_key->decrypt(de_ct[i], ct[i]); + } + } + + for (size_t i = 0; i < dsize; ++i) { + delete[] pt[i]; + delete[] ct[i]; + delete[] de_ct[i]; + } + + delete[] pt; + delete[] ct; + delete[] de_ct; +} + +BENCHMARK(BM_Decrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); + +static void BM_Decrypt_buff8(benchmark::State& state) { + size_t dsize = state.range(0); + keyPair key = generateKeypair(2048, true); + + BigNumber** pt = new BigNumber*[dsize / 8]; + BigNumber** ct = new BigNumber*[dsize / 8]; + BigNumber** de_ct = new BigNumber*[dsize / 8]; + + for (size_t i = 0; i < dsize / 8; ++i) { + pt[i] = new BigNumber[8]; + ct[i] = new BigNumber[8]; + de_ct[i] = new BigNumber[8]; + for (size_t j = 0; j < 8; ++j) + pt[i][j] = BigNumber((unsigned int)(i * 8 + j)); + } + + for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); + + for (auto _ : state) { + for (size_t i = 0; i < dsize / 8; ++i) + key.priv_key->decrypt(de_ct[i], ct[i]); + } + + for (size_t i = 0; i < dsize / 8; ++i) { + delete[] pt[i]; + delete[] ct[i]; + delete[] de_ct[i]; + } + delete[] pt; + delete[] ct; + delete[] de_ct; +} + +BENCHMARK(BM_Decrypt_buff8) + ->Unit(benchmark::kMicrosecond) + ->Args({16}) + ->Args({64}); + +#ifdef BENCHMARK_OMP +static void BM_Encrypt_OMP(benchmark::State& state) { + size_t dsize = state.range(0); + keyPair key = generateKeypair(2048, true); + + BigNumber** pt = new BigNumber*[dsize]; + BigNumber** ct = new BigNumber*[dsize]; + + for (size_t i = 0; i < dsize; ++i) { + pt[i] = new BigNumber[8]; + ct[i] = new BigNumber[8]; + pt[i][0] = BigNumber((unsigned int)i); + } + + for (auto _ : state) { +#pragma omp parallel for + for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); + } + + for (size_t i = 0; i < dsize; ++i) { + delete[] pt[i]; + delete[] ct[i]; + } + + delete[] pt; + delete[] ct; +} +BENCHMARK(BM_Encrypt_OMP) + ->Unit(benchmark::kMicrosecond) + ->Args({16}) + ->Args({64}); + +static void BM_Encrypt_buff8_OMP(benchmark::State& state) { + size_t dsize = state.range(0); + keyPair key = generateKeypair(2048, true); + + BigNumber** pt = new BigNumber*[dsize / 8]; + BigNumber** ct = new BigNumber*[dsize / 8]; + + for (size_t i = 0; i < dsize / 8; ++i) { + pt[i] = new BigNumber[8]; + ct[i] = new BigNumber[8]; + for (size_t j = 0; j < 8; ++j) + pt[i][j] = BigNumber((unsigned int)(i * 8 + j)); + } + + for (auto _ : state) { +#pragma omp parallel for + for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); + } + + for (size_t i = 0; i < dsize / 8; ++i) { + delete[] pt[i]; + delete[] ct[i]; + } + delete[] pt; + delete[] ct; +} + +BENCHMARK(BM_Encrypt_buff8_OMP) + ->Unit(benchmark::kMicrosecond) + ->Args({16}) + ->Args({64}); + +static void BM_Decrypt_OMP(benchmark::State& state) { + size_t dsize = state.range(0); + keyPair key = generateKeypair(2048, true); + + BigNumber** pt = new BigNumber*[dsize]; + BigNumber** ct = new BigNumber*[dsize]; + BigNumber** de_ct = new BigNumber*[dsize]; + for (size_t i = 0; i < dsize; ++i) { + pt[i] = new BigNumber[8]; + ct[i] = new BigNumber[8]; + de_ct[i] = new BigNumber[8]; + pt[i][0] = BigNumber((unsigned int)i); + } + + for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); + + for (auto _ : state) { +#pragma omp parallel for + for (size_t i = 0; i < dsize; ++i) { + key.priv_key->decrypt(de_ct[i], ct[i]); + } + } + + for (size_t i = 0; i < dsize; ++i) { + delete[] pt[i]; + delete[] ct[i]; + delete[] de_ct[i]; + } + + delete[] pt; + delete[] ct; + delete[] de_ct; +} + +BENCHMARK(BM_Decrypt_OMP) + ->Unit(benchmark::kMicrosecond) + ->Args({16}) + ->Args({64}); + +static void BM_Decrypt_buff8_OMP(benchmark::State& state) { + size_t dsize = state.range(0); + keyPair key = generateKeypair(2048, true); + + BigNumber** pt = new BigNumber*[dsize / 8]; + BigNumber** ct = new BigNumber*[dsize / 8]; + BigNumber** de_ct = new BigNumber*[dsize / 8]; + + for (size_t i = 0; i < dsize / 8; ++i) { + pt[i] = new BigNumber[8]; + ct[i] = new BigNumber[8]; + de_ct[i] = new BigNumber[8]; + for (size_t j = 0; j < 8; ++j) + pt[i][j] = BigNumber((unsigned int)(i * 8 + j)); + } + + for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); + + for (auto _ : state) { +#pragma omp parallel for + for (size_t i = 0; i < dsize / 8; ++i) + key.priv_key->decrypt(de_ct[i], ct[i]); + } + + for (size_t i = 0; i < dsize / 8; ++i) { + delete[] pt[i]; + delete[] ct[i]; + delete[] de_ct[i]; + } + delete[] pt; + delete[] ct; + delete[] de_ct; +} + +BENCHMARK(BM_Decrypt_buff8_OMP) + ->Unit(benchmark::kMicrosecond) + ->Args({16}) + ->Args({64}); +#endif diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp new file mode 100644 index 0000000..4964025 --- /dev/null +++ b/benchmark/bench_ops.cpp @@ -0,0 +1,545 @@ +// Copyright (C) 2021-2022 Intel Corporation + +#include + +#include +#ifdef BENCHMARK_OMP +#include +#endif +#include + +#include "ipcl/key_pair.hpp" +#include "ipcl/paillier_ops.hpp" + +static void BM_Add_CTCT(benchmark::State& state) { + size_t dsize = state.range(0); + keyPair key = generateKeypair(2048, true); + + BigNumber** a = new BigNumber*[dsize]; + BigNumber** b = new BigNumber*[dsize]; + BigNumber** ct_a = new BigNumber*[dsize]; + BigNumber** ct_b = new BigNumber*[dsize]; + + for (size_t i = 0; i < dsize; ++i) { + a[i] = new BigNumber[8]; + a[i][0] = BigNumber((unsigned int)i); + ct_a[i] = new BigNumber[8]; + key.pub_key->encrypt(ct_a[i], a[i]); + + b[i] = new BigNumber[8]; + b[i][0] = BigNumber((unsigned int)i); + ct_b[i] = new BigNumber[8]; + key.pub_key->encrypt(ct_b[i], b[i]); + } + + for (auto _ : state) { + for (size_t i = 0; i < dsize; ++i) { + PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); + PaillierEncryptedNumber sum = pen_a + pen_b; + } + } + + for (size_t i = 0; i < dsize; ++i) { + delete[] a[i]; + delete[] b[i]; + delete[] ct_a[i]; + delete[] ct_b[i]; + } + + delete[] a; + delete[] ct_a; + delete[] b; + delete[] ct_b; +} + +BENCHMARK(BM_Add_CTCT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); + +static void BM_Add_CTCT_buff8(benchmark::State& state) { + size_t dsize = state.range(0); + keyPair key = generateKeypair(2048, true); + + BigNumber** a = new BigNumber*[dsize / 8]; + BigNumber** b = new BigNumber*[dsize / 8]; + BigNumber** ct_a = new BigNumber*[dsize / 8]; + BigNumber** ct_b = new BigNumber*[dsize / 8]; + + for (size_t i = 0; i < dsize / 8; ++i) { + a[i] = new BigNumber[8]; + ct_a[i] = new BigNumber[8]; + + b[i] = new BigNumber[8]; + ct_b[i] = new BigNumber[8]; + for (size_t j = 0; j < 8; ++j) { + a[i][j] = BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = BigNumber((unsigned int)(i * 8 + j)); + } + + key.pub_key->encrypt(ct_a[i], a[i]); + key.pub_key->encrypt(ct_b[i], b[i]); + } + + for (auto _ : state) { + for (size_t i = 0; i < dsize / 8; ++i) { + PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); + PaillierEncryptedNumber sum = pen_a + pen_b; + } + } + + for (size_t i = 0; i < dsize / 8; ++i) { + delete[] a[i]; + delete[] b[i]; + delete[] ct_a[i]; + delete[] ct_b[i]; + } + + delete[] a; + delete[] ct_a; + delete[] b; + delete[] ct_b; +} + +BENCHMARK(BM_Add_CTCT_buff8) + ->Unit(benchmark::kMicrosecond) + ->Args({16}) + ->Args({64}); + +static void BM_Add_CTPT(benchmark::State& state) { + size_t dsize = state.range(0); + keyPair key = generateKeypair(2048, true); + + BigNumber** a = new BigNumber*[dsize]; + BigNumber** ct_a = new BigNumber*[dsize]; + BigNumber** b = new BigNumber*[dsize]; + + for (size_t i = 0; i < dsize; ++i) { + a[i] = new BigNumber[8]; + a[i][0] = BigNumber((unsigned int)i); + ct_a[i] = new BigNumber[8]; + b[i] = new BigNumber[8]; + b[i][0] = BigNumber((unsigned int)i); + key.pub_key->encrypt(ct_a[i], a[i]); + } + + for (auto _ : state) { + for (size_t i = 0; i < dsize; ++i) { + PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + PaillierEncryptedNumber sum = pen_a + b[i]; + } + } + + for (size_t i = 0; i < dsize; ++i) { + delete[] a[i]; + delete[] b[i]; + delete[] ct_a[i]; + } + + delete[] a; + delete[] ct_a; + delete[] b; +} + +BENCHMARK(BM_Add_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); + +static void BM_Add_CTPT_buff8(benchmark::State& state) { + size_t dsize = state.range(0); + keyPair key = generateKeypair(2048, true); + + BigNumber** a = new BigNumber*[dsize / 8]; + BigNumber** b = new BigNumber*[dsize / 8]; + BigNumber** ct_a = new BigNumber*[dsize / 8]; + + for (size_t i = 0; i < dsize / 8; ++i) { + a[i] = new BigNumber[8]; + ct_a[i] = new BigNumber[8]; + + b[i] = new BigNumber[8]; + for (size_t j = 0; j < 8; ++j) { + a[i][j] = BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = BigNumber((unsigned int)(i * 8 + j)); + } + + key.pub_key->encrypt(ct_a[i], a[i]); + } + + for (auto _ : state) { + for (size_t i = 0; i < dsize / 8; ++i) { + PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + PaillierEncryptedNumber sum = pen_a + b[i]; + } + } + + for (size_t i = 0; i < dsize / 8; ++i) { + delete[] a[i]; + delete[] b[i]; + delete[] ct_a[i]; + } + + delete[] a; + delete[] ct_a; + delete[] b; +} + +BENCHMARK(BM_Add_CTPT_buff8) + ->Unit(benchmark::kMicrosecond) + ->Args({16}) + ->Args({64}); + +static void BM_Mul_CTPT(benchmark::State& state) { + size_t dsize = state.range(0); + keyPair key = generateKeypair(2048, true); + + BigNumber** a = new BigNumber*[dsize]; + BigNumber** ct_a = new BigNumber*[dsize]; + BigNumber** b = new BigNumber*[dsize]; + + for (size_t i = 0; i < dsize; ++i) { + a[i] = new BigNumber[8]; + a[i][0] = BigNumber((unsigned int)i); + ct_a[i] = new BigNumber[8]; + b[i] = new BigNumber[8]; + b[i][0] = BigNumber((unsigned int)i); + key.pub_key->encrypt(ct_a[i], a[i]); + } + + for (auto _ : state) { + for (size_t i = 0; i < dsize; ++i) { + PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + PaillierEncryptedNumber pen_b(key.pub_key, b[i]); + PaillierEncryptedNumber sum = pen_a * pen_b; + } + } + + for (size_t i = 0; i < dsize; ++i) { + delete[] a[i]; + delete[] b[i]; + delete[] ct_a[i]; + } + + delete[] a; + delete[] ct_a; + delete[] b; +} + +BENCHMARK(BM_Mul_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); + +static void BM_Mul_CTPT_buff8(benchmark::State& state) { + size_t dsize = state.range(0); + keyPair key = generateKeypair(2048, true); + + BigNumber** a = new BigNumber*[dsize / 8]; + BigNumber** b = new BigNumber*[dsize / 8]; + BigNumber** ct_a = new BigNumber*[dsize / 8]; + + for (size_t i = 0; i < dsize / 8; ++i) { + a[i] = new BigNumber[8]; + ct_a[i] = new BigNumber[8]; + + b[i] = new BigNumber[8]; + for (size_t j = 0; j < 8; ++j) { + a[i][j] = BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = BigNumber((unsigned int)(i * 8 + j)); + } + + key.pub_key->encrypt(ct_a[i], a[i]); + } + + for (auto _ : state) { + for (size_t i = 0; i < dsize / 8; ++i) { + PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + PaillierEncryptedNumber pen_b(key.pub_key, b[i]); + PaillierEncryptedNumber sum = pen_a * pen_b; + } + } + + for (size_t i = 0; i < dsize / 8; ++i) { + delete[] a[i]; + delete[] b[i]; + delete[] ct_a[i]; + } + + delete[] a; + delete[] ct_a; + delete[] b; +} + +BENCHMARK(BM_Mul_CTPT_buff8) + ->Unit(benchmark::kMicrosecond) + ->Args({16}) + ->Args({64}); + +#ifdef BENCHMARK_OMP +static void BM_Add_CTCT_OMP(benchmark::State& state) { + size_t dsize = state.range(0); + keyPair key = generateKeypair(2048, true); + + BigNumber** a = new BigNumber*[dsize]; + BigNumber** b = new BigNumber*[dsize]; + BigNumber** ct_a = new BigNumber*[dsize]; + BigNumber** ct_b = new BigNumber*[dsize]; + + for (size_t i = 0; i < dsize; ++i) { + a[i] = new BigNumber[8]; + a[i][0] = BigNumber((unsigned int)i); + ct_a[i] = new BigNumber[8]; + key.pub_key->encrypt(ct_a[i], a[i]); + + b[i] = new BigNumber[8]; + b[i][0] = BigNumber((unsigned int)i); + ct_b[i] = new BigNumber[8]; + key.pub_key->encrypt(ct_b[i], b[i]); + } + + for (auto _ : state) { +#pragma omp parallel for + for (size_t i = 0; i < dsize; ++i) { + PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); + PaillierEncryptedNumber sum = pen_a + pen_b; + } + } + + for (size_t i = 0; i < dsize; ++i) { + delete[] a[i]; + delete[] b[i]; + delete[] ct_a[i]; + delete[] ct_b[i]; + } + + delete[] a; + delete[] ct_a; + delete[] b; + delete[] ct_b; +} + +BENCHMARK(BM_Add_CTCT_OMP) + ->Unit(benchmark::kMicrosecond) + ->Args({16}) + ->Args({64}); + +static void BM_Add_CTCT_buff8_OMP(benchmark::State& state) { + size_t dsize = state.range(0); + keyPair key = generateKeypair(2048, true); + + BigNumber** a = new BigNumber*[dsize / 8]; + BigNumber** b = new BigNumber*[dsize / 8]; + BigNumber** ct_a = new BigNumber*[dsize / 8]; + BigNumber** ct_b = new BigNumber*[dsize / 8]; + + for (size_t i = 0; i < dsize / 8; ++i) { + a[i] = new BigNumber[8]; + ct_a[i] = new BigNumber[8]; + + b[i] = new BigNumber[8]; + ct_b[i] = new BigNumber[8]; + for (size_t j = 0; j < 8; ++j) { + a[i][j] = BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = BigNumber((unsigned int)(i * 8 + j)); + } + + key.pub_key->encrypt(ct_a[i], a[i]); + key.pub_key->encrypt(ct_b[i], b[i]); + } + + for (auto _ : state) { +#pragma omp parallel for + for (size_t i = 0; i < dsize / 8; ++i) { + PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); + PaillierEncryptedNumber sum = pen_a + pen_b; + } + } + + for (size_t i = 0; i < dsize / 8; ++i) { + delete[] a[i]; + delete[] b[i]; + delete[] ct_a[i]; + delete[] ct_b[i]; + } + + delete[] a; + delete[] ct_a; + delete[] b; + delete[] ct_b; +} + +BENCHMARK(BM_Add_CTCT_buff8_OMP) + ->Unit(benchmark::kMicrosecond) + ->Args({16}) + ->Args({64}); + +static void BM_Add_CTPT_OMP(benchmark::State& state) { + size_t dsize = state.range(0); + keyPair key = generateKeypair(2048, true); + + BigNumber** a = new BigNumber*[dsize]; + BigNumber** ct_a = new BigNumber*[dsize]; + BigNumber** b = new BigNumber*[dsize]; + + for (size_t i = 0; i < dsize; ++i) { + a[i] = new BigNumber[8]; + a[i][0] = BigNumber((unsigned int)i); + ct_a[i] = new BigNumber[8]; + b[i] = new BigNumber[8]; + b[i][0] = BigNumber((unsigned int)i); + key.pub_key->encrypt(ct_a[i], a[i]); + } + + for (auto _ : state) { +#pragma omp parallel for + for (size_t i = 0; i < dsize; ++i) { + PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + PaillierEncryptedNumber sum = pen_a + b[i]; + } + } + + for (size_t i = 0; i < dsize; ++i) { + delete[] a[i]; + delete[] b[i]; + delete[] ct_a[i]; + } + + delete[] a; + delete[] ct_a; + delete[] b; +} + +BENCHMARK(BM_Add_CTPT_OMP) + ->Unit(benchmark::kMicrosecond) + ->Args({16}) + ->Args({64}); + +static void BM_Add_CTPT_buff8_OMP(benchmark::State& state) { + size_t dsize = state.range(0); + keyPair key = generateKeypair(2048, true); + + BigNumber** a = new BigNumber*[dsize / 8]; + BigNumber** b = new BigNumber*[dsize / 8]; + BigNumber** ct_a = new BigNumber*[dsize / 8]; + + for (size_t i = 0; i < dsize / 8; ++i) { + a[i] = new BigNumber[8]; + ct_a[i] = new BigNumber[8]; + + b[i] = new BigNumber[8]; + for (size_t j = 0; j < 8; ++j) { + a[i][j] = BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = BigNumber((unsigned int)(i * 8 + j)); + } + + key.pub_key->encrypt(ct_a[i], a[i]); + } + + for (auto _ : state) { +#pragma omp parallel for + for (size_t i = 0; i < dsize / 8; ++i) { + PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + PaillierEncryptedNumber sum = pen_a + b[i]; + } + } + + for (size_t i = 0; i < dsize / 8; ++i) { + delete[] a[i]; + delete[] b[i]; + delete[] ct_a[i]; + } + + delete[] a; + delete[] ct_a; + delete[] b; +} + +BENCHMARK(BM_Add_CTPT_buff8_OMP) + ->Unit(benchmark::kMicrosecond) + ->Args({16}) + ->Args({64}); + +static void BM_Mul_CTPT_OMP(benchmark::State& state) { + size_t dsize = state.range(0); + keyPair key = generateKeypair(2048, true); + + BigNumber** a = new BigNumber*[dsize]; + BigNumber** ct_a = new BigNumber*[dsize]; + BigNumber** b = new BigNumber*[dsize]; + + for (size_t i = 0; i < dsize; ++i) { + a[i] = new BigNumber[8]; + a[i][0] = BigNumber((unsigned int)i); + ct_a[i] = new BigNumber[8]; + b[i] = new BigNumber[8]; + b[i][0] = BigNumber((unsigned int)i); + key.pub_key->encrypt(ct_a[i], a[i]); + } + + for (auto _ : state) { +#pragma omp parallel for + for (size_t i = 0; i < dsize; ++i) { + PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + PaillierEncryptedNumber pen_b(key.pub_key, b[i]); + PaillierEncryptedNumber sum = pen_a * pen_b; + } + } + + for (size_t i = 0; i < dsize; ++i) { + delete[] a[i]; + delete[] b[i]; + delete[] ct_a[i]; + } + + delete[] a; + delete[] ct_a; + delete[] b; +} + +BENCHMARK(BM_Mul_CTPT_OMP) + ->Unit(benchmark::kMicrosecond) + ->Args({16}) + ->Args({64}); + +static void BM_Mul_CTPT_buff8_OMP(benchmark::State& state) { + size_t dsize = state.range(0); + keyPair key = generateKeypair(2048, true); + + BigNumber** a = new BigNumber*[dsize / 8]; + BigNumber** b = new BigNumber*[dsize / 8]; + BigNumber** ct_a = new BigNumber*[dsize / 8]; + + for (size_t i = 0; i < dsize / 8; ++i) { + a[i] = new BigNumber[8]; + ct_a[i] = new BigNumber[8]; + + b[i] = new BigNumber[8]; + for (size_t j = 0; j < 8; ++j) { + a[i][j] = BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = BigNumber((unsigned int)(i * 8 + j)); + } + + key.pub_key->encrypt(ct_a[i], a[i]); + } + + for (auto _ : state) { +#pragma omp parallel for + for (size_t i = 0; i < dsize / 8; ++i) { + PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + PaillierEncryptedNumber pen_b(key.pub_key, b[i]); + PaillierEncryptedNumber sum = pen_a * pen_b; + } + } + + for (size_t i = 0; i < dsize / 8; ++i) { + delete[] a[i]; + delete[] b[i]; + delete[] ct_a[i]; + } + + delete[] a; + delete[] ct_a; + delete[] b; +} + +BENCHMARK(BM_Mul_CTPT_buff8_OMP) + ->Unit(benchmark::kMicrosecond) + ->Args({16}) + ->Args({64}); +#endif diff --git a/benchmark/main.cpp b/benchmark/main.cpp new file mode 100644 index 0000000..4e746ac --- /dev/null +++ b/benchmark/main.cpp @@ -0,0 +1,10 @@ +// Copyright (C) 2021-2022 Intel Corporation + +#include + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + benchmark::RunSpecifiedBenchmarks(); + + return 0; +} diff --git a/cmake/gbenchmark.cmake b/cmake/gbenchmark.cmake new file mode 100644 index 0000000..d0fefb0 --- /dev/null +++ b/cmake/gbenchmark.cmake @@ -0,0 +1,37 @@ +# Copyright (C) 2021-2022 Intel Corporation + +include(ExternalProject) + +set(GBENCHMARK_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_gbenchmark) + +set(GBENCHMARK_SRC_DIR ${GBENCHMARK_PREFIX}/src/ext_gbenchmark/) +set(GBENCHMARK_BUILD_DIR ${GBENCHMARK_PREFIX}/src/ext_gbenchmark-build/) +set(GBENCHMARK_REPO_URL https://github.com/google/benchmark.git) +set(GBENCHMARK_GIT_TAG v1.5.6) +set(GBENCHMARK_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS} -fPIC") + +set(GBENCHMARK_PATHS ${GBENCHMARK_SRC_DIR} ${GBENCHMARK_BUILD_DIR}/src/libbenchmark.a) + +ExternalProject_Add( + ext_gbenchmark + GIT_REPOSITORY ${GBENCHMARK_REPO_URL} + GIT_TAG ${GBENCHMARK_GIT_TAG} + PREFIX ${GBENCHMARK_PREFIX} + CMAKE_ARGS ${GBENCHMARK_CXX_FLAGS} + -DCMAKE_INSTALL_PREFIX=${GBENCHMARK_PREFIX} + -DBENCHMARK_ENABLE_GTEST_TESTS=OFF + -DBENCHMARK_ENABLE_TESTING=OFF + -DCMAKE_BUILD_TYPE=Release + BUILD_BYPRODUCTS ${GBENCHMARK_PATHS} + # Skip updates + UPDATE_COMMAND "" +) + +add_library(libgbenchmark INTERFACE) +add_dependencies(libgbenchmark ext_gbenchmark) + +ExternalProject_Get_Property(ext_gbenchmark SOURCE_DIR BINARY_DIR) +target_link_libraries(libgbenchmark INTERFACE ${GBENCHMARK_PREFIX}/lib/libbenchmark.a) + +target_include_directories(libgbenchmark SYSTEM + INTERFACE ${GBENCHMARK_PREFIX}/include) diff --git a/cmake/gtest.cmake b/cmake/gtest.cmake new file mode 100644 index 0000000..c6e359f --- /dev/null +++ b/cmake/gtest.cmake @@ -0,0 +1,27 @@ +# Copyright (C) 2021-2022 Intel Corporation + +include(ExternalProject) + +set(GTEST_GIT_REPO_URL https://github.com/google/googletest.git) +set(GTEST_GIT_LABEL release-1.10.0) +set(GTEST_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS} -fPIC") + +ExternalProject_Add( + ext_gtest + PREFIX ext_gtest + GIT_REPOSITORY ${GTEST_GIT_REPO_URL} + GIT_TAG ${GTEST_GIT_LABEL} + CMAKE_ARGS ${GTEST_CXX_FLAGS} -DCMAKE_BUILD_TYPE=Release + INSTALL_COMMAND "" + UPDATE_COMMAND "" + EXCLUDE_FROM_ALL TRUE) + +ExternalProject_Get_Property(ext_gtest SOURCE_DIR BINARY_DIR) + +add_library(libgtest INTERFACE) +add_dependencies(libgtest ext_gtest) + +target_include_directories(libgtest SYSTEM + INTERFACE ${SOURCE_DIR}/googletest/include) +target_link_libraries(libgtest + INTERFACE ${BINARY_DIR}/lib/libgtest.a) diff --git a/cmake/ipcl/IPCLConfig.cmake.in b/cmake/ipcl/IPCLConfig.cmake.in new file mode 100644 index 0000000..510eb69 --- /dev/null +++ b/cmake/ipcl/IPCLConfig.cmake.in @@ -0,0 +1,21 @@ +# Copyright (C) 2021-2022 Intel Corporation + +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) + +include(${CMAKE_CURRENT_LIST_DIR}/ipclTargets.cmake) + +if(TARGET IPCL::ipcl) + set(IPCL_FOUND TRUE) + message(STATUS "Intel Paillier Cryptosystem Library found") +else() + message(STATUS "Intel Paillier Cryptosystem Library not found") +endif() + +set(IPCL_VERSION "@IPCL_VERSION") +set(IPCL_VERSION_MAJOR "@IPCL_VERSION_MAJOR") +set(IPCL_VERSION_MINOR "@IPCL_VERSION") +set(IPCL_VERSION_PATCH "@IPCL_VERSION") + +set(IPCL_DEBUG "@IPCL_DEBUG") diff --git a/cmake/ipcl/ipcl-util.cmake b/cmake/ipcl/ipcl-util.cmake new file mode 100644 index 0000000..c2361ff --- /dev/null +++ b/cmake/ipcl/ipcl-util.cmake @@ -0,0 +1,112 @@ +function(ipcl_check_compile_flag SOURCE_FILE OUTPUT_FLAG) + if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + set(NATIVE_COMPILE_DEFINITIONS "/arch:AVX512") + else() + set(NATIVE_COMPILE_DEFINITIONS "-march=native") + endif() + + try_run(CAN_RUN CAN_COMPILE ${CMAKE_BINARY_DIR} + "${SOURCE_FILE}" + COMPILE_DEFINITIONS ${NATIVE_COMPILE_DEFINITIONS} + OUTPUT_VARIABLE TRY_COMPILE_OUTPUT + ) + # Uncomment below to debug + # message("TRY_COMPILE_OUTPUT ${TRY_COMPILE_OUTPUT}") + if (CAN_COMPILE AND CAN_RUN STREQUAL 0) + message(STATUS "Setting ${OUTPUT_FLAG}") + add_definitions(-D${OUTPUT_FLAG}) + set(${OUTPUT_FLAG} 1 PARENT_SCOPE) + else() + message(STATUS "Compile flag not found: ${OUTPUT_FLAG}") + endif() +endfunction() + +# Checks the supported compiler versions +function(ipcl_check_compiler_version) + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0) + message(FATAL_ERROR "IPCL requires gcc version >= 7.0") + endif() + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0) + message(WARN "gcc version should be at least 8.0 for best performance on processors with AVX512IFMA support") + endif() + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) + message(FATAL_ERROR "IPCL requires clang++ >= 5.0") + endif() + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) + message(WARNING "Clang version should be at least 6.0 for best performance on processors with AVX512IFMA support") + endif() + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19) + message(FATAL_ERROR "IPCL requires MSVC >= 19") + endif() + endif() +endfunction() + +# If the input variable is set, stores its value in a _CACHE variable +function(ipcl_cache_variable variable) + if (DEFINED ${variable}) + set(${variable}_CACHE ${${variable}} PARENT_SCOPE) + endif() +endfunction() + +# If the input variable is cached, restores its value from the cache +function(ipcl_uncache_variable variable) + if (DEFINED ${variable}_CACHE) + set(${variable} ${${variable}_CACHE} CACHE BOOL "" FORCE ) + endif() +endfunction() + +# Defines compiler-specific CMake variables +function(ipcl_add_compiler_definition) + if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + set(IPCL_USE_MSVC ON PARENT_SCOPE) + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(IPCL_USE_GNU ON PARENT_SCOPE) + elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(IPCL_USE_CLANG ON PARENT_SCOPE) + else() + message(WARNING "Unsupported compiler ${CMAKE_CXX_COMPILER_ID}") + endif() +endfunction() + +# Link IPCL with AddressSanitizer in Debug mode on Mac/Linux +function(ipcl_add_asan_flag target) + if(IPCL_DEBUG AND UNIX) + target_compile_options(${target} PUBLIC -fsanitize=address) + target_link_options(${target} PUBLIC -fsanitize=address) + set(IPCL_ASAN_LINK "-fsanitize=address" PARENT_SCOPE) + else() + set(IPCL_ASAN_LINK "" PARENT_SCOPE) + endif() +endfunction() + +# Add dependency to the target archive +function(ipcl_create_archive target dependency) + # For proper export of IPCLConfig.cmake / IPCLTargets.cmake, + # we avoid explicitly linking dependencies via target_link_libraries, since + # this would add dependencies to the exported ipcl target. + add_dependencies(${target} ${dependency}) + + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + add_custom_command(TARGET ${target} POST_BUILD + COMMAND ar -x $ + COMMAND ar -x $ + COMMAND ar -qcs $ *.o + COMMAND rm -f *.o + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${target} ${dependency} + ) + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + add_custom_command(TARGET ${target} POST_BUILD + COMMAND lib.exe /OUT:$ + $ + $ + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${target} ${dependency} + ) + else() + message(WARNING "Unsupported compiler ${CMAKE_CXX_COMPILER_ID}") + endif() +endfunction() diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake new file mode 100644 index 0000000..da7c349 --- /dev/null +++ b/cmake/ippcrypto.cmake @@ -0,0 +1,63 @@ +# Copyright (C) 2021-2022 Intel Corporation + +include(ExternalProject) +MESSAGE(STATUS "Configuring ipp-crypto") +set(IPPCRYPTO_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_ipp-crypto) +set(IPPCRYPTO_GIT_REPO_URL https://github.com/intel/ipp-crypto.git) +set(IPPCRYPTO_GIT_LABEL ipp-crypto_2021_4) +set(IPPCRYPTO_SRC_DIR ${IPPCRYPTO_PREFIX}/src/ext_ipp-crypto/) + +set(IPPCRYPTO_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS} -DNONPIC_LIB:BOOL=off -DMERGED_BLD:BOOL=on") + +set(IPPCRYPTO_ARCH intel64) +set(BUILD_x64 ON) +if(BUILD_x64) + if(NOT ${BUILD_x64}) + set(IPPCRYPTO_ARCH ia32) + endif() +endif() + +ExternalProject_Add( + ext_ipp-crypto + GIT_REPOSITORY ${IPPCRYPTO_GIT_REPO_URL} + GIT_TAG ${IPPCRYPTO_GIT_LABEL} + PREFIX ${IPPCRYPTO_PREFIX} + INSTALL_DIR ${IPPCRYPTO_PREFIX} + CMAKE_ARGS ${IPPCRYPTO_CXX_FLAGS} + -DCMAKE_INSTALL_PREFIX=${IPPCRYPTO_PREFIX} + -DARCH=${IPPCRYPTO_ARCH} + -DCMAKE_ASM_NASM_COMPILER=nasm + -DCMAKE_BUILD_TYOE=Release + UPDATE_COMMAND "" +) + +# needed to setup interface +file(MAKE_DIRECTORY ${IPPCRYPTO_PREFIX}/include) +set(IPPCRYPTO_INC_DIR ${IPPCRYPTO_PREFIX}/include) +ExternalProject_Get_Property(ext_ipp-crypto SOURCE_DIR BINARY_DIR) + + +add_library(libippcrypto::ippcp STATIC IMPORTED GLOBAL) +add_library(libippcrypto::crypto_mb STATIC IMPORTED GLOBAL) + +add_dependencies(libippcrypto::ippcp ext_ipp-crypto) +add_dependencies(libippcrypto::crypto_mb ext_ipp-crypto) + +find_package(OpenSSL REQUIRED) + +set_target_properties(libippcrypto::ippcp PROPERTIES + IMPORTED_LOCATION ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libippcp.a + INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} +) + +set_target_properties(libippcrypto::crypto_mb PROPERTIES + IMPORTED_LOCATION ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libcrypto_mb.a + INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} +) + +add_library(libippcrypto INTERFACE IMPORTED) +set_property(TARGET libippcrypto PROPERTY INTERFACE_LINK_LIBRARIES libippcrypto::ippcp libippcrypto::crypto_mb) +target_include_directories(libippcrypto SYSTEM INTERFACE ${IPPCRYPTO_INC_DIR}) +target_link_libraries(libippcrypto INTERFACE OpenSSL::SSL OpenSSL::Crypto) + +add_dependencies(libippcrypto ext_ipp-crypto) diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt new file mode 100644 index 0000000..ffd844b --- /dev/null +++ b/docs/CMakeLists.txt @@ -0,0 +1,23 @@ +# Copyright (C) 2021-2022 Intel Corporation + +# Build Doxygen documentation +SET(DOXYGEN_MIN_VERSION "1.8.17") +find_package(Doxygen ${DOXYGEN_MIN_VERSION} REQUIRED) + +set(DOXYGEN_INDEX_FILE ${CMAKE_CURRENT_SOURCE_DIR}/doxygen/xml/indexl.html) +set(DOXYGEN_OUTPUT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/doxygen) +set(DOXYFILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in) +set(DOXYFILE_OUT ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile) + +# Create Doxyfile +configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY) + +file(MAKE_DIRECTORY ${DOXYGEN_OUTPUT_DIR}) # Doxygen won't create this for us + +add_custom_command(OUTPUT ${DOXYGEN_INDEX_FILE} + DEPENDS ${IPP_PAILLIER_INC_DIR} + COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE_OUT} + MAIN_DEPENDENCY ${DOXYFILE_OUT} ${DOXYFILE_IN} + COMMENT "Generating Doxygen documentation") + +add_custom_target(Doxygen ALL DEPENDS ${DOXYGEN_INDEX_FILE}) diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in new file mode 100644 index 0000000..4f12bfb --- /dev/null +++ b/docs/Doxyfile.in @@ -0,0 +1,29 @@ +# Copyright (C) 2021-2022 Intel Corporation + +PROJECT_NAME = "Project PHE" +PROJECT_BRIEF = "Project Paillier HE library w/ Intel IPP-Crypto" + +OUTPUT_DIRECTORY = @CMAKE_CURRENT_SOURCE_DIR@/doxygen +INPUT = @CMAKE_SOURCE_DIR@/paillier/include \ + @CMAKE_SOURCE_DIR@/README.md +RECURSIVE = YES +USE_MDFILE_AS_MAINPAGE = @CMAKE_SOURCE_DIR@/README.md +USE_MATHJAX = YES +FULL_PATH_NAMES = NO + +GENERATE_XML = YES +EXTRACT_ALL = YES +EXTRACT_PRIVATE = NO +SHOW_NAMESPACES = YES +GENERATE_LATEX = YES + +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = YES +WARN_AS_ERROR = YES + +QUIET = NO + +SEARCHENGINE = YES +SERVER_BASED_SEARCH = NO diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..c344624 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,2 @@ + + diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..39a2a7c --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,10 @@ +.. Copyright (C) 2021-2022 Intel Corporation + + +Project PHE Documentation +============================== + +.. toctree:: + api + +.. mdinclude:: ../README.md diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt new file mode 100644 index 0000000..4e05963 --- /dev/null +++ b/ipcl/CMakeLists.txt @@ -0,0 +1,109 @@ +# Copyright (C) 2021-2022 Intel Corporation + +# # BigNumber library +# add_library(bignum SHARED +# bignum.cpp) +# target_include_directories(bignum +# PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} +# PUBLIC ${IPCL_INC_DIR} +# ) +# target_link_libraries(bignum PRIVATE libippcrypto Threads::Threads) + + +# Ipp-crypto Paillier Library + +set(IPCL_SRCS paillier_pri.cpp + paillier_pub.cpp + paillier_ops.cpp + key_pair.cpp + bignum.cpp +) + + +if(IPCL_SHARED) + add_library(ipcl SHARED ${IPCL_SRCS}) +else() + add_library(ipcl STATIC ${IPCL_SRCS}) +endif() + +add_library(IPCL::ipcl ALIAS ipcl) + +target_include_directories(ipcl + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PUBLIC $ + PUBLIC $ +) + +install(DIRECTORY ${IPCL_INC_DIR}/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ + FILES_MATCHING + PATTERN "*.hpp" + PATTERN "*.h") + +if(IPCL_SHARED) + target_link_libraries(ipcl PRIVATE libippcrypto Threads::Threads) +else() + target_link_libraries(ipcl PRIVATE Threads::Threads) + target_link_libraries(ipcl PRIVATE OpenSSL::SSL OpenSSL::Crypto) + ipcl_create_archive(ipcl libippcrypto::ippcp) + ipcl_create_archive(ipcl libippcrypto::crypto_mb) + target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) +endif() + + +set_target_properties(ipcl PROPERTIES POSITION_INDEPENDENT_CODE ON) +set_target_properties(ipcl PROPERTIES VERSION ${IPCL_VERSION}) +if(IPCL_DEBUG) + set_target_properties(ipcl PROPERTIES OUTPUT_NAME "ipcl_debug") +else() + set_target_properties(ipcl PROPERTIES OUTPUT_NAME "ipcl") +endif() + + +install(DIRECTORY ${IPCL_INC_DIR}/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ + FILES_MATCHING + PATTERN "*.hpp" + PATTERN "*.h" +) + +install(TARGETS ipcl DESTINATION ${CMAKE_INSTALL_LIBDIR}) + +# config cmake config and target file +set(IPCL_TARGET_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/cmake/ipcl-${IPCL_VERSION}/IPCLTargets.cmake) +set(IPCL_CONFIG_IN_FILENAME ${IPCL_CMAKE_PATH}/IPCLConfig.cmake.in) +set(IPCL_CONFIG_FILENAME ${IPCL_ROOT_DIR}/cmake/ipcl-${IPCL_VERSION}/IPCLConfig.cmake) +set(IPCL_CONFIG_VERSION_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/cmake/ipcl-${IPCL_VERSION}/IPCLConfigVersion.cmake) +set(IPCL_CONFIG_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/ipcl-${IPCL_VERSION}/) + +install( + EXPORT IPCLTargets + NAMESPACE IPCL:: + DESTINATION ${IPCL_CONFIG_INSTALL_DIR} +) + +write_basic_package_version_file( + ${IPCL_CONFIG_VERSION_FILENAME} + VERSION ${IPCL_VERSION} + COMPATIBILITY ExactVersion +) + +configure_package_config_file( + ${IPCL_CONFIG_IN_FILENAME} ${IPCL_CONFIG_FILENAME} + INSTALL_DESTINATION ${IPCL_CONFIG_INSTALL_DIR} +) + +install( + TARGETS ipcl + EXPORT IPCLTargets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) + +install(FILES ${IPCL_CONFIG_FILENAME} + ${IPCL_CONFIG_VERSION_FILENAME} + DESTINATION ${IPCL_CONFIG_INSTALL_DIR}) + +export(EXPORT IPCLTargets + FILE ${IPCL_TARGET_FILENAME}) diff --git a/ipcl/bignum.cpp b/ipcl/bignum.cpp new file mode 100644 index 0000000..d8ea436 --- /dev/null +++ b/ipcl/bignum.cpp @@ -0,0 +1,499 @@ +/******************************************************************************* + * Copyright 2019-2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + +#include "ipcl/bignum.h" + +#include +#include + +////////////////////////////////////////////////////////////////////// +// +// BigNumber +// +////////////////////////////////////////////////////////////////////// +BigNumber::~BigNumber() { delete[](Ipp8u*) m_pBN; } + +bool BigNumber::create(const Ipp32u* pData, int length, IppsBigNumSGN sgn) { + int size; + ippsBigNumGetSize(length, &size); + m_pBN = (IppsBigNumState*)(new Ipp8u[size]); + if (!m_pBN) return false; + ippsBigNumInit(length, m_pBN); + if (pData) ippsSet_BN(sgn, length, pData, m_pBN); + return true; +} + +// +// constructors +// +BigNumber::BigNumber(Ipp32u value) { create(&value, 1, IppsBigNumPOS); } + +BigNumber::BigNumber(Ipp32s value) { + Ipp32s avalue = abs(value); + create((Ipp32u*)&avalue, 1, (value < 0) ? IppsBigNumNEG : IppsBigNumPOS); +} + +BigNumber::BigNumber(const IppsBigNumState* pBN) { + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, pBN); + + create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); +} + +BigNumber::BigNumber(const Ipp32u* pData, int length, IppsBigNumSGN sgn) { + create(pData, length, sgn); +} + +// Bin: Following GMP lower case +static char HexDigitList[] = "0123456789abcdef"; + +BigNumber::BigNumber(const char* s) { + bool neg = '-' == s[0]; + if (neg) s++; + bool hex = ('0' == s[0]) && (('x' == s[1]) || ('X' == s[1])); + + int dataLen; + Ipp32u base; + if (hex) { + s += 2; + base = 0x10; + dataLen = (int)(strlen(s) + 7) / 8; + } else { + base = 10; + dataLen = (int)(strlen(s) + 9) / 10; + } + + create(0, dataLen); + *(this) = Zero(); + while (*s) { + char tmp[2] = {s[0], 0}; + Ipp32u digit = (Ipp32u)strcspn(HexDigitList, tmp); + *this = (*this) * base + BigNumber(digit); + s++; + } + + if (neg) (*this) = Zero() - (*this); +} + +BigNumber::BigNumber(const BigNumber& bn) { + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); + + create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); +} + +// +// set value +// +void BigNumber::Set(const Ipp32u* pData, int length, + IppsBigNumSGN sgn) { // = IppsBigNumPOS) { + ippsSet_BN(sgn, length, pData, BN(*this)); +} + +// +// constants +// +const BigNumber& BigNumber::Zero() { + static const BigNumber zero(0); + return zero; +} + +const BigNumber& BigNumber::One() { + static const BigNumber one(1); + return one; +} + +const BigNumber& BigNumber::Two() { + static const BigNumber two(2); + return two; +} + +// +// arithmetic operators +// +BigNumber& BigNumber::operator=(const BigNumber& bn) { + if (this != &bn) { // prevent self copy + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); + + delete (Ipp8u*)m_pBN; + create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); + } + return *this; +} + +BigNumber& BigNumber::operator+=(const BigNumber& bn) { + int aBitLen; + ippsRef_BN(nullptr, &aBitLen, nullptr, *this); + int bBitLen; + ippsRef_BN(nullptr, &bBitLen, nullptr, bn); + int rBitLen = IPP_MAX(aBitLen, bBitLen) + 1; + + BigNumber result(0, BITSIZE_WORD(rBitLen)); + ippsAdd_BN(*this, bn, result); + *this = result; + return *this; +} + +// Bin: Support integer add +BigNumber& BigNumber::operator+=(Ipp32u n) { + int aBitLen; + ippsRef_BN(nullptr, &aBitLen, nullptr, *this); + int rBitLen = IPP_MAX(aBitLen, sizeof(Ipp32u) * 8) + 1; + + BigNumber result(0, BITSIZE_WORD(rBitLen)); + BigNumber bn(n); + ippsAdd_BN(*this, bn, result); + *this = result; + return *this; +} + +BigNumber& BigNumber::operator-=(const BigNumber& bn) { + int aBitLen; + ippsRef_BN(nullptr, &aBitLen, nullptr, *this); + int bBitLen; + ippsRef_BN(nullptr, &bBitLen, nullptr, bn); + int rBitLen = IPP_MAX(aBitLen, bBitLen); + + BigNumber result(0, BITSIZE_WORD(rBitLen)); + ippsSub_BN(*this, bn, result); + *this = result; + return *this; +} + +// Bin: Support integer sub +BigNumber& BigNumber::operator-=(Ipp32u n) { + int aBitLen; + ippsRef_BN(nullptr, &aBitLen, nullptr, *this); + int rBitLen = IPP_MAX(aBitLen, sizeof(Ipp32u) * 8); + + BigNumber result(0, BITSIZE_WORD(rBitLen)); + BigNumber bn(n); + ippsSub_BN(*this, bn, result); + *this = result; + return *this; +} + +BigNumber& BigNumber::operator*=(const BigNumber& bn) { + int aBitLen; + ippsRef_BN(nullptr, &aBitLen, nullptr, *this); + int bBitLen; + ippsRef_BN(nullptr, &bBitLen, nullptr, bn); + int rBitLen = aBitLen + bBitLen; + + BigNumber result(0, BITSIZE_WORD(rBitLen)); + ippsMul_BN(*this, bn, result); + *this = result; + return *this; +} + +// Bin: Support integer multiply +BigNumber& BigNumber::operator*=(Ipp32u n) { + int aBitLen; + ippsRef_BN(nullptr, &aBitLen, nullptr, *this); + + BigNumber result(0, BITSIZE_WORD(aBitLen + 32)); + BigNumber bn(n); + ippsMul_BN(*this, bn, result); + *this = result; + return *this; +} + +BigNumber& BigNumber::operator%=(const BigNumber& bn) { + BigNumber remainder(bn); + ippsMod_BN(BN(*this), BN(bn), BN(remainder)); + *this = remainder; + return *this; +} + +// Bin: Support integer mod +BigNumber& BigNumber::operator%=(Ipp32u n) { + int aBitLen; + ippsRef_BN(nullptr, &aBitLen, nullptr, *this); + + BigNumber result(0, BITSIZE_WORD(aBitLen)); + BigNumber bn(n); + ippsMod_BN(*this, bn, result); + *this = result; + return *this; +} + +BigNumber& BigNumber::operator/=(const BigNumber& bn) { + BigNumber quotient(*this); + BigNumber remainder(bn); + ippsDiv_BN(BN(*this), BN(bn), BN(quotient), BN(remainder)); + *this = quotient; + return *this; +} + +// Bin: Support integer div +BigNumber& BigNumber::operator/=(Ipp32u n) { + BigNumber quotient(*this); + BigNumber bn(n); + BigNumber remainder(bn); + ippsDiv_BN(BN(*this), BN(bn), BN(quotient), BN(remainder)); + *this = quotient; + return *this; +} + +BigNumber operator+(const BigNumber& a, const BigNumber& b) { + BigNumber r(a); + return r += b; +} + +// Bin: Support integer add +BigNumber operator+(const BigNumber& a, Ipp32u n) { + BigNumber r(a); + return r += n; +} + +BigNumber operator-(const BigNumber& a, const BigNumber& b) { + BigNumber r(a); + return r -= b; +} + +// Bin: Support integer sub +BigNumber operator-(const BigNumber& a, Ipp32u n) { + BigNumber r(a); + return r -= n; +} + +BigNumber operator*(const BigNumber& a, const BigNumber& b) { + BigNumber r(a); + return r *= b; +} + +// Bin: Support integer mul +BigNumber operator*(const BigNumber& a, Ipp32u n) { + BigNumber r(a); + return r *= n; +} + +BigNumber operator/(const BigNumber& a, const BigNumber& b) { + BigNumber q(a); + return q /= b; +} + +// Bin: Support integer div +BigNumber operator/(const BigNumber& a, Ipp32u n) { + BigNumber q(a); + return q /= n; +} + +BigNumber operator%(const BigNumber& a, const BigNumber& b) { + BigNumber r(b); + ippsMod_BN(BN(a), BN(b), BN(r)); + return r; +} + +// Bin: Support integer mod +BigNumber operator%(const BigNumber& a, Ipp32u n) { + BigNumber r(a); + BigNumber bn(n); + ippsMod_BN(BN(a), BN(bn), BN(r)); + return r; +} + +// +// modulo arithmetic +// +BigNumber BigNumber::Modulo(const BigNumber& a) const { return a % *this; } + +BigNumber BigNumber::InverseAdd(const BigNumber& a) const { + BigNumber t = Modulo(a); + if (t == BigNumber::Zero()) + return t; + else + return *this - t; +} + +BigNumber BigNumber::InverseMul(const BigNumber& a) const { + BigNumber r(*this); + ippsModInv_BN(BN(a), BN(*this), BN(r)); + return r; +} + +BigNumber BigNumber::ModAdd(const BigNumber& a, const BigNumber& b) const { + BigNumber r = this->Modulo(a + b); + return r; +} + +BigNumber BigNumber::ModSub(const BigNumber& a, const BigNumber& b) const { + BigNumber r = this->Modulo(a + this->InverseAdd(b)); + return r; +} + +BigNumber BigNumber::ModMul(const BigNumber& a, const BigNumber& b) const { + BigNumber r = this->Modulo(a * b); + return r; +} + +BigNumber BigNumber::gcd(const BigNumber& q) const { + BigNumber gcd(*this); + + ippsGcd_BN(BN(*this), BN(q), BN(gcd)); + + return gcd; +} + +// +// comparison +// +int BigNumber::compare(const BigNumber& bn) const { + Ipp32u result; + BigNumber tmp = *this - bn; + ippsCmpZero_BN(BN(tmp), &result); + return (result == IS_ZERO) ? 0 : (result == GREATER_THAN_ZERO) ? 1 : -1; +} + +bool operator<(const BigNumber& a, const BigNumber& b) { + return a.compare(b) < 0; +} +bool operator>(const BigNumber& a, const BigNumber& b) { + return a.compare(b) > 0; +} +bool operator==(const BigNumber& a, const BigNumber& b) { + return 0 == a.compare(b); +} +bool operator!=(const BigNumber& a, const BigNumber& b) { + return 0 != a.compare(b); +} + +// easy tests +// +bool BigNumber::IsOdd() const { + Ipp32u* bnData; + ippsRef_BN(nullptr, nullptr, &bnData, *this); + return bnData[0] & 1; +} + +// Bin: Support TestBit +bool BigNumber::TestBit(int index) const { + int bnIndex = index / 32; + int shift = index % 32; + Ipp32u* bnData; + int aBitLen; + ippsRef_BN(nullptr, &aBitLen, &bnData, *this); + if (index > aBitLen) + return 0; + else + return (bnData[bnIndex] >> shift) & 1; +} + +// +// size of BigNumber +// +int BigNumber::LSB() const { + if (*this == BigNumber::Zero()) return 0; + + vector v; + num2vec(v); + + int lsb = 0; + vector::iterator i; + for (i = v.begin(); i != v.end(); i++) { + Ipp32u x = *i; + if (0 == x) + lsb += 32; + else { + while (0 == (x & 1)) { + lsb++; + x >>= 1; + } + break; + } + } + return lsb; +} + +int BigNumber::MSB() const { + if (*this == BigNumber::Zero()) return 0; + + vector v; + num2vec(v); + + int msb = (int)v.size() * 32 - 1; + vector::reverse_iterator i; + for (i = v.rbegin(); i != v.rend(); i++) { + Ipp32u x = *i; + if (0 == x) + msb -= 32; + else { + while (!(x & 0x80000000)) { + msb--; + x <<= 1; + } + break; + } + } + return msb; +} + +int Bit(const vector& v, int n) { + return 0 != (v[n >> 5] & (1 << (n & 0x1F))); +} + +// +// conversions and output +// +void BigNumber::num2vec(vector& v) const { + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(nullptr, &bnBitLen, &bnData, *this); + + int len = BITSIZE_WORD(bnBitLen); + ; + for (int n = 0; n < len; n++) v.push_back(bnData[n]); +} + +void BigNumber::num2hex(string& s) const { + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, *this); + + int len = BITSIZE_WORD(bnBitLen); + + s.append(1, (bnSgn == ippBigNumNEG) ? '-' : ' '); + s.append(1, '0'); + s.append(1, 'x'); + + // remove zero value head + int first_no_zero = 0; + for (int n = len; n > 0; n--) { + Ipp32u x = bnData[n - 1]; + for (int nd = 8; nd > 0; nd--) { + char c = HexDigitList[(x >> (nd - 1) * 4) & 0xF]; + if (c != '0' || first_no_zero) { + first_no_zero = 1; + s.append(1, c); + } + } + } +} + +ostream& operator<<(ostream& os, const BigNumber& a) { + string s; + a.num2hex(s); + os << s; + return os; +} diff --git a/ipcl/include/ipcl/bignum.h b/ipcl/include/ipcl/bignum.h new file mode 100644 index 0000000..7e87853 --- /dev/null +++ b/ipcl/include/ipcl/bignum.h @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright 2019-2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + +#ifndef _BIGNUM_H_ +#define _BIGNUM_H_ + +#include +#include + +#include "ippcp.h" + +using namespace std; + +class BigNumber { + public: + BigNumber(Ipp32u value = 0); + BigNumber(Ipp32s value); + BigNumber(const IppsBigNumState* pBN); + BigNumber(const Ipp32u* pData, int length = 1, + IppsBigNumSGN sgn = IppsBigNumPOS); + BigNumber(const BigNumber& bn); + BigNumber(const char* s); + virtual ~BigNumber(); + const void* addr = static_cast(this); + + // set value + void Set(const Ipp32u* pData, int length = 1, + IppsBigNumSGN sgn = IppsBigNumPOS); + // conversion to IppsBigNumState + friend IppsBigNumState* BN(const BigNumber& bn) { return bn.m_pBN; } + operator IppsBigNumState*() const { return m_pBN; } + + // some useful constants + static const BigNumber& Zero(); + static const BigNumber& One(); + static const BigNumber& Two(); + + // arithmetic operators probably need + BigNumber& operator=(const BigNumber& bn); + // Bin: Support integer add + BigNumber& operator+=(Ipp32u n); + BigNumber& operator+=(const BigNumber& bn); + // Bin: Support integer sub + BigNumber& operator-=(Ipp32u n); + BigNumber& operator-=(const BigNumber& bn); + // Bin: Support integer mul + BigNumber& operator*=(Ipp32u n); + BigNumber& operator*=(const BigNumber& bn); + // Bin: Support integer div + BigNumber& operator/=(Ipp32u n); + BigNumber& operator/=(const BigNumber& bn); + // Bin: Support integer mod + BigNumber& operator%=(Ipp32u n); + BigNumber& operator%=(const BigNumber& bn); + friend BigNumber operator+(const BigNumber& a, const BigNumber& b); + // Bin: Support integer add + friend BigNumber operator+(const BigNumber& a, Ipp32u); + friend BigNumber operator-(const BigNumber& a, const BigNumber& b); + // Bin: Support integer sub + friend BigNumber operator-(const BigNumber& a, Ipp32u); + friend BigNumber operator*(const BigNumber& a, const BigNumber& b); + // Bin: Support integer mul + friend BigNumber operator*(const BigNumber& a, Ipp32u); + friend BigNumber operator%(const BigNumber& a, const BigNumber& b); + // Bin: Support integer mod + friend BigNumber operator%(const BigNumber& a, Ipp32u); + friend BigNumber operator/(const BigNumber& a, const BigNumber& b); + // Bin: Support integer div + friend BigNumber operator/(const BigNumber& a, Ipp32u); + + // modulo arithmetic + BigNumber Modulo(const BigNumber& a) const; + BigNumber ModAdd(const BigNumber& a, const BigNumber& b) const; + BigNumber ModSub(const BigNumber& a, const BigNumber& b) const; + BigNumber ModMul(const BigNumber& a, const BigNumber& b) const; + BigNumber InverseAdd(const BigNumber& a) const; + BigNumber InverseMul(const BigNumber& a) const; + BigNumber gcd(const BigNumber& q) const; + int compare(const BigNumber&) const; + + // comparisons + friend bool operator<(const BigNumber& a, const BigNumber& b); + friend bool operator>(const BigNumber& a, const BigNumber& b); + friend bool operator==(const BigNumber& a, const BigNumber& b); + friend bool operator!=(const BigNumber& a, const BigNumber& b); + friend bool operator<=(const BigNumber& a, const BigNumber& b) { + return !(a > b); + } + friend bool operator>=(const BigNumber& a, const BigNumber& b) { + return !(a < b); + } + + // easy tests + bool IsOdd() const; + bool IsEven() const { return !IsOdd(); } + // Bin: Support TestBit + bool TestBit(int index) const; + + // size of BigNumber + int MSB() const; + int LSB() const; + int BitSize() const { return MSB() + 1; } + int DwordSize() const { return (BitSize() + 31) >> 5; } + friend int Bit(const vector& v, int n); + + // conversion and output + void num2hex(string& s) const; // convert to hex string + void num2vec(vector& v) const; // convert to 32-bit word vector + friend ostream& operator<<(ostream& os, const BigNumber& a); + + protected: + bool create(const Ipp32u* pData, int length, + IppsBigNumSGN sgn = IppsBigNumPOS); + IppsBigNumState* m_pBN; +}; + +// convert bit size into 32-bit words +#define BITSIZE_WORD(n) ((((n) + 31) >> 5)) + +// Bin: convert bit size into 64-bit words +#define BITSIZE_DWORD(n) ((((n) + 63) >> 6)) + +#endif // _BIGNUM_H_ diff --git a/ipcl/include/ipcl/key_pair.hpp b/ipcl/include/ipcl/key_pair.hpp new file mode 100644 index 0000000..193fd0b --- /dev/null +++ b/ipcl/include/ipcl/key_pair.hpp @@ -0,0 +1,32 @@ +// Copyright (C) 2021-2022 Intel Corporation + +#ifndef IPCL_INCLUDE_IPCL_KEY_PAIR_HPP_ +#define IPCL_INCLUDE_IPCL_KEY_PAIR_HPP_ + +#include "ipcl/pri_key.hpp" +#include "ipcl/pub_key.hpp" + +/** + * Paillier key structure contains a public key and private key + * pub_key: paillier public key + * priv_key: paillier private key + */ +struct keyPair { + PaillierPublicKey* pub_key; + PaillierPrivateKey* priv_key; +}; + +/** + * Generate Prime Big Number + * @param[in] maxBitSize Maxmuim bit length of generated Prime + */ +BigNumber getPrimeBN(int maxBitSize); + +/** + * Generate a pair of key + * @param[in] n_length Bit length of key size + * @param[in] enable_DJN Default enabled DJN + */ +keyPair generateKeypair(int64_t n_length, bool enable_DJN = true); + +#endif // IPCL_INCLUDE_IPCL_KEY_PAIR_HPP_ diff --git a/ipcl/include/ipcl/paillier_ops.hpp b/ipcl/include/ipcl/paillier_ops.hpp new file mode 100644 index 0000000..8e1da6d --- /dev/null +++ b/ipcl/include/ipcl/paillier_ops.hpp @@ -0,0 +1,133 @@ +// Copyright (C) 2021-2022 Intel Corporation + +#ifndef IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ +#define IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ + +#include + +#include "ipcl/pub_key.hpp" + +class PaillierEncryptedNumber { + public: + /** + * PaillierEncryptedNumber construct function + * @param[in] pub_key paillier public key + * @param[in] bn ciphtext encrypted by paillier + */ + PaillierEncryptedNumber(PaillierPublicKey* pub_key, const BigNumber& bn); + + /** + * PaillierEncryptedNumber construct function + * @param[in] pub_key paillier public key + * @param[in] bn array of ciphtext encrypted by paillier + * @param[in] length elements of array + */ + PaillierEncryptedNumber(PaillierPublicKey* pub_key, const BigNumber bn[8], + size_t length = 8); + + /** + * PaillierEncryptedNumber construct function + * @param[in] pub_key paillier public key + * @param[in] scalar array of scalar + * integer) + * @param[in] length elements of array + */ + PaillierEncryptedNumber(PaillierPublicKey* pub_key, const uint32_t scalar[8], + size_t length = 8); + + /** + * Arithmetic addition operator + * @param[in] bn augend + */ + PaillierEncryptedNumber operator+(const PaillierEncryptedNumber& bn) const; + + /** + * Arithmetic addition operator + * @param[in] other augend + */ + PaillierEncryptedNumber operator+(const BigNumber& other) const; + + /** + * Arithmetic addition operator + * @param[in] other array of augend + */ + PaillierEncryptedNumber operator+(const BigNumber other[8]) const; + + /** + * Arithmetic multiply operator + * @param[in] bn multiplicand + */ + PaillierEncryptedNumber operator*(const PaillierEncryptedNumber& bn) const; + + /** + * Arithmetic multiply operator + * @param[in] other multiplicand + */ + PaillierEncryptedNumber operator*(const BigNumber& other) const; + + /** + * Apply obfuscator for ciphertext, obfuscated needed only when the result is + * shared to untrusted parties + */ + void apply_obfuscator() { + b_isObfuscator = true; + BigNumber obfuscator[8]; + m_pubkey->apply_obfuscator(obfuscator); + + BigNumber sq = m_pubkey->getNSQ(); + for (int i = 0; i < m_available; i++) + m_bn[i] = sq.ModMul(m_bn[i], obfuscator[i]); + } + + /** + * Get output of Arithmetic operators + * @param[in] idx index of output array + */ + BigNumber getBN(size_t idx = 0) const { + if (m_available == 1 && idx > 0) + throw std::out_of_range("PaillierEncryptedNumber only has 1 BigNumber"); + + return m_bn[idx]; + } + + /** + * Get public key for python wrapper + */ + PaillierPublicKey getPK() const { return *m_pubkey; } + + /** + * Rotate PaillierEncryptedNumber + */ + PaillierEncryptedNumber rotate(int shift); + + /** + * Get array output of Arithmetic operators + * @param[out] bn output array + */ + void getArrayBN(BigNumber bn[8]) const { std::copy_n(m_bn, 8, bn); } + + /** + * Element in PaillierEncryptedNumber is single + */ + bool isSingle() const { return m_available == 1; } + + /** + * Elements in PaillierEncryptedNumber + */ + size_t getLength() const { return m_length; } + + const void* addr = static_cast(this); + + private: + bool b_isObfuscator; + int m_available; + PaillierPublicKey* m_pubkey; + size_t m_length; + BigNumber m_bn[8]; + + BigNumber raw_add(const BigNumber& a, const BigNumber& b); + BigNumber raw_mul(const BigNumber& a, const BigNumber& b); + void raw_mul(BigNumber res[8], BigNumber a[8], BigNumber b[8]); +}; + +#endif // IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ diff --git a/ipcl/include/ipcl/pri_key.hpp b/ipcl/include/ipcl/pri_key.hpp new file mode 100644 index 0000000..7316c69 --- /dev/null +++ b/ipcl/include/ipcl/pri_key.hpp @@ -0,0 +1,125 @@ +// Copyright (C) 2021-2022 Intel Corporation + +#ifndef IPCL_INCLUDE_IPCL_PRI_KEY_HPP_ +#define IPCL_INCLUDE_IPCL_PRI_KEY_HPP_ + +#include "ipcl/bignum.h" +#include "ipcl/paillier_ops.hpp" +#include "ipcl/pub_key.hpp" + +class PaillierPrivateKey { + public: + /** + * PaillierPrivateKey construct function + * @param[in] public_key paillier public key + * @param[in] p p of private key in paillier paper + * @param[in] q q of private key in paillier paper + */ + PaillierPrivateKey(PaillierPublicKey* public_key, const BigNumber& p, + const BigNumber& q); + + /** + * Chinese-remaindering enabling + * @param[in] crt Apply Chinese remaindering theorem + */ + void enableCRT(bool crt) { m_enable_crt = crt; } + + /** + * Decrypt ciphtext + * @param[out] plaintext output of the decryption + * @param[in] ciphertext ciphertext to be decrypted + */ + void decrypt(BigNumber plaintext[8], const BigNumber ciphertext[8]); + + /** + * Decrypt ciphtext + * @param[out] plaintext output of the decryption + * @param[in] ciphertext PaillierEncryptedNumber to be decrypted + */ + void decrypt(BigNumber plaintext[8], + const PaillierEncryptedNumber ciphertext); + + const void* addr = static_cast(this); + + /** + * Get N of public key in paillier paper + */ + BigNumber getN() const { return m_n; } + + /** + * Get p of private key in paillier paper + */ + BigNumber getP() const { return m_p; } + + /** + * Get q of private key in paillier paper + */ + BigNumber getQ() const { return m_q; } + + /** + * Get bits of key + */ + int getBits() const { return m_bits; } + + /** + * Get public key + */ + PaillierPublicKey* getPubKey() const { return m_pubkey; } + + private: + PaillierPublicKey* m_pubkey; + BigNumber m_n; + BigNumber m_nsquare; + BigNumber m_g; + BigNumber m_p; + BigNumber m_q; + BigNumber m_pminusone; + BigNumber m_qminusone; + BigNumber m_psquare; + BigNumber m_qsquare; + BigNumber m_pinverse; + BigNumber m_hp; + BigNumber m_hq; + BigNumber m_lambda; + BigNumber m_x; + int m_bits; + int m_dwords; + bool m_enable_crt; + + /** + * Compute L function in paillier paper + * @param[in] a input a + * @param[in] b input b + */ + BigNumber computeLfun(const BigNumber& a, const BigNumber& b); + + /** + * Compute H function in paillier paper + * @param[in] a input a + * @param[in] b input b + */ + BigNumber computeHfun(const BigNumber& a, const BigNumber& b); + + /** + * Compute CRT function in paillier paper + * @param[in] mp input mp + * @param[in] mq input mq + */ + BigNumber computeCRT(const BigNumber& mp, const BigNumber& mq); + + /** + * Raw decryption function without CRT optimization + * @param[out] plaintext output plaintext + * @param[in] ciphertext input ciphertext + */ + void decryptRAW(BigNumber plaintext[8], const BigNumber ciphertext[8]); + + /** + * Raw decryption function with CRT optimization + * @param[out] plaintext output plaintext + * @param[in] ciphertext input ciphertext + */ + void decryptCRT(BigNumber plaintext[8], const BigNumber ciphertext[8]); +}; + +#endif // IPCL_INCLUDE_IPCL_PRI_KEY_HPP_ diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp new file mode 100644 index 0000000..efe2e18 --- /dev/null +++ b/ipcl/include/ipcl/pub_key.hpp @@ -0,0 +1,141 @@ +// Copyright (C) 2021-2022 Intel Corporation + +#ifndef IPCL_INCLUDE_IPCL_PUB_KEY_HPP_ +#define IPCL_INCLUDE_IPCL_PUB_KEY_HPP_ + +#include "ipcl/bignum.h" + +class PaillierPublicKey { + public: + /** + * PaillierPublicKey construct function + * @param[in] n n of public key in paillier paper + * @param[in] bits bit length of public key + */ + explicit PaillierPublicKey(const BigNumber& n, int bits = 1024, + bool enableDJN_ = false); + + /** + * PaillierPublicKey construct function + * @param[in] n n of public key in paillier paper + * @param[in] bits bit length of public key + */ + explicit PaillierPublicKey(const Ipp32u n, int bits = 1024, + bool enableDJN_ = false) + : PaillierPublicKey(BigNumber(n), bits, enableDJN_) {} + + /** + * DJN enabling function + */ + void enableDJN(); + + /** + * Encrypt plaintext + * @param[out] ciphertext output of the encryption + * @param[in] value array plaintext need to be encrypted + * @param[in] make_secure apply obfuscator + */ + void encrypt(BigNumber ciphertext[8], const BigNumber value[8], + bool make_secure = true); + + /** + * Encrypt plaintext + * @param[out] ciphertext output of the encryption + * @param[in] value plaintext need to be encrypted + */ + void encrypt(BigNumber& ciphertext, const BigNumber& value); + + /** + * Modular exponentiation + * @param[in] base base of the exponentiation + * @param[in] pow pow of the exponentiation + * @param[in] m modular + */ + BigNumber ippMontExp(const BigNumber& base, const BigNumber& pow, + const BigNumber& m); + + /** + * Multi-buffered modular exponentiation + * @param[out] res array result of the modular exponentiation + * @param[in] base array base of the exponentiation + * @param[in] pow arrya pow of the exponentiation + * @param[in] m arrayodular + */ + void ippMultiBuffExp(BigNumber res[8], BigNumber base[8], + const BigNumber pow[8], BigNumber m[8]); + + /** + * Invert function needed by encoder(float to integer) + * @param[in] a input of a + * @param[in] b input of b + */ + BigNumber IPP_invert(BigNumber a, BigNumber b); + + /** + * Get N of public key in paillier paper + */ + BigNumber getN() const { return m_n; } + + /** + * Get NSQ of public key in paillier paper + */ + BigNumber getNSQ() const { return m_nsquare; } + + /** + * Get G of public key in paillier paper + */ + BigNumber getG() const { return m_g; } + + /** + * Get bits of key + */ + int getBits() const { return m_bits; } + + /** + * Get Dword of key + */ + int getDwords() const { return m_dwords; } + + /** + * Apply obfuscator for ciphertext + * @param[out] obfuscator output of obfuscator with random value + */ + void apply_obfuscator(BigNumber obfuscator[8]); + + const void* addr = static_cast(this); + + private: + BigNumber m_n; + BigNumber m_g; + BigNumber m_nsquare; + BigNumber m_hs; + int m_bits; + int m_randbits; + int m_dwords; + unsigned int m_init_seed; + bool m_enable_DJN; + + /** + * Get random value + * @param[in] addr addr of random + * @param[in] size size of random + */ + Ipp32u* randIpp32u(Ipp32u* addr, int size); + + /** + * Raw encrypt function + * @param[out] ciphertext array output of the encryption + * @param[in] plaintext array plaintext need to be encrypted + * @param[in] make_secure apply obfuscator + */ + void raw_encrypt(BigNumber ciphertext[8], const BigNumber plaintext[8], + bool make_secure = true); + + /** + * Get random value + * @param[in] length bit length of random + */ + BigNumber getRandom(int length); +}; + +#endif // IPCL_INCLUDE_IPCL_PUB_KEY_HPP_ diff --git a/ipcl/key_pair.cpp b/ipcl/key_pair.cpp new file mode 100644 index 0000000..4d2f585 --- /dev/null +++ b/ipcl/key_pair.cpp @@ -0,0 +1,103 @@ +// Copyright (C) 2021-2022 Intel Corporation + +#include "ipcl/key_pair.hpp" + +#include +#include +#include + +static inline void rand32u(vector& addr) { + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + for (auto& x : addr) x = (dist(rng) << 16) + dist(rng); +} + +BigNumber getPrimeBN(int maxBitSize) { + int PrimeSize; + ippsPrimeGetSize(maxBitSize, &PrimeSize); + auto primeGen = vector(PrimeSize); + ippsPrimeInit(maxBitSize, reinterpret_cast(primeGen.data())); + + // define Pseudo Random Generator (default settings) + int seedBitSize = 160; + int seedSize = BITSIZE_WORD(seedBitSize); + + ippsPRNGGetSize(&PrimeSize); + auto rand = vector(PrimeSize); + ippsPRNGInit(seedBitSize, reinterpret_cast(rand.data())); + + auto seed = vector(seedSize); + rand32u(seed); + BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); + + ippsPRNGSetSeed(BN(bseed), reinterpret_cast(rand.data())); + + // generate maxBit prime + BigNumber pBN(0, maxBitSize / 8); + while (ippStsNoErr != + ippsPrimeGen_BN(pBN, maxBitSize, 10, + reinterpret_cast(primeGen.data()), + ippsPRNGen, + reinterpret_cast(rand.data()))) { + } + + return pBN; +} + +inline void getNormalBN(int64_t n_length, BigNumber& p, BigNumber& q, + BigNumber& n) { + for (int64_t len = 0; len != n_length; len = n.BitSize()) { + p = getPrimeBN(n_length / 2); + q = p; + while (q == p) { + q = getPrimeBN(n_length / 2); + } + n = p * q; + } +} + +inline void getDJNBN(int64_t n_length, BigNumber& p, BigNumber& q, + BigNumber& n) { + BigNumber gcd; + do { + do { + p = getPrimeBN(n_length / 2); + } while (!p.TestBit(1)); // get p: p mod 4 = 3 + + do { + q = getPrimeBN(n_length / 2); + } while (q == p || !p.TestBit(1)); // get q: q!=p and q mod 4 = 3 + + BigNumber pminusone = p - 1; + BigNumber qminusone = q - 1; + gcd = pminusone.gcd(qminusone); + } while (gcd.compare(2)); // gcd(p-1,q-1)=2 + + n = p * q; +} + +keyPair generateKeypair(int64_t n_length, bool enable_DJN) { + /* + https://www.intel.com/content/www/us/en/develop/documentation/ipp-crypto-reference/top/multi-buffer-cryptography-functions/modular-exponentiation/mbx-exp-1024-2048-3072-4096-mb8.html + modulus size = n * n (keySize * keySize ) + */ + if (n_length > 2048) { + throw std::runtime_error( + "modulus size in bits should belong to either 1Kb, 2Kb, " + "3Kb or 4Kb range only, key size exceed the range!!!"); + } + + BigNumber p, q, n; + + if (enable_DJN) + getDJNBN(n_length, p, q, n); + else + getNormalBN(n_length, p, q, n); + + PaillierPublicKey* public_key = + new PaillierPublicKey(n, n_length, enable_DJN); + PaillierPrivateKey* private_key = new PaillierPrivateKey(public_key, p, q); + + return keyPair{public_key, private_key}; +} diff --git a/ipcl/paillier_ops.cpp b/ipcl/paillier_ops.cpp new file mode 100644 index 0000000..3942b96 --- /dev/null +++ b/ipcl/paillier_ops.cpp @@ -0,0 +1,150 @@ +// Copyright (C) 2021-2022 Intel Corporation + +#include "ipcl/paillier_ops.hpp" + +#include + +// constructors +// +PaillierEncryptedNumber::PaillierEncryptedNumber(PaillierPublicKey* pub_key, + const BigNumber& bn) + : b_isObfuscator(false), + m_available(1), + m_pubkey(pub_key), + m_length(1), + m_bn{bn} // m_bn[0] +{} + +PaillierEncryptedNumber::PaillierEncryptedNumber(PaillierPublicKey* pub_key, + const BigNumber bn[8], + size_t length) + : b_isObfuscator(false), + m_pubkey(pub_key), + m_available(8), + m_length(length), + m_bn{bn[0], bn[1], bn[2], bn[3], bn[4], bn[5], bn[6], bn[7]} {} + +PaillierEncryptedNumber::PaillierEncryptedNumber(PaillierPublicKey* pub_key, + const uint32_t scalar[8], + size_t length) + : b_isObfuscator(false), + m_pubkey(pub_key), + m_available(8), + m_length(length), + m_bn{scalar[0], scalar[1], scalar[2], scalar[3], + scalar[4], scalar[5], scalar[6], scalar[7]} {} + +// CT+CT +PaillierEncryptedNumber PaillierEncryptedNumber::operator+( + const PaillierEncryptedNumber& other) const { + if (m_pubkey->getN() != other.m_pubkey->getN()) { + throw std::runtime_error("two different public keys detected!!"); + } + + PaillierEncryptedNumber a = *this; + PaillierEncryptedNumber b = other; + + if (m_available == 1) { + BigNumber sum = a.raw_add(a.m_bn[0], b.m_bn[0]); + return PaillierEncryptedNumber(m_pubkey, sum); + } else { + BigNumber sum[8]; + for (int i = 0; i < m_available; i++) + sum[i] = a.raw_add(a.m_bn[i], b.m_bn[i]); + return PaillierEncryptedNumber(m_pubkey, sum); + } +} + +// CT+PT +PaillierEncryptedNumber PaillierEncryptedNumber::operator+( + const BigNumber& other) const { + PaillierEncryptedNumber a = *this; + BigNumber b; + a.m_pubkey->encrypt(b, other); + + BigNumber sum = a.raw_add(a.m_bn[0], b); + return PaillierEncryptedNumber(m_pubkey, sum); +} + +// multi encrypted CT+PT +PaillierEncryptedNumber PaillierEncryptedNumber::operator+( + const BigNumber other[8]) const { + PaillierEncryptedNumber a = *this; + + BigNumber b[8], sum[8]; + a.m_pubkey->encrypt(b, other, false); + for (int i = 0; i < 8; i++) sum[i] = a.raw_add(a.m_bn[i], b[i]); + return PaillierEncryptedNumber(m_pubkey, sum); +} + +// CT*PT PaillierEncryptedNumber store a plaintext integer, not an encrypted +// integer +PaillierEncryptedNumber PaillierEncryptedNumber::operator*( + const PaillierEncryptedNumber& other) const { + if (m_pubkey->getN() != other.m_pubkey->getN()) { + throw std::runtime_error("two different public keys detected!!"); + } + + PaillierEncryptedNumber a = *this; + PaillierEncryptedNumber b = other; + + if (m_available == 1) { + BigNumber product = a.raw_mul(a.m_bn[0], b.m_bn[0]); + return PaillierEncryptedNumber(m_pubkey, product); + } else { + BigNumber product[8]; + a.raw_mul(product, a.m_bn, b.m_bn); + return PaillierEncryptedNumber(m_pubkey, product); + } +} + +// CT*PT +PaillierEncryptedNumber PaillierEncryptedNumber::operator*( + const BigNumber& other) const { + PaillierEncryptedNumber a = *this; + + BigNumber b = other; + BigNumber product = a.raw_mul(a.m_bn[0], b); + return PaillierEncryptedNumber(m_pubkey, product); +} + +BigNumber PaillierEncryptedNumber::raw_add(const BigNumber& a, + const BigNumber& b) { + // Hold a copy of nsquare for multi-threaded + BigNumber sq = m_pubkey->getNSQ(); + return a * b % sq; +} + +void PaillierEncryptedNumber::raw_mul(BigNumber res[8], BigNumber a[8], + BigNumber b[8]) { + BigNumber sq[8]; + for (int i = 0; i < 8; i++) sq[i] = m_pubkey->getNSQ(); + m_pubkey->ippMultiBuffExp(res, a, b, sq); +} + +BigNumber PaillierEncryptedNumber::raw_mul(const BigNumber& a, + const BigNumber& b) { + BigNumber sq = m_pubkey->getNSQ(); + return m_pubkey->ippMontExp(a, b, sq); +} + +PaillierEncryptedNumber PaillierEncryptedNumber::rotate(int shift) { + if (m_available == 1) + throw std::invalid_argument("Cannot rotate single PaillierEncryptedNumber"); + if (shift > 8 || shift < -8) + throw std::invalid_argument("Cannot shift more than 8 or -8"); + + if (shift == 0 || shift == 8 || shift == -8) + return PaillierEncryptedNumber(m_pubkey, m_bn); + + if (shift > 0) + shift = 8 - shift; + else + shift = -shift; + + BigNumber new_bn[8]; + getArrayBN(new_bn); + + std::rotate(std::begin(new_bn), std::begin(new_bn) + shift, std::end(new_bn)); + return PaillierEncryptedNumber(m_pubkey, new_bn); +} diff --git a/ipcl/paillier_pri.cpp b/ipcl/paillier_pri.cpp new file mode 100644 index 0000000..cd205d6 --- /dev/null +++ b/ipcl/paillier_pri.cpp @@ -0,0 +1,189 @@ +// Copyright (C) 2021-2022 Intel Corporation + +#include + +#include + +#include "ipcl/pri_key.hpp" + +/** + * Compute lcm for p and q + * @param[in] p p - 1 of private key + * @param[in] q q - 1 of private key + */ +static inline BigNumber lcm(const BigNumber& p, const BigNumber& q) { + BigNumber gcd(p); + ippsGcd_BN(BN(p), BN(q), BN(gcd)); + return p * q / gcd; +} + +PaillierPrivateKey::PaillierPrivateKey(PaillierPublicKey* public_key, + const BigNumber& p, const BigNumber& q) + : m_pubkey(public_key), + m_n(m_pubkey->getN()), + m_nsquare(m_pubkey->getNSQ()), + m_g(m_pubkey->getG()), + m_p((q < p) ? q : p), + m_q((q < p) ? p : q), + m_pminusone(m_p - 1), + m_qminusone(m_q - 1), + m_psquare(m_p * m_p), + m_qsquare(m_q * m_q), + m_pinverse(m_q.InverseMul(m_p)), + m_hp(computeHfun(m_p, m_psquare)), + m_hq(computeHfun(m_q, m_qsquare)), + // lcm(P-1,Q-1) = (P-1)*(Q-1)/gcd(P-1,Q-1), gcd in ipp-crypto is + // ippsGcd_BN + m_lambda(lcm(m_pminusone, m_qminusone)), + // TODO(bwang30): check if ippsModInv_BN does the same thing with + // mpz_invert + m_x(m_n.InverseMul(m_pubkey->ippMontExp(m_g, m_lambda, m_nsquare) - 1) / + m_n), + m_bits(m_pubkey->getBits()), + m_dwords(m_pubkey->getDwords()), + m_enable_crt(true) { + if (p * q != m_n) { + throw std::runtime_error("Public key does not match p * q."); + } + + if (p == q) { + throw std::runtime_error("p and q error."); + } +} + +void PaillierPrivateKey::decryptRAW(BigNumber plaintext[8], + const BigNumber ciphertext[8]) { + mbx_status st = MBX_STATUS_OK; + + Ipp64u* out_m[8]; + int64u* cip_array[8]; + + int bufferLen; + Ipp8u* pBuffer; + + // setup buffer for mbx_exp + bufferLen = mbx_exp_BufferSize(m_bits * 2); + pBuffer = reinterpret_cast(alloca(bufferLen)); + if (nullptr == pBuffer) throw std::runtime_error("error alloc memory"); + + int length = m_dwords * sizeof(int64u); + for (int i = 0; i < 8; i++) { + out_m[i] = reinterpret_cast(alloca(length)); + cip_array[i] = reinterpret_cast(alloca(length)); + + if (nullptr == out_m[i] || nullptr == cip_array[i]) + throw std::runtime_error("error alloc memory"); + } + + for (int i = 0; i < 8; i++) memset(cip_array[i], 0, m_dwords * 8); + + // TODO(bwang30): add multi-buffered modular exponentiation + Ipp32u *pow_c[8], *pow_lambda[8], *pow_nsquare[8], *pow_qsquare[8]; + int cBitLen, lBitLen, nsqBitLen; + BigNumber lambda = m_lambda; + for (int i = 0; i < 8; i++) { + ippsRef_BN(nullptr, &cBitLen, &pow_c[i], ciphertext[i]); + ippsRef_BN(nullptr, &lBitLen, &pow_lambda[i], lambda); + ippsRef_BN(nullptr, &nsqBitLen, &pow_nsquare[i], m_nsquare); + + memcpy(cip_array[i], pow_c[i], BITSIZE_WORD(cBitLen) * 4); + } + + st = mbx_exp_mb8(out_m, cip_array, reinterpret_cast(pow_lambda), + lBitLen, reinterpret_cast(pow_nsquare), nsqBitLen, + pBuffer, bufferLen); + + for (int i = 0; i < 8; i++) { + if (MBX_STATUS_OK != MBX_GET_STS(st, i)) + throw std::runtime_error( + std::string("error multi buffered exp modules, error code = ") + + std::to_string(MBX_GET_STS(st, i))); + } + + BigNumber ipp_res(m_nsquare); + BigNumber nn = m_n; + BigNumber xx = m_x; + for (int i = 0; i < 8; i++) { + ipp_res.Set(reinterpret_cast(out_m[i]), BITSIZE_WORD(nsqBitLen), + IppsBigNumPOS); + BigNumber m = (ipp_res - 1) / nn; + m = m * xx; + plaintext[i] = m % nn; + } +} + +void PaillierPrivateKey::decrypt(BigNumber plaintext[8], + const BigNumber ciphertext[8]) { + if (m_enable_crt) + decryptCRT(plaintext, ciphertext); + else + decryptRAW(plaintext, ciphertext); +} + +void PaillierPrivateKey::decrypt(BigNumber plaintext[8], + const PaillierEncryptedNumber ciphertext) { + // check key match + if (ciphertext.getPK().getN() != m_pubkey->getN()) + throw std::runtime_error("public key mismatch error."); + + BigNumber res[8]; + ciphertext.getArrayBN(res); + if (m_enable_crt) + decryptCRT(plaintext, res); + else + decryptRAW(plaintext, res); +} + +// CRT to calculate base^exp mod n^2 +void PaillierPrivateKey::decryptCRT(BigNumber plaintext[8], + const BigNumber ciphertext[8]) { + BigNumber resp[8]; + BigNumber resq[8]; + + BigNumber pm1[8]; + BigNumber qm1[8]; + + BigNumber psq[8], qsq[8]; + BigNumber basep[8], baseq[8]; + + for (int i = 0; i < 8; i++) { + psq[i] = m_psquare; + qsq[i] = m_qsquare; + pm1[i] = m_pminusone; + qm1[i] = m_qminusone; + + basep[i] = ciphertext[i] % psq[i]; + baseq[i] = ciphertext[i] % qsq[i]; + } + + // Based on the fact a^b mod n = (a mod n)^b mod n + m_pubkey->ippMultiBuffExp(resp, basep, pm1, psq); + m_pubkey->ippMultiBuffExp(resq, baseq, qm1, qsq); + + for (int i = 0; i < 8; i++) { + BigNumber dp = computeLfun(resp[i], m_p) * m_hp % m_p; + BigNumber dq = computeLfun(resq[i], m_q) * m_hq % m_q; + plaintext[i] = computeCRT(dp, dq); + } +} + +BigNumber PaillierPrivateKey::computeCRT(const BigNumber& mp, + const BigNumber& mq) { + BigNumber u = (mq - mp) * m_pinverse % m_q; + return mp + (u * m_p); +} + +BigNumber PaillierPrivateKey::computeLfun(const BigNumber& a, + const BigNumber& b) { + return (a - 1) / b; +} + +BigNumber PaillierPrivateKey::computeHfun(const BigNumber& a, + const BigNumber& b) { + // Based on the fact a^b mod n = (a mod n)^b mod n + BigNumber xm = a - 1; + BigNumber base = m_g % b; + BigNumber pm = m_pubkey->ippMontExp(base, xm, b); + BigNumber lcrt = computeLfun(pm, a); + return a.InverseMul(lcrt); +} diff --git a/ipcl/paillier_pub.cpp b/ipcl/paillier_pub.cpp new file mode 100644 index 0000000..7473e56 --- /dev/null +++ b/ipcl/paillier_pub.cpp @@ -0,0 +1,267 @@ +// Copyright (C) 2021-2022 Intel Corporation + +#include + +#include +#include +#include + +#include "ipcl/pub_key.hpp" + +static inline auto randomUniformUnsignedInt() { + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + return dist(rng); +} + +PaillierPublicKey::PaillierPublicKey(const BigNumber& n, int bits, + bool enableDJN_) + : m_n(n), + m_g(n + 1), + m_nsquare(n * n), + m_bits(bits), + m_dwords(BITSIZE_DWORD(bits * 2)), + m_init_seed(randomUniformUnsignedInt()), + m_enable_DJN(false) { + if (enableDJN_) this->enableDJN(); // this sets m_enable_DJN +} + +// array of 32-bit random, using rand() from stdlib +Ipp32u* PaillierPublicKey::randIpp32u(Ipp32u* addr, int size) { + for (int i = 0; i < size; i++) + addr[i] = (rand_r(&m_init_seed) << 16) + rand_r(&m_init_seed); + return addr; +} + +// length is Arbitery +BigNumber PaillierPublicKey::getRandom(int length) { + int size; + int seedBitSize = 160; + int seedSize = BITSIZE_WORD(seedBitSize); + Ipp32u* seed = reinterpret_cast(alloca(seedSize * sizeof(Ipp32u))); + if (nullptr == seed) throw std::runtime_error("error alloc memory"); + ippsPRNGGetSize(&size); + IppsPRNGState* pRand = reinterpret_cast(alloca(size)); + if (nullptr == pRand) throw std::runtime_error("error alloc memory"); + ippsPRNGInit(seedBitSize, pRand); + + Ipp32u* addr = randIpp32u(seed, seedSize); + BigNumber bseed(addr, seedSize, IppsBigNumPOS); + + ippsPRNGSetSeed(BN(bseed), pRand); + + // define length Big Numbers + int bn_size = BITSIZE_WORD(length); + ippsBigNumGetSize(bn_size, &size); + IppsBigNumState* pBN = reinterpret_cast(alloca(size)); + if (nullptr == pBN) throw std::runtime_error("error alloc memory"); + ippsBigNumInit(bn_size, pBN); + + int bnBitSize = length; + ippsPRNGenRDRAND_BN(pBN, bnBitSize, pRand); + BigNumber rand(pBN); + return rand; +} + +void PaillierPublicKey::enableDJN() { + BigNumber gcd; + BigNumber rmod; + do { + int rand_bit = m_n.BitSize(); + BigNumber rand = getRandom(rand_bit + 128); + rmod = rand % m_n; + gcd = rand.gcd(m_n); + } while (gcd.compare(1)); + + BigNumber rmod_sq = rmod * rmod; + BigNumber rmod_neg = rmod_sq * -1; + BigNumber h = rmod_neg % m_n; + m_hs = ippMontExp(h, m_n, m_nsquare); + m_randbits = m_bits >> 1; // bits/2 + + m_enable_DJN = true; +} + +void PaillierPublicKey::apply_obfuscator(BigNumber obfuscator[8]) { + BigNumber r[8]; + BigNumber pown[8]; + BigNumber base[8]; + BigNumber sq[8]; + + if (m_enable_DJN) { + for (int i = 0; i < 8; i++) { + r[i] = getRandom(m_randbits); + base[i] = m_hs; + sq[i] = m_nsquare; + } + + ippMultiBuffExp(obfuscator, base, r, sq); + } else { + for (int i = 0; i < 8; i++) { + r[i] = getRandom(m_bits); + r[i] = r[i] % (m_n - 1) + 1; + pown[i] = m_n; + sq[i] = m_nsquare; + } + ippMultiBuffExp(obfuscator, r, pown, sq); + } +} + +void PaillierPublicKey::raw_encrypt(BigNumber ciphertext[8], + const BigNumber plaintext[8], + bool make_secure) { + // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 + BigNumber sq = m_nsquare; + for (int i = 0; i < 8; i++) { + BigNumber bn(plaintext[i]); + ciphertext[i] = (m_n * bn + 1) % sq; + } + + if (make_secure) { + BigNumber obfuscator[8]; + apply_obfuscator(obfuscator); + + for (int i = 0; i < 8; i++) + ciphertext[i] = sq.ModMul(ciphertext[i], obfuscator[i]); + } +} + +void PaillierPublicKey::encrypt(BigNumber ciphertext[8], + const BigNumber value[8], bool make_secure) { + raw_encrypt(ciphertext, value, make_secure); +} + +// Used for CT+PT, where PT do not need to add obfuscator +void PaillierPublicKey::encrypt(BigNumber& ciphertext, const BigNumber& value) { + // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 + BigNumber bn = value; + BigNumber sq = m_nsquare; + ciphertext = (m_n * bn + 1) % sq; + + /*----- Path to caculate (n+1)^plaintext mod n^2 ------------ + BigNumber bn(value); + ciphertext = ippMontExp(m_g, bn, m_nsquare); + ---------------------------------------------------------- */ +} + +void PaillierPublicKey::ippMultiBuffExp(BigNumber res[8], BigNumber base[8], + const BigNumber pow[8], + BigNumber m[8]) { + mbx_status st = MBX_STATUS_OK; + + // Memory used for multi-buffered modular exponentiation + Ipp64u* out_x[8]; + + int64u* b_array[8]; + int64u* p_array[8]; + + int bufferLen; + Ipp8u* pBuffer; + + // setup buffer for mbx_exp + int bits = m[0].BitSize(); + int dwords = BITSIZE_DWORD(bits); + bufferLen = mbx_exp_BufferSize(bits); + pBuffer = reinterpret_cast(alloca(bufferLen)); + if (nullptr == pBuffer) throw std::runtime_error("error alloc memory"); + + int length = dwords * sizeof(int64u); + for (int i = 0; i < 8; i++) { + out_x[i] = reinterpret_cast(alloca(length)); + + b_array[i] = reinterpret_cast(alloca(length)); + p_array[i] = reinterpret_cast(alloca(length)); + + if (nullptr == out_x[i] || nullptr == b_array[i] || nullptr == p_array[i]) + throw std::runtime_error("error alloc memory"); + } + + for (int i = 0; i < 8; i++) { + memset(b_array[i], 0, dwords * 8); + memset(p_array[i], 0, dwords * 8); + } + + Ipp32u *pow_b[8], *pow_p[8], *pow_nsquare[8]; + int bBitLen, pBitLen, nsqBitLen; + int expBitLen = 0; + for (int i = 0; i < 8; i++) { + ippsRef_BN(nullptr, &bBitLen, &pow_b[i], base[i]); + ippsRef_BN(nullptr, &pBitLen, &pow_p[i], pow[i]); + ippsRef_BN(nullptr, &nsqBitLen, &pow_nsquare[i], m[i]); + + memcpy(b_array[i], pow_b[i], BITSIZE_WORD(bBitLen) * 4); + memcpy(p_array[i], pow_p[i], BITSIZE_WORD(pBitLen) * 4); + if (expBitLen < pBitLen) expBitLen = pBitLen; + } + + /* + *Note: If actual sizes of exp are different, set the exp_bits parameter equal + *to maximum size of the actual module in bit size and extend all the modules + *with zero bits + */ + st = mbx_exp_mb8(out_x, b_array, p_array, expBitLen, + reinterpret_cast(pow_nsquare), nsqBitLen, pBuffer, + bufferLen); + + for (int i = 0; i < 8; i++) { + if (MBX_STATUS_OK != MBX_GET_STS(st, i)) + throw std::runtime_error( + std::string("error multi buffered exp modules, error code = ") + + std::to_string(MBX_GET_STS(st, i))); + } + + // It is important to hold a copy of nsquare for thread-safe purpose + BigNumber bn_c(m[0]); + for (int i = 0; i < 8; i++) { + bn_c.Set(reinterpret_cast(out_x[i]), BITSIZE_WORD(nsqBitLen), + IppsBigNumPOS); + + res[i] = bn_c; + } +} + +BigNumber PaillierPublicKey::ippMontExp(const BigNumber& base, + const BigNumber& pow, + const BigNumber& m) { + IppStatus st = ippStsNoErr; + // It is important to declear res * bform bit length refer to ipp-crypto spec: + // R should not be less than the data length of the modulus m + BigNumber res(m); + + int bnBitLen; + Ipp32u* pow_m; + ippsRef_BN(nullptr, &bnBitLen, &pow_m, BN(m)); + int nlen = BITSIZE_WORD(bnBitLen); + + int size; + // define and initialize Montgomery Engine over Modulus N + ippsMontGetSize(IppsBinaryMethod, nlen, &size); + IppsMontState* pMont = reinterpret_cast(new Ipp8u[size]); + if (nullptr == pMont) throw std::runtime_error("error alloc memory"); + ippsMontInit(IppsBinaryMethod, nlen, pMont); + ippsMontSet(pow_m, nlen, pMont); + + // encode base into Montfomery form + BigNumber bform(m); + ippsMontForm(BN(base), pMont, BN(bform)); + + // compute R = base^pow mod N + st = ippsMontExp(BN(bform), BN(pow), pMont, BN(res)); + if (ippStsNoErr != st) + throw std::runtime_error(std::string("ippsMontExp error code = ") + + std::to_string(st)); + + BigNumber one(1); + st = ippsMontMul(BN(res), BN(one), pMont, BN(res)); // R = MontMul(R,1) + if (ippStsNoErr != st) + throw std::runtime_error(std::string("ippsMontMul error code = ") + + std::to_string(st)); + + delete[] reinterpret_cast(pMont); + return res; +} + +BigNumber PaillierPublicKey::IPP_invert(BigNumber a, BigNumber b) { + return b.InverseMul(a); +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..60d56d8 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,15 @@ +# Unit tests + +# main unittest +add_executable(unit-test test.cpp) +target_include_directories(unit-test PUBLIC ${IPCL_INC_DIR}) +target_link_libraries(unit-test PRIVATE ipcl libgtest Threads::Threads) + +# omp unittest +if(IPCL_TEST_OMP) + find_package(OpenMP REQUIRED) + + add_executable(unit-test_omp test_omp.cpp) + target_include_directories(unit-test_omp PUBLIC ${IPCL_INC_DIR}) + target_link_libraries(unit-test_omp PRIVATE ipcl OpenMP::OpenMP_CXX libgtest Threads::Threads) +endif() diff --git a/test/test.cpp b/test/test.cpp new file mode 100644 index 0000000..7ef35f0 --- /dev/null +++ b/test/test.cpp @@ -0,0 +1,404 @@ +// Copyright (C) 2021-2022 Intel Corporation + +#include +#include +#include +#include + +#include "gtest/gtest.h" +#include "ipcl/key_pair.hpp" +#include "ipcl/paillier_ops.hpp" + +const int numRuns = 10; +clock_t t1, t2; +double time_ms; + +#define BENCHMARK(target, x) \ + for (int i = 0; i < 2; ++i) x t1 = clock(); \ + for (int i = 0; i < numRuns; ++i) x t2 = clock(); \ + \ + time_ms = static_cast(t2 - t1) / CLOCKS_PER_SEC; \ + std::cout << target << " " << time_ms * 1000 / numRuns << "ms" << std::endl; + +void CtPlusCt(BigNumber res[8], BigNumber ct1[8], BigNumber ct2[8], + keyPair key) { + for (int i = 0; i < 8; i++) { + PaillierEncryptedNumber a(key.pub_key, ct1[i]); + PaillierEncryptedNumber b(key.pub_key, ct2[i]); + PaillierEncryptedNumber sum = a + b; + res[i] = sum.getBN(); + } +} + +void CtPlusCtArray(BigNumber res[8], BigNumber ct1[8], BigNumber ct2[8], + keyPair key) { + PaillierEncryptedNumber a(key.pub_key, ct1); + PaillierEncryptedNumber b(key.pub_key, ct2); + PaillierEncryptedNumber sum = a + b; + sum.getArrayBN(res); +} + +void CtPlusPt(BigNumber res[8], BigNumber ct1[8], uint32_t pt2[8], + keyPair key) { + for (int i = 0; i < 8; i++) { + PaillierEncryptedNumber a(key.pub_key, ct1[i]); + BigNumber b = pt2[i]; + PaillierEncryptedNumber sum = a + b; + res[i] = sum.getBN(); + } +} + +void CtPlusPtArray(BigNumber res[8], BigNumber ct1[8], BigNumber ptbn2[8], + keyPair key) { + BigNumber stmp[8]; + PaillierEncryptedNumber a(key.pub_key, ct1); + PaillierEncryptedNumber sum = a + ptbn2; + sum.getArrayBN(res); +} + +void CtMultiplyPt(BigNumber res[8], BigNumber ct1[8], uint32_t pt2[8], + keyPair key) { + for (int i = 0; i < 8; i++) { + PaillierEncryptedNumber a(key.pub_key, ct1[i]); + PaillierEncryptedNumber b(key.pub_key, pt2[i]); + PaillierEncryptedNumber sum = a * b; + res[i] = sum.getBN(); + } +} + +void CtMultiplyPtArray(BigNumber res[8], BigNumber ct1[8], uint32_t pt2[8], + keyPair key) { + PaillierEncryptedNumber a(key.pub_key, ct1); + PaillierEncryptedNumber b(key.pub_key, pt2); + PaillierEncryptedNumber sum = a * b; + sum.getArrayBN(res); +} + +void AddSub(BigNumber res[8], BigNumber ct1[8], BigNumber ct2[8], keyPair key) { + for (int i = 0; i < 8; i++) { + PaillierEncryptedNumber a(key.pub_key, ct1[i]); + PaillierEncryptedNumber b(key.pub_key, ct2[i]); + BigNumber m1(2); + a = a + b * m1; + PaillierEncryptedNumber sum = a + b; + res[i] = sum.getBN(); + } +} + +TEST(OperationTest, CtPlusCtTest) { + keyPair key = generateKeypair(2048); + + BigNumber ct1[8], ct2[8]; + BigNumber dt[8], res[8]; + + uint32_t pt1[8], pt2[8]; + BigNumber ptbn1[8], ptbn2[8]; + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < 8; i++) { + pt1[i] = dist(rng); + pt2[i] = dist(rng); + ptbn1[i] = pt1[i]; + ptbn2[i] = pt2[i]; + } + + key.pub_key->encrypt(ct1, ptbn1); + key.pub_key->encrypt(ct2, ptbn2); + + BENCHMARK("Paillier CT + CT", CtPlusCt(res, ct1, ct2, key);); + + key.priv_key->decrypt(dt, res); + + for (int i = 0; i < 8; i++) { + vector v; + dt[i].num2vec(v); + + uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; + uint64_t v_dp = v[0]; + if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + + EXPECT_EQ(v_dp, v_pp); + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, CtPlusCtArrayTest) { + keyPair key = generateKeypair(2048); + + BigNumber ct1[8], ct2[8]; + BigNumber dt[8], res[8]; + + uint32_t pt1[8], pt2[8]; + BigNumber ptbn1[8], ptbn2[8]; + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < 8; i++) { + pt1[i] = dist(rng); + pt2[i] = dist(rng); + ptbn1[i] = pt1[i]; + ptbn2[i] = pt2[i]; + } + + key.pub_key->encrypt(ct1, ptbn1); + key.pub_key->encrypt(ct2, ptbn2); + + BENCHMARK("Paillier array CT + CT", CtPlusCtArray(res, ct1, ct2, key);); + + key.priv_key->decrypt(dt, res); + + for (int i = 0; i < 8; i++) { + vector v; + dt[i].num2vec(v); + + uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; + uint64_t v_dp = v[0]; + if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + + EXPECT_EQ(v_dp, v_pp); + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, CtPlusPtTest) { + keyPair key = generateKeypair(2048); + + BigNumber ct1[8], ct2[8]; + BigNumber dt[8], res[8]; + + uint32_t pt1[8], pt2[8]; + BigNumber ptbn1[8]; + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < 8; i++) { + pt1[i] = dist(rng); + pt2[i] = dist(rng); + ptbn1[i] = pt1[i]; + } + + key.pub_key->encrypt(ct1, ptbn1); + + BENCHMARK("Paillier CT + PT", CtPlusPt(res, ct1, pt2, key);); + + key.priv_key->decrypt(dt, res); + + for (int i = 0; i < 8; i++) { + vector v; + dt[i].num2vec(v); + + uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; + uint64_t v_dp = v[0]; + if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + + EXPECT_EQ(v_dp, v_pp); + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, CtPlusPtArrayTest) { + keyPair key = generateKeypair(2048); + + BigNumber ct1[8], ct2[8]; + BigNumber dt[8], res[8]; + + uint32_t pt1[8], pt2[8]; + BigNumber ptbn1[8], ptbn2[8]; + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < 8; i++) { + pt1[i] = dist(rng); + pt2[i] = dist(rng); + ptbn1[i] = pt1[i]; + ptbn2[i] = pt2[i]; + } + + key.pub_key->encrypt(ct1, ptbn1); + + BENCHMARK("Paillier array CT + PT", CtPlusPtArray(res, ct1, ptbn2, key);); + + key.priv_key->decrypt(dt, res); + + for (int i = 0; i < 8; i++) { + vector v; + dt[i].num2vec(v); + + uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; + uint64_t v_dp = v[0]; + if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + + EXPECT_EQ(v_dp, v_pp); + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, CtMultiplyPtTest) { + keyPair key = generateKeypair(2048); + + BigNumber ct1[8], ct2[8]; + BigNumber dt[8], res[8]; + + uint32_t pt1[8], pt2[8]; + BigNumber ptbn1[8]; + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < 8; i++) { + pt1[i] = dist(rng); + pt2[i] = dist(rng); + ptbn1[i] = pt1[i]; + } + + key.pub_key->encrypt(ct1, ptbn1); + + BENCHMARK("Paillier CT * PT", CtMultiplyPt(res, ct1, pt2, key);); + + key.priv_key->decrypt(dt, res); + + for (int i = 0; i < 8; i++) { + vector v; + dt[i].num2vec(v); + + uint64_t v_pp = (uint64_t)pt1[i] * (uint64_t)pt2[i]; + uint64_t v_dp = v[0]; + if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + + EXPECT_EQ(v_dp, v_pp); + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, CtMultiplyPtArrayTest) { + keyPair key = generateKeypair(2048); + + BigNumber ct1[8]; + BigNumber dt[8], res[8]; + + uint32_t pt1[8], pt2[8]; + BigNumber ptbn1[8], ptbn2[8]; + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < 8; i++) { + pt1[i] = dist(rng); + pt2[i] = dist(rng); + ptbn1[i] = pt1[i]; + ptbn2[i] = pt2[i]; + } + + key.pub_key->encrypt(ct1, ptbn1); + + BENCHMARK("Paillier multi-buffered CT * PT", + CtMultiplyPtArray(res, ct1, pt2, key);); + + key.priv_key->decrypt(dt, res); + + for (int i = 0; i < 8; i++) { + vector v; + dt[i].num2vec(v); + + uint64_t v_pp = (uint64_t)pt1[i] * (uint64_t)pt2[i]; + uint64_t v_dp = v[0]; + if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + + EXPECT_EQ(v_dp, v_pp); + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, AddSubTest) { + keyPair key = generateKeypair(2048); + + BigNumber ct1[8], ct2[8]; + BigNumber dt[8], res[8]; + + uint32_t pt1[8], pt2[8]; + BigNumber ptbn1[8], ptbn2[8]; + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < 8; i++) { + pt1[i] = dist(rng); + pt2[i] = dist(rng); + ptbn1[i] = pt1[i]; + ptbn2[i] = pt2[i]; + } + + key.pub_key->encrypt(ct1, ptbn1); + key.pub_key->encrypt(ct2, ptbn2); + + BENCHMARK("Paillier addsub", AddSub(res, ct1, ct2, key);); + key.priv_key->decrypt(dt, res); + + for (int i = 0; i < 8; i++) { + vector v; + dt[i].num2vec(v); + + uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i] * 3; + uint64_t v_dp = v[0]; + if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + + EXPECT_EQ(v_dp, v_pp); + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(CryptoTest, CryptoTest) { + keyPair key = generateKeypair(2048); + + BigNumber ct[8]; + BigNumber dt[8]; + + uint32_t pt[8]; + BigNumber ptbn[8]; + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < 8; i++) { + pt[i] = dist(rng); + ptbn[i] = pt[i]; + } + + BENCHMARK("Paillier Encryption", key.pub_key->encrypt(ct, ptbn);); + BENCHMARK("Paillier Decryption", key.priv_key->decrypt(dt, ct);); + + for (int i = 0; i < 8; i++) { + vector v; + dt[i].num2vec(v); + EXPECT_EQ(v[0], pt[i]); + } + + delete key.pub_key; + delete key.priv_key; +} + +int main(int argc, char** argv) { + // Use system clock for seed + srand(time(nullptr)); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/test_omp.cpp b/test/test_omp.cpp new file mode 100644 index 0000000..6792e91 --- /dev/null +++ b/test/test_omp.cpp @@ -0,0 +1,549 @@ +// Copyright (C) 2021-2022 Intel Corporation + +#include +#include + +#include +#include +#include + +#include "ipcl/key_pair.hpp" +#include "ipcl/paillier_ops.hpp" + +const int numRuns = 10; +double t1, t2; +double time_ms; + +#define BENCHMARK(target, x) \ + for (int i = 0; i < 2; ++i) x t1 = omp_get_wtime(); \ + for (int i = 0; i < numRuns; ++i) x t2 = omp_get_wtime(); \ + \ + time_ms = static_cast(t2 - t1); \ + std::cout << target << " " << time_ms * 1000.f / numRuns << "ms" << std::endl; + +void Encryption(int num_threads, vector v_ct, + vector v_ptbn, keyPair key) { +#pragma omp parallel for + for (int i = 0; i < num_threads; i++) { + key.pub_key->encrypt(v_ct[i], v_ptbn[i]); + } +} + +void Decryption(int num_threads, vector v_dt, + vector v_ct, keyPair key) { +#pragma omp parallel for + for (int i = 0; i < num_threads; i++) { + key.priv_key->decrypt(v_dt[i], v_ct[i]); + } +} + +void CtPlusCt(int num_threads, vector v_sum, + vector v_ct1, vector v_ct2, keyPair key) { +#pragma omp parallel for + for (int i = 0; i < num_threads; i++) { + for (int j = 0; j < 8; j++) { + PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); + PaillierEncryptedNumber b(key.pub_key, v_ct2[i][j]); + PaillierEncryptedNumber sum = a + b; + v_sum[i][j] = sum.getBN(); + } + } +} + +void CtPlusPt(int num_threads, vector v_sum, + vector v_ct1, vector v_pt2, keyPair key) { +#pragma omp parallel for + for (int i = 0; i < num_threads; i++) { + for (int j = 0; j < 8; j++) { + BigNumber b = v_pt2[i][j]; + PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); + PaillierEncryptedNumber sum = a + b; + v_sum[i][j] = sum.getBN(); + } + } +} + +void CtPlusPtArray(int num_threads, vector v_sum, + vector v_ct1, vector v_pt2, + keyPair key) { +#pragma omp parallel for + for (int i = 0; i < num_threads; i++) { + PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); + BigNumber b[8]; + for (int j = 0; j < 8; j++) { + b[j] = v_pt2[i][j]; + } + PaillierEncryptedNumber sum = a + b; + sum.getArrayBN(v_sum[i]); + } +} + +void CtMultiplyPt(int num_threads, vector v_product, + vector v_ct1, vector v_pt2, + keyPair key) { +#pragma omp parallel for + for (int i = 0; i < num_threads; i++) { + for (int j = 0; j < 8; j++) { + PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); + BigNumber b = v_pt2[i][j]; + PaillierEncryptedNumber product = a * b; + v_product[i][j] = product.getBN(); + } + } +} + +void CtMultiplyPtArray(int num_threads, vector v_product, + vector v_ct1, vector v_pt2, + keyPair key) { +#pragma omp parallel for + for (int i = 0; i < num_threads; i++) { + PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); + PaillierEncryptedNumber b(key.pub_key, v_pt2[i]); + PaillierEncryptedNumber product = a * b; + product.getArrayBN(v_product[i]); + } +} + +TEST(OperationTest, CtPlusCtTest) { + keyPair key = generateKeypair(2048); + + size_t num_threads = omp_get_max_threads(); + // std::cout << "available threads: " << num_threads << std::endl; + + std::vector v_ct1(num_threads); + std::vector v_ct2(num_threads); + std::vector v_dt(num_threads); + std::vector v_sum(num_threads); + std::vector v_pt1(num_threads); + std::vector v_pt2(num_threads); + std::vector v_ptbn1(num_threads); + std::vector v_ptbn2(num_threads); + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < num_threads; i++) { + v_ct1[i] = new BigNumber[8]; + v_ct2[i] = new BigNumber[8]; + v_dt[i] = new BigNumber[8]; + v_sum[i] = new BigNumber[8]; + v_pt1[i] = new uint32_t[8]; + v_pt2[i] = new uint32_t[8]; + v_ptbn1[i] = new BigNumber[8]; + v_ptbn2[i] = new BigNumber[8]; + + // for each threads, generated different rand testing value + for (int j = 0; j < 8; j++) { + v_pt1[i][j] = dist(rng); + v_pt2[i][j] = dist(rng); + v_ptbn1[i][j] = v_pt1[i][j]; + v_ptbn2[i][j] = v_pt2[i][j]; + } + } + +#pragma omp parallel for + for (int i = 0; i < num_threads; i++) { + key.pub_key->encrypt(v_ct1[i], v_ptbn1[i]); + key.pub_key->encrypt(v_ct2[i], v_ptbn2[i]); + } + + BENCHMARK("OMP Paillier CT + CT", + CtPlusCt(num_threads, v_sum, v_ct1, v_ct2, key);); + +#pragma omp parallel for + for (int i = 0; i < num_threads; i++) { + key.priv_key->decrypt(v_dt[i], v_sum[i]); + } + + // check output for all threads + for (int i = 0; i < num_threads; i++) { + for (int j = 0; j < 8; j++) { + std::vector v; + v_dt[i][j].num2vec(v); + + uint64_t v_pp = (uint64_t)v_pt1[i][j] + (uint64_t)v_pt2[i][j]; + uint64_t v_dp = v[0]; + if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + + EXPECT_EQ(v_dp, v_pp); + } + } + + for (int i = 0; i < num_threads; i++) { + delete[] v_ct1[i]; + delete[] v_ct2[i]; + delete[] v_dt[i]; + delete[] v_pt1[i]; + delete[] v_pt2[i]; + delete[] v_ptbn1[i]; + delete[] v_ptbn2[i]; + delete[] v_sum[i]; + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, CtPlusPtTest) { + keyPair key = generateKeypair(2048); + + size_t num_threads = omp_get_max_threads(); + + std::vector v_ct1(num_threads); + std::vector v_dt(num_threads); + std::vector v_sum(num_threads); + std::vector v_pt1(num_threads); + std::vector v_pt2(num_threads); + std::vector v_ptbn1(num_threads); + std::vector v_ptbn2(num_threads); + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < num_threads; i++) { + v_ct1[i] = new BigNumber[8]; + v_dt[i] = new BigNumber[8]; + v_sum[i] = new BigNumber[8]; + v_pt1[i] = new uint32_t[8]; + v_pt2[i] = new uint32_t[8]; + v_ptbn1[i] = new BigNumber[8]; + v_ptbn2[i] = new BigNumber[8]; + + // for each threads, generated different rand testing value + for (int j = 0; j < 8; j++) { + v_pt1[i][j] = dist(rng); + v_pt2[i][j] = dist(rng); + v_ptbn1[i][j] = v_pt1[i][j]; + v_ptbn2[i][j] = v_pt2[i][j]; + } + } + +#pragma omp parallel for + for (int i = 0; i < num_threads; i++) { + key.pub_key->encrypt(v_ct1[i], v_ptbn1[i]); + } + + BENCHMARK("OMP Paillier CT + PT", + CtPlusPt(num_threads, v_sum, v_ct1, v_pt2, key);); + +#pragma omp parallel for + for (int i = 0; i < num_threads; i++) { + key.priv_key->decrypt(v_dt[i], v_sum[i]); + } + + // check output for all threads + for (int i = 0; i < num_threads; i++) { + for (int j = 0; j < 8; j++) { + std::vector v; + v_dt[i][j].num2vec(v); + + uint64_t v_pp = (uint64_t)v_pt1[i][j] + (uint64_t)v_pt2[i][j]; + uint64_t v_dp = v[0]; + if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + + EXPECT_EQ(v_dp, v_pp); + } + } + + for (int i = 0; i < num_threads; i++) { + delete[] v_ct1[i]; + delete[] v_dt[i]; + delete[] v_pt1[i]; + delete[] v_pt2[i]; + delete[] v_ptbn1[i]; + delete[] v_ptbn2[i]; + delete[] v_sum[i]; + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, CtPlusPtArrayTest) { + keyPair key = generateKeypair(2048); + + size_t num_threads = omp_get_max_threads(); + std::cout << "available threads: " << num_threads << std::endl; + + std::vector v_ct1(num_threads); + std::vector v_dt(num_threads); + std::vector v_sum(num_threads); + std::vector v_pt1(num_threads); + std::vector v_pt2(num_threads); + std::vector v_ptbn1(num_threads); + std::vector v_ptbn2(num_threads); + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < num_threads; i++) { + v_ct1[i] = new BigNumber[8]; + v_dt[i] = new BigNumber[8]; + v_sum[i] = new BigNumber[8]; + v_pt1[i] = new uint32_t[8]; + v_pt2[i] = new uint32_t[8]; + v_ptbn1[i] = new BigNumber[8]; + v_ptbn2[i] = new BigNumber[8]; + + // for each threads, generated different rand testing value + for (int j = 0; j < 8; j++) { + v_pt1[i][j] = dist(rng); + v_pt2[i][j] = dist(rng); + v_ptbn1[i][j] = v_pt1[i][j]; + v_ptbn2[i][j] = v_pt2[i][j]; + } + } + +#pragma omp parallel for + for (int i = 0; i < num_threads; i++) { + key.pub_key->encrypt(v_ct1[i], v_ptbn1[i]); + } + + BENCHMARK("OMP array Paillier CT + PT", + CtPlusPtArray(num_threads, v_sum, v_ct1, v_pt2, key);); + +#pragma omp parallel for + for (int i = 0; i < num_threads; i++) { + key.priv_key->decrypt(v_dt[i], v_sum[i]); + } + + // check output for all threads + for (int i = 0; i < num_threads; i++) { + for (int j = 0; j < 8; j++) { + std::vector v; + v_dt[i][j].num2vec(v); + + uint64_t v_pp = (uint64_t)v_pt1[i][j] + (uint64_t)v_pt2[i][j]; + uint64_t v_dp = v[0]; + if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + + EXPECT_EQ(v_dp, v_pp); + } + } + + for (int i = 0; i < num_threads; i++) { + delete[] v_ct1[i]; + delete[] v_dt[i]; + delete[] v_pt1[i]; + delete[] v_pt2[i]; + delete[] v_ptbn1[i]; + delete[] v_ptbn2[i]; + delete[] v_sum[i]; + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, test_CtMultiplyPt) { + keyPair key = generateKeypair(2048); + + size_t num_threads = omp_get_max_threads(); + // std::cout << "available threads: " << num_threads << std::endl; + + std::vector v_ct1(num_threads); + std::vector v_dt(num_threads); + std::vector v_product(num_threads); + std::vector v_pt1(num_threads); + std::vector v_pt2(num_threads); + std::vector v_ptbn1(num_threads); + std::vector v_ptbn2(num_threads); + + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < num_threads; i++) { + v_ct1[i] = new BigNumber[8]; + v_dt[i] = new BigNumber[8]; + v_product[i] = new BigNumber[8]; + v_pt1[i] = new uint32_t[8]; + v_pt2[i] = new uint32_t[8]; + v_ptbn1[i] = new BigNumber[8]; + v_ptbn2[i] = new BigNumber[8]; + + // for each threads, generated different rand testing value + for (int j = 0; j < 8; j++) { + v_pt1[i][j] = dist(rng); + v_pt2[i][j] = dist(rng); + v_ptbn1[i][j] = v_pt1[i][j]; + v_ptbn2[i][j] = v_pt2[i][j]; + } + } + +#pragma omp parallel for + for (int i = 0; i < num_threads; i++) { + key.pub_key->encrypt(v_ct1[i], v_ptbn1[i]); + } + + BENCHMARK("OMP Paillier CT * PT", + CtMultiplyPt(num_threads, v_product, v_ct1, v_pt2, key);); + +#pragma omp parallel for + for (int i = 0; i < num_threads; i++) { + key.priv_key->decrypt(v_dt[i], v_product[i]); + } + + // check output for all threads + for (int i = 0; i < num_threads; i++) { + for (int j = 0; j < 8; j++) { + std::vector v; + v_dt[i][j].num2vec(v); + + uint64_t v_pp = (uint64_t)v_pt1[i][j] * (uint64_t)v_pt2[i][j]; + uint64_t v_dp = v[0]; + if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + EXPECT_EQ(v_dp, v_pp); + } + } + + for (int i = 0; i < num_threads; i++) { + delete[] v_ct1[i]; + delete[] v_dt[i]; + delete[] v_pt1[i]; + delete[] v_pt2[i]; + delete[] v_ptbn1[i]; + delete[] v_ptbn2[i]; + delete[] v_product[i]; + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, test_CtMultiplyPtArray) { + keyPair key = generateKeypair(2048); + + size_t num_threads = omp_get_max_threads(); + // std::cout << "available threads: " << num_threads << std::endl; + + std::vector v_ct1(num_threads); + std::vector v_dt(num_threads); + std::vector v_product(num_threads); + std::vector v_pt1(num_threads); + std::vector v_pt2(num_threads); + std::vector v_ptbn1(num_threads); + std::vector v_ptbn2(num_threads); + + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < num_threads; i++) { + v_ct1[i] = new BigNumber[8]; + v_dt[i] = new BigNumber[8]; + v_product[i] = new BigNumber[8]; + v_pt1[i] = new uint32_t[8]; + v_pt2[i] = new uint32_t[8]; + v_ptbn1[i] = new BigNumber[8]; + v_ptbn2[i] = new BigNumber[8]; + + // for each threads, generated different rand testing value + + for (int j = 0; j < 8; j++) { + v_pt1[i][j] = dist(rng); + v_pt2[i][j] = dist(rng); + v_ptbn1[i][j] = v_pt1[i][j]; + v_ptbn2[i][j] = v_pt2[i][j]; + } + } + + for (int i = 0; i < num_threads; i++) { + key.pub_key->encrypt(v_ct1[i], v_ptbn1[i]); + } + + BENCHMARK("OMP Paillier multi-buffered CT * PT", + CtMultiplyPtArray(num_threads, v_product, v_ct1, v_pt2, key);); + +#pragma omp parallel for + for (int i = 0; i < num_threads; i++) { + key.priv_key->decrypt(v_dt[i], v_product[i]); + } + + // check output for all threads + for (int i = 0; i < num_threads; i++) { + for (int j = 0; j < 8; j++) { + std::vector v; + v_dt[i][j].num2vec(v); + + uint64_t v_pp = (uint64_t)v_pt1[i][j] * (uint64_t)v_pt2[i][j]; + uint64_t v_dp = v[0]; + if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + EXPECT_EQ(v_dp, v_pp); + } + } + + for (int i = 0; i < num_threads; i++) { + delete[] v_ct1[i]; + delete[] v_dt[i]; + delete[] v_pt1[i]; + delete[] v_pt2[i]; + delete[] v_ptbn1[i]; + delete[] v_ptbn2[i]; + delete[] v_product[i]; + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(CryptoTest, CryptoTest) { + // use one keypair to do several encryption/decryption + keyPair key = generateKeypair(2048); + + size_t num_threads = omp_get_max_threads(); + // std::cout << "available threads: " << num_threads << std::endl; + + std::vector v_ct(num_threads); + std::vector v_dt(num_threads); + std::vector v_pt(num_threads); + std::vector v_ptbn(num_threads); + + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < num_threads; i++) { + v_ct[i] = new BigNumber[8]; + v_dt[i] = new BigNumber[8]; + v_pt[i] = new uint32_t[8]; + v_ptbn[i] = new BigNumber[8]; + + // for each threads, generated different rand testing value + for (int j = 0; j < 8; j++) { + v_pt[i][j] = dist(rng); + v_ptbn[i][j] = v_pt[i][j]; + } + } + + BENCHMARK("OMP Paillier Encryption", + Encryption(num_threads, v_ct, v_ptbn, key);); + BENCHMARK("OMP Paillier Decryption", + Decryption(num_threads, v_dt, v_ct, key);); + + // check output for all threads + for (int i = 0; i < num_threads; i++) { + for (int j = 0; j < 8; j++) { + std::vector v; + v_dt[i][j].num2vec(v); + EXPECT_EQ(v[0], v_pt[i][j]); + } + } + + for (int i = 0; i < num_threads; i++) { + delete[] v_ct[i]; + delete[] v_dt[i]; + delete[] v_pt[i]; + delete[] v_ptbn[i]; + } + + delete key.pub_key; + delete key.priv_key; +} + +int main(int argc, char** argv) { + // Use system clock for seed + srand(time(nullptr)); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} From a7129be0748bca09e73a6bdf3317d08d7a89f6ab Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Thu, 17 Feb 2022 12:27:42 -0800 Subject: [PATCH 002/364] CI/CD test --- ipcl/CMakeLists.txt | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 4e05963..e4dbd21 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -1,17 +1,5 @@ # Copyright (C) 2021-2022 Intel Corporation -# # BigNumber library -# add_library(bignum SHARED -# bignum.cpp) -# target_include_directories(bignum -# PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} -# PUBLIC ${IPCL_INC_DIR} -# ) -# target_link_libraries(bignum PRIVATE libippcrypto Threads::Threads) - - -# Ipp-crypto Paillier Library - set(IPCL_SRCS paillier_pri.cpp paillier_pub.cpp paillier_ops.cpp @@ -47,7 +35,8 @@ else() target_link_libraries(ipcl PRIVATE OpenSSL::SSL OpenSSL::Crypto) ipcl_create_archive(ipcl libippcrypto::ippcp) ipcl_create_archive(ipcl libippcrypto::crypto_mb) - target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) + target_link_libraries(ipcl PRIVATE libippcrypto Threads::Threads) + # target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) endif() From b50c5c1dfa2a73bab4e7628fb0ee22f7dbc33d82 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Thu, 17 Feb 2022 12:41:43 -0800 Subject: [PATCH 003/364] testing --- cmake/ippcrypto.cmake | 1 - ipcl/CMakeLists.txt | 4 ++-- ipcl/include/ipcl/bignum.h | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake index da7c349..02d8b1f 100644 --- a/cmake/ippcrypto.cmake +++ b/cmake/ippcrypto.cmake @@ -31,7 +31,6 @@ ExternalProject_Add( UPDATE_COMMAND "" ) -# needed to setup interface file(MAKE_DIRECTORY ${IPPCRYPTO_PREFIX}/include) set(IPPCRYPTO_INC_DIR ${IPPCRYPTO_PREFIX}/include) ExternalProject_Get_Property(ext_ipp-crypto SOURCE_DIR BINARY_DIR) diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index e4dbd21..324437b 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -30,13 +30,13 @@ install(DIRECTORY ${IPCL_INC_DIR}/ if(IPCL_SHARED) target_link_libraries(ipcl PRIVATE libippcrypto Threads::Threads) + target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) else() target_link_libraries(ipcl PRIVATE Threads::Threads) target_link_libraries(ipcl PRIVATE OpenSSL::SSL OpenSSL::Crypto) ipcl_create_archive(ipcl libippcrypto::ippcp) ipcl_create_archive(ipcl libippcrypto::crypto_mb) - target_link_libraries(ipcl PRIVATE libippcrypto Threads::Threads) - # target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) + target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) endif() diff --git a/ipcl/include/ipcl/bignum.h b/ipcl/include/ipcl/bignum.h index 7e87853..9fa2f7d 100644 --- a/ipcl/include/ipcl/bignum.h +++ b/ipcl/include/ipcl/bignum.h @@ -17,11 +17,11 @@ #ifndef _BIGNUM_H_ #define _BIGNUM_H_ +#include + #include #include -#include "ippcp.h" - using namespace std; class BigNumber { From 1458207444c9b368bf9fa160531c430c8286f1be Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Thu, 17 Feb 2022 13:08:19 -0800 Subject: [PATCH 004/364] fix WIP --- benchmark/CMakeLists.txt | 5 +++-- ipcl/CMakeLists.txt | 4 ++-- test/CMakeLists.txt | 5 +++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index fc96711..aeba17e 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -6,14 +6,15 @@ set(SRC main.cpp add_executable(bench_ipcl ${SRC}) target_include_directories(bench_ipcl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - ${IPP_PAILLIER_INC_DIR} + ${IPCL_INC_DIR} + ) target_link_libraries(bench_ipcl PRIVATE ipcl libgbenchmark Threads::Threads ) -if(IPP_PAILLIER_TEST_OMP) +if(IPCL_TEST_OMP) find_package(OpenMP REQUIRED) add_compile_definitions(BENCHMARK_OMP) target_link_libraries(bench_ipcl PRIVATE OpenMP::OpenMP_CXX) diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 324437b..6068ef2 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -30,13 +30,13 @@ install(DIRECTORY ${IPCL_INC_DIR}/ if(IPCL_SHARED) target_link_libraries(ipcl PRIVATE libippcrypto Threads::Threads) - target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) + target_include_directories(ipcl PUBLIC ${IPPCRYPTO_INC_DIR}) else() target_link_libraries(ipcl PRIVATE Threads::Threads) target_link_libraries(ipcl PRIVATE OpenSSL::SSL OpenSSL::Crypto) ipcl_create_archive(ipcl libippcrypto::ippcp) ipcl_create_archive(ipcl libippcrypto::crypto_mb) - target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) + target_include_directories(ipcl PUBLIC ${IPPCRYPTO_INC_DIR}) endif() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 60d56d8..9f002ba 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,15 +1,16 @@ # Unit tests +message(STATUS "TEST ==== ippcrypto inc dir: ${IPPCRYPTO_INC_DIR}") # main unittest add_executable(unit-test test.cpp) -target_include_directories(unit-test PUBLIC ${IPCL_INC_DIR}) target_link_libraries(unit-test PRIVATE ipcl libgtest Threads::Threads) +target_include_directories(unit-test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${IPCL_INC_DIR} ${IPPCRYPTO_INC_DIR}) # omp unittest if(IPCL_TEST_OMP) find_package(OpenMP REQUIRED) add_executable(unit-test_omp test_omp.cpp) - target_include_directories(unit-test_omp PUBLIC ${IPCL_INC_DIR}) target_link_libraries(unit-test_omp PRIVATE ipcl OpenMP::OpenMP_CXX libgtest Threads::Threads) + target_include_directories(unit-test_omp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${IPCL_INC_DIR} ${IPPCRYPTO_INC_DIR}) endif() From e245d14b8fc970aa1272732e7d0f0ac92d41f1f9 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Thu, 17 Feb 2022 13:13:19 -0800 Subject: [PATCH 005/364] Fixed private includes error --- benchmark/CMakeLists.txt | 2 +- ipcl/CMakeLists.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index aeba17e..64aef81 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -7,7 +7,7 @@ add_executable(bench_ipcl ${SRC}) target_include_directories(bench_ipcl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${IPCL_INC_DIR} - + ${IPPCRYPTO_INC_DIR} ) target_link_libraries(bench_ipcl PRIVATE diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 6068ef2..324437b 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -30,13 +30,13 @@ install(DIRECTORY ${IPCL_INC_DIR}/ if(IPCL_SHARED) target_link_libraries(ipcl PRIVATE libippcrypto Threads::Threads) - target_include_directories(ipcl PUBLIC ${IPPCRYPTO_INC_DIR}) + target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) else() target_link_libraries(ipcl PRIVATE Threads::Threads) target_link_libraries(ipcl PRIVATE OpenSSL::SSL OpenSSL::Crypto) ipcl_create_archive(ipcl libippcrypto::ippcp) ipcl_create_archive(ipcl libippcrypto::crypto_mb) - target_include_directories(ipcl PUBLIC ${IPPCRYPTO_INC_DIR}) + target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) endif() From 97a40e148be2c2cbe7815971096b1e061843ab2b Mon Sep 17 00:00:00 2001 From: sejunkim Date: Thu, 17 Feb 2022 13:19:03 -0800 Subject: [PATCH 006/364] Minor fixes - Old names (ipp paillier) replaced with ipcl - Typo fixes --- README.md | 2 +- cmake/ippcrypto.cmake | 2 +- docs/CMakeLists.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8688533..41e4325 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ cmake --build build --target benchmark ``` OpenMP benchmarks will automatically be applied if `-DIPCL_TEST_OMP=ON` is set. -The unit-test executable itself is located at `build/test/unit-test`, `build/test/unit-test_omp` and `build/benchmark/bench_ipp_paillier`. +The unit-test executable itself is located at `build/test/unit-test`, `build/test/unit-test_omp` and `build/benchmark/bench_ipcl`. # Contributors Main contributors to this project, sorted by alphabetical order of last name are: diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake index 02d8b1f..f7e7bc7 100644 --- a/cmake/ippcrypto.cmake +++ b/cmake/ippcrypto.cmake @@ -27,7 +27,7 @@ ExternalProject_Add( -DCMAKE_INSTALL_PREFIX=${IPPCRYPTO_PREFIX} -DARCH=${IPPCRYPTO_ARCH} -DCMAKE_ASM_NASM_COMPILER=nasm - -DCMAKE_BUILD_TYOE=Release + -DCMAKE_BUILD_TYPE=Release UPDATE_COMMAND "" ) diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index ffd844b..37e7cd7 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -15,7 +15,7 @@ configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY) file(MAKE_DIRECTORY ${DOXYGEN_OUTPUT_DIR}) # Doxygen won't create this for us add_custom_command(OUTPUT ${DOXYGEN_INDEX_FILE} - DEPENDS ${IPP_PAILLIER_INC_DIR} + DEPENDS ${IPCL_INC_DIR} COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE_OUT} MAIN_DEPENDENCY ${DOXYFILE_OUT} ${DOXYFILE_IN} COMMENT "Generating Doxygen documentation") From 4a81c4f4dd4e10a64b6f4e9d308dd8bb96052a49 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Thu, 17 Feb 2022 15:24:26 -0800 Subject: [PATCH 007/364] fix testing --- benchmark/CMakeLists.txt | 1 - cmake/ippcrypto.cmake | 50 ++++++++++++++++++++++++---------------- ipcl/CMakeLists.txt | 13 ++++++++--- test/CMakeLists.txt | 4 ++-- 4 files changed, 42 insertions(+), 26 deletions(-) diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 64aef81..acb2897 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -7,7 +7,6 @@ add_executable(bench_ipcl ${SRC}) target_include_directories(bench_ipcl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${IPCL_INC_DIR} - ${IPPCRYPTO_INC_DIR} ) target_link_libraries(bench_ipcl PRIVATE diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake index f7e7bc7..b0bfa59 100644 --- a/cmake/ippcrypto.cmake +++ b/cmake/ippcrypto.cmake @@ -31,32 +31,42 @@ ExternalProject_Add( UPDATE_COMMAND "" ) -file(MAKE_DIRECTORY ${IPPCRYPTO_PREFIX}/include) +# file(MAKE_DIRECTORY ${IPPCRYPTO_PREFIX}/include) set(IPPCRYPTO_INC_DIR ${IPPCRYPTO_PREFIX}/include) -ExternalProject_Get_Property(ext_ipp-crypto SOURCE_DIR BINARY_DIR) +# ExternalProject_Get_Property(ext_ipp-crypto SOURCE_DIR BINARY_DIR) +if(IPCL_SHARED) + add_library(libippcrypto INTERFACE) + add_dependencies(libippcrypto ext_ipp-crypto) -add_library(libippcrypto::ippcp STATIC IMPORTED GLOBAL) -add_library(libippcrypto::crypto_mb STATIC IMPORTED GLOBAL) + ExternalProject_Get_Property(ext_ipp-crypto SOURCE_DIR BINARY_DIR) -add_dependencies(libippcrypto::ippcp ext_ipp-crypto) -add_dependencies(libippcrypto::crypto_mb ext_ipp-crypto) + target_link_libraries(libippcrypto INTERFACE ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libippcp.a ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libcrypto_mb.a) + target_include_directories(libippcrypto SYSTEM INTERFACE ${IPPCRYPTO_PREFIX}/include) -find_package(OpenSSL REQUIRED) +else() -set_target_properties(libippcrypto::ippcp PROPERTIES - IMPORTED_LOCATION ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libippcp.a - INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} -) + add_library(libippcrypto::ippcp STATIC IMPORTED GLOBAL) + add_library(libippcrypto::crypto_mb STATIC IMPORTED GLOBAL) -set_target_properties(libippcrypto::crypto_mb PROPERTIES - IMPORTED_LOCATION ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libcrypto_mb.a - INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} -) + add_dependencies(libippcrypto::ippcp ext_ipp-crypto) + add_dependencies(libippcrypto::crypto_mb ext_ipp-crypto) + + find_package(OpenSSL REQUIRED) -add_library(libippcrypto INTERFACE IMPORTED) -set_property(TARGET libippcrypto PROPERTY INTERFACE_LINK_LIBRARIES libippcrypto::ippcp libippcrypto::crypto_mb) -target_include_directories(libippcrypto SYSTEM INTERFACE ${IPPCRYPTO_INC_DIR}) -target_link_libraries(libippcrypto INTERFACE OpenSSL::SSL OpenSSL::Crypto) + set_target_properties(libippcrypto::ippcp PROPERTIES + IMPORTED_LOCATION ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libippcp.a + INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} + ) + + set_target_properties(libippcrypto::crypto_mb PROPERTIES + IMPORTED_LOCATION ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libcrypto_mb.a + INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} + ) +endif() +# add_library(libippcrypto INTERFACE IMPORTED) +# set_property(TARGET libippcrypto PROPERTY INTERFACE_LINK_LIBRARIES libippcrypto::ippcp libippcrypto::crypto_mb) +# target_include_directories(libippcrypto SYSTEM INTERFACE ${IPPCRYPTO_INC_DIR}) +# target_link_libraries(libippcrypto INTERFACE OpenSSL::SSL OpenSSL::Crypto) -add_dependencies(libippcrypto ext_ipp-crypto) +# add_dependencies(libippcrypto ext_ipp-crypto) diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 324437b..4ffb44c 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -22,18 +22,25 @@ target_include_directories(ipcl PUBLIC $ ) + +target_include_directories(ipcl + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PUBLIC $ + PUBLIC $ +) + install(DIRECTORY ${IPCL_INC_DIR}/ DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h") +target_link_libraries(ipcl PUBLIC OpenSSL::SSL OpenSSL::Crypto Threads::Threads) + if(IPCL_SHARED) - target_link_libraries(ipcl PRIVATE libippcrypto Threads::Threads) + target_link_libraries(ipcl PRIVATE libippcrypto) target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) else() - target_link_libraries(ipcl PRIVATE Threads::Threads) - target_link_libraries(ipcl PRIVATE OpenSSL::SSL OpenSSL::Crypto) ipcl_create_archive(ipcl libippcrypto::ippcp) ipcl_create_archive(ipcl libippcrypto::crypto_mb) target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9f002ba..472b533 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -4,7 +4,7 @@ message(STATUS "TEST ==== ippcrypto inc dir: ${IPPCRYPTO_INC_DIR}") # main unittest add_executable(unit-test test.cpp) target_link_libraries(unit-test PRIVATE ipcl libgtest Threads::Threads) -target_include_directories(unit-test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${IPCL_INC_DIR} ${IPPCRYPTO_INC_DIR}) +target_include_directories(unit-test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${IPCL_INC_DIR})# ${IPPCRYPTO_INC_DIR}) # omp unittest if(IPCL_TEST_OMP) @@ -12,5 +12,5 @@ if(IPCL_TEST_OMP) add_executable(unit-test_omp test_omp.cpp) target_link_libraries(unit-test_omp PRIVATE ipcl OpenMP::OpenMP_CXX libgtest Threads::Threads) - target_include_directories(unit-test_omp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${IPCL_INC_DIR} ${IPPCRYPTO_INC_DIR}) + target_include_directories(unit-test_omp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${IPCL_INC_DIR})# ${IPPCRYPTO_INC_DIR}) endif() From 239964cd99191a5eba6165ae755119c4c2dec24c Mon Sep 17 00:00:00 2001 From: sejunkim Date: Thu, 17 Feb 2022 15:31:18 -0800 Subject: [PATCH 008/364] fix2 --- ipcl/CMakeLists.txt | 8 +++++++- test/CMakeLists.txt | 1 - 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 4ffb44c..a332cef 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -25,7 +25,7 @@ target_include_directories(ipcl target_include_directories(ipcl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PUBLIC $ + PUBLIC $ PUBLIC $ ) @@ -35,6 +35,12 @@ install(DIRECTORY ${IPCL_INC_DIR}/ PATTERN "*.hpp" PATTERN "*.h") +install(DIRECTORY ${IPPCRYPTO_INC_DIR}/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ + FILES_MATCHING + PATTERN "*.hpp" + PATTERN "*.h") + target_link_libraries(ipcl PUBLIC OpenSSL::SSL OpenSSL::Crypto Threads::Threads) if(IPCL_SHARED) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 472b533..ec49c27 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,6 +1,5 @@ # Unit tests -message(STATUS "TEST ==== ippcrypto inc dir: ${IPPCRYPTO_INC_DIR}") # main unittest add_executable(unit-test test.cpp) target_link_libraries(unit-test PRIVATE ipcl libgtest Threads::Threads) From de519cdcf6948ae0d742c928447cc23e1535bccb Mon Sep 17 00:00:00 2001 From: sejunkim Date: Thu, 17 Feb 2022 21:58:12 -0800 Subject: [PATCH 009/364] documentation wip --- README.md | 13 +++++++++---- cmake/ippcrypto.cmake | 8 -------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 41e4325..a146d71 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # Intel Paillier Cryptosystem Library -Intel Paillier Cryptosystem Library is an open-source library which provides accelerated performance of a partial homomorphic encryption (HE), named Paillier cryptosystem, by utilizing IntelĀ® [IPP-Crypto](https://github.com/intel/ipp-crypto) technologies on Intel CPUs supporting the AVX512IFMA instructions. The library is written in modern standard C++ and provides the essential API for the Paillier cryptosystem scheme. +Intel Paillier Cryptosystem Library is an open-source library which provides accelerated performance of a partial homomorphic encryption (HE), named Paillier cryptosystem, by utilizing IntelĀ® [Integrated Performance Primitives Cryptography](https://github.com/intel/ipp-crypto) technologies on Intel CPUs supporting the AVX512IFMA instructions. The library is written in modern standard C++ and provides the essential API for the Paillier cryptosystem scheme. ## Contents -- [Paillier Homomorphic Encryption library with Intel ipp-crypto](#paillier-homomorphic-encryption-library-with-intel-ipp-crypto) - - [Contents](#content) +- [Intel Paillier Cryptosystem Library](#intel-paillier-cryptosystem-library) + - [Contents](#contents) - [Introduction](#introduction) - [Building the Library](#building-the-library) - [Dependencies](#dependencies) @@ -12,7 +12,12 @@ Intel Paillier Cryptosystem Library is an open-source library which provides acc - [Contributors](#contributors) ## Introduction -adding intro +Paillier cryptosystem is a probabilistic asymmetric algorithm for public key cryptography and a partial homomorphic encryption scheme which allows two types of computation: +- addition of two ciphertexts +- addition and multiplication of a ciphertext by a plaintext number + +Conventional implementations of the Paillier cryptosystem utilized the GNU Multiple Precision Arithmetic Library (GMP) for handling key lengths larger than 1024 bits. The essential computation of the scheme relies on the modular exponentiation, and our library takes advantage of the multi-buffer modular exponentiation function (```mbx_exp_mb8```) of IPP-Crypto library. +As a result, on AVX512IFMA instruction enabled CPUs, ## Building the Library ### Dependencies diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake index b0bfa59..927427a 100644 --- a/cmake/ippcrypto.cmake +++ b/cmake/ippcrypto.cmake @@ -31,9 +31,7 @@ ExternalProject_Add( UPDATE_COMMAND "" ) -# file(MAKE_DIRECTORY ${IPPCRYPTO_PREFIX}/include) set(IPPCRYPTO_INC_DIR ${IPPCRYPTO_PREFIX}/include) -# ExternalProject_Get_Property(ext_ipp-crypto SOURCE_DIR BINARY_DIR) if(IPCL_SHARED) add_library(libippcrypto INTERFACE) @@ -64,9 +62,3 @@ else() INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} ) endif() -# add_library(libippcrypto INTERFACE IMPORTED) -# set_property(TARGET libippcrypto PROPERTY INTERFACE_LINK_LIBRARIES libippcrypto::ippcp libippcrypto::crypto_mb) -# target_include_directories(libippcrypto SYSTEM INTERFACE ${IPPCRYPTO_INC_DIR}) -# target_link_libraries(libippcrypto INTERFACE OpenSSL::SSL OpenSSL::Crypto) - -# add_dependencies(libippcrypto ext_ipp-crypto) From 27d416fc3e66a51bcd9ae39e1505352704754c82 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Fri, 18 Feb 2022 13:20:29 -0800 Subject: [PATCH 010/364] README updates - minor fixes: libgbenchmark directory changes --- README.md | 30 +++++++++++++++++++++++------- cmake/gbenchmark.cmake | 8 +++++++- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index a146d71..7c1a486 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ Intel Paillier Cryptosystem Library is an open-source library which provides acc - [Contents](#contents) - [Introduction](#introduction) - [Building the Library](#building-the-library) + - [Requirements](#requirements) - [Dependencies](#dependencies) - [Instructions](#instructions) - [Testing and Benchmarking](#testing-and-benchmarking) @@ -16,13 +17,24 @@ Paillier cryptosystem is a probabilistic asymmetric algorithm for public key cry - addition of two ciphertexts - addition and multiplication of a ciphertext by a plaintext number -Conventional implementations of the Paillier cryptosystem utilized the GNU Multiple Precision Arithmetic Library (GMP) for handling key lengths larger than 1024 bits. The essential computation of the scheme relies on the modular exponentiation, and our library takes advantage of the multi-buffer modular exponentiation function (```mbx_exp_mb8```) of IPP-Crypto library. -As a result, on AVX512IFMA instruction enabled CPUs, +As a public key encryption scheme, Paillier cryptosystem has three stages: + + - Generate public-private key pair + - Encryption with public key + - Decryption with private key + +For increased security, typically the key length is at least 1024 bits, but recommendation is 2048 bits or larger. To handle such large size integers, conventional implementations of the Paillier cryptosystem utilizes the GNU Multiple Precision Arithmetic Library (GMP). The essential computation of the scheme relies on the modular exponentiation, and our library takes advantage of the multi-buffer modular exponentiation function (```mbx_exp_mb8```) of IPP-Crypto library, which is enabled in AVX512IFMA instruction sets supporting SKUs, such as Intel Icelake Xeon CPUs. ## Building the Library -### Dependencies -The library has been tested on Ubuntu 18.04 and 20.04 +### Requirements +The hardware requirement to use the library is AVX512IFMA instruction sets enabled CPUs, as listed in Intel codenames: + - Intel Cannon Lake + - Intel Ice Lake +We are planning to add support for more SKUs. + +Currently the library has been tested and confirmed to work on Ubuntu 18.04, 20.04 and RHEL 8.4. +### Dependencies Must have dependencies include: ``` cmake >=3.15.1 @@ -35,14 +47,18 @@ python >= 3.8 The following libraries are also required, ``` nasm>=2.15 -OpenSSL +OpenSSL>=1.1.0 ``` -which can be installed by: + +For ```nasm``` installation, please refer to the [Netwide Assembler](https://nasm.us/) for installation details. + +On Ubuntu, ```OpenSSL``` can be installed by: ```bash sudo apt update sudo apt install libssl-dev ``` -For ```nasm```, please refer to the [Netwide Assembler webpage](https://nasm.us/) for installation details. +On RHEL, it needs to be built and installed from source as the static libraries are not installed with package managers. Please refer to [OpenSSL Project](https://github.com/openssl/openssl) for installation details. + ### Instructions The library can be built using the following commands: diff --git a/cmake/gbenchmark.cmake b/cmake/gbenchmark.cmake index d0fefb0..675d596 100644 --- a/cmake/gbenchmark.cmake +++ b/cmake/gbenchmark.cmake @@ -31,7 +31,13 @@ add_library(libgbenchmark INTERFACE) add_dependencies(libgbenchmark ext_gbenchmark) ExternalProject_Get_Property(ext_gbenchmark SOURCE_DIR BINARY_DIR) -target_link_libraries(libgbenchmark INTERFACE ${GBENCHMARK_PREFIX}/lib/libbenchmark.a) +if(EXISTS ${GBENCHMARK_PREFIX}/lib/libbenchmark.a) + target_link_libraries(libgbenchmark INTERFACE ${GBENCHMARK_PREFIX}/lib/libbenchmark.a) +elseif(EXISTS ${GBENCHMARK_PREFIX}/lib64/libbenchmark.a) + target_link_libraries(libgbenchmark INTERFACE ${GBENCHMARK_PREFIX}/lib64/libbenchmark.a) +else() + message(FATAL "gBenchmark build failed") +endif() target_include_directories(libgbenchmark SYSTEM INTERFACE ${GBENCHMARK_PREFIX}/include) From 0cf8a770f86f41d261fc0a84d11859a173b8d5cf Mon Sep 17 00:00:00 2001 From: sejunkim Date: Fri, 18 Feb 2022 13:40:39 -0800 Subject: [PATCH 011/364] Detect linux distro for google benchmark library installation path --- cmake/gbenchmark.cmake | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/cmake/gbenchmark.cmake b/cmake/gbenchmark.cmake index 675d596..d19bbb4 100644 --- a/cmake/gbenchmark.cmake +++ b/cmake/gbenchmark.cmake @@ -31,12 +31,14 @@ add_library(libgbenchmark INTERFACE) add_dependencies(libgbenchmark ext_gbenchmark) ExternalProject_Get_Property(ext_gbenchmark SOURCE_DIR BINARY_DIR) -if(EXISTS ${GBENCHMARK_PREFIX}/lib/libbenchmark.a) +file(STRINGS /etc/os-release LINUX_ID REGEX "^ID=") +string(REGEX REPLACE "ID=\(.*)" "\\1" LINUX_ID "${LINUX_ID}") +message(STATUS "linux_id : ${LINUX_ID}") +if(${LINUX_ID} STREQUAL "ubuntu") target_link_libraries(libgbenchmark INTERFACE ${GBENCHMARK_PREFIX}/lib/libbenchmark.a) -elseif(EXISTS ${GBENCHMARK_PREFIX}/lib64/libbenchmark.a) - target_link_libraries(libgbenchmark INTERFACE ${GBENCHMARK_PREFIX}/lib64/libbenchmark.a) else() - message(FATAL "gBenchmark build failed") + # non debian systems install gbenchmark lib under lib64 + target_link_libraries(libgbenchmark INTERFACE ${GBENCHMARK_PREFIX}/lib64/libbenchmark.a) endif() target_include_directories(libgbenchmark SYSTEM From 97eaf72e2efd0982eab03e07427a7f53c016b5b8 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Fri, 18 Feb 2022 13:50:50 -0800 Subject: [PATCH 012/364] Minor fix - Fixed typos - Removed debugging messages --- README.md | 1 - cmake/gbenchmark.cmake | 1 - 2 files changed, 2 deletions(-) diff --git a/README.md b/README.md index 7c1a486..6004fd7 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,6 @@ sudo apt install libssl-dev ``` On RHEL, it needs to be built and installed from source as the static libraries are not installed with package managers. Please refer to [OpenSSL Project](https://github.com/openssl/openssl) for installation details. - ### Instructions The library can be built using the following commands: ```bash diff --git a/cmake/gbenchmark.cmake b/cmake/gbenchmark.cmake index d19bbb4..164c238 100644 --- a/cmake/gbenchmark.cmake +++ b/cmake/gbenchmark.cmake @@ -33,7 +33,6 @@ add_dependencies(libgbenchmark ext_gbenchmark) ExternalProject_Get_Property(ext_gbenchmark SOURCE_DIR BINARY_DIR) file(STRINGS /etc/os-release LINUX_ID REGEX "^ID=") string(REGEX REPLACE "ID=\(.*)" "\\1" LINUX_ID "${LINUX_ID}") -message(STATUS "linux_id : ${LINUX_ID}") if(${LINUX_ID} STREQUAL "ubuntu") target_link_libraries(libgbenchmark INTERFACE ${GBENCHMARK_PREFIX}/lib/libbenchmark.a) else() From 834fb693d69f629f12f04323fe63e186ecd36b08 Mon Sep 17 00:00:00 2001 From: fdiasmor Date: Fri, 18 Feb 2022 15:43:19 -0800 Subject: [PATCH 013/364] Initial commit --- LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 1 + 2 files changed, 202 insertions(+) create mode 100644 LICENSE create mode 100644 README.md diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..0be9277 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# libraries.security.cryptography.homomorphic-encryption.glade.he-qat \ No newline at end of file From d9dd71edc8803ed8dcf67974e6e1276de995a7d6 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Sat, 19 Feb 2022 16:12:59 -0800 Subject: [PATCH 014/364] Initial commit. --- .gitignore | 2 + CMakeLists.txt | 44 ++ common/CMakeLists.txt | 23 + common/cpa_sample_utils.c | 285 ++++++++++++ he_qat_context.c | 79 ++++ he_qat_context.h | 4 + he_qat_types.h | 9 + include/cpa_sample_cnv_utils.h | 260 +++++++++++ include/cpa_sample_utils.h | 618 +++++++++++++++++++++++++++ ln_mod_exp/CMakeLists.txt | 33 ++ ln_mod_exp/cpa_mod_exp_sample.c | 601 ++++++++++++++++++++++++++ ln_mod_exp/cpa_mod_exp_sample_user.c | 265 ++++++++++++ ln_mod_exp/qat_modexp_validation.c | 235 ++++++++++ run.sh | 6 + 14 files changed, 2464 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 common/CMakeLists.txt create mode 100644 common/cpa_sample_utils.c create mode 100644 he_qat_context.c create mode 100644 he_qat_context.h create mode 100644 he_qat_types.h create mode 100644 include/cpa_sample_cnv_utils.h create mode 100644 include/cpa_sample_utils.h create mode 100644 ln_mod_exp/CMakeLists.txt create mode 100644 ln_mod_exp/cpa_mod_exp_sample.c create mode 100644 ln_mod_exp/cpa_mod_exp_sample_user.c create mode 100644 ln_mod_exp/qat_modexp_validation.c create mode 100755 run.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bcdff71 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build +install diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..5f6265f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,44 @@ +cmake_minimum_required(VERSION 3.13) + +project(QATModExp LANGUAGES C CXX) + +set(CMAKE_C_STANDARD 99) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +include(CheckCCompilerFlag) +include(CheckCXXCompilerFlag) +include(CMakePackageConfigHelpers) + +set(COMMON_INC_DIR ${CMAKE_CURRENT_LIST_DIR}/include) + +set(CMAKE_INSTALL_PREFIX "install") + +set(ICP_ROOT $ENV{ICP_ROOT}) +set(ICP_BUILDOUTPUT_PATH ${ICP_ROOT}/build) +set(ICP_BUILDSYSTEM_PATH ${ICP_ROOT}/quickassist/build_system) +set(ICP_API_DIR ${ICP_ROOT}/quickassist) +set(ICP_LAC_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer) +set(ICP_OSAL_DIR ${ICP_ROOT}/quickassist/utilities/oasl) +set(ICP_ADF_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/qat_direct) +set(CMN_ROOT ${ICP_ROOT}/quickassist/utilities/libusdm_drv) + +list(APPEND COMMON_INC_DIR + ${ICP_API_DIR}/include + ${ICP_LAC_DIR}/include + ${ICP_ADF_DIR}/include + ${CMN_ROOT} +) + +# Macros for the test case +add_definitions(-DDO_CRYPTO) +add_definitions(-DUSER_SPACE) +add_compile_options(-fPIC) + +# Common utility functions +add_subdirectory(common) + +# Compile test case +add_subdirectory(ln_mod_exp) + diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt new file mode 100644 index 0000000..4d7110e --- /dev/null +++ b/common/CMakeLists.txt @@ -0,0 +1,23 @@ + +# Include directories +list(APPEND COMMON_INC_DIR + ${ICP_API_DIR}/include/dc + ${ICP_API_DIR}/include/lac +) +message(STATUS "COMMON_INC_DIR: ${COMMON_INC_DIR}") + +# Source files +set(COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/cpa_sample_utils.c) + +add_library(cpa_sample_utils ${COMMON_SRC}) +target_include_directories(cpa_sample_utils + PUBLIC $ # Public headers + PUBLIC $ # Public headers + PRIVATE ${COMMON_INC_DIR} # Private headers +) +target_link_libraries(cpa_sample_utils PRIVATE udev pthread crypto z) +target_link_libraries(cpa_sample_utils PUBLIC ${ICP_BUILDOUTPUT_PATH}/libqat_s.so) +target_link_libraries(cpa_sample_utils PUBLIC ${ICP_BUILDOUTPUT_PATH}/libusdm_drv_s.so) + +set(COMMON_INC_DIR ${COMMON_INC_DIR} PARENT_SCOPE) + diff --git a/common/cpa_sample_utils.c b/common/cpa_sample_utils.c new file mode 100644 index 0000000..5949134 --- /dev/null +++ b/common/cpa_sample_utils.c @@ -0,0 +1,285 @@ +/*************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Corporation + * + * BSD LICENSE + * + * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * version: QAT.L.4.15.0-00011 + * + ***************************************************************************/ + +/** + ***************************************************************************** + * @file cpa_sample_utils.c + * + * @ingroup sampleCode + * + * @description + * Defines functions to get an instance and poll an instance + * + ***************************************************************************/ + +#include "cpa_sample_utils.h" +#include "cpa_dc.h" +#include "icp_sal_poll.h" + +/* + * Maximum number of instances to query from the API + */ +#ifdef USER_SPACE +#define MAX_INSTANCES 1024 +#else +#define MAX_INSTANCES 1 +#endif + +#ifdef DO_CRYPTO +static sampleThread gPollingThread; +static volatile int gPollingCy = 0; +#endif + +static sampleThread gPollingThreadDc; +static volatile int gPollingDc = 0; + +#ifdef SC_ENABLE_DYNAMIC_COMPRESSION +CpaDcHuffType huffmanType_g = CPA_DC_HT_FULL_DYNAMIC; +#else +CpaDcHuffType huffmanType_g = CPA_DC_HT_STATIC; +#endif +/* ************************************************************* + * + * Common instance functions + * + * ************************************************************* + */ + +/* + * This function returns a handle to an instance of the cryptographic + * API. It does this by querying the API for all instances and + * returning the first such instance. + */ +// +#ifdef DO_CRYPTO +void sampleCyGetInstance(CpaInstanceHandle *pCyInstHandle) +{ + CpaInstanceHandle cyInstHandles[MAX_INSTANCES]; + Cpa16U numInstances = 0; + CpaStatus status = CPA_STATUS_SUCCESS; + + *pCyInstHandle = NULL; + status = cpaCyGetNumInstances(&numInstances); + if (numInstances >= MAX_INSTANCES) + { + numInstances = MAX_INSTANCES; + } + if ((status == CPA_STATUS_SUCCESS) && (numInstances > 0)) + { + status = cpaCyGetInstances(numInstances, cyInstHandles); + if (status == CPA_STATUS_SUCCESS) + *pCyInstHandle = cyInstHandles[0]; + } + + if (0 == numInstances) + { + PRINT_ERR("No instances found for 'SSL'\n"); + PRINT_ERR("Please check your section names"); + PRINT_ERR(" in the config file.\n"); + PRINT_ERR("Also make sure to use config file version 2.\n"); + } +} + +void symSessionWaitForInflightReq(CpaCySymSessionCtx pSessionCtx) +{ + +/* Session reuse is available since Cryptographic API version 2.2 */ +#if CY_API_VERSION_AT_LEAST(2, 2) + CpaBoolean sessionInUse = CPA_FALSE; + + do + { + cpaCySymSessionInUse(pSessionCtx, &sessionInUse); + } while (sessionInUse); +#endif + + return; +} +#endif +// + +/* + * This function polls a crypto instance. + * + */ +#ifdef DO_CRYPTO +static void sal_polling(CpaInstanceHandle cyInstHandle) +{ + gPollingCy = 1; + while (gPollingCy) + { + icp_sal_CyPollInstance(cyInstHandle, 0); + OS_SLEEP(10); + } + + sampleThreadExit(); +} +#endif +/* + * This function checks the instance info. If the instance is + * required to be polled then it starts a polling thread. + */ + +#ifdef DO_CRYPTO +void sampleCyStartPolling(CpaInstanceHandle cyInstHandle) +{ + CpaInstanceInfo2 info2 = {0}; + CpaStatus status = CPA_STATUS_SUCCESS; + + status = cpaCyInstanceGetInfo2(cyInstHandle, &info2); + if ((status == CPA_STATUS_SUCCESS) && (info2.isPolled == CPA_TRUE)) + { + /* Start thread to poll instance */ + sampleThreadCreate(&gPollingThread, sal_polling, cyInstHandle); + } +} +#endif +/* + * This function stops the polling of a crypto instance. + */ +#ifdef DO_CRYPTO +void sampleCyStopPolling(void) +{ + gPollingCy = 0; + OS_SLEEP(10); +} +#endif + +/* + * This function returns a handle to an instance of the data + * compression API. It does this by querying the API for all + * instances and returning the first such instance. + */ +// +void sampleDcGetInstance(CpaInstanceHandle *pDcInstHandle) +{ + CpaInstanceHandle dcInstHandles[MAX_INSTANCES]; + Cpa16U numInstances = 0; + CpaStatus status = CPA_STATUS_SUCCESS; + + *pDcInstHandle = NULL; + status = cpaDcGetNumInstances(&numInstances); + if (numInstances >= MAX_INSTANCES) + { + numInstances = MAX_INSTANCES; + } + if ((status == CPA_STATUS_SUCCESS) && (numInstances > 0)) + { + status = cpaDcGetInstances(numInstances, dcInstHandles); + if (status == CPA_STATUS_SUCCESS) + *pDcInstHandle = dcInstHandles[0]; + } + + if (0 == numInstances) + { + PRINT_ERR("No instances found for 'SSL'\n"); + PRINT_ERR("Please check your section names"); + PRINT_ERR(" in the config file.\n"); + PRINT_ERR("Also make sure to use config file version 2.\n"); + } +} +// + +/* + * This function polls a compression instance. + * + */ +static void sal_dc_polling(CpaInstanceHandle dcInstHandle) +{ + + gPollingDc = 1; + while (gPollingDc) + { + icp_sal_DcPollInstance(dcInstHandle, 0); + OS_SLEEP(10); + } + + sampleThreadExit(); +} + +/* + * This function checks the instance info. If the instance is + * required to be polled then it starts a polling thread. + */ +void sampleDcStartPolling(CpaInstanceHandle dcInstHandle) +{ + CpaInstanceInfo2 info2 = {0}; + CpaStatus status = CPA_STATUS_SUCCESS; + + status = cpaDcInstanceGetInfo2(dcInstHandle, &info2); + if ((status == CPA_STATUS_SUCCESS) && (info2.isPolled == CPA_TRUE)) + { + /* Start thread to poll instance */ + sampleThreadCreate(&gPollingThreadDc, sal_dc_polling, dcInstHandle); + } +} + +/* + * This function stops the thread polling the compression instance. + */ +void sampleDcStopPolling(void) +{ + gPollingDc = 0; + OS_SLEEP(10); +} + diff --git a/he_qat_context.c b/he_qat_context.c new file mode 100644 index 0000000..c053d40 --- /dev/null +++ b/he_qat_context.c @@ -0,0 +1,79 @@ + +#include "heqat_types.h" + +#include "cpa_sample_utils.h" + +//CpaStatus get_qat_instances(CpaInstanceHandle *_instances, int *_num_instances=-1) +//{ +// +//} + +const int MAX_NUM_INST 8 + +enum HEQAT_EXEC_MODE { HEQAT_BLOCK_SYNC=1 }; +enum HEQAT_STATUS { HEQAT_SUCCESS = 0, HEQAT_FAIL = 1 }; + + +typedef struct InstConfigStruct { + CpaInstanceHandle inst_handle; + volatile int polling; +} InstConfig; + +pthread_t threads[MAX_NUM_INST]; + +static void sal_inst_polling(InstConfig *config) +{ + if (!config) return ; + + config->polling = 1; + + while (config->polling) { + icp_sal_CyPollInstance(config->inst_handle, 0); + OS_SLEEP(10); + } + + return ; +} + +/// @brief +/// @function acquire_qat_devices +/// Acquire QAT instances and set up QAT execution environment. +HEQAT_STATUS acquire_qat_devices() +{ + CpaInstanceHandle _inst_handle = NULL; + + // TODO: @fdiasmor Create a CyGetInstance that retrieves more than one. + sampleCyGetInstance(&_inst_handle); + + if (_inst_handle == NULL) { + return HEQAT_FAIL; + } + + // Dispatch worker threads + pthread_attr_t attr; + cpu_set_t cpus; + pthread_attr_init(&attr); + for (int i = 0; i < HEQAT_BLOCK_SYNC; i++) { + CPU_ZERO(&cpus); + CPU_SET(i, &cpus); + pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpus); + + // configure thread + InstConfig *config = (InstConfig *) malloc(sizeof(InstConfig)); + if (config == NULL) return HEQAT_FAIL; + config->inst_handle = _inst_handle[i]; + pthread_create(&threads[i], &attr, sal_polling, config); // + } + + + return ; +} + +/// @brief +/// @function release_qat_devices +/// Release QAT instances and tear down QAT execution environment. +void release_qat_devices() +{ + return ; +} + diff --git a/he_qat_context.h b/he_qat_context.h new file mode 100644 index 0000000..013aab5 --- /dev/null +++ b/he_qat_context.h @@ -0,0 +1,4 @@ + +void acquire_qat_devices(); +void release_qat_devices(); + diff --git a/he_qat_types.h b/he_qat_types.h new file mode 100644 index 0000000..5c75319 --- /dev/null +++ b/he_qat_types.h @@ -0,0 +1,9 @@ + + +typedef struct QATInstConfigStruct +{ + +} QATInstConfig; + + + diff --git a/include/cpa_sample_cnv_utils.h b/include/cpa_sample_cnv_utils.h new file mode 100644 index 0000000..322481f --- /dev/null +++ b/include/cpa_sample_cnv_utils.h @@ -0,0 +1,260 @@ +/*************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Corporation + * + * BSD LICENSE + * + * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * version: QAT.L.4.15.0-00011 + * + ***************************************************************************/ + +/** + ***************************************************************************** + * @file qat_compression_cnv_utils.h + * + * @defgroup compression + * + * @ingroup compression + * + * @description + * Functions types and macros to determine CnV-E environment + * Helper functions and macros to set the CnV flag in API + * + * + ***************************************************************************/ +#ifndef QAT_SAMPLE_CNV_UTILS_H_ +#define QAT_SAMPLE_CNV_UTILS_H_ + +/* Common macro definitions */ +#ifndef DC_API_VERSION_AT_LEAST +#define DC_API_VERSION_AT_LEAST(major, minor) \ + (CPA_DC_API_VERSION_NUM_MAJOR > major || \ + (CPA_DC_API_VERSION_NUM_MAJOR == major && \ + CPA_DC_API_VERSION_NUM_MINOR >= minor)) +#endif + +/* CNV with Recovery mode capability is present in DC API version 2.2 + * and higher. + */ +#if DC_API_VERSION_AT_LEAST(2, 2) +#define CNV(x) (x)->compressAndVerify +#define SET_CNV(x, v) (CNV(x) = (v)) +#define CNV_RECOVERY(x) (x)->compressAndVerifyAndRecover +#define SET_CNV_RECOVERY(x, v) (CNV_RECOVERY(x) = v) +#else +#define CNV(x) CPA_FALSE +#define SET_CNV(x, v) +#define CNV_RECOVERY(x) CPA_FALSE +#define SET_CNV_RECOVERY(x, v) +#endif + +#define INIT_OPDATA(x, flag) \ + do \ + { \ + (x)->flushFlag = (flag); \ + SET_CNV(x, getCnVFlag()); \ + SET_CNV_RECOVERY(x, getCnVnRFlag()); \ + (x)->inputSkipData.skipMode = CPA_DC_SKIP_DISABLED; \ + (x)->outputSkipData.skipMode = CPA_DC_SKIP_DISABLED; \ + } while (0) + +#define INIT_DC_DP_CNV_OPDATA(x) \ + do \ + { \ + SET_CNV(x, getCnVFlag()); \ + SET_CNV_RECOVERY(x, getCnVnRFlag()); \ + } while (0) + +static CpaBoolean getCnVFlag(void) __attribute__((unused)); +static CpaBoolean getCnVnRFlag(void) __attribute__((unused)); +static const char *getSampleCnVModeStr(void) __attribute__((unused)); + +static void getCnvFlagInternal(CpaBoolean *cnv, CpaBoolean *cnvnr); +static void EvaluateSampleCnVFlag(const CpaDcInstanceCapabilities *const cap, + CpaBoolean *cnv, + CpaBoolean *cnvnr); +static CpaStatus getSampleDcCapabilities( + CpaDcInstanceCapabilities *capabilities); + +static CpaBoolean getCnVFlag(void) +{ + static CpaBoolean cnvOpFlag; + static CpaBoolean initialised = CPA_FALSE; + + if (initialised == CPA_FALSE) + { + getCnvFlagInternal(&cnvOpFlag, NULL); + initialised = CPA_TRUE; + } + + return cnvOpFlag; +} + +static CpaBoolean getCnVnRFlag(void) +{ + static CpaBoolean cnvnrOpFlag; + static CpaBoolean initialised = CPA_FALSE; + + if (initialised == CPA_FALSE) + { + getCnvFlagInternal(NULL, &cnvnrOpFlag); + initialised = CPA_TRUE; + } + + return cnvnrOpFlag; +} + +static const char *getSampleCnVModeStr(void) +{ + static const char *cmpWithVer = "Compression with Verification"; + static const char *cmpOnly = "Compression Only"; + + return (getCnVFlag() == CPA_TRUE ? cmpWithVer : cmpOnly); +} + +static void getCnvFlagInternal(CpaBoolean *cnv, CpaBoolean *cnvnr) +{ + CpaDcInstanceCapabilities cap = {0}; + if (getSampleDcCapabilities(&cap) != CPA_STATUS_SUCCESS) + { + return EvaluateSampleCnVFlag(NULL, cnv, cnvnr); + } + + return EvaluateSampleCnVFlag(&cap, cnv, cnvnr); +} + +static void EvaluateSampleCnVFlag(const CpaDcInstanceCapabilities *const cap, + CpaBoolean *cnv, + CpaBoolean *cnvnr) +{ + CpaBoolean fw_cnv_capable = CPA_FALSE; + CpaBoolean cnv_loose_mode = CPA_FALSE; + CpaBoolean cnvOpFlag = CPA_FALSE; + CpaBoolean cnvnrOpFlag = CPA_FALSE; + + /* When capabilities are known, fill in the queried values */ + if (cap != NULL) + { + fw_cnv_capable = CNV(cap); +/* CNV mode capabilities is present in DC API version 2.1 and above */ +#if DC_API_VERSION_AT_LEAST(2, 1) + cnv_loose_mode = + (cap->compressAndVerifyStrict != CPA_TRUE) ? CPA_TRUE : CPA_FALSE; +#endif + cnvnrOpFlag = CNV_RECOVERY(cap); + } + /* Determine the value of CompressAndVerify flag used by DP and + * Traditional API depending on the FW CNV capability and CNV mode + * of operation. The API will accept the submission of payload only + * if this flag value is correct for the combination. + * FW-CNV-CAPABLE MODE PERMITTED-OPERATION CNVFLAG + * Y S CompressWithVerify CPA_TRUE + * Y L Compress only CPA_FALSE + * N S NONE NA + * N L Compress only CPA_FALSE + */ + if (fw_cnv_capable == CPA_TRUE) + { + cnvOpFlag = (cnv_loose_mode == CPA_FALSE) ? CPA_TRUE : CPA_FALSE; + } + else + { + cnvOpFlag = CPA_FALSE; + } + + /* CNV Recovery only possible when + * CNV is enabled/present. + */ + if (cnvOpFlag == CPA_FALSE) + { + cnvnrOpFlag = CPA_FALSE; + } + + if (cnv != NULL) + *cnv = cnvOpFlag; + + if (cnvnr != NULL) + *cnvnr = cnvnrOpFlag; + + return; +} + +static CpaStatus getSampleDcCapabilities( + CpaDcInstanceCapabilities *capabilities) +{ + CpaStatus status; + CpaInstanceHandle instHandle; + Cpa16U numInstances = 0; + + /* Get the number of instances */ + status = cpaDcGetNumInstances(&numInstances); + if (CPA_STATUS_SUCCESS != status) + return CPA_STATUS_FAIL; + + if (numInstances == 0) + return CPA_STATUS_FAIL; + + status = cpaDcGetInstances(1, &instHandle); + if (status != CPA_STATUS_SUCCESS) + return CPA_STATUS_FAIL; + + status = cpaDcQueryCapabilities(instHandle, capabilities); + if (CPA_STATUS_SUCCESS != status) + return CPA_STATUS_FAIL; + + return CPA_STATUS_SUCCESS; +} +#endif /* QAT_SAMPLE_CNV_UTILS_H_ */ diff --git a/include/cpa_sample_utils.h b/include/cpa_sample_utils.h new file mode 100644 index 0000000..418b200 --- /dev/null +++ b/include/cpa_sample_utils.h @@ -0,0 +1,618 @@ +/*************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Corporation + * + * BSD LICENSE + * + * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * version: QAT.L.4.15.0-00011 + * + ***************************************************************************/ + +/** + ***************************************************************************** + * @file cpa_sample_utils.h + * + * @defgroup sampleUtils Macro and inline function definitions + * + * @ingroup sampleCode + * + * @description + * Defines macros for printing and debugging, inline functions for memory + * allocating and freeing and thread creation + * + ***************************************************************************/ + +#ifndef CPA_SAMPLE_UTILS_H +#define CPA_SAMPLE_UTILS_H + +#include "cpa.h" +#include "cpa_cy_im.h" +#include "cpa_dc.h" + + +#ifdef DO_CRYPTO +#include "cpa_cy_sym.h" +#endif +#include "cpa_sample_cnv_utils.h" + +#ifdef USER_SPACE +/* User space utils */ +#include +#include +#include +#include +#include +#include +/* Performance sample code mem utils */ + +#include "qae_mem.h" + +extern CpaDcHuffType huffmanType_g; +extern CpaStatus qaeMemInit(void); +extern void qaeMemDestroy(void); +/* Threads */ +typedef pthread_t sampleThread; + +/* Check for CY API version */ +#define CY_API_VERSION_AT_LEAST(major, minor) \ + (CPA_CY_API_VERSION_NUM_MAJOR > major || \ + (CPA_CY_API_VERSION_NUM_MAJOR == major && \ + CPA_CY_API_VERSION_NUM_MINOR >= minor)) + +/* Printing */ +/**< Prints the name of the function and the arguments only if gDebugParam is + * CPA_TRUE. + */ +#define PRINT_DBG(args...) \ + do \ + { \ + if (CPA_TRUE == gDebugParam) \ + { \ + printf("%s(): ", __func__); \ + printf(args); \ + fflush(stdout); \ + } \ + } while (0) + +/**< Prints the arguments */ +#ifndef PRINT +#define PRINT(args...) \ + do \ + { \ + printf(args); \ + } while (0) +#endif + +/**< Prints the name of the function and the arguments */ +#ifndef PRINT_ERR +#define PRINT_ERR(args...) \ + do \ + { \ + printf("%s(): ", __func__); \ + printf(args); \ + } while (0) +#endif +/** + ******************************************************************************* + * @ingroup sampleUtils + * Completion definitions + * + ******************************************************************************/ +struct completion_struct +{ + sem_t semaphore; +}; +/* Use semaphores to signal completion of events */ +#define COMPLETION_STRUCT completion_struct + +#define COMPLETION_INIT(s) sem_init(&((s)->semaphore), 0, 0); + +#define COMPLETION_WAIT(s, timeout) (sem_wait(&((s)->semaphore)) == 0) + +#define COMPLETE(s) sem_post(&((s)->semaphore)) + +#define COMPLETION_DESTROY(s) sem_destroy(&((s)->semaphore)) + +#else +/* Kernel space utils */ +#include +#include +#include +#include +#include +#include +#include + +#ifdef __x86_64__ +#define SAMPLE_ADDR_LEN uint64_t +#else +#define SAMPLE_ADDR_LEN uint32_t +#endif + +extern CpaDcHuffType huffmanType_g; + +/* Threads */ +typedef struct task_struct *sampleThread; + +/* Check for CY API version */ +#define CY_API_VERSION_AT_LEAST(major, minor) \ + (CPA_CY_API_VERSION_NUM_MAJOR > major || \ + (CPA_CY_API_VERSION_NUM_MAJOR == major && \ + CPA_CY_API_VERSION_NUM_MINOR >= minor)) + +/* Printing */ +/**< Prints the name of the function and the arguments only if gDebugParam is + * CPA_TRUE. + */ +#define PRINT_DBG(args...) \ + do \ + { \ + if (CPA_TRUE == gDebugParam) \ + { \ + printk("%s(): ", __func__); \ + printk(KERN_CONT args); \ + } \ + } while (0) + +/**< Regular prints */ +#ifndef PRINT +#define PRINT(args...) \ + do \ + { \ + printk(KERN_CONT args); \ + } while (0) +#endif + +/**< Prints the name of the function and the arguments */ +#ifndef PRINT_ERR +#define PRINT_ERR(args...) \ + do \ + { \ + printk("%s(): ", __func__); \ + printk(KERN_CONT args); \ + } while (0) +#endif +/** + ******************************************************************************* + * @ingroup sampleUtils + * Completion definitions + * + ******************************************************************************/ +#define COMPLETION_STRUCT completion + +#define COMPLETION_INIT(c) init_completion(c) + +#define COMPLETION_WAIT(c, timeout) \ + wait_for_completion_interruptible_timeout(c, timeout) + +#define COMPLETE(c) complete(c) + +#define COMPLETION_DESTROY(s) + +#endif + +#ifndef BYTE_ALIGNMENT_8 +#define BYTE_ALIGNMENT_8 (8) +#endif +#ifndef BYTE_ALIGNMENT_64 +#define BYTE_ALIGNMENT_64 (64) +#endif + +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function and associated macro sleeps for ms milliseconds + * + * @param[in] ms sleep time in ms + * + * @retval none + * + ******************************************************************************/ +static __inline CpaStatus sampleSleep(Cpa32U ms) +{ +#ifdef USER_SPACE + int ret = 0; + struct timespec resTime, remTime; + resTime.tv_sec = ms / 1000; + resTime.tv_nsec = (ms % 1000) * 1000000; + do + { + ret = nanosleep(&resTime, &remTime); + resTime = remTime; + } while ((ret != 0) && (errno == EINTR)); + + if (ret != 0) + { + PRINT_ERR("nanoSleep failed with code %d\n", ret); + return CPA_STATUS_FAIL; + } + else + { + return CPA_STATUS_SUCCESS; + } +#else + if (ms != 0) + { + set_current_state((long)TASK_INTERRUPTIBLE); + schedule_timeout((ms * HZ) / 1000); + } + else + { + schedule(); + } + + return CPA_STATUS_SUCCESS; +#endif +} +/** + ******************************************************************************* + * @ingroup sampleUtils + * Macro from the sampleSleep function + * + ******************************************************************************/ +#define OS_SLEEP(ms) sampleSleep((ms)) + +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function and associated macro allocates the memory for the given + * size and stores the address of the memory allocated in the pointer. + * Memory allocated by this function is NOT guaranteed to be physically + * contiguous. + * + * @param[out] ppMemAddr address of pointer where address will be stored + * @param[in] sizeBytes the size of the memory to be allocated + * + * @retval CPA_STATUS_RESOURCE Macro failed to allocate Memory + * @retval CPA_STATUS_SUCCESS Macro executed successfully + * + ******************************************************************************/ +static __inline CpaStatus Mem_OsMemAlloc(void **ppMemAddr, Cpa32U sizeBytes) +{ +#ifdef USER_SPACE + *ppMemAddr = malloc(sizeBytes); + if (NULL == *ppMemAddr) + { + return CPA_STATUS_RESOURCE; + } + return CPA_STATUS_SUCCESS; +#else + *ppMemAddr = kmalloc(sizeBytes, GFP_KERNEL); + if (NULL == *ppMemAddr) + { + return CPA_STATUS_RESOURCE; + } + return CPA_STATUS_SUCCESS; +#endif +} + +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function and associated macro allocates the memory for the given + * size for the given alignment and stores the address of the memory + * allocated in the pointer. Memory allocated by this function is + * guaranteed to be physically contiguous. + * + * @param[out] ppMemAddr address of pointer where address will be stored + * @param[in] sizeBytes the size of the memory to be allocated + * @param[in] alignement the alignment of the memory to be allocated + *(non-zero) + * + * @retval CPA_STATUS_RESOURCE Macro failed to allocate Memory + * @retval CPA_STATUS_SUCCESS Macro executed successfully + * + ******************************************************************************/ +static __inline CpaStatus Mem_Alloc_Contig(void **ppMemAddr, + Cpa32U sizeBytes, + Cpa32U alignment) +{ +#ifdef USER_SPACE + /* Use perf sample code memory allocator */ + + /* In this sample all allocations are done from node=0 + * This might not be optimal in a dual processor system. + */ + *ppMemAddr = qaeMemAllocNUMA(sizeBytes, 0, alignment); + if (NULL == *ppMemAddr) + { + return CPA_STATUS_RESOURCE; + } + return CPA_STATUS_SUCCESS; +#else + void *pAlloc = NULL; + uint32_t align = 0; + + pAlloc = + kmalloc_node((sizeBytes + alignment + sizeof(void *)), GFP_KERNEL, 0); + if (NULL == pAlloc) + { + return CPA_STATUS_RESOURCE; + } + + *ppMemAddr = pAlloc + sizeof(void *); + + align = ((SAMPLE_ADDR_LEN)(*ppMemAddr)) % alignment; + + *ppMemAddr += (alignment - align); + *(SAMPLE_ADDR_LEN *)(*ppMemAddr - sizeof(void *)) = (SAMPLE_ADDR_LEN)pAlloc; + + return CPA_STATUS_SUCCESS; +#endif +} + +/** + ******************************************************************************* + * @ingroup sampleUtils + * Macro from the Mem_OsMemAlloc function + * + ******************************************************************************/ +#define OS_MALLOC(ppMemAddr, sizeBytes) \ + Mem_OsMemAlloc((void *)(ppMemAddr), (sizeBytes)) + +/** + ******************************************************************************* + * @ingroup sampleUtils + * Macro from the Mem_Alloc_Contig function + * + ******************************************************************************/ +#define PHYS_CONTIG_ALLOC(ppMemAddr, sizeBytes) \ + Mem_Alloc_Contig((void *)(ppMemAddr), (sizeBytes), 1) + +/** + ******************************************************************************* + * @ingroup sampleUtils + * Algined version of PHYS_CONTIG_ALLOC() macro + * + ******************************************************************************/ +#define PHYS_CONTIG_ALLOC_ALIGNED(ppMemAddr, sizeBytes, alignment) \ + Mem_Alloc_Contig((void *)(ppMemAddr), (sizeBytes), (alignment)) + +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function and associated macro frees the memory at the given address + * and resets the pointer to NULL. The memory must have been allocated by + * the function Mem_OsMemAlloc() + * + * @param[out] ppMemAddr address of pointer where mem address is stored. + * If pointer is NULL, the function will exit silently + * + * @retval void + * + ******************************************************************************/ +static __inline void Mem_OsMemFree(void **ppMemAddr) +{ +#ifdef USER_SPACE + if (NULL != *ppMemAddr) + { + free(*ppMemAddr); + *ppMemAddr = NULL; + } +#else + if (NULL != *ppMemAddr) + { + kfree(*ppMemAddr); + *ppMemAddr = NULL; + } +#endif +} + +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function and associated macro frees the memory at the given address + * and resets the pointer to NULL. The memory must have been allocated by + * the function Mem_Alloc_Contig(). + * + * @param[out] ppMemAddr address of pointer where mem address is stored. + * If pointer is NULL, the function will exit silently + * + * @retval void + * + ******************************************************************************/ +static __inline void Mem_Free_Contig(void **ppMemAddr) +{ +#ifdef USER_SPACE + if (NULL != *ppMemAddr) + { + qaeMemFreeNUMA(ppMemAddr); + *ppMemAddr = NULL; + } +#else + void *pAlloc = NULL; + + if (NULL != *ppMemAddr) + { + pAlloc = (void *)(*((SAMPLE_ADDR_LEN *)(*ppMemAddr - sizeof(void *)))); + kfree(pAlloc); + *ppMemAddr = NULL; + } +#endif +} + +/** + ******************************************************************************* + * @ingroup sampleUtils + * Macro from the Mem_OsMemFree function + * + ******************************************************************************/ +#define OS_FREE(pMemAddr) Mem_OsMemFree((void *)&pMemAddr) + +/** + ******************************************************************************* + * @ingroup sampleUtils + * Macro from the Mem_Free_Contig function + * + ******************************************************************************/ +#define PHYS_CONTIG_FREE(pMemAddr) Mem_Free_Contig((void *)&pMemAddr) + +#define _4K_PAGE_SIZE (4 * 1024) + +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function returns the physical address for a given virtual address. + * In case of error 0 is returned. + * + * @param[in] virtAddr Virtual address + * + * @retval CpaPhysicalAddr Physical address or 0 in case of error + * + ******************************************************************************/ + +static __inline CpaPhysicalAddr sampleVirtToPhys(void *virtAddr) +{ +#ifdef USER_SPACE + return (CpaPhysicalAddr)qaeVirtToPhysNUMA(virtAddr); +#else + return (CpaPhysicalAddr)virt_to_phys(virtAddr); +#endif +} + +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function creates a thread + * + ******************************************************************************/ + +static __inline CpaStatus sampleThreadCreate(sampleThread *thread, + void *funct, + void *args) +{ +#ifdef USER_SPACE + if (pthread_create(thread, NULL, funct, args) != 0) + { + PRINT_ERR("Failed create thread\n"); + return CPA_STATUS_FAIL; + } + else + { + pthread_detach(*thread); + return CPA_STATUS_SUCCESS; + } +#else + *thread = kthread_create(funct, args, "SAMPLE_THREAD"); + wake_up_process(*thread); + return CPA_STATUS_SUCCESS; +#endif +} + +static __inline void sampleThreadExit(void) +{ +#ifdef USER_SPACE + pthread_exit(NULL); +#endif +} + +#ifdef DO_CRYPTO +void sampleCyGetInstance(CpaInstanceHandle *pCyInstHandle); + +void sampleCyStartPolling(CpaInstanceHandle cyInstHandle); + +void sampleCyStopPolling(void); + +void symSessionWaitForInflightReq(CpaCySymSessionCtx pSessionCtx); +#endif // DO_CRYPTO + +void sampleDcGetInstance(CpaInstanceHandle *pDcInstHandle); + +void sampleDcStartPolling(CpaInstanceHandle dcInstHandle); + +void sampleDcStopPolling(void); + + +#endif + +/** + ***************************************************************************** + * @ingroup fipsSampleCodeUtils + * displayHexArray + * + * @description + * Display the contents of a buffer + * + * @param[in] pLabel String to giving a short description of the printed + * value + * @param[in] pBuff pointer to the data to be printed + * @param[in] len len of the data to be printed + * + * @retval none + * + * @pre + * none + * @post + * none + *****************************************************************************/ +static inline void displayHexArray(const char *restrict pLabel, + const Cpa8U *restrict pBuff, + Cpa32U len) +{ + + int i = 0; + PRINT("%s(%d)", pLabel, len); + if (NULL == pBuff) + { + PRINT("%s(%d) Buff is NULL!!\n", __FUNCTION__, __LINE__); + return; + } + for (i = 0; i < len; i++) + { + PRINT("%02x", pBuff[i]); + } + PRINT("\n"); +} diff --git a/ln_mod_exp/CMakeLists.txt b/ln_mod_exp/CMakeLists.txt new file mode 100644 index 0000000..d62066f --- /dev/null +++ b/ln_mod_exp/CMakeLists.txt @@ -0,0 +1,33 @@ + +set(LNMODEXP_SRC cpa_mod_exp_sample.c) + +list(APPEND COMMON_INC_DIR ${CMAKE_CURRENT_LIST_DIR}) + +add_library(ln_mod_exp SHARED ${LNMODEXP_SRC}) +target_include_directories(ln_mod_exp PUBLIC ${COMMON_INC_DIR}) +target_link_directories(ln_mod_exp PUBLIC ${ICP_BUILDOUTPUT_PATH}) +target_link_libraries(ln_mod_exp PRIVATE cpa_sample_utils) +target_link_libraries(ln_mod_exp PUBLIC z pthread crypto qat_s usdm_drv_s) + +add_executable(test_ln_mod_exp cpa_mod_exp_sample_user.c) +target_include_directories(test_ln_mod_exp PUBLIC ${COMMON_INC_DIR}) +target_link_directories(test_ln_mod_exp PUBLIC ${ICP_BUILDOUTPUT_PATH}) +target_include_directories(test_ln_mod_exp PUBLIC /opt/openssl/include) +target_link_directories(test_ln_mod_exp PUBLIC /opt/openssl/lib) +target_link_libraries(test_ln_mod_exp PRIVATE cpa_sample_utils) +target_link_libraries(test_ln_mod_exp PRIVATE ln_mod_exp) +target_link_libraries(test_ln_mod_exp PUBLIC z pthread crypto ssl crypto qat_s usdm_drv_s) + +add_executable(qat_modexp_validation qat_modexp_validation.c) +target_include_directories(qat_modexp_validation PUBLIC ${COMMON_INC_DIR}) +target_link_directories(qat_modexp_validation PUBLIC ${ICP_BUILDOUTPUT_PATH}) +target_include_directories(qat_modexp_validation PUBLIC /opt/openssl/include) +target_link_directories(qat_modexp_validation PUBLIC /opt/openssl/lib) +target_link_libraries(qat_modexp_validation PRIVATE cpa_sample_utils) +target_link_libraries(qat_modexp_validation PRIVATE ln_mod_exp) +target_link_libraries(qat_modexp_validation PUBLIC z pthread crypto ssl crypto qat_s usdm_drv_s) + +install(TARGETS ln_mod_exp DESTINATION "lib") +install(TARGETS test_ln_mod_exp DESTINATION "bin") +install(TARGETS qat_modexp_validation DESTINATION "bin") + diff --git a/ln_mod_exp/cpa_mod_exp_sample.c b/ln_mod_exp/cpa_mod_exp_sample.c new file mode 100644 index 0000000..0d5647b --- /dev/null +++ b/ln_mod_exp/cpa_mod_exp_sample.c @@ -0,0 +1,601 @@ +/*************************************************************************** + * + * BSD LICENSE + * + * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * version: QAT.L.4.15.0-00011 + * + ***************************************************************************/ + +/* + * This is sample code that uses the primality testing APIs. A hard-coded + * prime number is tested with four different algorithms: + * + * - GCD primality test + * - Fermat primality test + * - Miller-Rabin primality test. This test requires random numbers that are + * also hardcoded here (see unsigned char MR[]) + * - Lucas primality test + */ + +#include "cpa.h" +#include "cpa_cy_im.h" +//#include "cpa_cy_prime.h" +#include "cpa_cy_ln.h" + +#include +#include + +#include "cpa_sample_utils.h" + +#define NB_MR_ROUNDS 2 +#define TIMEOUT_MS 5000 /* 5 seconds*/ + +extern int gDebugParam; + +/* Sample prime number: we want to test the primality of this number */ +//static Cpa8U sampleBase_1024[] = { +// 0x07, 0x3A, 0xD3, 0x1F, 0x2B, 0x41, 0xAD, 0x36, +// 0x23, 0xDD, 0xD0, 0x47, 0x8A, 0xB5, 0xC9, 0xD6, +// 0xC4, 0x5B, 0x43, 0x4C, 0xE7, 0x74, 0x9A, 0xA1, +// 0x3D, 0x38, 0xAD, 0xC1, 0x7E, 0x7A, 0xD2, 0xF2, +// 0xD4, 0x6C, 0x6D, 0x87, 0x32, 0x52, 0x1D, 0xDA, +// 0x16, 0x1C, 0xCB, 0x2B, 0x2C, 0x1D, 0x8E, 0x29, +// 0xA6, 0x3F, 0xD9, 0x0C, 0xD4, 0xCE, 0x2C, 0x9C, +// 0x0F, 0xBE, 0x5D, 0x6E, 0x68, 0x5A, 0xBF, 0x7D, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x36, 0x61, 0xAD, 0x36, 0x36, 0x61, 0xAD, 0x36, +// 0x96, 0x43, 0xC9, 0xD6, 0x96, 0x43, 0xC9, 0xD6, +// 0x5A, 0xA9, 0x9A, 0xA1, 0x5A, 0xA9, 0x9A, 0xA1, +// 0x95, 0xB4, 0xD2, 0xF2, 0x95, 0xB4, 0xD2, 0xF2, +// 0xC8, 0xDF, 0x1D, 0xDA, 0xC8, 0xDF, 0x1D, 0xDA, +// 0x7C, 0x82, 0x8E, 0x29, 0x7C, 0x82, 0x8E, 0x29, +// 0x40, 0xC9, 0x2C, 0x9C, 0x40, 0xC9, 0x2C, 0x9C}; + +// 216 (in big endian format) +static Cpa8U sampleBase_1024[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8}; + +// 7 (in big endian format) +static Cpa8U sampleModulus_1024[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07}; + +// 3 (in big endian format) +static Cpa8U sampleExponent_1024[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}; + + +/* Forward declaration */ +CpaStatus lnModExpSample(void); +CpaStatus bnModExpSample(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits); + +static clock_t qat_start; +static clock_t qat_elapsed; + +/* + * Callback function + * + * This function is "called back" (invoked by the implementation of + * the API) when the asynchronous operation has completed. The + * context in which it is invoked depends on the implementation, but + * as described in the API it should not sleep (since it may be called + * in a context which does not permit sleeping, e.g. a Linux bottom + * half). + * + * This function can perform whatever processing is appropriate to the + * application. For example, it may free memory, continue processing, + * etc. In this example, the function prints out the status of the + * primality test, and sets the complete variable to indicate it has + * been called. + */ +static void lnModExpCallback(void *pCallbackTag, + CpaStatus status, + void *pOpData, + CpaFlatBuffer *pOut) +{ + qat_elapsed = clock() - qat_start; + +#ifdef _DESTINY_DEBUG_VERBOSE + PRINT_DBG("lnModExpCallback, status = %d.\n", status); + if (NULL == pOpData) { + PRINT_ERR("pOpData is null, status = %d\n", status); + return; + } else { + CpaCyLnModExpOpData *opData = (CpaCyLnModExpOpData *) pOpData; + displayHexArray("\tbase: ",opData->base.pData, + opData->base.dataLenInBytes); + displayHexArray("\texponent: ",opData->exponent.pData, + opData->exponent.dataLenInBytes); + displayHexArray("\tmodulus: ",opData->modulus.pData, + opData->modulus.dataLenInBytes); + } +#endif + + if (CPA_STATUS_SUCCESS != status) { + PRINT_ERR("callback failed, status = %d\n", status); + } else { +#ifdef _DESTINY_DEBUG_VERBOSE + // 216^3 mod 7 = 6 + displayHexArray("\tb^e mod m: ", pOut->pData, pOut->dataLenInBytes); +#endif + printf("QAT: %.1lfus\t", qat_elapsed / (CLOCKS_PER_SEC / 1000000.0)); + + // The callback tag in this happens to be a synchronization object + if (NULL != pCallbackTag) { +#ifdef _DESTINY_DEBUG_VERBOSE + PRINT_DBG("Modular exponentiation completed.\n"); + PRINT_DBG("Wake up waiting thread from callback function.\n"); +#endif + COMPLETE((struct COMPLETION_STRUCT *)pCallbackTag); + } + } + + return ; +} + + +static CpaStatus bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits, CpaInstanceHandle cyInstHandle) +{ + // nbits is the number of security bits + int len = nbits / 8; // length in bytes + + CpaStatus status = CPA_STATUS_SUCCESS; + + //CpaBoolean testPassed = CPA_FALSE; + + // Mod Exp buffers + Cpa8U *pBase = NULL; + Cpa8U *pModulus = NULL; + Cpa8U *pExponent = NULL; + CpaFlatBuffer modExpRes = {.pData = NULL, .dataLenInBytes = 0}; + + struct COMPLETION_STRUCT complete; + +#ifdef _DESTINY_DEBUG_VERBOSE + PRINT_DBG("modExpPerformOp\n"); +#endif + + COMPLETION_INIT(&complete); + + // Allocate device memory and copy data from host + status = PHYS_CONTIG_ALLOC(&pBase, len); + if (NULL != pBase) { + unsigned char *bin = (unsigned char *) calloc(len, sizeof(unsigned char)); + if (BN_bn2binpad(b,bin,len)) { + memcpy(pBase,bin,len); + } else { + PHYS_CONTIG_FREE(pBase); + } + } + if (CPA_STATUS_SUCCESS == status) { + status = PHYS_CONTIG_ALLOC(&pModulus, len); + if (NULL != pModulus) { + unsigned char *bin = (unsigned char *) calloc(len, sizeof(unsigned char)); + if (BN_bn2binpad(m,bin,len)) { + memcpy(pModulus,bin,len); + } else { + PHYS_CONTIG_FREE(pModulus); + } + } + } + if (CPA_STATUS_SUCCESS == status) { + status = PHYS_CONTIG_ALLOC(&pExponent, len); + if (NULL != pExponent) { + unsigned char *bin = (unsigned char *) calloc(len, sizeof(unsigned char)); + if (BN_bn2binpad(e,bin,len)) { + memcpy(pExponent,bin,len); + } else { + PHYS_CONTIG_FREE(pExponent); + } + } + } + + // Create test op data for the modular exponentiation + CpaCyLnModExpOpData modExpOpData = { + .modulus = {.dataLenInBytes = 0, .pData = NULL}, + .base = {.dataLenInBytes = 0, .pData = NULL}, + .exponent = {.dataLenInBytes = 0, .pData = NULL}}; + + // Allocate memory to store modular exponentiation results + if (CPA_STATUS_SUCCESS == status) { + status = PHYS_CONTIG_ALLOC(&modExpRes.pData, len); + if (NULL != modExpRes.pData) { + modExpRes.dataLenInBytes = len; + } + } + +#ifdef _DESTINY_DEBUG_VERBOSE + printf("\tPerform %dth large number modular exponentiation.\n",i); +#endif + + if (CPA_STATUS_SUCCESS == status) { + modExpOpData.base.dataLenInBytes = len; + modExpOpData.base.pData = pBase; + modExpOpData.exponent.dataLenInBytes = len; + modExpOpData.exponent.pData = pExponent; + modExpOpData.modulus.dataLenInBytes = len; + modExpOpData.modulus.pData = pModulus; + + qat_start = clock(); + status = cpaCyLnModExp(cyInstHandle, + lnModExpCallback, //NULL, /*callback function*/ + (void *)&complete, //NULL, /*callback tag*/ + &modExpOpData, + &modExpRes); + + if ((CPA_STATUS_RETRY != status) && (CPA_STATUS_SUCCESS != status)) { + //if (CPA_STATUS_SUCCESS != + // cpaCyGetStatusText(cyInstHandle, status, statusErrorString)) { + // PRINT_ERR("Error retrieving status string.\n"); + //} +#ifdef _DESTINY_DEBUG_VERBOSE + PRINT_ERR("doModExp Fail -- "); //%s\n", statusErrorString); +#endif + status = CPA_STATUS_FAIL; + //goto finish; + } + } + + if (CPA_STATUS_SUCCESS == status) + { + /** Wait until the callback function has been called*/ + if (!COMPLETION_WAIT(&complete, TIMEOUT_MS)) + { +#ifdef _DESTINY_DEBUG_VERBOSE + PRINT_ERR("timeout or interruption in cpaCySymPerformOp\n"); +#endif + status = CPA_STATUS_FAIL; + } + } + + r = BN_bin2bn(modExpRes.pData, modExpRes.dataLenInBytes, r); + + /** Free all allocated structures before exit*/ + PHYS_CONTIG_FREE(pBase); + PHYS_CONTIG_FREE(pModulus); + PHYS_CONTIG_FREE(pExponent); + PHYS_CONTIG_FREE(modExpRes.pData); + + COMPLETION_DESTROY(&complete); + + return status; +} + + +/* + * Perform a primality test operation on an hardcoded prime number + */ +static CpaStatus lnModExpPerformOp(CpaInstanceHandle cyInstHandle) +{ + CpaStatus status = CPA_STATUS_SUCCESS; + + //CpaBoolean testPassed = CPA_FALSE; + + // Mod Exp buffers + Cpa8U *pBase = NULL; + Cpa8U *pModulus = NULL; + Cpa8U *pExponent = NULL; + CpaFlatBuffer modExpRes = {.pData = NULL, .dataLenInBytes = 0}; + + struct COMPLETION_STRUCT complete; + + PRINT_DBG("modExpPerformOp\n"); + + COMPLETION_INIT(&complete); + + // Allocate device memory and copy data from host + status = PHYS_CONTIG_ALLOC(&pBase, sizeof(sampleBase_1024)); + if (NULL != pBase) { + memcpy(pBase, sampleBase_1024, sizeof(sampleBase_1024)); + } + if (CPA_STATUS_SUCCESS == status) { + status = PHYS_CONTIG_ALLOC(&pModulus, sizeof(sampleModulus_1024)); + if (NULL != pModulus) { + memcpy(pModulus, sampleModulus_1024, sizeof(sampleModulus_1024)); + } + } + if (CPA_STATUS_SUCCESS == status) { + status = PHYS_CONTIG_ALLOC(&pExponent, sizeof(sampleExponent_1024)); + if (NULL != pExponent) { + memcpy(pExponent, sampleExponent_1024, sizeof(sampleExponent_1024)); + } + } + + // Create test op data for the modular exponentiation + //if (CPA_STATUS_SUCCESS == status) { + // status = OS_MALLOC(&pModExpTestOpData, sizeof(CpaCyPrimeTestOpData)); + //} + CpaCyLnModExpOpData modExpOpData = { + .modulus = {.dataLenInBytes = 0, .pData = NULL}, + .base = {.dataLenInBytes = 0, .pData = NULL}, + .exponent = {.dataLenInBytes = 0, .pData = NULL}}; + + // Allocate memory to store modular exponentiation results + if (CPA_STATUS_SUCCESS == status) { + status = PHYS_CONTIG_ALLOC(&modExpRes.pData, sizeof(sampleModulus_1024)); + if (NULL != modExpRes.pData) { + modExpRes.dataLenInBytes = sizeof(sampleModulus_1024); + } + } + + int i = 0; + //for (i = 0; i < 10; i++) { + printf("\tPerform %dth large number modular exponentiation.\n",i); + if (CPA_STATUS_SUCCESS == status) { + modExpOpData.base.dataLenInBytes = sizeof(sampleBase_1024); + modExpOpData.base.pData = pBase; + modExpOpData.exponent.dataLenInBytes = sizeof(sampleExponent_1024); + modExpOpData.exponent.pData = pExponent; + modExpOpData.modulus.dataLenInBytes = sizeof(sampleModulus_1024); + modExpOpData.modulus.pData = pModulus; + + displayHexArray("--base: ",pBase,//modExpOpData.base.pData, + modExpOpData.base.dataLenInBytes); + displayHexArray("--exponent: ",pExponent,//modExpOpData.exponent.pData, + modExpOpData.exponent.dataLenInBytes); + displayHexArray("--modulus: ",pModulus,//modExpOpData.modulus.pData, + modExpOpData.modulus.dataLenInBytes); + + + status = cpaCyLnModExp(cyInstHandle, + lnModExpCallback, //NULL, /*callback function*/ + (void *)&complete, //NULL, /*callback tag*/ + &modExpOpData, + &modExpRes); + + if ((CPA_STATUS_RETRY != status) && (CPA_STATUS_SUCCESS != status)) { + //if (CPA_STATUS_SUCCESS != + // cpaCyGetStatusText(cyInstHandle, status, statusErrorString)) { + // PRINT_ERR("Error retrieving status string.\n"); + //} + PRINT_ERR("doModExp Fail -- "); //%s\n", statusErrorString); + status = CPA_STATUS_FAIL; + //goto finish; + } + } + + if (CPA_STATUS_SUCCESS == status) + { + /** Wait until the callback function has been called*/ + if (!COMPLETION_WAIT(&complete, TIMEOUT_MS)) + { + PRINT_ERR("timeout or interruption in cpaCySymPerformOp\n"); + status = CPA_STATUS_FAIL; + } else { + + displayHexArray("--modExpRes: ",modExpRes.pData,modExpRes.dataLenInBytes); + } + } + //} + + displayHexArray("++modExpRes: ",modExpRes.pData,modExpRes.dataLenInBytes); + + /** Free all allocated structures before exit*/ + PHYS_CONTIG_FREE(pBase); + PHYS_CONTIG_FREE(pModulus); + PHYS_CONTIG_FREE(pExponent); + + COMPLETION_DESTROY(&complete); + + return status; +} + + +CpaStatus lnModExpSample(void) +{ + CpaStatus status = CPA_STATUS_SUCCESS; + CpaInstanceHandle cyInstHandle = NULL; + //CpaCyPrimeStats64 primeStats = {0}; + CpaCyLnStats64 lnStats = {0}; + + PRINT_DBG("start of modExp sample code\n"); + + /* + * In this simplified version of instance discovery, we discover + * exactly one instance of a crypto service. + */ + sampleCyGetInstance(&cyInstHandle); + if (cyInstHandle == NULL) { + return CPA_STATUS_FAIL; + } + + /* Start Cryptographic component */ + PRINT_DBG("cpaCyStartInstance\n"); + status = cpaCyStartInstance(cyInstHandle); + + if (CPA_STATUS_SUCCESS == status) { + // Set the address translation function for the instance + status = cpaCySetAddressTranslation(cyInstHandle, sampleVirtToPhys); + } + + if (CPA_STATUS_SUCCESS == status) { + /* + * If the instance is polled start the polling thread. Note that + * how the polling is done is implementation-dependent. + */ + sampleCyStartPolling(cyInstHandle); + + /** Perform large number modular exponentiation test operations */ + status = lnModExpPerformOp(cyInstHandle); + } + + if (CPA_STATUS_SUCCESS == status) { + PRINT_DBG("cpaCyLnStatsQuery\n"); + //status = cpaCyPrimeQueryStats64(cyInstHandle, &primeStats); + status = cpaCyLnStatsQuery64(cyInstHandle, &lnStats); + if (status != CPA_STATUS_SUCCESS) { + PRINT_ERR("cpaCyLnStatsQuery() failed. (status = %d)\n", status); + } + PRINT_DBG("Number of lnModExp requests: %llu\n", + (unsigned long long)lnStats.numLnModExpRequests); + } + + /* Stop the polling thread */ + sampleCyStopPolling(); + + /** Stop Cryptographic component */ + PRINT_DBG("cpaCyStopInstance\n"); + status = cpaCyStopInstance(cyInstHandle); + + if (CPA_STATUS_SUCCESS == status) + { + PRINT_DBG("Sample code ran successfully\n"); + } + else + { + PRINT_DBG("Sample code failed with status of %d\n", status); + } + + return status; +} + + +CpaStatus bnModExpSample(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits) +{ + CpaStatus status = CPA_STATUS_SUCCESS; + CpaInstanceHandle cyInstHandle = NULL; + //CpaCyPrimeStats64 primeStats = {0}; + CpaCyLnStats64 lnStats = {0}; + +#ifdef _DESTINY_DEBUG_VERBOSE + PRINT_DBG("start of bnModExp sample code\n"); +#endif + + /* + * In this simplified version of instance discovery, we discover + * exactly one instance of a crypto service. + */ + sampleCyGetInstance(&cyInstHandle); + if (cyInstHandle == NULL) { + return CPA_STATUS_FAIL; + } + +#ifdef _DESTINY_DEBUG_VERBOSE + /* Start Cryptographic component */ + PRINT_DBG("cpaCyStartInstance\n"); +#endif + status = cpaCyStartInstance(cyInstHandle); + + if (CPA_STATUS_SUCCESS == status) { + // Set the address translation function for the instance + status = cpaCySetAddressTranslation(cyInstHandle, sampleVirtToPhys); + } + + if (CPA_STATUS_SUCCESS == status) { + /* + * If the instance is polled start the polling thread. Note that + * how the polling is done is implementation-dependent. + */ + sampleCyStartPolling(cyInstHandle); + + /** Perform big number modular exponentiation test operation */ + status = bnModExpPerformOp(r, b, e, m, nbits, cyInstHandle); + } + + if (CPA_STATUS_SUCCESS == status) { +#ifdef _DESTINY_DEBUG_VERBOSE + PRINT_DBG("cpaCyLnStatsQuery\n"); +#endif + //status = cpaCyPrimeQueryStats64(cyInstHandle, &primeStats); + status = cpaCyLnStatsQuery64(cyInstHandle, &lnStats); + if (status != CPA_STATUS_SUCCESS) { + PRINT_ERR("cpaCyLnStatsQuery() failed. (status = %d)\n", status); + } +#ifdef _DESTINY_DEBUG_VERBOSE + PRINT_DBG("Number of bnModExp requests: %llu\n", + (unsigned long long)lnStats.numLnModExpRequests); +#endif + } + + /* Stop the polling thread */ + sampleCyStopPolling(); + +#ifdef _DESTINY_DEBUG_VERBOSE + /** Stop Cryptographic component */ + PRINT_DBG("cpaCyStopInstance\n"); +#endif + status = cpaCyStopInstance(cyInstHandle); + +#ifdef _DESTINY_DEBUG_VERBOSE + if (CPA_STATUS_SUCCESS == status) { + PRINT_DBG("Sample code ran successfully\n"); + } else { + PRINT_DBG("Sample code failed with status of %d\n", status); + } +#endif + return status; +} + diff --git a/ln_mod_exp/cpa_mod_exp_sample_user.c b/ln_mod_exp/cpa_mod_exp_sample_user.c new file mode 100644 index 0000000..dc60ee0 --- /dev/null +++ b/ln_mod_exp/cpa_mod_exp_sample_user.c @@ -0,0 +1,265 @@ +/****************************************************************************** + * + * BSD LICENSE + * + * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * version: QAT.L.4.15.0-00011 + * + *****************************************************************************/ + +/** + ****************************************************************************** + * @file cpa_mod_exp_sample_user.c + * + *****************************************************************************/ + +#include "cpa_sample_utils.h" +#include "icp_sal_user.h" + +#include +#include +#include + +#define LEN_OF_1024_BITS 128 +#define LEN_OF_2048_BITS 256 +#define msb_CAN_BE_ZERO -1 +#define msb_IS_ONE 0 +#define EVEN_RND_NUM 0 +#define ODD_RND_NUM 1 + +/* + * BN_rand() generates a cryptographically strong pseudo-random number of bits bits in length and stores it in rnd. If top is -1, the most significant bit of the random number can be zero. If top is 0, it is set to 1, and if top is 1, the two most significant bits of the number will be set to 1, so that the product of two such random numbers will always have 2*bits length. If bottom is true, the number will be odd. + */ + + +extern CpaStatus lnModExpSample(void); +extern CpaStatus bnModExpSample(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits); + +int gDebugParam = 1; + + +BIGNUM *generateTestBNData(int nbits) +{ + if (!RAND_status()) + return NULL; + printf("PRNG properly seeded.\n"); + + BIGNUM *bn = BN_new(); + + if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { + BN_free(bn); + printf("Error while generating BN random number: %lu\n",ERR_get_error()); + return NULL; + } + + return bn; +} + +unsigned char *paddingZeros(BIGNUM *bn, int nbits) +{ + if (!bn) return NULL; + + // Returns same address if it fails + int num_bytes = BN_num_bytes(bn); + int bytes_left = nbits/8 - num_bytes; + if (bytes_left <= 0) return NULL; + + // Returns same address if it fails + unsigned char *bin = NULL; + int len = bytes_left + num_bytes; + if (!(bin = OPENSSL_zalloc(len))) return NULL; + + printf("Padding bn with %d bytes to total %d bytes\n",bytes_left,len); + BN_bn2binpad(bn,bin,len); + if (ERR_get_error()) { + OPENSSL_free(bin); + return NULL; + } + + return bin; +} + +void showHexBN(BIGNUM *bn, int nbits) +{ + int len = nbits / 8; + unsigned char *bin = OPENSSL_zalloc(len); + if (!bin) return ; + if (BN_bn2binpad(bn,bin,len)) { + for (size_t i = 0; i < len; i++) + printf("%d",bin[i]); + printf("\n"); + } + OPENSSL_free(bin); + return ; +} + +void showHexBin(unsigned char *bin, int len) +{ + if (!bin) return ; + for (size_t i = 0; i < len; i++) + printf("%d",bin[i]); + printf("\n"); + return ; +} + +int main(int argc, const char **argv) +{ + //BIGNUM *base = NULL; + + // OpenSSL as baseline + + BN_CTX *ctx = BN_CTX_new(); + BN_CTX_start(ctx); + + BIGNUM *bn = generateTestBNData(1024); + + if (bn) { + char *bn_str = BN_bn2hex(bn); + printf("Generated BN: %s num_bytes: %d num_bits: %d\n",bn_str,BN_num_bytes(bn),BN_num_bits(bn)); + + BN_ULONG c0 = 7, c1 = 3, c2 = 216; + + printf("BN_ULONG size in bytes: %lu\n", sizeof(BN_ULONG)); + + BIGNUM *bn_c0, *bn_c1, *bn_c2, *res; + + res = BN_new(); + bn_c0 = BN_new(); + bn_c1 = BN_new(); + bn_c2 = BN_new(); + + BN_set_word(bn_c0,c0); + BN_set_word(bn_c1,c1); + BN_set_word(bn_c2,c2); + + bn_str = BN_bn2hex(bn_c0); + printf("BN c0: %s num_bytes: %d num_bits: %d\n",bn_str,BN_num_bytes(bn_c0),BN_num_bits(bn_c0)); + bn_str = BN_bn2hex(bn_c1); + printf("BN c1: %s num_bytes: %d num_bits: %d\n",bn_str,BN_num_bytes(bn_c1),BN_num_bits(bn_c1)); + bn_str = BN_bn2hex(bn_c2); + printf("BN c2: %s num_bytes: %d num_bits: %d\n",bn_str,BN_num_bytes(bn_c2),BN_num_bits(bn_c2)); + + if (BN_mod_exp(res, bn_c2, bn_c1, bn_c0, ctx)) { + bn_str = BN_bn2hex(res); + printf("BN mod exp res: %s num_bytes: %d num_bits: %d\n",bn_str,BN_num_bytes(res),BN_num_bits(res)); + showHexBN(res,1024); + } else { + printf("Modular exponentiation failed.\n"); + } + + // + CpaStatus status = CPA_STATUS_SUCCESS; + + PRINT_DBG("Starting bnModExp Sample Code App ...\n"); + + status = qaeMemInit(); + if (CPA_STATUS_SUCCESS != status) + { + PRINT_ERR("Failed to initialize memory driver\n"); + return (int)status; + } + + status = icp_sal_userStartMultiProcess("SSL", CPA_FALSE); + if (CPA_STATUS_SUCCESS != status) + { + PRINT_ERR("Failed to start user process SSL\n"); + qaeMemDestroy(); + return (int)status; + } + + //status = lnModExpSample(); + BIGNUM *r = BN_new(); + status = bnModExpSample(r, bn_c2, bn_c1, bn_c0, 1024); + if (CPA_STATUS_SUCCESS != status) + { + PRINT_ERR("\nbnModExp Sample Code App failed\n"); + } + else + { + PRINT_DBG("\nbnModExp Sample Code App finished\n"); + } + + icp_sal_userStop(); + qaeMemDestroy(); + + OPENSSL_free(bn_str); + //BN_free(res); + BN_free(bn_c0); + BN_free(bn_c1); + BN_free(bn_c2); + BN_free(bn); + } + + BN_CTX_end(ctx); + + return 0; + + // QAT + + CpaStatus stat = CPA_STATUS_SUCCESS; + + if (argc > 1) + { + gDebugParam = atoi(argv[1]); + } + + PRINT_DBG("Starting LnModExp Sample Code App ...\n"); + + stat = qaeMemInit(); + if (CPA_STATUS_SUCCESS != stat) + { + PRINT_ERR("Failed to initialize memory driver\n"); + return (int)stat; + } + + stat = icp_sal_userStartMultiProcess("SSL", CPA_FALSE); + if (CPA_STATUS_SUCCESS != stat) + { + PRINT_ERR("Failed to start user process SSL\n"); + qaeMemDestroy(); + return (int)stat; + } + + stat = lnModExpSample(); + if (CPA_STATUS_SUCCESS != stat) + { + PRINT_ERR("\nLnModExp Sample Code App failed\n"); + } + else + { + PRINT_DBG("\nLnModExp Sample Code App finished\n"); + } + + icp_sal_userStop(); + qaeMemDestroy(); + + return (int)stat; +} diff --git a/ln_mod_exp/qat_modexp_validation.c b/ln_mod_exp/qat_modexp_validation.c new file mode 100644 index 0000000..be59896 --- /dev/null +++ b/ln_mod_exp/qat_modexp_validation.c @@ -0,0 +1,235 @@ +/****************************************************************************** + * + * BSD LICENSE + * + * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * version: QAT.L.4.15.0-00011 + * + *****************************************************************************/ + +/** + ****************************************************************************** + * @file cpa_mod_exp_sample_user.c + * + *****************************************************************************/ + +#include "cpa_sample_utils.h" +#include "icp_sal_user.h" + +#include +#include +#include +#include + +#define LEN_OF_1024_BITS 128 +#define LEN_OF_2048_BITS 256 +#define msb_CAN_BE_ZERO -1 +#define msb_IS_ONE 0 +#define EVEN_RND_NUM 0 +#define ODD_RND_NUM 1 + +/* + * BN_rand() generates a cryptographically strong pseudo-random number of bits bits in length and stores it in rnd. If top is -1, the most significant bit of the random number can be zero. If top is 0, it is set to 1, and if top is 1, the two most significant bits of the number will be set to 1, so that the product of two such random numbers will always have 2*bits length. If bottom is true, the number will be odd. + */ + +extern CpaStatus lnModExpSample(void); +extern CpaStatus bnModExpSample(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits); + +int gDebugParam = 1; + + +BIGNUM *generateTestBNData(int nbits) +{ + if (!RAND_status()) + return NULL; +#ifdef _DESTINY_DEBUG_VERBOSE + printf("PRNG properly seeded.\n"); +#endif + + BIGNUM *bn = BN_new(); + + if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { + BN_free(bn); + printf("Error while generating BN random number: %lu\n",ERR_get_error()); + return NULL; + } + + return bn; +} + +unsigned char *paddingZeros(BIGNUM *bn, int nbits) +{ + if (!bn) return NULL; + + // Returns same address if it fails + int num_bytes = BN_num_bytes(bn); + int bytes_left = nbits/8 - num_bytes; + if (bytes_left <= 0) return NULL; + + // Returns same address if it fails + unsigned char *bin = NULL; + int len = bytes_left + num_bytes; + if (!(bin = OPENSSL_zalloc(len))) return NULL; + +#ifdef _DESTINY_DEBUG_VERBOSE + printf("Padding bn with %d bytes to total %d bytes\n",bytes_left,len); +#endif + BN_bn2binpad(bn,bin,len); + if (ERR_get_error()) { + OPENSSL_free(bin); + return NULL; + } + + return bin; +} + +void showHexBN(BIGNUM *bn, int nbits) +{ + int len = nbits / 8; + unsigned char *bin = OPENSSL_zalloc(len); + if (!bin) return ; + if (BN_bn2binpad(bn,bin,len)) { + for (size_t i = 0; i < len; i++) + printf("%d",bin[i]); + printf("\n"); + } + OPENSSL_free(bin); + return ; +} + +void showHexBin(unsigned char *bin, int len) +{ + if (!bin) return ; + for (size_t i = 0; i < len; i++) + printf("%d",bin[i]); + printf("\n"); + return ; +} + +int main(int argc, const char **argv) +{ + const size_t num_trials = 100; + const int bit_length = 1024; + + // OpenSSL as baseline + BN_CTX *ctx = BN_CTX_new(); + BN_CTX_start(ctx); + + CpaStatus status = CPA_STATUS_SUCCESS; + + for (size_t mod = 0; mod < num_trials; mod++) { + printf("Trial #%0.3lu\t",mod+1); + + BIGNUM *bn_mod = generateTestBNData(bit_length); + + if (!bn_mod) continue; + + char *bn_str = BN_bn2hex(bn_mod); +#ifdef _DESTINY_DEBUG_VERBOSE + printf("Generated modulus: %s num_bytes: %d num_bits: %d\n", + bn_str,BN_num_bytes(bn_mod),BN_num_bits(bn_mod)); +#endif + // bn_exponent in [0..bn_mod] + BIGNUM *bn_exponent = BN_new(); + if (!BN_rand_range(bn_exponent, bn_mod)) { + BN_free(bn_mod); + continue; + } + + BIGNUM *bn_base = generateTestBNData(bit_length); + + BIGNUM *ssl_res = BN_new(); + clock_t start = clock(); + BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); + clock_t elapsed = clock() - start; + printf("OpenSSL: %.1lfus\t", elapsed / (CLOCKS_PER_SEC / 1000000.0)); + + //if (BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx)) { + if (!ERR_get_error()) { + bn_str = BN_bn2hex(ssl_res); +#ifdef _DESTINY_DEBUG_VERBOSE + printf("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", + bn_str, BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); + showHexBN(ssl_res, bit_length); +#endif + } else { + printf("Modular exponentiation failed.\n"); + } + +#ifdef _DESTINY_DEBUG_VERBOSE + PRINT_DBG("Starting QAT bnModExp Sample Code App ...\n"); +#endif + status = qaeMemInit(); + if (CPA_STATUS_SUCCESS != status) { + PRINT_ERR("Failed to initialize memory driver\n"); + return (int)status; + } + + status = icp_sal_userStartMultiProcess("SSL", CPA_FALSE); + if (CPA_STATUS_SUCCESS != status) { + PRINT_ERR("Failed to start user process SSL\n"); + qaeMemDestroy(); + return (int)status; + } + + BIGNUM *qat_res = BN_new(); + status = bnModExpSample(qat_res, bn_base, bn_exponent, bn_mod, bit_length); + if (CPA_STATUS_SUCCESS != status) { + PRINT_ERR("\nQAT bnModExp Sample Code App failed\n"); + } +#ifdef _DESTINY_DEBUG_VERBOSE + else { + PRINT_DBG("\nQAT bnModExp Sample Code App finished\n"); + } +#endif + + icp_sal_userStop(); + qaeMemDestroy(); + + if (BN_cmp(qat_res, ssl_res) != 0) + printf("\t** FAIL **\n"); + else + printf("\t** PASS **\n"); + + OPENSSL_free(bn_str); + + BN_free(ssl_res); + BN_free(qat_res); + + BN_free(bn_mod); + BN_free(bn_base); + BN_free(bn_exponent); + } + + BN_CTX_end(ctx); + + return (int)status; +} diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..bd01707 --- /dev/null +++ b/run.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +export ICP_ROOT=$HOME/QAT +export LD_LIBRARY_PATH=$PWD/install/lib:$ICP_ROOT/build:$LD_LIBRARY_PATH +pushd ./install/bin +./qat_modexp_validation +popd From db6c8a9ab8dea51609039dcbd66ada5cd0161214 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 21 Feb 2022 21:58:41 -0800 Subject: [PATCH 015/364] Add initial 'code' to set up QAT context. --- he_qat_context.c | 75 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 10 deletions(-) diff --git a/he_qat_context.c b/he_qat_context.c index c053d40..a6db26f 100644 --- a/he_qat_context.c +++ b/he_qat_context.c @@ -1,6 +1,6 @@ #include "heqat_types.h" - +#include "icp_sal_poll.h" #include "cpa_sample_utils.h" //CpaStatus get_qat_instances(CpaInstanceHandle *_instances, int *_num_instances=-1) @@ -10,18 +10,42 @@ const int MAX_NUM_INST 8 +// Type definitions enum HEQAT_EXEC_MODE { HEQAT_BLOCK_SYNC=1 }; enum HEQAT_STATUS { HEQAT_SUCCESS = 0, HEQAT_FAIL = 1 }; - - -typedef struct InstConfigStruct { +typedef pthread_t QATInst; +typedef struct QATInstConfigStruct { CpaInstanceHandle inst_handle; + //void *func(); volatile int polling; -} InstConfig; - -pthread_t threads[MAX_NUM_INST]; +} QATInstConfig; + +// Global variable declarations +QATInst qat_instances [MAX_NUM_INST]; +QATInstConfig qat_inst_config [MAX_NUM_INST]; +/* +#define HEQAT_FREE_QATInstConfig(config) \ + do { \ + if (config) { \ + if (config->inst_handle) { \ + + } \ + free(config); \ + config = NULL; \ + } \ + } while (0) +*/ + +static void inst_thread() +{ + +} -static void sal_inst_polling(InstConfig *config) +/// @brief +/// @function start_inst_polling +/// @param[in] QATInstConfig Holds the parameter values to set up the QAT instance thread. +/// +static void start_inst_polling(QATInstConfig *config) { if (!config) return ; @@ -35,6 +59,23 @@ static void sal_inst_polling(InstConfig *config) return ; } +/// @brief This function +/// @function sal_stop_inst_polling +/// QATInstConfig Holds the parameter values to set up the QAT instance thread. +/// +static void stop_inst_polling() +{ + for (int i = 0; i < MAX_NUM_INSTS; i++) { + // Or check if the cpa_instance is not NULL (try it out) + //if (!qat_inst_config[i].inst_handle) continue; + if (!qat_inst_config[i].polling) continue; + qat_inst_config[i].polling = 0; + OS_SLEEP(10); + } + + return ; +} + /// @brief /// @function acquire_qat_devices /// Acquire QAT instances and set up QAT execution environment. @@ -59,13 +100,17 @@ HEQAT_STATUS acquire_qat_devices() pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpus); // configure thread - InstConfig *config = (InstConfig *) malloc(sizeof(InstConfig)); + QATInstConfig *config = (QATInstConfig *) malloc(sizeof(QATInstConfig)); if (config == NULL) return HEQAT_FAIL; config->inst_handle = _inst_handle[i]; - pthread_create(&threads[i], &attr, sal_polling, config); // + pthread_create(&qat_instances[i], &attr, start_inst_polling, config); } + for (int i = 0; i < HEQAT_BLOCK_SYNC; i++) { + pthread_ + } + return ; } @@ -74,6 +119,16 @@ HEQAT_STATUS acquire_qat_devices() /// Release QAT instances and tear down QAT execution environment. void release_qat_devices() { + CpaStatus status = CPA_STATUS_FAIL; + + // signal all qat instance + + for (int i = 0; i < MAX_NUM_INST; i++) { + status = cpaCyStopInstance(qat_inst_config[i].inst_handle); + if (CPA_STATUS_SUCCESS != status) { + printf("Failed to stop QAT instance #%d\n",i); + } + } return ; } From 774cd87aeabfd02a16ce556682640c966c0e36d9 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Tue, 22 Feb 2022 23:33:11 -0800 Subject: [PATCH 016/364] Docs licenses (#2) * work in progress - doc updates * Added license and codeowners * Updated internal repo codeowners --- .clang-format | 2 +- .gitignore | 11 +- .pre-commit-config.yaml | 9 +- .typos.toml | 3 +- CMakeLists.txt | 14 +- CODEOWNERS | 5 + LICENSE | 201 +++++++++++++++++++++++++++++ README.md | 17 ++- benchmark/CMakeLists.txt | 2 + benchmark/bench_cryptography.cpp | 1 + benchmark/bench_ops.cpp | 1 + benchmark/main.cpp | 1 + cmake/gbenchmark.cmake | 1 + cmake/gtest.cmake | 1 + cmake/ipcl/ipcl-util.cmake | 85 +----------- cmake/ippcrypto.cmake | 1 + docs/CMakeLists.txt | 1 + docs/Doxyfile.in | 1 + docs/index.rst | 2 +- ipcl/CMakeLists.txt | 1 + ipcl/include/ipcl/key_pair.hpp | 1 + ipcl/include/ipcl/paillier_ops.hpp | 1 + ipcl/include/ipcl/pri_key.hpp | 1 + ipcl/include/ipcl/pub_key.hpp | 1 + ipcl/key_pair.cpp | 1 + ipcl/paillier_ops.cpp | 1 + ipcl/paillier_pri.cpp | 1 + ipcl/paillier_pub.cpp | 1 + test/CMakeLists.txt | 5 +- test/test.cpp | 1 + test/test_omp.cpp | 1 + 31 files changed, 261 insertions(+), 114 deletions(-) create mode 100644 CODEOWNERS create mode 100644 LICENSE diff --git a/.clang-format b/.clang-format index 6ee397d..c2b1851 100644 --- a/.clang-format +++ b/.clang-format @@ -1,4 +1,4 @@ -# Copyright (C) 2020-2021 Intel Corporation +# Copyright (C) 2021-2022 Intel Corporation # SPDX-License-Identifier: Apache-2.0 BasedOnStyle: Google diff --git a/.gitignore b/.gitignore index 914bd42..f88e0c0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,10 @@ +# Copyright (C) 2021-2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + .vscode/ .vs/ build*/ - .DS_Store # Generated files @@ -11,12 +13,5 @@ docs/doxygen/ Doxyfile cmake/ipcl-*.*.*/IPCLConfig.cmake -# Python files -venv/ -__pycache__/ -.ipynb_checkpoints/ -.mypy_cache/ -.env - # vim **.swp diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d4dd2af..b194bad 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,3 +1,6 @@ +# Copyright (C) 2021-2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + exclude: 'docs/doxygen/' repos: - repo: https://github.com/pre-commit/pre-commit-hooks @@ -15,9 +18,9 @@ repos: - id: typos - repo: local hooks: - - id: clang-format-10 - name: clang-format-10 - entry: clang-format-10 + - id: clang-format + name: clang-format + entry: clang-format language: system files: \.(c|cc|cxx|cpp|h|hpp|hxx|js|proto)$ args: diff --git a/.typos.toml b/.typos.toml index 50006f5..35b631b 100644 --- a/.typos.toml +++ b/.typos.toml @@ -1,5 +1,4 @@ [default.extend-identifiers] +Adaptee = "Adaptee" [default.extend-words] -# variation of params -parms = "parms" diff --git a/CMakeLists.txt b/CMakeLists.txt index 97f7087..23577c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,6 @@ # Copyright (C) 2021-2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + cmake_minimum_required(VERSION 3.15.1) project(IPCL VERSION 1.0.0 LANGUAGES C CXX) @@ -24,12 +26,10 @@ else() set(CMAKE_BUILD_TYPE Release) endif() -# TODO(skmono): Assess if C++17 is necessary -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) -# Create compilation database compile_commands.json set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) @@ -52,7 +52,6 @@ option(IPCL_TEST "Enable testing" ON) option(IPCL_BENCHMARK "Enable benchmark" ON) option(IPCL_TEST_OMP "Enable OpenMP testing" ON) option(IPCL_DOCS "Enable document building" OFF) -# TODO(skmono): Fix static library build option(IPCL_SHARED "Build shared library" ON) if(CMAKE_BUILD_TYPE STREQUAL "Debug") @@ -66,14 +65,12 @@ set(IPCL_CMAKE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/ipcl") message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}") message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}") +message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") message(STATUS "IPCL_TEST: ${IPCL_TEST}") message(STATUS "IPCL_TEST_OMP: ${IPCL_TEST_OMP}") message(STATUS "IPCL_BENCHMARK: ${IPCL_BENCHMARK}") message(STATUS "IPCL_DOCS: ${IPCL_DOCS}") message(STATUS "IPCL_SHARED: ${IPCL_SHARED}") -message(STATUS "CMAKE_INSTALL_LIBDIR: ${CMAKE_INSTALL_LIBDIR}") -message(STATUS "CMAKE_INSTALL_INCLUDEDIR: ${CMAKE_INSTALL_INCLUDEDIR}") -message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") set(IPCL_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) set(IPCL_SRC_DIR ${IPCL_ROOT_DIR}/ipcl) @@ -95,7 +92,7 @@ set(IPCL_FORWARD_CMAKE_ARGS set(OPENSSL_USE_STATIC_LIBS TRUE) find_package(Threads REQUIRED) find_package(OpenSSL REQUIRED) -message(STATUS "OpenSSL Found: ${OPENSSL_FOUND}") + # External dependencies set(CMAKE_THREAD_PREFER_PTHREAD ON) set(THREADS_PREFER_PTHREAD_FLAG ON) @@ -114,6 +111,7 @@ endif() add_subdirectory(ipcl) +# unit-test and benchmarks if(IPCL_TEST) add_subdirectory(test) add_custom_target(unittest COMMAND $ DEPENDS unit-test) diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..702e633 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,5 @@ +# Copyright (C) 2021-2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Default codeowner for all files +* @dpg-dbio-glade-creek-projectphe-owners diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3aa303a --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2021-2022 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index 6004fd7..21f6901 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ Intel Paillier Cryptosystem Library is an open-source library which provides acc - [Dependencies](#dependencies) - [Instructions](#instructions) - [Testing and Benchmarking](#testing-and-benchmarking) +- [Standardization](#standardization) - [Contributors](#contributors) ## Introduction @@ -30,9 +31,10 @@ For increased security, typically the key length is at least 1024 bits, but reco The hardware requirement to use the library is AVX512IFMA instruction sets enabled CPUs, as listed in Intel codenames: - Intel Cannon Lake - Intel Ice Lake -We are planning to add support for more SKUs. -Currently the library has been tested and confirmed to work on Ubuntu 18.04, 20.04 and RHEL 8.4. +Note: We are planning to add support for more SKUs. + +As for the operating systems, ehe library has been tested and confirmed to work on Ubuntu 18.04, 20.04 and RHEL 8.0. ### Dependencies Must have dependencies include: @@ -41,7 +43,6 @@ cmake >=3.15.1 git pthread g++ >= 7.0 or clang >= 10.0 -python >= 3.8 ``` The following libraries are also required, @@ -50,14 +51,14 @@ nasm>=2.15 OpenSSL>=1.1.0 ``` -For ```nasm``` installation, please refer to the [Netwide Assembler](https://nasm.us/) for installation details. +For ```nasm```, please refer to the [Netwide Assembler](https://nasm.us/) for installation details. On Ubuntu, ```OpenSSL``` can be installed by: ```bash sudo apt update sudo apt install libssl-dev ``` -On RHEL, it needs to be built and installed from source as the static libraries are not installed with package managers. Please refer to [OpenSSL Project](https://github.com/openssl/openssl) for installation details. +On RHEL, it needs to be built and installed from source as the static libraries are not installed with package managers. Please refer to [OpenSSL Project](https://github.com/openssl/openssl) for installation details for static libraries. ### Instructions The library can be built using the following commands: @@ -95,7 +96,10 @@ cmake --build build --target benchmark ``` OpenMP benchmarks will automatically be applied if `-DIPCL_TEST_OMP=ON` is set. -The unit-test executable itself is located at `build/test/unit-test`, `build/test/unit-test_omp` and `build/benchmark/bench_ipcl`. +The unit-test executable itself is located at `${IPCL_DIR}/build/test/unit-test`, `${IPCL_DIR}/build/test/unit-test_omp` and `${IPCL_DIR}/build/benchmark/bench_ipcl`. + +# Standardization +This library is in compliance with the homomorphic encryption standards [ISO/IEC 18033-6](https://www.iso.org/standard/67740.html). # Contributors Main contributors to this project, sorted by alphabetical order of last name are: @@ -103,3 +107,4 @@ Main contributors to this project, sorted by alphabetical order of last name are - [Hamish Hunt](https://github.com/hamishun) - [Sejun Kim](https://github.com/skmono) (lead) - [Bin Wang](https://github.com/bwang30) + - [Pengfei Zhao](https://github.com/justalittlenoob) diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index acb2897..083a974 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -1,4 +1,6 @@ # Copyright (C) 2021-2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + set(SRC main.cpp bench_cryptography.cpp bench_ops.cpp) diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index 5adb7ed..1c7b8ea 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -1,4 +1,5 @@ // Copyright (C) 2021-2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #include diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index 4964025..1dfe7ba 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -1,4 +1,5 @@ // Copyright (C) 2021-2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #include diff --git a/benchmark/main.cpp b/benchmark/main.cpp index 4e746ac..dcdcd17 100644 --- a/benchmark/main.cpp +++ b/benchmark/main.cpp @@ -1,4 +1,5 @@ // Copyright (C) 2021-2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #include diff --git a/cmake/gbenchmark.cmake b/cmake/gbenchmark.cmake index 164c238..9849666 100644 --- a/cmake/gbenchmark.cmake +++ b/cmake/gbenchmark.cmake @@ -1,4 +1,5 @@ # Copyright (C) 2021-2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 include(ExternalProject) diff --git a/cmake/gtest.cmake b/cmake/gtest.cmake index c6e359f..a844452 100644 --- a/cmake/gtest.cmake +++ b/cmake/gtest.cmake @@ -1,4 +1,5 @@ # Copyright (C) 2021-2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 include(ExternalProject) diff --git a/cmake/ipcl/ipcl-util.cmake b/cmake/ipcl/ipcl-util.cmake index c2361ff..e56dfe8 100644 --- a/cmake/ipcl/ipcl-util.cmake +++ b/cmake/ipcl/ipcl-util.cmake @@ -1,86 +1,5 @@ -function(ipcl_check_compile_flag SOURCE_FILE OUTPUT_FLAG) - if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - set(NATIVE_COMPILE_DEFINITIONS "/arch:AVX512") - else() - set(NATIVE_COMPILE_DEFINITIONS "-march=native") - endif() - - try_run(CAN_RUN CAN_COMPILE ${CMAKE_BINARY_DIR} - "${SOURCE_FILE}" - COMPILE_DEFINITIONS ${NATIVE_COMPILE_DEFINITIONS} - OUTPUT_VARIABLE TRY_COMPILE_OUTPUT - ) - # Uncomment below to debug - # message("TRY_COMPILE_OUTPUT ${TRY_COMPILE_OUTPUT}") - if (CAN_COMPILE AND CAN_RUN STREQUAL 0) - message(STATUS "Setting ${OUTPUT_FLAG}") - add_definitions(-D${OUTPUT_FLAG}) - set(${OUTPUT_FLAG} 1 PARENT_SCOPE) - else() - message(STATUS "Compile flag not found: ${OUTPUT_FLAG}") - endif() -endfunction() - -# Checks the supported compiler versions -function(ipcl_check_compiler_version) - if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0) - message(FATAL_ERROR "IPCL requires gcc version >= 7.0") - endif() - if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0) - message(WARN "gcc version should be at least 8.0 for best performance on processors with AVX512IFMA support") - endif() - elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) - message(FATAL_ERROR "IPCL requires clang++ >= 5.0") - endif() - if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) - message(WARNING "Clang version should be at least 6.0 for best performance on processors with AVX512IFMA support") - endif() - elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19) - message(FATAL_ERROR "IPCL requires MSVC >= 19") - endif() - endif() -endfunction() - -# If the input variable is set, stores its value in a _CACHE variable -function(ipcl_cache_variable variable) - if (DEFINED ${variable}) - set(${variable}_CACHE ${${variable}} PARENT_SCOPE) - endif() -endfunction() - -# If the input variable is cached, restores its value from the cache -function(ipcl_uncache_variable variable) - if (DEFINED ${variable}_CACHE) - set(${variable} ${${variable}_CACHE} CACHE BOOL "" FORCE ) - endif() -endfunction() - -# Defines compiler-specific CMake variables -function(ipcl_add_compiler_definition) - if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - set(IPCL_USE_MSVC ON PARENT_SCOPE) - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set(IPCL_USE_GNU ON PARENT_SCOPE) - elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(IPCL_USE_CLANG ON PARENT_SCOPE) - else() - message(WARNING "Unsupported compiler ${CMAKE_CXX_COMPILER_ID}") - endif() -endfunction() - -# Link IPCL with AddressSanitizer in Debug mode on Mac/Linux -function(ipcl_add_asan_flag target) - if(IPCL_DEBUG AND UNIX) - target_compile_options(${target} PUBLIC -fsanitize=address) - target_link_options(${target} PUBLIC -fsanitize=address) - set(IPCL_ASAN_LINK "-fsanitize=address" PARENT_SCOPE) - else() - set(IPCL_ASAN_LINK "" PARENT_SCOPE) - endif() -endfunction() +# Copyright (C) 2021-2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 # Add dependency to the target archive function(ipcl_create_archive target dependency) diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake index 927427a..b5657f1 100644 --- a/cmake/ippcrypto.cmake +++ b/cmake/ippcrypto.cmake @@ -1,4 +1,5 @@ # Copyright (C) 2021-2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 include(ExternalProject) MESSAGE(STATUS "Configuring ipp-crypto") diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 37e7cd7..05f813e 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -1,4 +1,5 @@ # Copyright (C) 2021-2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 # Build Doxygen documentation SET(DOXYGEN_MIN_VERSION "1.8.17") diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in index 4f12bfb..6b3ce39 100644 --- a/docs/Doxyfile.in +++ b/docs/Doxyfile.in @@ -1,4 +1,5 @@ # Copyright (C) 2021-2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 PROJECT_NAME = "Project PHE" PROJECT_BRIEF = "Project Paillier HE library w/ Intel IPP-Crypto" diff --git a/docs/index.rst b/docs/index.rst index 39a2a7c..adcfc6a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,5 +1,5 @@ .. Copyright (C) 2021-2022 Intel Corporation - +.. SPDX-License-Identifier: Apache-2.0 Project PHE Documentation ============================== diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index a332cef..5ecf54c 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -1,4 +1,5 @@ # Copyright (C) 2021-2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 set(IPCL_SRCS paillier_pri.cpp paillier_pub.cpp diff --git a/ipcl/include/ipcl/key_pair.hpp b/ipcl/include/ipcl/key_pair.hpp index 193fd0b..67e98bb 100644 --- a/ipcl/include/ipcl/key_pair.hpp +++ b/ipcl/include/ipcl/key_pair.hpp @@ -1,4 +1,5 @@ // Copyright (C) 2021-2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #ifndef IPCL_INCLUDE_IPCL_KEY_PAIR_HPP_ #define IPCL_INCLUDE_IPCL_KEY_PAIR_HPP_ diff --git a/ipcl/include/ipcl/paillier_ops.hpp b/ipcl/include/ipcl/paillier_ops.hpp index 8e1da6d..cf90aa7 100644 --- a/ipcl/include/ipcl/paillier_ops.hpp +++ b/ipcl/include/ipcl/paillier_ops.hpp @@ -1,4 +1,5 @@ // Copyright (C) 2021-2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #ifndef IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ #define IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ diff --git a/ipcl/include/ipcl/pri_key.hpp b/ipcl/include/ipcl/pri_key.hpp index 7316c69..bddcbf3 100644 --- a/ipcl/include/ipcl/pri_key.hpp +++ b/ipcl/include/ipcl/pri_key.hpp @@ -1,4 +1,5 @@ // Copyright (C) 2021-2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #ifndef IPCL_INCLUDE_IPCL_PRI_KEY_HPP_ #define IPCL_INCLUDE_IPCL_PRI_KEY_HPP_ diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp index efe2e18..b580a10 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -1,4 +1,5 @@ // Copyright (C) 2021-2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #ifndef IPCL_INCLUDE_IPCL_PUB_KEY_HPP_ #define IPCL_INCLUDE_IPCL_PUB_KEY_HPP_ diff --git a/ipcl/key_pair.cpp b/ipcl/key_pair.cpp index 4d2f585..5ba75e3 100644 --- a/ipcl/key_pair.cpp +++ b/ipcl/key_pair.cpp @@ -1,4 +1,5 @@ // Copyright (C) 2021-2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #include "ipcl/key_pair.hpp" diff --git a/ipcl/paillier_ops.cpp b/ipcl/paillier_ops.cpp index 3942b96..651641b 100644 --- a/ipcl/paillier_ops.cpp +++ b/ipcl/paillier_ops.cpp @@ -1,4 +1,5 @@ // Copyright (C) 2021-2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #include "ipcl/paillier_ops.hpp" diff --git a/ipcl/paillier_pri.cpp b/ipcl/paillier_pri.cpp index cd205d6..2a2f91a 100644 --- a/ipcl/paillier_pri.cpp +++ b/ipcl/paillier_pri.cpp @@ -1,4 +1,5 @@ // Copyright (C) 2021-2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #include diff --git a/ipcl/paillier_pub.cpp b/ipcl/paillier_pub.cpp index 7473e56..2b2fc75 100644 --- a/ipcl/paillier_pub.cpp +++ b/ipcl/paillier_pub.cpp @@ -1,4 +1,5 @@ // Copyright (C) 2021-2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #include diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ec49c27..298af61 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,6 +1,7 @@ -# Unit tests +# Copyright (C) 2021-2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 -# main unittest +# Unit tests add_executable(unit-test test.cpp) target_link_libraries(unit-test PRIVATE ipcl libgtest Threads::Threads) target_include_directories(unit-test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${IPCL_INC_DIR})# ${IPPCRYPTO_INC_DIR}) diff --git a/test/test.cpp b/test/test.cpp index 7ef35f0..72c066c 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1,4 +1,5 @@ // Copyright (C) 2021-2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #include #include diff --git a/test/test_omp.cpp b/test/test_omp.cpp index 6792e91..3f8a0e8 100644 --- a/test/test_omp.cpp +++ b/test/test_omp.cpp @@ -1,4 +1,5 @@ // Copyright (C) 2021-2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #include #include From eaca07c8bfb918176f5011758975034b3929b53c Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Wed, 23 Feb 2022 16:30:51 -0800 Subject: [PATCH 017/364] Cleanup and unittest works (#3) * Cleanup and unittest works - Removed benchmark features from unittests - Added ISO/IEC 18033-6 compliance test in unittest - Added support functions to public/private keys - Rearranged OpenMP tests into cryptography and ops format similar to benchmark - Now has one unittest binary instead of two, OpenMP testing enabled during compile time - Updated flags and build targets accordingly - Updated ci/cd to reflect unittest binary change --- .github/workflows/github-ci.yml | 48 ++- CMakeLists.txt | 9 +- benchmark/CMakeLists.txt | 9 +- benchmark/bench_cryptography.cpp | 4 +- benchmark/bench_ops.cpp | 4 +- ipcl/include/ipcl/pri_key.hpp | 7 + ipcl/include/ipcl/pub_key.hpp | 12 + ipcl/paillier_pub.cpp | 9 +- test/CMakeLists.txt | 25 +- test/main.cpp | 13 + test/test.cpp | 405 ----------------------- test/test_cryptography.cpp | 258 +++++++++++++++ test/{test_omp.cpp => test_ops.cpp} | 485 +++++++++++++++++++++------- 13 files changed, 736 insertions(+), 552 deletions(-) create mode 100644 test/main.cpp delete mode 100644 test/test.cpp create mode 100644 test/test_cryptography.cpp rename test/{test_omp.cpp => test_ops.cpp} (57%) diff --git a/.github/workflows/github-ci.yml b/.github/workflows/github-ci.yml index bc6a98b..0bd1552 100644 --- a/.github/workflows/github-ci.yml +++ b/.github/workflows/github-ci.yml @@ -1,6 +1,7 @@ -# Copyright (C) 2021 Intel Corporation +# Copyright (C) 2021-2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 -name: project_phe +name: ipcl_internal on: # By default this will run when the activity type is "opened", "synchronize", # or "reopened". @@ -10,7 +11,6 @@ on: - development push: branches: - - main - development # Manually run this workflow on any specified branch. @@ -34,7 +34,7 @@ jobs: run: pre-commit run --all-files build-and-test: - name: Build, test and run kernels + name: Build, test and run kernels - shared needs: [format] runs-on: [self-hosted, linux, x64, icx] # Use environment protection (require review) @@ -62,7 +62,41 @@ jobs: # Unit tests and examples - name: Run the unit tests - run: ./build/test/unit-test + run: ./build/test/unittest_ipcl + + - name: Run the benchmarks + run: ./build/benchmark/bench_ipcl + + build-and-test-static: + name: Build, test and run kernels - static + needs: [format] + runs-on: [self-hosted, linux, x64, icx] + # Use environment protection (require review) + environment: intel_workflow + defaults: + run: + shell: bash + working-directory: . + steps: + - uses: actions/checkout@v2 + - name: Validate paths + run: | + whoami + echo $HOME + echo $GITHUB_WORKSPACE + echo "Testing from branch:" + echo $GITHUB_REF + pwd + + # Build library + - name: Build the repository + run: | + cmake -S . -B build -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=Release -DIPCL_SHARED=OFF + cmake --build build --target all -j + + # Unit tests and examples + - name: Run the unit tests + run: ./build/test/unittest_ipcl - - name: Run the unit tests - OpenMP - run: ./build/test/unit-test_omp + - name: Run the benchmarks + run: ./build/benchmark/bench_ipcl diff --git a/CMakeLists.txt b/CMakeLists.txt index 23577c4..f6e4891 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,7 +50,7 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) #--------------------------------------------------- option(IPCL_TEST "Enable testing" ON) option(IPCL_BENCHMARK "Enable benchmark" ON) -option(IPCL_TEST_OMP "Enable OpenMP testing" ON) +option(IPCL_ENABLE_OMP "Enable OpenMP testing/benchmarking" ON) option(IPCL_DOCS "Enable document building" OFF) option(IPCL_SHARED "Build shared library" ON) @@ -67,8 +67,8 @@ message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}") message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}") message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") message(STATUS "IPCL_TEST: ${IPCL_TEST}") -message(STATUS "IPCL_TEST_OMP: ${IPCL_TEST_OMP}") message(STATUS "IPCL_BENCHMARK: ${IPCL_BENCHMARK}") +message(STATUS "IPCL_ENABLE_OMP: ${IPCL_ENABLE_OMP}") message(STATUS "IPCL_DOCS: ${IPCL_DOCS}") message(STATUS "IPCL_SHARED: ${IPCL_SHARED}") @@ -114,10 +114,7 @@ add_subdirectory(ipcl) # unit-test and benchmarks if(IPCL_TEST) add_subdirectory(test) - add_custom_target(unittest COMMAND $ DEPENDS unit-test) - if(IPCL_TEST_OMP) - add_custom_target(unittest_omp COMMAND $ DEPENDS unit-test_omp) - endif() + add_custom_target(unittest COMMAND $ DEPENDS unittest_ipcl) endif() unset(IPCL_TEST CACHE) diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 083a974..e4f4a19 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -1,11 +1,11 @@ # Copyright (C) 2021-2022 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -set(SRC main.cpp +set(IPCL_BENCH_SRC main.cpp bench_cryptography.cpp bench_ops.cpp) -add_executable(bench_ipcl ${SRC}) +add_executable(bench_ipcl ${IPCL_BENCH_SRC}) target_include_directories(bench_ipcl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${IPCL_INC_DIR} @@ -15,8 +15,9 @@ target_link_libraries(bench_ipcl PRIVATE ipcl libgbenchmark Threads::Threads ) -if(IPCL_TEST_OMP) +# enable OpenMP benchmarks +if(IPCL_ENABLE_OMP) find_package(OpenMP REQUIRED) - add_compile_definitions(BENCHMARK_OMP) + add_compile_definitions(IPCL_BENCHMARK_OMP) target_link_libraries(bench_ipcl PRIVATE OpenMP::OpenMP_CXX) endif() diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index 1c7b8ea..ed17ec7 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -4,7 +4,7 @@ #include #include -#ifdef BENCHMARK_OMP +#ifdef IPCL_BENCHMARK_OMP #include #endif @@ -150,7 +150,7 @@ BENCHMARK(BM_Decrypt_buff8) ->Args({16}) ->Args({64}); -#ifdef BENCHMARK_OMP +#ifdef IPCL_BENCHMARK_OMP static void BM_Encrypt_OMP(benchmark::State& state) { size_t dsize = state.range(0); keyPair key = generateKeypair(2048, true); diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index 1dfe7ba..e705174 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -4,7 +4,7 @@ #include #include -#ifdef BENCHMARK_OMP +#ifdef IPCL_BENCHMARK_OMP #include #endif #include @@ -270,7 +270,7 @@ BENCHMARK(BM_Mul_CTPT_buff8) ->Args({16}) ->Args({64}); -#ifdef BENCHMARK_OMP +#ifdef IPCL_BENCHMARK_OMP static void BM_Add_CTCT_OMP(benchmark::State& state) { size_t dsize = state.range(0); keyPair key = generateKeypair(2048, true); diff --git a/ipcl/include/ipcl/pri_key.hpp b/ipcl/include/ipcl/pri_key.hpp index bddcbf3..27f0609 100644 --- a/ipcl/include/ipcl/pri_key.hpp +++ b/ipcl/include/ipcl/pri_key.hpp @@ -67,6 +67,13 @@ class PaillierPrivateKey { */ PaillierPublicKey* getPubKey() const { return m_pubkey; } + /** + * @brief Support function for ISO/IEC 18033-6 compliance check + * + * @return BigNumber + */ + BigNumber getLambda() { return m_lambda; } + private: PaillierPublicKey* m_pubkey; BigNumber m_n; diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp index b580a10..02919a0 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -103,6 +103,16 @@ class PaillierPublicKey { */ void apply_obfuscator(BigNumber obfuscator[8]); + /** + * @brief Set the Random object for ISO/IEC 18033-6 compliance check + * + * @param r + */ + void setRandom(BigNumber r[8]) { + for (int i = 0; i < 8; i++) m_r[i] = r[i]; + m_testv = true; + } + const void* addr = static_cast(this); private: @@ -115,6 +125,8 @@ class PaillierPublicKey { int m_dwords; unsigned int m_init_seed; bool m_enable_DJN; + BigNumber m_r[8]; + bool m_testv; /** * Get random value diff --git a/ipcl/paillier_pub.cpp b/ipcl/paillier_pub.cpp index 2b2fc75..ee2a9c8 100644 --- a/ipcl/paillier_pub.cpp +++ b/ipcl/paillier_pub.cpp @@ -26,6 +26,7 @@ PaillierPublicKey::PaillierPublicKey(const BigNumber& n, int bits, m_init_seed(randomUniformUnsignedInt()), m_enable_DJN(false) { if (enableDJN_) this->enableDJN(); // this sets m_enable_DJN + m_testv = false; } // array of 32-bit random, using rand() from stdlib @@ -100,8 +101,12 @@ void PaillierPublicKey::apply_obfuscator(BigNumber obfuscator[8]) { ippMultiBuffExp(obfuscator, base, r, sq); } else { for (int i = 0; i < 8; i++) { - r[i] = getRandom(m_bits); - r[i] = r[i] % (m_n - 1) + 1; + if (m_testv) { + r[i] = m_r[i]; + } else { + r[i] = getRandom(m_bits); + r[i] = r[i] % (m_n - 1) + 1; + } pown[i] = m_n; sq[i] = m_nsquare; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 298af61..e5808c3 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -2,15 +2,22 @@ # SPDX-License-Identifier: Apache-2.0 # Unit tests -add_executable(unit-test test.cpp) -target_link_libraries(unit-test PRIVATE ipcl libgtest Threads::Threads) -target_include_directories(unit-test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${IPCL_INC_DIR})# ${IPPCRYPTO_INC_DIR}) +set(IPCL_UNITTEST_SRC main.cpp +test_cryptography.cpp +test_ops.cpp) -# omp unittest -if(IPCL_TEST_OMP) - find_package(OpenMP REQUIRED) +add_executable(unittest_ipcl ${IPCL_UNITTEST_SRC}) +target_include_directories(unittest_ipcl PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${IPCL_INC_DIR} +) +target_link_libraries(unittest_ipcl PRIVATE + ipcl libgtest Threads::Threads +) - add_executable(unit-test_omp test_omp.cpp) - target_link_libraries(unit-test_omp PRIVATE ipcl OpenMP::OpenMP_CXX libgtest Threads::Threads) - target_include_directories(unit-test_omp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${IPCL_INC_DIR})# ${IPPCRYPTO_INC_DIR}) +# enable OpenMP unittests +if(IPCL_ENABLE_OMP) + find_package(OpenMP REQUIRED) + add_compile_definitions(IPCL_UNITTEST_OMP) + target_link_libraries(unittest_ipcl PRIVATE OpenMP::OpenMP_CXX) endif() diff --git a/test/main.cpp b/test/main.cpp new file mode 100644 index 0000000..bdb4542 --- /dev/null +++ b/test/main.cpp @@ -0,0 +1,13 @@ +// Copyright (C) 2021-2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include + +#include + +int main(int argc, char** argv) { + // Use system clock for seed + srand(time(nullptr)); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/test.cpp b/test/test.cpp deleted file mode 100644 index 72c066c..0000000 --- a/test/test.cpp +++ /dev/null @@ -1,405 +0,0 @@ -// Copyright (C) 2021-2022 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include - -#include "gtest/gtest.h" -#include "ipcl/key_pair.hpp" -#include "ipcl/paillier_ops.hpp" - -const int numRuns = 10; -clock_t t1, t2; -double time_ms; - -#define BENCHMARK(target, x) \ - for (int i = 0; i < 2; ++i) x t1 = clock(); \ - for (int i = 0; i < numRuns; ++i) x t2 = clock(); \ - \ - time_ms = static_cast(t2 - t1) / CLOCKS_PER_SEC; \ - std::cout << target << " " << time_ms * 1000 / numRuns << "ms" << std::endl; - -void CtPlusCt(BigNumber res[8], BigNumber ct1[8], BigNumber ct2[8], - keyPair key) { - for (int i = 0; i < 8; i++) { - PaillierEncryptedNumber a(key.pub_key, ct1[i]); - PaillierEncryptedNumber b(key.pub_key, ct2[i]); - PaillierEncryptedNumber sum = a + b; - res[i] = sum.getBN(); - } -} - -void CtPlusCtArray(BigNumber res[8], BigNumber ct1[8], BigNumber ct2[8], - keyPair key) { - PaillierEncryptedNumber a(key.pub_key, ct1); - PaillierEncryptedNumber b(key.pub_key, ct2); - PaillierEncryptedNumber sum = a + b; - sum.getArrayBN(res); -} - -void CtPlusPt(BigNumber res[8], BigNumber ct1[8], uint32_t pt2[8], - keyPair key) { - for (int i = 0; i < 8; i++) { - PaillierEncryptedNumber a(key.pub_key, ct1[i]); - BigNumber b = pt2[i]; - PaillierEncryptedNumber sum = a + b; - res[i] = sum.getBN(); - } -} - -void CtPlusPtArray(BigNumber res[8], BigNumber ct1[8], BigNumber ptbn2[8], - keyPair key) { - BigNumber stmp[8]; - PaillierEncryptedNumber a(key.pub_key, ct1); - PaillierEncryptedNumber sum = a + ptbn2; - sum.getArrayBN(res); -} - -void CtMultiplyPt(BigNumber res[8], BigNumber ct1[8], uint32_t pt2[8], - keyPair key) { - for (int i = 0; i < 8; i++) { - PaillierEncryptedNumber a(key.pub_key, ct1[i]); - PaillierEncryptedNumber b(key.pub_key, pt2[i]); - PaillierEncryptedNumber sum = a * b; - res[i] = sum.getBN(); - } -} - -void CtMultiplyPtArray(BigNumber res[8], BigNumber ct1[8], uint32_t pt2[8], - keyPair key) { - PaillierEncryptedNumber a(key.pub_key, ct1); - PaillierEncryptedNumber b(key.pub_key, pt2); - PaillierEncryptedNumber sum = a * b; - sum.getArrayBN(res); -} - -void AddSub(BigNumber res[8], BigNumber ct1[8], BigNumber ct2[8], keyPair key) { - for (int i = 0; i < 8; i++) { - PaillierEncryptedNumber a(key.pub_key, ct1[i]); - PaillierEncryptedNumber b(key.pub_key, ct2[i]); - BigNumber m1(2); - a = a + b * m1; - PaillierEncryptedNumber sum = a + b; - res[i] = sum.getBN(); - } -} - -TEST(OperationTest, CtPlusCtTest) { - keyPair key = generateKeypair(2048); - - BigNumber ct1[8], ct2[8]; - BigNumber dt[8], res[8]; - - uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8], ptbn2[8]; - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; - ptbn2[i] = pt2[i]; - } - - key.pub_key->encrypt(ct1, ptbn1); - key.pub_key->encrypt(ct2, ptbn2); - - BENCHMARK("Paillier CT + CT", CtPlusCt(res, ct1, ct2, key);); - - key.priv_key->decrypt(dt, res); - - for (int i = 0; i < 8; i++) { - vector v; - dt[i].num2vec(v); - - uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; - - EXPECT_EQ(v_dp, v_pp); - } - - delete key.pub_key; - delete key.priv_key; -} - -TEST(OperationTest, CtPlusCtArrayTest) { - keyPair key = generateKeypair(2048); - - BigNumber ct1[8], ct2[8]; - BigNumber dt[8], res[8]; - - uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8], ptbn2[8]; - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; - ptbn2[i] = pt2[i]; - } - - key.pub_key->encrypt(ct1, ptbn1); - key.pub_key->encrypt(ct2, ptbn2); - - BENCHMARK("Paillier array CT + CT", CtPlusCtArray(res, ct1, ct2, key);); - - key.priv_key->decrypt(dt, res); - - for (int i = 0; i < 8; i++) { - vector v; - dt[i].num2vec(v); - - uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; - - EXPECT_EQ(v_dp, v_pp); - } - - delete key.pub_key; - delete key.priv_key; -} - -TEST(OperationTest, CtPlusPtTest) { - keyPair key = generateKeypair(2048); - - BigNumber ct1[8], ct2[8]; - BigNumber dt[8], res[8]; - - uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8]; - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; - } - - key.pub_key->encrypt(ct1, ptbn1); - - BENCHMARK("Paillier CT + PT", CtPlusPt(res, ct1, pt2, key);); - - key.priv_key->decrypt(dt, res); - - for (int i = 0; i < 8; i++) { - vector v; - dt[i].num2vec(v); - - uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; - - EXPECT_EQ(v_dp, v_pp); - } - - delete key.pub_key; - delete key.priv_key; -} - -TEST(OperationTest, CtPlusPtArrayTest) { - keyPair key = generateKeypair(2048); - - BigNumber ct1[8], ct2[8]; - BigNumber dt[8], res[8]; - - uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8], ptbn2[8]; - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; - ptbn2[i] = pt2[i]; - } - - key.pub_key->encrypt(ct1, ptbn1); - - BENCHMARK("Paillier array CT + PT", CtPlusPtArray(res, ct1, ptbn2, key);); - - key.priv_key->decrypt(dt, res); - - for (int i = 0; i < 8; i++) { - vector v; - dt[i].num2vec(v); - - uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; - - EXPECT_EQ(v_dp, v_pp); - } - - delete key.pub_key; - delete key.priv_key; -} - -TEST(OperationTest, CtMultiplyPtTest) { - keyPair key = generateKeypair(2048); - - BigNumber ct1[8], ct2[8]; - BigNumber dt[8], res[8]; - - uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8]; - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; - } - - key.pub_key->encrypt(ct1, ptbn1); - - BENCHMARK("Paillier CT * PT", CtMultiplyPt(res, ct1, pt2, key);); - - key.priv_key->decrypt(dt, res); - - for (int i = 0; i < 8; i++) { - vector v; - dt[i].num2vec(v); - - uint64_t v_pp = (uint64_t)pt1[i] * (uint64_t)pt2[i]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; - - EXPECT_EQ(v_dp, v_pp); - } - - delete key.pub_key; - delete key.priv_key; -} - -TEST(OperationTest, CtMultiplyPtArrayTest) { - keyPair key = generateKeypair(2048); - - BigNumber ct1[8]; - BigNumber dt[8], res[8]; - - uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8], ptbn2[8]; - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; - ptbn2[i] = pt2[i]; - } - - key.pub_key->encrypt(ct1, ptbn1); - - BENCHMARK("Paillier multi-buffered CT * PT", - CtMultiplyPtArray(res, ct1, pt2, key);); - - key.priv_key->decrypt(dt, res); - - for (int i = 0; i < 8; i++) { - vector v; - dt[i].num2vec(v); - - uint64_t v_pp = (uint64_t)pt1[i] * (uint64_t)pt2[i]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; - - EXPECT_EQ(v_dp, v_pp); - } - - delete key.pub_key; - delete key.priv_key; -} - -TEST(OperationTest, AddSubTest) { - keyPair key = generateKeypair(2048); - - BigNumber ct1[8], ct2[8]; - BigNumber dt[8], res[8]; - - uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8], ptbn2[8]; - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; - ptbn2[i] = pt2[i]; - } - - key.pub_key->encrypt(ct1, ptbn1); - key.pub_key->encrypt(ct2, ptbn2); - - BENCHMARK("Paillier addsub", AddSub(res, ct1, ct2, key);); - key.priv_key->decrypt(dt, res); - - for (int i = 0; i < 8; i++) { - vector v; - dt[i].num2vec(v); - - uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i] * 3; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; - - EXPECT_EQ(v_dp, v_pp); - } - - delete key.pub_key; - delete key.priv_key; -} - -TEST(CryptoTest, CryptoTest) { - keyPair key = generateKeypair(2048); - - BigNumber ct[8]; - BigNumber dt[8]; - - uint32_t pt[8]; - BigNumber ptbn[8]; - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < 8; i++) { - pt[i] = dist(rng); - ptbn[i] = pt[i]; - } - - BENCHMARK("Paillier Encryption", key.pub_key->encrypt(ct, ptbn);); - BENCHMARK("Paillier Decryption", key.priv_key->decrypt(dt, ct);); - - for (int i = 0; i < 8; i++) { - vector v; - dt[i].num2vec(v); - EXPECT_EQ(v[0], pt[i]); - } - - delete key.pub_key; - delete key.priv_key; -} - -int main(int argc, char** argv) { - // Use system clock for seed - srand(time(nullptr)); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp new file mode 100644 index 0000000..cdc4709 --- /dev/null +++ b/test/test_cryptography.cpp @@ -0,0 +1,258 @@ +// Copyright (C) 2021-2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include + +#ifdef IPCL_UNITTEST_OMP +#include +#endif + +#include "gtest/gtest.h" +#include "ipcl/key_pair.hpp" +#include "ipcl/paillier_ops.hpp" + +TEST(CryptoTest, CryptoTest) { + keyPair key = generateKeypair(2048); + + BigNumber ct[8]; + BigNumber dt[8]; + + uint32_t pt[8]; + BigNumber ptbn[8]; + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < 8; i++) { + pt[i] = dist(rng); + ptbn[i] = pt[i]; + } + + key.pub_key->encrypt(ct, ptbn); + key.priv_key->decrypt(dt, ct); + + for (int i = 0; i < 8; i++) { + vector v; + dt[i].num2vec(v); + EXPECT_EQ(v[0], pt[i]); + } + + delete key.pub_key; + delete key.priv_key; +} + +#ifdef IPCL_UNITTEST_OMP +void Encryption(int num_threads, vector v_ct, + vector v_ptbn, keyPair key) { +#pragma omp parallel for + for (int i = 0; i < num_threads; i++) { + key.pub_key->encrypt(v_ct[i], v_ptbn[i]); + } +} + +void Decryption(int num_threads, vector v_dt, + vector v_ct, keyPair key) { +#pragma omp parallel for + for (int i = 0; i < num_threads; i++) { + key.priv_key->decrypt(v_dt[i], v_ct[i]); + } +} + +TEST(CryptoTest, CryptoTest_OMP) { + // use one keypair to do several encryption/decryption + keyPair key = generateKeypair(2048); + + size_t num_threads = omp_get_max_threads(); + // std::cout << "available threads: " << num_threads << std::endl; + + std::vector v_ct(num_threads); + std::vector v_dt(num_threads); + std::vector v_pt(num_threads); + std::vector v_ptbn(num_threads); + + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < num_threads; i++) { + v_ct[i] = new BigNumber[8]; + v_dt[i] = new BigNumber[8]; + v_pt[i] = new uint32_t[8]; + v_ptbn[i] = new BigNumber[8]; + + // for each threads, generated different rand testing value + for (int j = 0; j < 8; j++) { + v_pt[i][j] = dist(rng); + v_ptbn[i][j] = v_pt[i][j]; + } + } + + Encryption(num_threads, v_ct, v_ptbn, key); + Decryption(num_threads, v_dt, v_ct, key); + + // check output for all threads + for (int i = 0; i < num_threads; i++) { + for (int j = 0; j < 8; j++) { + std::vector v; + v_dt[i][j].num2vec(v); + EXPECT_EQ(v[0], v_pt[i][j]); + } + } + + for (int i = 0; i < num_threads; i++) { + delete[] v_ct[i]; + delete[] v_dt[i]; + delete[] v_pt[i]; + delete[] v_ptbn[i]; + } + + delete key.pub_key; + delete key.priv_key; +} +#endif + +TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { + BigNumber p = + "0xff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c" + "8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b4" + "0a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff76" + "4dd8b091f11a0943a2dd2b983b0df02f4c4d00b413"; + BigNumber q = + "0xdacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d" + "9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de70" + "72a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49b" + "aa0f610bad100cdf47cc86e5034e2a0b2179e04ec7"; + + BigNumber n = p * q; + int n_length = n.BitSize(); + + PaillierPublicKey* public_key = new PaillierPublicKey(n, n_length); + PaillierPrivateKey* private_key = new PaillierPrivateKey(public_key, p, q); + + keyPair key = {public_key, private_key}; + + BigNumber ptbn[8]; + BigNumber ct[8]; + BigNumber dt[8]; + BigNumber ir[8]; + + BigNumber c1 = + "0x1fb7f08a42deb47876e4cbdc3f0b172c033563a696ad7a7c76fa5971b793fa488dcdd6" + "bd65c7c5440d67d847cb89ccca468b2c96763fff5a5ece8330251112d65e59b7da94cfe9" + "309f441ccc8f59c67dec75113d37b1ee929c8d4ce6b5e561a30a91104b0526de892e4eff" + "9f4fbecba3db8ed94267be31df360feaffb1151ef5b5a8e51777f09d38072bcb1b1ad15d" + "80d5448fd0edb41cc499f8eebae2af26569427a26d0afeaa833173d6ae4e5f84eb88c0c6" + "8c29baecf7ec5af2c1c5577336ca9482690f1c94597654afda84c6fb74df95cdd08fa9a6" + "6296126b4061b0530d124f3797426a08f72e90ef4994eeb348f5e92bd12d41cd3343a9e2" + "71a2f73d2cc7ffbd65bf64fb63e759f312e615aae01ae9f4573a21f1a70f56a61cfbb94d" + "8f96fcf06c2b3216ed9574f6888df86cd5e471b641507ac6815ca781f6d31e69d6848e54" + "2a7c57dc21109b5574b63365a19273783fafc93639c414b9475ea5ea82e73958ff5fdba9" + "67d52721ff71209e5a3db3c580e1bfd142ba4b8ab77eb16cb488d46a04a672662cd108b7" + "e9c58ba13dfb850653208f81956539475ffce85e0b0da59e5bd8d90051be9b2cc99e37c0" + "60ce09814e1524458bfb5427d7a16b672682be448fa16464fcb3e7f1dca6812a2c5a9814" + "b98ccb676367b7b3b269c670cd0210edf70ad9cb337f766af75fe06d18b3f7f7c2eae656" + "5ff2815c2c09b1a1f5"; + + BigNumber c2 = + "0x61803645f2798c06f2c08fc254eee612c55542051c8777d6ce69ede9c84a179afb2081" + "167494dee727488ae5e9b56d98f4fcf132514616859fc854fbd3acf6aecd97324ac3f2af" + "fa9f44864a9afc505754aa3b564b4617e887d6aa1f88095bccf6b47f458566f9d85e80fc" + "d478a58d4c2e895d0ed428aa8919d8ce752472bdc704fe9f01b1f663e3a9defca4b38471" + "34883d5433b6bebb7d5a0358bcc8e3385cdf8787a1c78165eb03fc295c2ee93809d7a7a4" + "689e79faf173e4ca3d0a6a9175887d0c70b35c529aa02699c4d4e8c98a9f3b8f2be41f35" + "905adebf8a6940a93875d1e24e578a93bdb7cbf66cd3cdb736466588649ac237d55121ce" + "0c0d18bc5da660d8faf9f0849ed1775ffcc5edb6900ebfb6c1e33459d29655edf706324c" + "f642c8f36433d6b850a43ee0e788e120737b8a2858d1b5302bad3413102fd7dccfe458b2" + "57fdbf920fe942e23ec446b1b302d41710fe56b26e11987ac06cfa635664c7a0ec18f8c8" + "c871919fc893a3117ff5e73d4c115e66e3bc5bd2b9127b2bb816c549245c65cf22a533a3" + "d2b6cb7c46757d3a87173f93e8b431891697f8d60c59631734f46cf3d70d9065f0167d5a" + "d7353c0812af024ced593273551d29c89232f2f3d548b9248291c1b8e833ed178eb2cf1a" + "d6f1d6864f1fd3e2e3937e00d391ad330b443aec85528571740ed5538188c32caab27c7b" + "f437df2bb97cb90e02"; + + BigNumber c1c2 = + "0x309f6e614d875e3bb0a77eedeb8895e7c6f297f161f576aef4f8b72bb5b81ef78b831a" + "af134b09fe8697159cfd678c49920cb790e36580c5201a96848d7242fceb025808dd26b5" + "0ff573ffca3f65e51b3b9fe85c7e44f5c8df0a9e524f64a5acc5c62cba7475978eb55e08" + "93eff1c40547ef9db087f8a54a13bf33a4648c4719233cfb107ba469c61f1c07578d9c19" + "fa8012b743d31fbca8eb4250ad902cf0c3d24c619fcd0874ad6a12ab8eafffabca6ed1aa" + "a4ba0df1544c3826364ac955c5853dc0490b9992e867e2dc95ec4b8742f177b7b24f29f6" + "8de4d552f32ca0da7d5cb2d85f020eefb8b58261c93643a4b63a9223efea803367b932b4" + "30ae47730d9b493e4194cbc7e8aa6d8aae45aa016d7f197dab5bb9508d5af6c3f47c0ec4" + "8ff604e53edbafa9a1bdae6add7169b83278a025f0be7980688806deaa9afaf80ca4212d" + "53079c4841546bc1622c5bf211a9db1f8933211b6a5b5f312d6919181bf7797188645052" + "a9fff167c7acbc43454cd3caab36a501feba27f28720f2ab23d5dea3c73d4421b059eef9" + "f1c227a3ed59c487c9483a08e98bfd34920349fa861b41ce61a4caa8b7f0fc1fcba7dedb" + "8f9c64ab3a42968f6c88f45541c734d7c0206968a103d02985854a5156d9edb99a332de9" + "a6d47f9af6e68e18960fa5916cc48994334354d6303312b8e96602766bec337a8a92c596" + "b21b6038828a6c9744"; + + BigNumber m1m2 = "0x616263646566676869606a6b6c6d6e6f"; + + BigNumber r0 = + "0x57fb19590c31dc7c034b2a889cf4037ce3db799909c1eb0adb6199d8e96791daca9018" + "891f34309daff32dced4af7d793d16734d055e28023acab7295956bfbfdf62bf0ccb2ed3" + "1d5d176ca8b404e93007565fb6b72c33a512b4dc4f719231d62e27e34c3733929af32247" + "f88c20d1ee77096cc80d3d642464054c815b35878ba812349c8bdc3c6b645daf1a0de609" + "65f44dcf705681032480f1eeba82243196b96903becdc0df0801d4120cbd6db1c4b2841a" + "27991c44a43750c24ed0825718ad14cfb9c6b40b78ff3d25f71741f2def1c9d420d4b0fa" + "1e0a02e7851b5ec6a81133a368b80d1500b0f28fc653d2e6ff4366236dbf80ae3b4beae3" + "5e04579f2c"; + BigNumber r1 = + "0x6ee8ed76227672a7bcaa1e7f152c2ea39f2fa225f0713f58210c59b2270b110e38b650" + "69aaedbeffc713c021336cc12f65227cc0357ca531c07c706e7224c2c11c3145bc0a05b1" + "64f426ec03350820f9f416377e8720ddb577843cae929178bfe5772e2cc1e9b94e8fce81" + "4eaf136c6ed218ca7b10ea4d5218e7ba82bd74bb9f19d3ccc7d2e140e91cfb25f76f54aa" + "70f2ed88ef343dd5fb98617c0036b7717f7458ec847d7b52e8764a4e92c397133a95e35e" + "9a82d5dc264ff423398cfadfbaec4727854e68f2e9e210d6a65c39b5a9b2a0ebdc538983" + "4883680e42b5d8582344e3e07a01fbd6c46328dcfa03074d0bc02927f58466c2fa74ab60" + "8177e3ec1b"; + + for (int i = 0; i < 8; i++) { + ir[i] = r0; + ptbn[i] = "0x414243444546474849404a4b4c4d4e4f"; + } + ir[1] = r1; + ptbn[1] = "0x20202020202020202020202020202020"; + + key.pub_key->setRandom(ir); + + key.pub_key->encrypt(ct, ptbn); + + PaillierEncryptedNumber a(key.pub_key, ct[0]); + PaillierEncryptedNumber b(key.pub_key, ct[1]); + PaillierEncryptedNumber sum = a + b; + BigNumber res = sum.getBN(); + + BigNumber ct12[8], dt12[8]; + for (int i = 0; i < 8; i++) { + ct12[i] = res; + } + + key.priv_key->decrypt(dt, ct); + key.priv_key->decrypt(dt12, ct12); + + string str1, str2; + + c1.num2hex(str1); + ct[0].num2hex(str2); + EXPECT_EQ(str1, str2); + + c2.num2hex(str1); + ct[1].num2hex(str2); + EXPECT_EQ(str1, str2); + + c1c2.num2hex(str1); + res.num2hex(str2); + EXPECT_EQ(str1, str2); + + m1m2.num2hex(str1); + dt12[0].num2hex(str2); + EXPECT_EQ(str1, str2); + + delete key.pub_key; + delete key.priv_key; +} diff --git a/test/test_omp.cpp b/test/test_ops.cpp similarity index 57% rename from test/test_omp.cpp rename to test/test_ops.cpp index 3f8a0e8..4d7dbb5 100644 --- a/test/test_omp.cpp +++ b/test/test_ops.cpp @@ -1,45 +1,368 @@ // Copyright (C) 2021-2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include -#include - #include +#include #include #include +#ifdef IPCL_UNITTEST_OMP +#include +#endif + +#include "gtest/gtest.h" #include "ipcl/key_pair.hpp" #include "ipcl/paillier_ops.hpp" -const int numRuns = 10; -double t1, t2; -double time_ms; +void CtPlusCt(BigNumber res[8], BigNumber ct1[8], BigNumber ct2[8], + keyPair key) { + for (int i = 0; i < 8; i++) { + PaillierEncryptedNumber a(key.pub_key, ct1[i]); + PaillierEncryptedNumber b(key.pub_key, ct2[i]); + PaillierEncryptedNumber sum = a + b; + res[i] = sum.getBN(); + } +} -#define BENCHMARK(target, x) \ - for (int i = 0; i < 2; ++i) x t1 = omp_get_wtime(); \ - for (int i = 0; i < numRuns; ++i) x t2 = omp_get_wtime(); \ - \ - time_ms = static_cast(t2 - t1); \ - std::cout << target << " " << time_ms * 1000.f / numRuns << "ms" << std::endl; +void CtPlusCtArray(BigNumber res[8], BigNumber ct1[8], BigNumber ct2[8], + keyPair key) { + PaillierEncryptedNumber a(key.pub_key, ct1); + PaillierEncryptedNumber b(key.pub_key, ct2); + PaillierEncryptedNumber sum = a + b; + sum.getArrayBN(res); +} -void Encryption(int num_threads, vector v_ct, - vector v_ptbn, keyPair key) { -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - key.pub_key->encrypt(v_ct[i], v_ptbn[i]); +void CtPlusPt(BigNumber res[8], BigNumber ct1[8], uint32_t pt2[8], + keyPair key) { + for (int i = 0; i < 8; i++) { + PaillierEncryptedNumber a(key.pub_key, ct1[i]); + BigNumber b = pt2[i]; + PaillierEncryptedNumber sum = a + b; + res[i] = sum.getBN(); } } -void Decryption(int num_threads, vector v_dt, - vector v_ct, keyPair key) { -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - key.priv_key->decrypt(v_dt[i], v_ct[i]); +void CtPlusPtArray(BigNumber res[8], BigNumber ct1[8], BigNumber ptbn2[8], + keyPair key) { + BigNumber stmp[8]; + PaillierEncryptedNumber a(key.pub_key, ct1); + PaillierEncryptedNumber sum = a + ptbn2; + sum.getArrayBN(res); +} + +void CtMultiplyPt(BigNumber res[8], BigNumber ct1[8], uint32_t pt2[8], + keyPair key) { + for (int i = 0; i < 8; i++) { + PaillierEncryptedNumber a(key.pub_key, ct1[i]); + PaillierEncryptedNumber b(key.pub_key, pt2[i]); + PaillierEncryptedNumber sum = a * b; + res[i] = sum.getBN(); + } +} + +void CtMultiplyPtArray(BigNumber res[8], BigNumber ct1[8], uint32_t pt2[8], + keyPair key) { + PaillierEncryptedNumber a(key.pub_key, ct1); + PaillierEncryptedNumber b(key.pub_key, pt2); + PaillierEncryptedNumber sum = a * b; + sum.getArrayBN(res); +} + +void AddSub(BigNumber res[8], BigNumber ct1[8], BigNumber ct2[8], keyPair key) { + for (int i = 0; i < 8; i++) { + PaillierEncryptedNumber a(key.pub_key, ct1[i]); + PaillierEncryptedNumber b(key.pub_key, ct2[i]); + BigNumber m1(2); + a = a + b * m1; + PaillierEncryptedNumber sum = a + b; + res[i] = sum.getBN(); } } -void CtPlusCt(int num_threads, vector v_sum, - vector v_ct1, vector v_ct2, keyPair key) { +TEST(OperationTest, CtPlusCtTest) { + keyPair key = generateKeypair(2048); + + BigNumber ct1[8], ct2[8]; + BigNumber dt[8], res[8]; + + uint32_t pt1[8], pt2[8]; + BigNumber ptbn1[8], ptbn2[8]; + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < 8; i++) { + pt1[i] = dist(rng); + pt2[i] = dist(rng); + ptbn1[i] = pt1[i]; + ptbn2[i] = pt2[i]; + } + + key.pub_key->encrypt(ct1, ptbn1); + key.pub_key->encrypt(ct2, ptbn2); + + CtPlusCt(res, ct1, ct2, key); + + key.priv_key->decrypt(dt, res); + + for (int i = 0; i < 8; i++) { + vector v; + dt[i].num2vec(v); + + uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; + uint64_t v_dp = v[0]; + if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + + EXPECT_EQ(v_dp, v_pp); + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, CtPlusCtArrayTest) { + keyPair key = generateKeypair(2048); + + BigNumber ct1[8], ct2[8]; + BigNumber dt[8], res[8]; + + uint32_t pt1[8], pt2[8]; + BigNumber ptbn1[8], ptbn2[8]; + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < 8; i++) { + pt1[i] = dist(rng); + pt2[i] = dist(rng); + ptbn1[i] = pt1[i]; + ptbn2[i] = pt2[i]; + } + + key.pub_key->encrypt(ct1, ptbn1); + key.pub_key->encrypt(ct2, ptbn2); + + CtPlusCtArray(res, ct1, ct2, key); + + key.priv_key->decrypt(dt, res); + + for (int i = 0; i < 8; i++) { + vector v; + dt[i].num2vec(v); + + uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; + uint64_t v_dp = v[0]; + if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + + EXPECT_EQ(v_dp, v_pp); + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, CtPlusPtTest) { + keyPair key = generateKeypair(2048); + + BigNumber ct1[8], ct2[8]; + BigNumber dt[8], res[8]; + + uint32_t pt1[8], pt2[8]; + BigNumber ptbn1[8]; + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < 8; i++) { + pt1[i] = dist(rng); + pt2[i] = dist(rng); + ptbn1[i] = pt1[i]; + } + + key.pub_key->encrypt(ct1, ptbn1); + + CtPlusPt(res, ct1, pt2, key); + + key.priv_key->decrypt(dt, res); + + for (int i = 0; i < 8; i++) { + vector v; + dt[i].num2vec(v); + + uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; + uint64_t v_dp = v[0]; + if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + + EXPECT_EQ(v_dp, v_pp); + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, CtPlusPtArrayTest) { + keyPair key = generateKeypair(2048); + + BigNumber ct1[8], ct2[8]; + BigNumber dt[8], res[8]; + + uint32_t pt1[8], pt2[8]; + BigNumber ptbn1[8], ptbn2[8]; + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < 8; i++) { + pt1[i] = dist(rng); + pt2[i] = dist(rng); + ptbn1[i] = pt1[i]; + ptbn2[i] = pt2[i]; + } + + key.pub_key->encrypt(ct1, ptbn1); + + CtPlusPtArray(res, ct1, ptbn2, key); + + key.priv_key->decrypt(dt, res); + + for (int i = 0; i < 8; i++) { + vector v; + dt[i].num2vec(v); + + uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; + uint64_t v_dp = v[0]; + if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + + EXPECT_EQ(v_dp, v_pp); + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, CtMultiplyPtTest) { + keyPair key = generateKeypair(2048); + + BigNumber ct1[8], ct2[8]; + BigNumber dt[8], res[8]; + + uint32_t pt1[8], pt2[8]; + BigNumber ptbn1[8]; + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < 8; i++) { + pt1[i] = dist(rng); + pt2[i] = dist(rng); + ptbn1[i] = pt1[i]; + } + + key.pub_key->encrypt(ct1, ptbn1); + + CtMultiplyPt(res, ct1, pt2, key); + + key.priv_key->decrypt(dt, res); + + for (int i = 0; i < 8; i++) { + vector v; + dt[i].num2vec(v); + + uint64_t v_pp = (uint64_t)pt1[i] * (uint64_t)pt2[i]; + uint64_t v_dp = v[0]; + if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + + EXPECT_EQ(v_dp, v_pp); + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, CtMultiplyPtArrayTest) { + keyPair key = generateKeypair(2048); + + BigNumber ct1[8]; + BigNumber dt[8], res[8]; + + uint32_t pt1[8], pt2[8]; + BigNumber ptbn1[8], ptbn2[8]; + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < 8; i++) { + pt1[i] = dist(rng); + pt2[i] = dist(rng); + ptbn1[i] = pt1[i]; + ptbn2[i] = pt2[i]; + } + + key.pub_key->encrypt(ct1, ptbn1); + + CtMultiplyPtArray(res, ct1, pt2, key); + + key.priv_key->decrypt(dt, res); + + for (int i = 0; i < 8; i++) { + vector v; + dt[i].num2vec(v); + + uint64_t v_pp = (uint64_t)pt1[i] * (uint64_t)pt2[i]; + uint64_t v_dp = v[0]; + if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + + EXPECT_EQ(v_dp, v_pp); + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, AddSubTest) { + keyPair key = generateKeypair(2048); + + BigNumber ct1[8], ct2[8]; + BigNumber dt[8], res[8]; + + uint32_t pt1[8], pt2[8]; + BigNumber ptbn1[8], ptbn2[8]; + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < 8; i++) { + pt1[i] = dist(rng); + pt2[i] = dist(rng); + ptbn1[i] = pt1[i]; + ptbn2[i] = pt2[i]; + } + + key.pub_key->encrypt(ct1, ptbn1); + key.pub_key->encrypt(ct2, ptbn2); + + AddSub(res, ct1, ct2, key); + key.priv_key->decrypt(dt, res); + + for (int i = 0; i < 8; i++) { + vector v; + dt[i].num2vec(v); + + uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i] * 3; + uint64_t v_dp = v[0]; + if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + + EXPECT_EQ(v_dp, v_pp); + } + + delete key.pub_key; + delete key.priv_key; +} + +#ifdef IPCL_UNITTEST_OMP +void CtPlusCt_OMP(int num_threads, vector v_sum, + vector v_ct1, vector v_ct2, + keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { @@ -51,8 +374,9 @@ void CtPlusCt(int num_threads, vector v_sum, } } -void CtPlusPt(int num_threads, vector v_sum, - vector v_ct1, vector v_pt2, keyPair key) { +void CtPlusPt_OMP(int num_threads, vector v_sum, + vector v_ct1, vector v_pt2, + keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { @@ -64,9 +388,9 @@ void CtPlusPt(int num_threads, vector v_sum, } } -void CtPlusPtArray(int num_threads, vector v_sum, - vector v_ct1, vector v_pt2, - keyPair key) { +void CtPlusPtArray_OMP(int num_threads, vector v_sum, + vector v_ct1, vector v_pt2, + keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); @@ -79,9 +403,9 @@ void CtPlusPtArray(int num_threads, vector v_sum, } } -void CtMultiplyPt(int num_threads, vector v_product, - vector v_ct1, vector v_pt2, - keyPair key) { +void CtMultiplyPt_OMP(int num_threads, vector v_product, + vector v_ct1, vector v_pt2, + keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { @@ -93,9 +417,9 @@ void CtMultiplyPt(int num_threads, vector v_product, } } -void CtMultiplyPtArray(int num_threads, vector v_product, - vector v_ct1, vector v_pt2, - keyPair key) { +void CtMultiplyPtArray_OMP(int num_threads, vector v_product, + vector v_ct1, vector v_pt2, + keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); @@ -105,11 +429,10 @@ void CtMultiplyPtArray(int num_threads, vector v_product, } } -TEST(OperationTest, CtPlusCtTest) { +TEST(OperationTest, CtPlusCtTest_OMP) { keyPair key = generateKeypair(2048); size_t num_threads = omp_get_max_threads(); - // std::cout << "available threads: " << num_threads << std::endl; std::vector v_ct1(num_threads); std::vector v_ct2(num_threads); @@ -148,8 +471,7 @@ TEST(OperationTest, CtPlusCtTest) { key.pub_key->encrypt(v_ct2[i], v_ptbn2[i]); } - BENCHMARK("OMP Paillier CT + CT", - CtPlusCt(num_threads, v_sum, v_ct1, v_ct2, key);); + CtPlusCt_OMP(num_threads, v_sum, v_ct1, v_ct2, key); #pragma omp parallel for for (int i = 0; i < num_threads; i++) { @@ -185,7 +507,7 @@ TEST(OperationTest, CtPlusCtTest) { delete key.priv_key; } -TEST(OperationTest, CtPlusPtTest) { +TEST(OperationTest, CtPlusPtTest_OMP) { keyPair key = generateKeypair(2048); size_t num_threads = omp_get_max_threads(); @@ -224,8 +546,7 @@ TEST(OperationTest, CtPlusPtTest) { key.pub_key->encrypt(v_ct1[i], v_ptbn1[i]); } - BENCHMARK("OMP Paillier CT + PT", - CtPlusPt(num_threads, v_sum, v_ct1, v_pt2, key);); + CtPlusPt_OMP(num_threads, v_sum, v_ct1, v_pt2, key); #pragma omp parallel for for (int i = 0; i < num_threads; i++) { @@ -260,11 +581,10 @@ TEST(OperationTest, CtPlusPtTest) { delete key.priv_key; } -TEST(OperationTest, CtPlusPtArrayTest) { +TEST(OperationTest, CtPlusPtArrayTest_OMP) { keyPair key = generateKeypair(2048); size_t num_threads = omp_get_max_threads(); - std::cout << "available threads: " << num_threads << std::endl; std::vector v_ct1(num_threads); std::vector v_dt(num_threads); @@ -300,8 +620,7 @@ TEST(OperationTest, CtPlusPtArrayTest) { key.pub_key->encrypt(v_ct1[i], v_ptbn1[i]); } - BENCHMARK("OMP array Paillier CT + PT", - CtPlusPtArray(num_threads, v_sum, v_ct1, v_pt2, key);); + CtPlusPtArray_OMP(num_threads, v_sum, v_ct1, v_pt2, key); #pragma omp parallel for for (int i = 0; i < num_threads; i++) { @@ -336,11 +655,10 @@ TEST(OperationTest, CtPlusPtArrayTest) { delete key.priv_key; } -TEST(OperationTest, test_CtMultiplyPt) { +TEST(OperationTest, CtMultiplyPtTest_OMP) { keyPair key = generateKeypair(2048); size_t num_threads = omp_get_max_threads(); - // std::cout << "available threads: " << num_threads << std::endl; std::vector v_ct1(num_threads); std::vector v_dt(num_threads); @@ -377,8 +695,7 @@ TEST(OperationTest, test_CtMultiplyPt) { key.pub_key->encrypt(v_ct1[i], v_ptbn1[i]); } - BENCHMARK("OMP Paillier CT * PT", - CtMultiplyPt(num_threads, v_product, v_ct1, v_pt2, key);); + CtMultiplyPt_OMP(num_threads, v_product, v_ct1, v_pt2, key); #pragma omp parallel for for (int i = 0; i < num_threads; i++) { @@ -412,11 +729,10 @@ TEST(OperationTest, test_CtMultiplyPt) { delete key.priv_key; } -TEST(OperationTest, test_CtMultiplyPtArray) { +TEST(OperationTest, CtMultiplyPtArrayTest_OMP) { keyPair key = generateKeypair(2048); size_t num_threads = omp_get_max_threads(); - // std::cout << "available threads: " << num_threads << std::endl; std::vector v_ct1(num_threads); std::vector v_dt(num_threads); @@ -453,8 +769,7 @@ TEST(OperationTest, test_CtMultiplyPtArray) { key.pub_key->encrypt(v_ct1[i], v_ptbn1[i]); } - BENCHMARK("OMP Paillier multi-buffered CT * PT", - CtMultiplyPtArray(num_threads, v_product, v_ct1, v_pt2, key);); + CtMultiplyPtArray_OMP(num_threads, v_product, v_ct1, v_pt2, key); #pragma omp parallel for for (int i = 0; i < num_threads; i++) { @@ -487,64 +802,4 @@ TEST(OperationTest, test_CtMultiplyPtArray) { delete key.pub_key; delete key.priv_key; } - -TEST(CryptoTest, CryptoTest) { - // use one keypair to do several encryption/decryption - keyPair key = generateKeypair(2048); - - size_t num_threads = omp_get_max_threads(); - // std::cout << "available threads: " << num_threads << std::endl; - - std::vector v_ct(num_threads); - std::vector v_dt(num_threads); - std::vector v_pt(num_threads); - std::vector v_ptbn(num_threads); - - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < num_threads; i++) { - v_ct[i] = new BigNumber[8]; - v_dt[i] = new BigNumber[8]; - v_pt[i] = new uint32_t[8]; - v_ptbn[i] = new BigNumber[8]; - - // for each threads, generated different rand testing value - for (int j = 0; j < 8; j++) { - v_pt[i][j] = dist(rng); - v_ptbn[i][j] = v_pt[i][j]; - } - } - - BENCHMARK("OMP Paillier Encryption", - Encryption(num_threads, v_ct, v_ptbn, key);); - BENCHMARK("OMP Paillier Decryption", - Decryption(num_threads, v_dt, v_ct, key);); - - // check output for all threads - for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < 8; j++) { - std::vector v; - v_dt[i][j].num2vec(v); - EXPECT_EQ(v[0], v_pt[i][j]); - } - } - - for (int i = 0; i < num_threads; i++) { - delete[] v_ct[i]; - delete[] v_dt[i]; - delete[] v_pt[i]; - delete[] v_ptbn[i]; - } - - delete key.pub_key; - delete key.priv_key; -} - -int main(int argc, char** argv) { - // Use system clock for seed - srand(time(nullptr)); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} +#endif From d378bd8acf68a8bb440a9e6f44a021d145e10f5c Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Wed, 23 Feb 2022 22:36:01 -0800 Subject: [PATCH 018/364] Update readme (#7) --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 21f6901..5c61789 100644 --- a/README.md +++ b/README.md @@ -100,10 +100,13 @@ The unit-test executable itself is located at `${IPCL_DIR}/build/test/unit-test` # Standardization This library is in compliance with the homomorphic encryption standards [ISO/IEC 18033-6](https://www.iso.org/standard/67740.html). +The compliance test is included in the [unit-test](test/test_cryptography.cpp#L117-L258). # Contributors Main contributors to this project, sorted by alphabetical order of last name are: - [Xiaoran Fang](https://github.com/fangxiaoran) + - [Hengrui Hu](https://github.com/hhr293) + - [Xiaojun Huang](https://github.com/xhuan28) - [Hamish Hunt](https://github.com/hamishun) - [Sejun Kim](https://github.com/skmono) (lead) - [Bin Wang](https://github.com/bwang30) From fbd43262592d482671360299de13b5c438dd492a Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 23 Feb 2022 23:45:44 -0800 Subject: [PATCH 019/364] Update initial source code design of Milestone 1. --- he_qat_bn_ops.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++ he_qat_bn_ops.h | 32 +++++++++++ he_qat_context.c | 113 ++++++++++++++++++++++++-------------- he_qat_context.h | 17 +++++- he_qat_types.h | 38 +++++++++++-- 5 files changed, 291 insertions(+), 47 deletions(-) create mode 100644 he_qat_bn_ops.c create mode 100644 he_qat_bn_ops.h diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c new file mode 100644 index 0000000..0eecc8a --- /dev/null +++ b/he_qat_bn_ops.c @@ -0,0 +1,138 @@ + +#include "cpa.h" +#include "cpa_cy_ln.h" + +#include "cpa_sample_utils.h" + +#include "he_qat_types.h" +#include "he_qat_bn_ops.h" + +/// @brief +/// @function +/// Callback function for lnModExpPerformOp. It performs any data processing +/// required after the modular exponentiation. +static void lnModExpCallback(void *pCallbackTag, + CpaStatus status, + void *pOpData, + CpaFlatBuffer *pOut) +{ + if (CPA_STATUS_SUCCESS != status) { + // Update request status as an error (in pOpData) + return ; + } + + // Check if input data for the op is available and do something + if (NULL != pOpData) { + // Collect the device output in pOut + // Mark request as complete or ready to be used + } + + // Asynchronous call needs to send wake-up signal to semaphore + if (NULL != pCallbackTag) { + COMPLETE((struct COMPLETION_STRUCT *)pCallbackTag); + } + + return ; +} + + +/// @brief +/// @function +/// Thread-safe producer implementation for the shared request buffer. +/// Stores requests in a buffer that will be offload to QAT devices. +void submit_next_request(HE_QAT_RequestBuffer *_buffer, void *args) +{ + pthread_mutex_lock(&_buffer->mutex); + + while (_bufffer->count >= BSIZE) + pthread_cond_wait(&_buffer->any_free_slot, &b->mutex); + + assert(_buffer->count < BSIZE); + + _buffer->data[b->next_free_slot++] = args; + + _buffer->next_free_slot %= HE_QAT_BUFFER_SIZE; + _buffer->count++; + + /* now: either b->occupied < BSIZE and b->nextin is the index + of the next empty slot in the buffer, or + b->occupied == BSIZE and b->nextin is the index of the + next (occupied) slot that will be emptied by a consumer + (such as b->nextin == b->nextout) */ + + pthread_cond_signal(&_buffer->any_more_data); + pthread_mutex_unlock(&_buffer->mutex); +} + +/// @brief +/// @function +/// Thread-safe consumer implementation for the shared request buffer. +/// Read requests from a buffer to finally offload the work to QAT devices. +HE_QAT_TaskRequest *get_next_request(HE_QAT_RequestBuffer *_buffer) +{ + void *item = NULL; + pthread_mutex_lock(&_buffer->mutex); + while(_buffer->count <= 0) + pthread_cond_wait(&_buffer->any_more_data, &_buffer->mutex); + + assert(_buffer->count > 0); + + printf("[%02d]:",_buffer->next_data_slot); + item = _buffer->data[b->next_data_slot++]; + _buffer->next_data_slot %= HE_QAT_BUFFER_SIZE; + _buffer->count--; + + /* now: either b->occupied > 0 and b->nextout is the index + of the next occupied slot in the buffer, or + b->occupied == 0 and b->nextout is the index of the next + (empty) slot that will be filled by a producer (such as + b->nextout == b->nextin) */ + + pthread_cond_signal(&_buffer->any_free_slot); + pthread_mutex_unlock(&_buffer->mutex); + + return (HE_QAT_TaskRequest *) (item); +} + +/// @brief +/// @function +/// Perform large number modular exponentiation. +/// @param[in] cyInstHandle QAT instance handle. +//static CpaStatus lnModExpPerformOp(CpaInstanceHandle cyInstHandle) +//static CpaStatus lnModExpPerformOp(QATaskRequest *request) +void *run_qat_op_engine(void *_inst_config) +{ + CpaStatus status = CPA_STATUS_FAIL; + QATInstConfig *config = (QATInstConfig *) _inst_config; + config->running = 1; + while (config->running) { + // Try consume data from butter to perform requested operation + void *task_request = get_next_request(&config->he_qat_buffer); + + unsigned retries = 0; + do { + retries++; + + // Realize the type of operation from data + // Select the appropriate action + status = cpaCyLnModExp(config->inst_handle, + lnModExpCallback, + (void *) task_request->callback, + &task_request->op_data, + &task_request->op_output); + + + } while (CPA_STATUS_RETRY == status && retries < HE_QAT_MAX_RETRY); + } + + pthread_exit(NULL); + + return NULL; +} + + +CpaStatus bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits) +{ + +} + diff --git a/he_qat_bn_ops.h b/he_qat_bn_ops.h new file mode 100644 index 0000000..65b252b --- /dev/null +++ b/he_qat_bn_ops.h @@ -0,0 +1,32 @@ +#pragma once + +// One for each consumer +typedef struct { + HE_QAT_STATUS request_status; + CpaStatus op_status; + CpaCyLnModExpOpData op_data; + CpaFlatBuffer op_output; + sem_t callback; + +} HE_QAT_ModExpRequest; + + +/// @brief +/// @function +/// Callback function for lnModExpPerformOp. It performs any data processing +/// required after the modular exponentiation. +void lnModExpCallback(void *pCallbackTag, + CpaStatus status, + void *pOpData, + CpaFlatBuffer *pOut); + +/// @brief +/// @function +/// Perform large number modular exponentiation. +/// @param[in] cyInstHandle QAT instance handle. +CpaStatus lnModExpPerformOp(CpaInstanceHandle cyInstHandle); +//CpaStatus lnModExpPerformOp(QATOpRequestBuffer *buffer); + + +CpaStatus bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits); + diff --git a/he_qat_context.c b/he_qat_context.c index a6db26f..9312a21 100644 --- a/he_qat_context.c +++ b/he_qat_context.c @@ -1,28 +1,21 @@ -#include "heqat_types.h" +#include "he_qat_types.h" +#include "he_qat_context.h" + +#include #include "icp_sal_poll.h" #include "cpa_sample_utils.h" +// Global variable declarations +HE_QAT_Inst he_qat_instances [HE_QAT_MAX_NUM_INST]; +HE_QAT_InstConfig he_qat_inst_config [HE_QAT_MAX_NUM_INST]; +HE_QAT_RequestBuffer he_qat_buffer; + //CpaStatus get_qat_instances(CpaInstanceHandle *_instances, int *_num_instances=-1) //{ // //} -const int MAX_NUM_INST 8 - -// Type definitions -enum HEQAT_EXEC_MODE { HEQAT_BLOCK_SYNC=1 }; -enum HEQAT_STATUS { HEQAT_SUCCESS = 0, HEQAT_FAIL = 1 }; -typedef pthread_t QATInst; -typedef struct QATInstConfigStruct { - CpaInstanceHandle inst_handle; - //void *func(); - volatile int polling; -} QATInstConfig; - -// Global variable declarations -QATInst qat_instances [MAX_NUM_INST]; -QATInstConfig qat_inst_config [MAX_NUM_INST]; /* #define HEQAT_FREE_QATInstConfig(config) \ do { \ @@ -36,21 +29,24 @@ QATInstConfig qat_inst_config [MAX_NUM_INST]; } while (0) */ -static void inst_thread() -{ - -} - /// @brief /// @function start_inst_polling /// @param[in] QATInstConfig Holds the parameter values to set up the QAT instance thread. /// -static void start_inst_polling(QATInstConfig *config) +static void start_inst_polling(HE_QAT_InstConfig *config) { if (!config) return ; - + if (!config->inst_handle) return ; + + CpaStatus status = CPA_STATUS_FAIL; + status = cpaCyStartInstance(config->inst_handle); + if (CPA_STATUS_SUCCESS == status) { + status = cpaCySetAddressTranslation(config->inst_handle, + sampleVirtToPhys); + } + + // What is harmful for polling without performing any operation? config->polling = 1; - while (config->polling) { icp_sal_CyPollInstance(config->inst_handle, 0); OS_SLEEP(10); @@ -65,7 +61,7 @@ static void start_inst_polling(QATInstConfig *config) /// static void stop_inst_polling() { - for (int i = 0; i < MAX_NUM_INSTS; i++) { + for (int i = 0; i < HE_QAT_MAX_NUM_INSTS; i++) { // Or check if the cpa_instance is not NULL (try it out) //if (!qat_inst_config[i].inst_handle) continue; if (!qat_inst_config[i].polling) continue; @@ -79,36 +75,61 @@ static void stop_inst_polling() /// @brief /// @function acquire_qat_devices /// Acquire QAT instances and set up QAT execution environment. -HEQAT_STATUS acquire_qat_devices() +HE_QAT_STATUS acquire_qat_devices() { - CpaInstanceHandle _inst_handle = NULL; + CpaStatus status = CPA_STATUS_FAIL; + + // Initialize QAT memory pool allocator + status = qaeMemInit(); + if (CPA_STATUS_SUCCESS != status) { + return HE_QAT_STATUS_FAIL; // HEQAT_STATUS_ERROR + } + // Not sure if for multiple instances the id will need to be specified, e.g. "SSL1" + status = icp_sal_userStartMultiProcess("SSL", CPA_FALSE); + if (CPA_STATUS_SUCCESS != status) { + printf("Failed to start user process SSL\n"); + qaeMemDestroy(); + return HE_QAT_STATUS_FAIL; // HEQAT_STATUS_ERROR + } + + CpaInstanceHandle _inst_handle = NULL; // TODO: @fdiasmor Create a CyGetInstance that retrieves more than one. sampleCyGetInstance(&_inst_handle); - if (_inst_handle == NULL) { - return HEQAT_FAIL; + return HE_QAT_STATUS_FAIL; } - // Dispatch worker threads + // Creating QAT instances (consumer threads) to process op requests pthread_attr_t attr; cpu_set_t cpus; pthread_attr_init(&attr); - for (int i = 0; i < HEQAT_BLOCK_SYNC; i++) { + for (int i = 0; i < HE_QAT_SYNC; i++) { CPU_ZERO(&cpus); CPU_SET(i, &cpus); pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpus); // configure thread - QATInstConfig *config = (QATInstConfig *) malloc(sizeof(QATInstConfig)); - if (config == NULL) return HEQAT_FAIL; + HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) + malloc(sizeof(QATInstConfig)); + if (config == NULL) return HE_QAT_FAIL; config->inst_handle = _inst_handle[i]; - pthread_create(&qat_instances[i], &attr, start_inst_polling, config); + pthread_create(&he_qat_instances[i], &attr, start_inst_polling, config); } + // Dispatch the qat instances to run independently in the background + for (int i = 0; i < HE_QAT_SYNC; i++) { + pthread_detach(qat_instances[i]); + } + + // Initialize QAT buffer synchronization attributes + he_qat_buffer.count = 0; + he_qat_buffer.next_free_slot = 0; + he_qat_buffer.next_data_slot = 0; - for (int i = 0; i < HEQAT_BLOCK_SYNC; i++) { - pthread_ + // Initialize QAT memory buffer + for (int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { + he_qat_buffer.data[i] = NULL; } return ; @@ -117,18 +138,28 @@ HEQAT_STATUS acquire_qat_devices() /// @brief /// @function release_qat_devices /// Release QAT instances and tear down QAT execution environment. -void release_qat_devices() +HE_QAT_STATUS release_qat_devices() { CpaStatus status = CPA_STATUS_FAIL; - // signal all qat instance + // signal all qat instance to stop polling + stop_inst_polling(); - for (int i = 0; i < MAX_NUM_INST; i++) { - status = cpaCyStopInstance(qat_inst_config[i].inst_handle); + // Release QAT instances handles + for (int i = 0; i < HE_QAT_MAX_NUM_INST; i++) { + status = cpaCyStopInstance(he_qat_inst_config[i].inst_handle); if (CPA_STATUS_SUCCESS != status) { printf("Failed to stop QAT instance #%d\n",i); + return HE_QAT_STATUS_FAIL; } } - return ; + + // Stop QAT SSL service + icp_sal_userStop(); + + // Release QAT allocated memory + qaeMemDestroy(); + + return HE_QAT_STATUS_SUCCESS; } diff --git a/he_qat_context.h b/he_qat_context.h index 013aab5..4347961 100644 --- a/he_qat_context.h +++ b/he_qat_context.h @@ -1,4 +1,17 @@ -void acquire_qat_devices(); -void release_qat_devices(); +#pragma once + +#include "he_qat_types.h" + +const int HE_QAT_MAX_NUM_INST 8 + +/// @brief +/// @function acquire_qat_devices +/// Configure and initialize QAT runtime environment. +HE_QAT_STATUS acquire_qat_devices(); + +/// @brief +/// @function release_qat_devices +/// Configure and initialize QAT runtime environment. +HE_QAT_STATUS release_qat_devices(); diff --git a/he_qat_types.h b/he_qat_types.h index 5c75319..e90f64d 100644 --- a/he_qat_types.h +++ b/he_qat_types.h @@ -1,9 +1,39 @@ +#pragma once -typedef struct QATInstConfigStruct -{ - -} QATInstConfig; +#include +#define HE_QAT_BUFFER_SIZE 4 +// Type definitions +enum HE_QAT_EXEC_MODE { + HE_QAT_SYNC = 1, + HE_QAT_ASYNC = 2 +}; + +enum HE_QAT_STATUS { + HE_QAT_READY = 1, + HE_QAT_SUCCESS = 0, + HE_QAT_FAIL = -1 +}; + +typedef pthread_t HE_QAT_Inst; + +typedef struct { + CpaInstanceHandle inst_handle; + volatile int polling; + volatile int running; +} HE_QAT_InstConfig; + +typedef struct { + void *data[HE_QAT_BUFFER_SIZE]; // + int count; // occupied track number of buffer enties + int next_free_slot; // nextin index of the next free slot to accommodate a request + int next_data_slot; // nextout index of next request to be processed + pthread_mutex_t mutex; // + pthread_cond_t any_more_data; // more + pthread_cond_t any_free_slot; // less +} HE_QAT_RequestBuffer; + +//QATOpRequestBuffer qat_request_buffer; From 1a6c6fa45df92de624233d43e6c75f49961dfd52 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Thu, 24 Feb 2022 17:10:02 -0800 Subject: [PATCH 020/364] Fix typos and doxygen generator (#9) --- docs/Doxyfile.in | 2 +- ipcl/include/ipcl/pub_key.hpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in index 6b3ce39..a4f6a60 100644 --- a/docs/Doxyfile.in +++ b/docs/Doxyfile.in @@ -5,7 +5,7 @@ PROJECT_NAME = "Project PHE" PROJECT_BRIEF = "Project Paillier HE library w/ Intel IPP-Crypto" OUTPUT_DIRECTORY = @CMAKE_CURRENT_SOURCE_DIR@/doxygen -INPUT = @CMAKE_SOURCE_DIR@/paillier/include \ +INPUT = @CMAKE_SOURCE_DIR@/ipcl/include \ @CMAKE_SOURCE_DIR@/README.md RECURSIVE = YES USE_MDFILE_AS_MAINPAGE = @CMAKE_SOURCE_DIR@/README.md diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp index 02919a0..6eafbcf 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -12,6 +12,7 @@ class PaillierPublicKey { * PaillierPublicKey construct function * @param[in] n n of public key in paillier paper * @param[in] bits bit length of public key + * @param[in] enableDJN_ enables DJN scheme */ explicit PaillierPublicKey(const BigNumber& n, int bits = 1024, bool enableDJN_ = false); @@ -20,6 +21,7 @@ class PaillierPublicKey { * PaillierPublicKey construct function * @param[in] n n of public key in paillier paper * @param[in] bits bit length of public key + * @param[in] enableDJN_ enables DJN scheme */ explicit PaillierPublicKey(const Ipp32u n, int bits = 1024, bool enableDJN_ = false) From 681ce7db98857e96e79f4d52a350d169a0d37a52 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Thu, 24 Feb 2022 17:23:22 -0800 Subject: [PATCH 021/364] Fixed doxygen strings with new IPCL names --- docs/Doxyfile.in | 6 +++--- docs/index.rst | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in index a4f6a60..a0815a3 100644 --- a/docs/Doxyfile.in +++ b/docs/Doxyfile.in @@ -1,14 +1,14 @@ # Copyright (C) 2021-2022 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -PROJECT_NAME = "Project PHE" -PROJECT_BRIEF = "Project Paillier HE library w/ Intel IPP-Crypto" +PROJECT_NAME = "Intel Paillier Cryptosystem Library" +PROJECT_BRIEF = "Intel Paillier Cryptosystem library C++ backend with Intel IPP-Crypto" OUTPUT_DIRECTORY = @CMAKE_CURRENT_SOURCE_DIR@/doxygen INPUT = @CMAKE_SOURCE_DIR@/ipcl/include \ @CMAKE_SOURCE_DIR@/README.md RECURSIVE = YES -USE_MDFILE_AS_MAINPAGE = @CMAKE_SOURCE_DIR@/README.md +USE_MDFILE_AS_MAINPAGE = README.md USE_MATHJAX = YES FULL_PATH_NAMES = NO diff --git a/docs/index.rst b/docs/index.rst index adcfc6a..3aaefde 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,7 +1,7 @@ .. Copyright (C) 2021-2022 Intel Corporation .. SPDX-License-Identifier: Apache-2.0 -Project PHE Documentation +IPCL Documentation ============================== .. toctree:: From e2041152b3767fbbcbf52dc32bea5b868ab18059 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 24 Feb 2022 23:10:51 -0800 Subject: [PATCH 022/364] Update to the design of he_qat_context and he_qat_bn_ops. --- he_qat_bn_ops.c | 105 ++++++++++++++++++++++++++++++----------------- he_qat_bn_ops.h | 76 +++++++++++++++++++++++----------- he_qat_context.c | 25 +++++++---- he_qat_types.h | 18 +++++--- 4 files changed, 147 insertions(+), 77 deletions(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index 0eecc8a..64f3272 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -7,30 +7,47 @@ #include "he_qat_types.h" #include "he_qat_bn_ops.h" +#include +#include + /// @brief /// @function /// Callback function for lnModExpPerformOp. It performs any data processing /// required after the modular exponentiation. -static void lnModExpCallback(void *pCallbackTag, +static void lnModExpCallback(void *pCallbackTag, // This type can be variable CpaStatus status, - void *pOpData, + void *pOpData, // This is fixed -- please swap it CpaFlatBuffer *pOut) { - if (CPA_STATUS_SUCCESS != status) { - // Update request status as an error (in pOpData) - return ; - } + HE_QAT_TaskRequest *request = NULL; + + //if (CPA_STATUS_SUCCESS != status) { + // // Update request status as an error (in pOpData) + // + // return ; + //} // Check if input data for the op is available and do something - if (NULL != pOpData) { + if (NULL != pCallbackTag) { + // Read request data + request = (HE_QAT_TaskRequest *) pCallbackTag; + // Collect the device output in pOut - // Mark request as complete or ready to be used + + request->op_status = status; + if (pOpData == &request->op_data) + // Mark request as complete or ready to be used + request->request_status = HE_QAT_READY; + else + request->request_status = HE_QAT_FAIL; + + COMPLETE((struct COMPLETION_STRUCT *)request->callback); } // Asynchronous call needs to send wake-up signal to semaphore - if (NULL != pCallbackTag) { - COMPLETE((struct COMPLETION_STRUCT *)pCallbackTag); - } + // if (NULL != pCallbackTag) { + // COMPLETE((struct COMPLETION_STRUCT *)pCallbackTag); + // } return ; } @@ -40,7 +57,7 @@ static void lnModExpCallback(void *pCallbackTag, /// @function /// Thread-safe producer implementation for the shared request buffer. /// Stores requests in a buffer that will be offload to QAT devices. -void submit_next_request(HE_QAT_RequestBuffer *_buffer, void *args) +void submit_request(HE_QAT_RequestBuffer *_buffer, void *args) { pthread_mutex_lock(&_buffer->mutex); @@ -68,7 +85,7 @@ void submit_next_request(HE_QAT_RequestBuffer *_buffer, void *args) /// @function /// Thread-safe consumer implementation for the shared request buffer. /// Read requests from a buffer to finally offload the work to QAT devices. -HE_QAT_TaskRequest *get_next_request(HE_QAT_RequestBuffer *_buffer) +HE_QAT_TaskRequest *read_request(HE_QAT_RequestBuffer *_buffer) { void *item = NULL; pthread_mutex_lock(&_buffer->mutex); @@ -77,7 +94,7 @@ HE_QAT_TaskRequest *get_next_request(HE_QAT_RequestBuffer *_buffer) assert(_buffer->count > 0); - printf("[%02d]:",_buffer->next_data_slot); + //printf("[%02d]:",_buffer->next_data_slot); item = _buffer->data[b->next_data_slot++]; _buffer->next_data_slot %= HE_QAT_BUFFER_SIZE; _buffer->count--; @@ -95,44 +112,56 @@ HE_QAT_TaskRequest *get_next_request(HE_QAT_RequestBuffer *_buffer) } /// @brief -/// @function -/// Perform large number modular exponentiation. -/// @param[in] cyInstHandle QAT instance handle. -//static CpaStatus lnModExpPerformOp(CpaInstanceHandle cyInstHandle) -//static CpaStatus lnModExpPerformOp(QATaskRequest *request) -void *run_qat_op_engine(void *_inst_config) +/// @function perform_op +/// Offload operation to QAT endpoints; for example, large number modular exponentiation. +/// @param[in] HE_QAT_InstConfig *: contains the handle to CPA instance, pointer the global buffer of requests. +void *perform_op(void *_inst_config) { CpaStatus status = CPA_STATUS_FAIL; - QATInstConfig *config = (QATInstConfig *) _inst_config; + HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) _inst_config; config->running = 1; while (config->running) { // Try consume data from butter to perform requested operation - void *task_request = get_next_request(&config->he_qat_buffer); - - unsigned retries = 0; - do { - retries++; + HE_QAT_TaskRequest *request = + (HE_QAT_TaskRequest *) read_request(config->he_qat_buffer); + if (!request) continue; + + unsigned retry = 0; + do { // Realize the type of operation from data - // Select the appropriate action - status = cpaCyLnModExp(config->inst_handle, - lnModExpCallback, - (void *) task_request->callback, - &task_request->op_data, - &task_request->op_output); + switch (request->op_type) { + // Select appropriate action + case HE_QAT_MODEXP: + status = cpaCyLnModExp(config->inst_handle, + lnModExpCallback, + (void *) request->callback, + &request->op_data, + &request->op_output); + retry++; + break; + case HE_QAT_NO_OP: + default: + retry = HE_QAT_MAX_RETRY; + break; + } - - } while (CPA_STATUS_RETRY == status && retries < HE_QAT_MAX_RETRY); + } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); + + // Update the status of the request + request->op_status = status; + if (CPA_STATUS_SUCCESS != status) + request->request_status = HE_QAT_FAIL; + else + request->request_status = HE_QAT_READY; } - pthread_exit(NULL); - - return NULL; + //return NULL; } CpaStatus bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits) { - + } diff --git a/he_qat_bn_ops.h b/he_qat_bn_ops.h index 65b252b..d83e4c1 100644 --- a/he_qat_bn_ops.h +++ b/he_qat_bn_ops.h @@ -1,32 +1,60 @@ +// New compilers #pragma once -// One for each consumer -typedef struct { - HE_QAT_STATUS request_status; - CpaStatus op_status; - CpaCyLnModExpOpData op_data; - CpaFlatBuffer op_output; - sem_t callback; - -} HE_QAT_ModExpRequest; +// Legacy compilers +#ifndef _HE_QAT_BN_OPS_H_ +#define _HE_QAT_BN_OPS_H_ +#include "cpa.h" +#include "cpa_cy_ln.h" -/// @brief -/// @function -/// Callback function for lnModExpPerformOp. It performs any data processing -/// required after the modular exponentiation. -void lnModExpCallback(void *pCallbackTag, - CpaStatus status, - void *pOpData, - CpaFlatBuffer *pOut); +#include "he_qat_types.h" -/// @brief -/// @function -/// Perform large number modular exponentiation. -/// @param[in] cyInstHandle QAT instance handle. -CpaStatus lnModExpPerformOp(CpaInstanceHandle cyInstHandle); -//CpaStatus lnModExpPerformOp(QATOpRequestBuffer *buffer); +#include +#include +// #include "bignum.h" or create a standard interface -CpaStatus bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits); +#define HE_QAT_MAX_RETRY 100 +// One for each consumer +typedef struct { + sem_t callback; + HE_QAT_OP op_type; + CpaStatus op_status; + CpaFlatBuffer op_output; + CpaCyLnModExpOpData op_data; + //void *op_data; + HE_QAT_STATUS request_status; +} HE_QAT_TaskRequest; + + +/// @brief +/// @function +/// Perform big number modular exponentiation for input data in +/// OpenSSL's BIGNUM format. +/// @param[out] Remainder number of the modular exponentiation operation. +/// @param[in] Base number of the modular exponentiation operation. +/// @param[in] Exponent number of the modular exponentiation operation. +/// @param[in] Modulus number of the modular exponentiation operation. +/// @param[in] Number of bits (bit precision) of input/output big numbers. +HE_QAT_STATUS bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits); + +/// @brief +/// @function setModExpRequest(unsigned worksize) +/// Allocate buffer to hold and monitor up to 'worksize' number of outstanding requests. +/// @param[in] worksize Total number of modular exponentiation to perform in the next code section. +//void setModExpRequest(unsigned worksize) + +/// @brief +/// @function getModExpRequest() +/// Monitor outstanding request to be complete and then deallocate buffer holding outstanding request; +/// thus, releasing temporary memory. +// create private buffer for code section +// create QAT contiguous memory space +// copy data and package into a request +// use producer to place request into qat buffer +// wait for all outstanding requests to complete +//getModExpRequest() + +#endif diff --git a/he_qat_context.c b/he_qat_context.c index 9312a21..fd9464a 100644 --- a/he_qat_context.c +++ b/he_qat_context.c @@ -11,6 +11,8 @@ HE_QAT_Inst he_qat_instances [HE_QAT_MAX_NUM_INST]; HE_QAT_InstConfig he_qat_inst_config [HE_QAT_MAX_NUM_INST]; HE_QAT_RequestBuffer he_qat_buffer; +extern void *perform_op(void *_inst_config); + //CpaStatus get_qat_instances(CpaInstanceHandle *_instances, int *_num_instances=-1) //{ // @@ -99,6 +101,18 @@ HE_QAT_STATUS acquire_qat_devices() if (_inst_handle == NULL) { return HE_QAT_STATUS_FAIL; } + + // Initialize QAT buffer synchronization attributes + he_qat_buffer.count = 0; + he_qat_buffer.next_free_slot = 0; + he_qat_buffer.next_data_slot = 0; + + // Initialize QAT memory buffer + for (int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { + // preallocate for 1024, 2048, 4096 of worksize/or less + // + he_qat_buffer.data[i] = NULL; + } // Creating QAT instances (consumer threads) to process op requests pthread_attr_t attr; @@ -122,15 +136,6 @@ HE_QAT_STATUS acquire_qat_devices() pthread_detach(qat_instances[i]); } - // Initialize QAT buffer synchronization attributes - he_qat_buffer.count = 0; - he_qat_buffer.next_free_slot = 0; - he_qat_buffer.next_data_slot = 0; - - // Initialize QAT memory buffer - for (int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { - he_qat_buffer.data[i] = NULL; - } return ; } @@ -154,6 +159,8 @@ HE_QAT_STATUS release_qat_devices() } } + // Deallocate memory of QAT InstConfig + // Stop QAT SSL service icp_sal_userStop(); diff --git a/he_qat_types.h b/he_qat_types.h index e90f64d..5f1099a 100644 --- a/he_qat_types.h +++ b/he_qat_types.h @@ -17,13 +17,12 @@ enum HE_QAT_STATUS { HE_QAT_FAIL = -1 }; -typedef pthread_t HE_QAT_Inst; +enum HE_QAT_OP { + HE_QAT_NO_OP = 0, + HE_QAT_MODEXP = 1 +}; -typedef struct { - CpaInstanceHandle inst_handle; - volatile int polling; - volatile int running; -} HE_QAT_InstConfig; +typedef pthread_t HE_QAT_Inst; typedef struct { void *data[HE_QAT_BUFFER_SIZE]; // @@ -35,5 +34,12 @@ typedef struct { pthread_cond_t any_free_slot; // less } HE_QAT_RequestBuffer; +typedef struct { + CpaInstanceHandle inst_handle; + HE_QAT_RequestBuffer *he_qat_buffer; + volatile int polling; + volatile int running; +} HE_QAT_InstConfig; + //QATOpRequestBuffer qat_request_buffer; From 3e69073f676acca7dc4d74ece73d596a19600c34 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 24 Feb 2022 23:17:39 -0800 Subject: [PATCH 023/364] Rename BSIZE to HE_QAT_BUFFER_SIZE. --- he_qat_bn_ops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index 64f3272..4ee8407 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -61,10 +61,10 @@ void submit_request(HE_QAT_RequestBuffer *_buffer, void *args) { pthread_mutex_lock(&_buffer->mutex); - while (_bufffer->count >= BSIZE) + while (_bufffer->count >= HE_QAT_BUFFER_SIZE) pthread_cond_wait(&_buffer->any_free_slot, &b->mutex); - assert(_buffer->count < BSIZE); + assert(_buffer->count < HE_QAT_BUFFER_SIZE); _buffer->data[b->next_free_slot++] = args; From 890c1ad39a1f35798b329ab0ee9fe4c898c10b48 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 24 Feb 2022 23:23:24 -0800 Subject: [PATCH 024/364] Fix object passed as pCallbackTag. --- he_qat_bn_ops.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index 4ee8407..812b569 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -135,7 +135,7 @@ void *perform_op(void *_inst_config) case HE_QAT_MODEXP: status = cpaCyLnModExp(config->inst_handle, lnModExpCallback, - (void *) request->callback, + (void *) request, &request->op_data, &request->op_output); retry++; @@ -149,11 +149,11 @@ void *perform_op(void *_inst_config) } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); // Update the status of the request - request->op_status = status; - if (CPA_STATUS_SUCCESS != status) - request->request_status = HE_QAT_FAIL; - else - request->request_status = HE_QAT_READY; + //request->op_status = status; + //if (CPA_STATUS_SUCCESS != status) + // request->request_status = HE_QAT_FAIL; + //else + // request->request_status = HE_QAT_READY; } pthread_exit(NULL); //return NULL; From ceb84756c347a94be598381661cc7aea756dc371 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 24 Feb 2022 23:28:33 -0800 Subject: [PATCH 025/364] Fix return type of bnModExpPerformOp. --- he_qat_bn_ops.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index 812b569..ee81be4 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -160,8 +160,9 @@ void *perform_op(void *_inst_config) } -CpaStatus bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits) +HE_QAT_STATUS bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits) { - + + return HE_QAT_SUCCESS; } From ed50995b8a1d2b2d38b6ff2b826ce2b0345746ef Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 25 Feb 2022 19:01:30 -0800 Subject: [PATCH 026/364] Update custom type definitions. --- he_qat_types.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/he_qat_types.h b/he_qat_types.h index 5f1099a..20f025e 100644 --- a/he_qat_types.h +++ b/he_qat_types.h @@ -1,9 +1,16 @@ #pragma once +#ifndef _HE_QAT_TYPES_H_ +#define _HE_QAT_TYPES_H_ + +#include "cpa.h" +#include "cpa_cy_im.h" + #include #define HE_QAT_BUFFER_SIZE 4 +//const unsigned HE_QAT_BUFFER_SIZE = 4; // Type definitions enum HE_QAT_EXEC_MODE { @@ -36,10 +43,11 @@ typedef struct { typedef struct { CpaInstanceHandle inst_handle; + pthread_attr_t *attr; HE_QAT_RequestBuffer *he_qat_buffer; volatile int polling; volatile int running; } HE_QAT_InstConfig; -//QATOpRequestBuffer qat_request_buffer; +#endif From e659e158acfaac0cb6e432443f9f301b3134aa73 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 25 Feb 2022 19:03:14 -0800 Subject: [PATCH 027/364] Encapsulate polling thread and refactor processing thread. --- he_qat_bn_ops.c | 92 +++++++++++++++++++++++++++++++++++++++++++++---- he_qat_bn_ops.h | 6 ++-- 2 files changed, 90 insertions(+), 8 deletions(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index ee81be4..460bfae 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -1,5 +1,6 @@ #include "cpa.h" +#include "cpa_cy_im.h" #include "cpa_cy_ln.h" #include "cpa_sample_utils.h" @@ -10,6 +11,9 @@ #include #include +// Global buffer for the runtime environment +HE_QAT_RequestBuffer he_qat_buffer; + /// @brief /// @function /// Callback function for lnModExpPerformOp. It performs any data processing @@ -41,7 +45,7 @@ static void lnModExpCallback(void *pCallbackTag, // This type can be variable else request->request_status = HE_QAT_FAIL; - COMPLETE((struct COMPLETION_STRUCT *)request->callback); + COMPLETE((struct COMPLETION_STRUCT *)&request->callback); } // Asynchronous call needs to send wake-up signal to semaphore @@ -57,7 +61,7 @@ static void lnModExpCallback(void *pCallbackTag, // This type can be variable /// @function /// Thread-safe producer implementation for the shared request buffer. /// Stores requests in a buffer that will be offload to QAT devices. -void submit_request(HE_QAT_RequestBuffer *_buffer, void *args) +static void submit_request(HE_QAT_RequestBuffer *_buffer, void *args) { pthread_mutex_lock(&_buffer->mutex); @@ -85,7 +89,7 @@ void submit_request(HE_QAT_RequestBuffer *_buffer, void *args) /// @function /// Thread-safe consumer implementation for the shared request buffer. /// Read requests from a buffer to finally offload the work to QAT devices. -HE_QAT_TaskRequest *read_request(HE_QAT_RequestBuffer *_buffer) +static HE_QAT_TaskRequest *read_request(HE_QAT_RequestBuffer *_buffer) { void *item = NULL; pthread_mutex_lock(&_buffer->mutex); @@ -111,14 +115,66 @@ HE_QAT_TaskRequest *read_request(HE_QAT_RequestBuffer *_buffer) return (HE_QAT_TaskRequest *) (item); } +/// @brief +/// @function start_inst_polling +/// @param[in] HE_QAT_InstConfig Parameter values to start and poll instances. +/// +static void start_inst_polling(HE_QAT_InstConfig *config) +{ + if (!config) return ; + if (!config->inst_handle) return ; + + CpaStatus status = CPA_STATUS_FAIL; + status = cpaCyStartInstance(config->inst_handle); + if (CPA_STATUS_SUCCESS == status) { + status = cpaCySetAddressTranslation(config->inst_handle, + sampleVirtToPhys); + } + + // What is harmful for polling without performing any operation? + config->polling = 1; + while (config->polling) { + icp_sal_CyPollInstance(config->inst_handle, 0); + OS_SLEEP(10); + } + + pthread_exit(NULL); +} + +/// @brief This function +/// @function stop_inst_polling +/// Stop polling instances and halt polling thread. +static void stop_inst_polling(HE_QAT_InstConfig *config) +{ + config->polling = 0; + OS_SLEEP(10); + return ; +} + /// @brief /// @function perform_op /// Offload operation to QAT endpoints; for example, large number modular exponentiation. /// @param[in] HE_QAT_InstConfig *: contains the handle to CPA instance, pointer the global buffer of requests. -void *perform_op(void *_inst_config) +void *start_perform_op(void *_inst_config) { CpaStatus status = CPA_STATUS_FAIL; HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) _inst_config; + + if (!config) return ; + + // Start QAT instance and start polling + pthread_t polling_thread; + if (pthread_create(&polling_thread, config->attr, + start_inst_polling, (void *) config) != 0) { + printf("Failed at creating and starting polling thread.\n"); + pthread_exit(NULL); + } + + if (pthread_detach(polling_thread) != 0) { + printf("Failed at detaching polling thread.\n"); + pthread_exit(NULL); + } + config->running = 1; while (config->running) { // Try consume data from butter to perform requested operation @@ -156,13 +212,37 @@ void *perform_op(void *_inst_config) // request->request_status = HE_QAT_READY; } pthread_exit(NULL); - //return NULL; } +void stop_perform_op(HE_QAT_InstConfig *config, unsigned num_inst) +{ + // Stop runnning and polling instances + for (unsigned i = 0; i < num_inst; i++) { + config[i].running = 0; + config[i].polling = 0; + OS_SLEEP(10); + //stop_inst_polling(&config[i]); + } + + // Release QAT instances handles + CpaStatus status = CPA_STATUS_FAIL; + for (unsigned i = 0; i < num_inst; i++) { + status = cpaCyStopInstance(config[i].inst_handle); + if (CPA_STATUS_SUCCESS != status) { + printf("Failed to stop QAT instance #%d\n",i); + //return HE_QAT_STATUS_FAIL; + } + } + + return ; +} HE_QAT_STATUS bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits) { - + // Unpack data and copy to QAT friendly memory space + // Pack it as a QAT Task Request + // + return HE_QAT_SUCCESS; } diff --git a/he_qat_bn_ops.h b/he_qat_bn_ops.h index d83e4c1..158c878 100644 --- a/he_qat_bn_ops.h +++ b/he_qat_bn_ops.h @@ -9,8 +9,9 @@ #include "cpa_cy_ln.h" #include "he_qat_types.h" +#include "cpa_sample_utils.h" -#include +//#include #include // #include "bignum.h" or create a standard interface @@ -19,7 +20,8 @@ // One for each consumer typedef struct { - sem_t callback; + //sem_t callback; + struct COMPLETION_STRUCT callback; HE_QAT_OP op_type; CpaStatus op_status; CpaFlatBuffer op_output; From abd917b7bb5342bf3cd0eae21f142a66d085a26d Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 25 Feb 2022 19:04:32 -0800 Subject: [PATCH 028/364] Refactor interfaces to acquire and release QAT endpoints. --- he_qat_context.c | 144 +++++++++++++++++++---------------------------- he_qat_context.h | 7 ++- 2 files changed, 63 insertions(+), 88 deletions(-) diff --git a/he_qat_context.c b/he_qat_context.c index fd9464a..2dc2dc8 100644 --- a/he_qat_context.c +++ b/he_qat_context.c @@ -1,78 +1,20 @@ -#include "he_qat_types.h" #include "he_qat_context.h" #include + #include "icp_sal_poll.h" #include "cpa_sample_utils.h" // Global variable declarations HE_QAT_Inst he_qat_instances [HE_QAT_MAX_NUM_INST]; +pthread_attr_t he_qat_inst_attr [HE_QAT_MAX_NUM_INST]; HE_QAT_InstConfig he_qat_inst_config [HE_QAT_MAX_NUM_INST]; -HE_QAT_RequestBuffer he_qat_buffer; - -extern void *perform_op(void *_inst_config); - -//CpaStatus get_qat_instances(CpaInstanceHandle *_instances, int *_num_instances=-1) -//{ -// -//} - -/* -#define HEQAT_FREE_QATInstConfig(config) \ - do { \ - if (config) { \ - if (config->inst_handle) { \ - - } \ - free(config); \ - config = NULL; \ - } \ - } while (0) -*/ +//HE_QAT_RequestBuffer he_qat_buffer; -/// @brief -/// @function start_inst_polling -/// @param[in] QATInstConfig Holds the parameter values to set up the QAT instance thread. -/// -static void start_inst_polling(HE_QAT_InstConfig *config) -{ - if (!config) return ; - if (!config->inst_handle) return ; - - CpaStatus status = CPA_STATUS_FAIL; - status = cpaCyStartInstance(config->inst_handle); - if (CPA_STATUS_SUCCESS == status) { - status = cpaCySetAddressTranslation(config->inst_handle, - sampleVirtToPhys); - } - - // What is harmful for polling without performing any operation? - config->polling = 1; - while (config->polling) { - icp_sal_CyPollInstance(config->inst_handle, 0); - OS_SLEEP(10); - } - - return ; -} - -/// @brief This function -/// @function sal_stop_inst_polling -/// QATInstConfig Holds the parameter values to set up the QAT instance thread. -/// -static void stop_inst_polling() -{ - for (int i = 0; i < HE_QAT_MAX_NUM_INSTS; i++) { - // Or check if the cpa_instance is not NULL (try it out) - //if (!qat_inst_config[i].inst_handle) continue; - if (!qat_inst_config[i].polling) continue; - qat_inst_config[i].polling = 0; - OS_SLEEP(10); - } - - return ; -} +extern HE_QAT_RequestBuffer he_qat_buffer; +extern void *start_perform_op(void *_inst_config); +extern void stop_perform_op(void *_inst_config); /// @brief /// @function acquire_qat_devices @@ -84,23 +26,35 @@ HE_QAT_STATUS acquire_qat_devices() // Initialize QAT memory pool allocator status = qaeMemInit(); if (CPA_STATUS_SUCCESS != status) { + printf("Failed to initialized QAT memory.\n"); return HE_QAT_STATUS_FAIL; // HEQAT_STATUS_ERROR } +#ifdef _DESTINY_DEBUG_VERBOSE + printf("QAT memory successfully initialized.\n"); +#endif // Not sure if for multiple instances the id will need to be specified, e.g. "SSL1" status = icp_sal_userStartMultiProcess("SSL", CPA_FALSE); if (CPA_STATUS_SUCCESS != status) { - printf("Failed to start user process SSL\n"); + printf("Failed to start SAL user process SSL\n"); qaeMemDestroy(); return HE_QAT_STATUS_FAIL; // HEQAT_STATUS_ERROR } +#ifdef _DESTINY_DEBUG_VERBOSE + printf("SAL user process successfully started.\n"); +#endif + // Potential out-of-scope hazard for segmentation fault CpaInstanceHandle _inst_handle = NULL; // TODO: @fdiasmor Create a CyGetInstance that retrieves more than one. sampleCyGetInstance(&_inst_handle); if (_inst_handle == NULL) { + printf("Failed to find QAT endpoints.\n"); return HE_QAT_STATUS_FAIL; } +#ifdef _DESTINY_DEBUG_VERBOSE + printf("Found QAT endpoints.\n"); +#endif // Initialize QAT buffer synchronization attributes he_qat_buffer.count = 0; @@ -109,35 +63,40 @@ HE_QAT_STATUS acquire_qat_devices() // Initialize QAT memory buffer for (int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { - // preallocate for 1024, 2048, 4096 of worksize/or less - // he_qat_buffer.data[i] = NULL; } // Creating QAT instances (consumer threads) to process op requests pthread_attr_t attr; cpu_set_t cpus; - pthread_attr_init(&attr); for (int i = 0; i < HE_QAT_SYNC; i++) { CPU_ZERO(&cpus); CPU_SET(i, &cpus); - pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpus); + pthread_attr_init(&he_qat_inst_attr[i]); + pthread_attr_setaffinity_np(&he_qat_inst_attr[i], sizeof(cpu_set_t), &cpus); // configure thread - HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) - malloc(sizeof(QATInstConfig)); - if (config == NULL) return HE_QAT_FAIL; - config->inst_handle = _inst_handle[i]; - pthread_create(&he_qat_instances[i], &attr, start_inst_polling, config); + //HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) + // malloc(sizeof(QATInstConfig)); + //if (config == NULL) return HE_QAT_FAIL; + he_qat_inst_config->inst_handle = _inst_handle[i]; + he_qat_inst_config->attr = &he_qat_inst_attr[i]; + pthread_create(&he_qat_instances[i], he_qat_inst_config->attr, + start_perform_op, (void *) &he_qat_inst_config); } +#ifdef _DESTINY_DEBUG_VERBOSE + printf("Created processing threads.\n"); +#endif // Dispatch the qat instances to run independently in the background for (int i = 0; i < HE_QAT_SYNC; i++) { - pthread_detach(qat_instances[i]); + pthread_detach(he_qat_instances[i]); } +#ifdef _DESTINY_DEBUG_VERBOSE + printf("Detached processing threads.\n"); +#endif - - return ; + return HE_STATUS_SUCCESS; } /// @brief @@ -148,24 +107,35 @@ HE_QAT_STATUS release_qat_devices() CpaStatus status = CPA_STATUS_FAIL; // signal all qat instance to stop polling - stop_inst_polling(); - - // Release QAT instances handles - for (int i = 0; i < HE_QAT_MAX_NUM_INST; i++) { - status = cpaCyStopInstance(he_qat_inst_config[i].inst_handle); - if (CPA_STATUS_SUCCESS != status) { - printf("Failed to stop QAT instance #%d\n",i); - return HE_QAT_STATUS_FAIL; - } - } +// stop_inst_polling(); +// +// // Release QAT instances handles +// for (int i = 0; i < HE_QAT_MAX_NUM_INST; i++) { +// status = cpaCyStopInstance(he_qat_inst_config[i].inst_handle); +// if (CPA_STATUS_SUCCESS != status) { +// printf("Failed to stop QAT instance #%d\n",i); +// return HE_QAT_STATUS_FAIL; +// } +// } + + stop_perform_op(&he_qat_inst_config[0],HE_QAT_SYNC); +#ifdef _DESTINY_DEBUG_VERBOSE + printf("Stopped polling and processing threads.\n"); +#endif // Deallocate memory of QAT InstConfig // Stop QAT SSL service icp_sal_userStop(); +#ifdef _DESTINY_DEBUG_VERBOSE + printf("Stopped SAL user process.\n"); +#endif // Release QAT allocated memory qaeMemDestroy(); +#ifdef _DESTINY_DEBUG_VERBOSE + printf("Release QAT memory.\n"); +#endif return HE_QAT_STATUS_SUCCESS; } diff --git a/he_qat_context.h b/he_qat_context.h index 4347961..2c8762c 100644 --- a/he_qat_context.h +++ b/he_qat_context.h @@ -1,9 +1,13 @@ #pragma once +#ifndef _HE_QAT_CONTEXT_H_ +#define _HE_QAT_CONTEXT_H_ + #include "he_qat_types.h" -const int HE_QAT_MAX_NUM_INST 8 +#define HE_QAT_MAX_NUM_INST 8 +//const unsigned HE_QAT_MAX_NUM_INST = 8 /// @brief /// @function acquire_qat_devices @@ -15,3 +19,4 @@ HE_QAT_STATUS acquire_qat_devices(); /// Configure and initialize QAT runtime environment. HE_QAT_STATUS release_qat_devices(); +#endif From 4bfbdbc7abe3073025df7d50ed007e381fcebea3 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 25 Feb 2022 19:16:38 -0800 Subject: [PATCH 029/364] Fix initialization of the instances configuration objects. --- he_qat_context.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/he_qat_context.c b/he_qat_context.c index 2dc2dc8..cd1337b 100644 --- a/he_qat_context.c +++ b/he_qat_context.c @@ -79,10 +79,12 @@ HE_QAT_STATUS acquire_qat_devices() //HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) // malloc(sizeof(QATInstConfig)); //if (config == NULL) return HE_QAT_FAIL; - he_qat_inst_config->inst_handle = _inst_handle[i]; - he_qat_inst_config->attr = &he_qat_inst_attr[i]; - pthread_create(&he_qat_instances[i], he_qat_inst_config->attr, - start_perform_op, (void *) &he_qat_inst_config); + he_qat_inst_config[i].polling = 0; + he_qat_inst_config[i].running = 0; + he_qat_inst_config[i].inst_handle = _inst_handle[i]; + he_qat_inst_config[i].attr = &he_qat_inst_attr[i]; + pthread_create(&he_qat_instances[i], he_qat_inst_config[i].attr, + start_perform_op, (void *) &he_qat_inst_config[i]); } #ifdef _DESTINY_DEBUG_VERBOSE printf("Created processing threads.\n"); From 93518029582cc74417ea16ccee641108bc6360aa Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 25 Feb 2022 19:18:51 -0800 Subject: [PATCH 030/364] Fix return value in acquire_qat_devices().wq --- he_qat_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/he_qat_context.c b/he_qat_context.c index cd1337b..08d319d 100644 --- a/he_qat_context.c +++ b/he_qat_context.c @@ -98,7 +98,7 @@ HE_QAT_STATUS acquire_qat_devices() printf("Detached processing threads.\n"); #endif - return HE_STATUS_SUCCESS; + return HE_QAT_STATUS_SUCCESS; } /// @brief From 7074ab820ae073d7966e7a28ee1e9aec799f14cd Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 25 Feb 2022 22:46:10 -0800 Subject: [PATCH 031/364] Fix bugs for compilation. --- he_qat_bn_ops.c | 12 +++--- he_qat_context.c | 17 +++++++-- he_qat_context.h | 1 + he_qat_types.h | 16 ++++---- include/cpa_sample_utils.h | 75 +++++++++++++++++++------------------- 5 files changed, 67 insertions(+), 54 deletions(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index 460bfae..0361dad 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -43,7 +43,7 @@ static void lnModExpCallback(void *pCallbackTag, // This type can be variable // Mark request as complete or ready to be used request->request_status = HE_QAT_READY; else - request->request_status = HE_QAT_FAIL; + request->request_status = HE_QAT_STATUS_FAIL; COMPLETE((struct COMPLETION_STRUCT *)&request->callback); } @@ -65,12 +65,12 @@ static void submit_request(HE_QAT_RequestBuffer *_buffer, void *args) { pthread_mutex_lock(&_buffer->mutex); - while (_bufffer->count >= HE_QAT_BUFFER_SIZE) - pthread_cond_wait(&_buffer->any_free_slot, &b->mutex); + while (_buffer->count >= HE_QAT_BUFFER_SIZE) + pthread_cond_wait(&_buffer->any_free_slot, &_buffer->mutex); assert(_buffer->count < HE_QAT_BUFFER_SIZE); - _buffer->data[b->next_free_slot++] = args; + _buffer->data[_buffer->next_free_slot++] = args; _buffer->next_free_slot %= HE_QAT_BUFFER_SIZE; _buffer->count++; @@ -99,7 +99,7 @@ static HE_QAT_TaskRequest *read_request(HE_QAT_RequestBuffer *_buffer) assert(_buffer->count > 0); //printf("[%02d]:",_buffer->next_data_slot); - item = _buffer->data[b->next_data_slot++]; + item = _buffer->data[_buffer->next_data_slot++]; _buffer->next_data_slot %= HE_QAT_BUFFER_SIZE; _buffer->count--; @@ -243,6 +243,6 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int // Pack it as a QAT Task Request // - return HE_QAT_SUCCESS; + return HE_QAT_STATUS_SUCCESS; } diff --git a/he_qat_context.c b/he_qat_context.c index 08d319d..f704c38 100644 --- a/he_qat_context.c +++ b/he_qat_context.c @@ -1,8 +1,19 @@ +#define _GNU_SOURCE + +#include "he_qat_types.h" #include "he_qat_context.h" #include +//#include + +//#include +//#include +//#include +#include +#include + #include "icp_sal_poll.h" #include "cpa_sample_utils.h" @@ -14,7 +25,7 @@ HE_QAT_InstConfig he_qat_inst_config [HE_QAT_MAX_NUM_INST]; extern HE_QAT_RequestBuffer he_qat_buffer; extern void *start_perform_op(void *_inst_config); -extern void stop_perform_op(void *_inst_config); +extern void stop_perform_op(void *_inst_config, unsigned num_inst); /// @brief /// @function acquire_qat_devices @@ -81,7 +92,7 @@ HE_QAT_STATUS acquire_qat_devices() //if (config == NULL) return HE_QAT_FAIL; he_qat_inst_config[i].polling = 0; he_qat_inst_config[i].running = 0; - he_qat_inst_config[i].inst_handle = _inst_handle[i]; + he_qat_inst_config[i].inst_handle = _inst_handle; he_qat_inst_config[i].attr = &he_qat_inst_attr[i]; pthread_create(&he_qat_instances[i], he_qat_inst_config[i].attr, start_perform_op, (void *) &he_qat_inst_config[i]); @@ -120,7 +131,7 @@ HE_QAT_STATUS release_qat_devices() // } // } - stop_perform_op(&he_qat_inst_config[0],HE_QAT_SYNC); + stop_perform_op(&he_qat_inst_config[0], HE_QAT_SYNC); #ifdef _DESTINY_DEBUG_VERBOSE printf("Stopped polling and processing threads.\n"); #endif diff --git a/he_qat_context.h b/he_qat_context.h index 2c8762c..bcf833a 100644 --- a/he_qat_context.h +++ b/he_qat_context.h @@ -5,6 +5,7 @@ #define _HE_QAT_CONTEXT_H_ #include "he_qat_types.h" +#include #define HE_QAT_MAX_NUM_INST 8 //const unsigned HE_QAT_MAX_NUM_INST = 8 diff --git a/he_qat_types.h b/he_qat_types.h index 20f025e..b27e8c0 100644 --- a/he_qat_types.h +++ b/he_qat_types.h @@ -13,21 +13,21 @@ //const unsigned HE_QAT_BUFFER_SIZE = 4; // Type definitions -enum HE_QAT_EXEC_MODE { +typedef enum { HE_QAT_SYNC = 1, HE_QAT_ASYNC = 2 -}; +} HE_QAT_EXEC_MODE; -enum HE_QAT_STATUS { +typedef enum { HE_QAT_READY = 1, - HE_QAT_SUCCESS = 0, - HE_QAT_FAIL = -1 -}; + HE_QAT_STATUS_SUCCESS = 0, + HE_QAT_STATUS_FAIL = -1 +} HE_QAT_STATUS; -enum HE_QAT_OP { +typedef enum { HE_QAT_NO_OP = 0, HE_QAT_MODEXP = 1 -}; +} HE_QAT_OP; typedef pthread_t HE_QAT_Inst; diff --git a/include/cpa_sample_utils.h b/include/cpa_sample_utils.h index 418b200..b82e666 100644 --- a/include/cpa_sample_utils.h +++ b/include/cpa_sample_utils.h @@ -251,6 +251,44 @@ typedef struct task_struct *sampleThread; #define BYTE_ALIGNMENT_64 (64) #endif +/** + ***************************************************************************** + * @ingroup fipsSampleCodeUtils + * displayHexArray + * + * @description + * Display the contents of a buffer + * + * @param[in] pLabel String to giving a short description of the printed + * value + * @param[in] pBuff pointer to the data to be printed + * @param[in] len len of the data to be printed + * + * @retval none + * + * @pre + * none + * @post + * none + *****************************************************************************/ +static inline void displayHexArray(const char *restrict pLabel, + const Cpa8U *restrict pBuff, + Cpa32U len) +{ + + int i = 0; + PRINT("%s(%d)", pLabel, len); + if (NULL == pBuff) + { + PRINT("%s(%d) Buff is NULL!!\n", __FUNCTION__, __LINE__); + return; + } + for (i = 0; i < len; i++) + { + PRINT("%02x", pBuff[i]); + } + PRINT("\n"); +} /** ******************************************************************************* * @ingroup sampleUtils @@ -578,41 +616,4 @@ void sampleDcStopPolling(void); #endif -/** - ***************************************************************************** - * @ingroup fipsSampleCodeUtils - * displayHexArray - * - * @description - * Display the contents of a buffer - * - * @param[in] pLabel String to giving a short description of the printed - * value - * @param[in] pBuff pointer to the data to be printed - * @param[in] len len of the data to be printed - * - * @retval none - * - * @pre - * none - * @post - * none - *****************************************************************************/ -static inline void displayHexArray(const char *restrict pLabel, - const Cpa8U *restrict pBuff, - Cpa32U len) -{ - int i = 0; - PRINT("%s(%d)", pLabel, len); - if (NULL == pBuff) - { - PRINT("%s(%d) Buff is NULL!!\n", __FUNCTION__, __LINE__); - return; - } - for (i = 0; i < len; i++) - { - PRINT("%02x", pBuff[i]); - } - PRINT("\n"); -} From 82a0b9c05cafdc0a2b4045f6b558683e40170d6f Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Sat, 26 Feb 2022 15:04:39 -0800 Subject: [PATCH 032/364] Fix segmentation fault in acquire_qat_devices(). --- he_qat_bn_ops.c | 27 ++++++++++++++++++++------- he_qat_context.c | 2 +- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index 0361dad..b06c103 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -2,6 +2,7 @@ #include "cpa.h" #include "cpa_cy_im.h" #include "cpa_cy_ln.h" +#include "icp_sal_poll.h" #include "cpa_sample_utils.h" @@ -119,10 +120,16 @@ static HE_QAT_TaskRequest *read_request(HE_QAT_RequestBuffer *_buffer) /// @function start_inst_polling /// @param[in] HE_QAT_InstConfig Parameter values to start and poll instances. /// -static void start_inst_polling(HE_QAT_InstConfig *config) +static void *start_inst_polling (void *_inst_config) { - if (!config) return ; - if (!config->inst_handle) return ; + if (NULL == _inst_config) { + printf("Failed at start_inst_polling: argument is NULL."); //,__FUNC__); + pthread_exit(NULL); + } + + HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) _inst_config; + + if (!config->inst_handle) return NULL; CpaStatus status = CPA_STATUS_FAIL; status = cpaCyStartInstance(config->inst_handle); @@ -160,7 +167,10 @@ void *start_perform_op(void *_inst_config) CpaStatus status = CPA_STATUS_FAIL; HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) _inst_config; - if (!config) return ; + if (NULL == config) { + printf("Failed in start_perform_op: _inst_config is NULL.\n"); + pthread_exit(NULL); + } // Start QAT instance and start polling pthread_t polling_thread; @@ -178,8 +188,8 @@ void *start_perform_op(void *_inst_config) config->running = 1; while (config->running) { // Try consume data from butter to perform requested operation - HE_QAT_TaskRequest *request = - (HE_QAT_TaskRequest *) read_request(config->he_qat_buffer); + HE_QAT_TaskRequest *request = NULL; + // (HE_QAT_TaskRequest *) read_request(config->he_qat_buffer); if (!request) continue; @@ -218,15 +228,18 @@ void stop_perform_op(HE_QAT_InstConfig *config, unsigned num_inst) { // Stop runnning and polling instances for (unsigned i = 0; i < num_inst; i++) { - config[i].running = 0; config[i].polling = 0; + config[i].running = 0; OS_SLEEP(10); + printf("Stopping instance #%d\n",i); //stop_inst_polling(&config[i]); } // Release QAT instances handles CpaStatus status = CPA_STATUS_FAIL; for (unsigned i = 0; i < num_inst; i++) { + if (config[i].inst_handle == NULL) continue; + printf("cpaCyStopInstance\n"); status = cpaCyStopInstance(config[i].inst_handle); if (CPA_STATUS_SUCCESS != status) { printf("Failed to stop QAT instance #%d\n",i); diff --git a/he_qat_context.c b/he_qat_context.c index f704c38..3bc9d36 100644 --- a/he_qat_context.c +++ b/he_qat_context.c @@ -131,7 +131,7 @@ HE_QAT_STATUS release_qat_devices() // } // } - stop_perform_op(&he_qat_inst_config[0], HE_QAT_SYNC); + stop_perform_op(he_qat_inst_config, HE_QAT_SYNC); #ifdef _DESTINY_DEBUG_VERBOSE printf("Stopped polling and processing threads.\n"); #endif From 5b914118b82acb55674d8efbc0ffd496b46c1892 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Sat, 26 Feb 2022 15:12:26 -0800 Subject: [PATCH 033/364] Fix compilation warnings of implicit declarations in he_qat_context.c. --- he_qat_context.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/he_qat_context.c b/he_qat_context.c index 3bc9d36..a1abcd4 100644 --- a/he_qat_context.c +++ b/he_qat_context.c @@ -14,8 +14,9 @@ #include #include -#include "icp_sal_poll.h" #include "cpa_sample_utils.h" +#include "icp_sal_user.h" +#include "icp_sal_poll.h" // Global variable declarations HE_QAT_Inst he_qat_instances [HE_QAT_MAX_NUM_INST]; From 87638d31d78142636973c757dd3c6eddb34f73b9 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Sat, 26 Feb 2022 15:14:39 -0800 Subject: [PATCH 034/364] Add simple unit test for he_qat_context.*. --- CMakeLists.txt | 20 +++++++++++++++++++- test_context.c | 26 ++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 test_context.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f6265f..73719cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,24 @@ add_compile_options(-fPIC) # Common utility functions add_subdirectory(common) +set(HE_QAT_SRC ${CMAKE_CURRENT_LIST_DIR}/he_qat_bn_ops.c + ${CMAKE_CURRENT_LIST_DIR}/he_qat_context.c) +add_library(he_qat SHARED ${HE_QAT_SRC}) +target_include_directories(he_qat PUBLIC ${COMMON_INC_DIR}) +target_include_directories(he_qat PUBLIC /opt/openssl/include) +target_link_directories(he_qat PUBLIC ${ICP_BUILDOUTPUT_PATH}) +target_link_directories(he_qat PUBLIC /opt/openssl/lib) +target_link_libraries(he_qat PRIVATE cpa_sample_utils) +target_link_libraries(he_qat PUBLIC z pthread crypto ssl crypto qat_s usdm_drv_s) + +add_definitions(-D_DESTINY_DEBUG_VERBOSE) + +add_executable(test_context test_context.c) +target_link_libraries(test_context PUBLIC he_qat) +target_link_libraries(test_context PUBLIC cpa_sample_utils) +target_link_libraries(test_context PUBLIC z pthread crypto ssl crypto qat_s usdm_drv_s) + + # Compile test case -add_subdirectory(ln_mod_exp) +#add_subdirectory(ln_mod_exp) diff --git a/test_context.c b/test_context.c new file mode 100644 index 0000000..cf1eb5e --- /dev/null +++ b/test_context.c @@ -0,0 +1,26 @@ + +#include +#include "he_qat_context.h" + +int main() +{ + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + status = acquire_qat_devices(); + if (HE_QAT_STATUS_SUCCESS == status) { + printf("Completed acquire_qat_devices() successfully.\n"); + } else { + printf("acquire_qat_devices() failed.\n"); + exit(1); + } + + status = release_qat_devices(); + if (HE_QAT_STATUS_SUCCESS == status) { + printf("Completed release_qat_devices() successfully.\n"); + } else { + printf("release_qat_devices() failed.\n"); + exit(1); + } + + return 0; +} From c08e06b283eeec72f016cbcf46be8962ef89d1cb Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Sun, 27 Feb 2022 17:16:51 -0800 Subject: [PATCH 035/364] Add sleep time to test context. --- test_context.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test_context.c b/test_context.c index cf1eb5e..cfdb129 100644 --- a/test_context.c +++ b/test_context.c @@ -1,5 +1,6 @@ #include +#include "cpa_sample_utils.h" #include "he_qat_context.h" int main() @@ -14,6 +15,8 @@ int main() exit(1); } + OS_SLEEP(5000); + status = release_qat_devices(); if (HE_QAT_STATUS_SUCCESS == status) { printf("Completed release_qat_devices() successfully.\n"); From ffcf3f33014bb65105c9b09aad0d51f43d8a23a4 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Sun, 27 Feb 2022 17:18:08 -0800 Subject: [PATCH 036/364] Fix synchronization issue between acquire and release. --- he_qat_bn_ops.c | 94 +++++++++++++++++++++++++++++++++--------------- he_qat_context.c | 22 +++++++++--- he_qat_types.h | 4 +++ 3 files changed, 88 insertions(+), 32 deletions(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index b06c103..45802ab 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -14,6 +14,7 @@ // Global buffer for the runtime environment HE_QAT_RequestBuffer he_qat_buffer; +//he_qat_buffer.count = 0; /// @brief /// @function @@ -129,14 +130,7 @@ static void *start_inst_polling (void *_inst_config) HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) _inst_config; - if (!config->inst_handle) return NULL; - - CpaStatus status = CPA_STATUS_FAIL; - status = cpaCyStartInstance(config->inst_handle); - if (CPA_STATUS_SUCCESS == status) { - status = cpaCySetAddressTranslation(config->inst_handle, - sampleVirtToPhys); - } + if (NULL == config->inst_handle) return NULL; // What is harmful for polling without performing any operation? config->polling = 1; @@ -164,14 +158,38 @@ static void stop_inst_polling(HE_QAT_InstConfig *config) /// @param[in] HE_QAT_InstConfig *: contains the handle to CPA instance, pointer the global buffer of requests. void *start_perform_op(void *_inst_config) { - CpaStatus status = CPA_STATUS_FAIL; - HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) _inst_config; - - if (NULL == config) { + if (NULL == _inst_config) { printf("Failed in start_perform_op: _inst_config is NULL.\n"); pthread_exit(NULL); } + + HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) _inst_config; + + CpaStatus status = CPA_STATUS_FAIL; + + // If called again, wait + pthread_mutex_lock(&config->mutex); + while (config->active) + pthread_cond_wait(&config->ready, &config->mutex); + + //assert(0 == config->active); + //assert(NULL == config->inst_handle); + + status = cpaCyStartInstance(config->inst_handle); + config->status = status; + if (CPA_STATUS_SUCCESS == status) { + printf("Cpa CyInstance has successfully started.\n "); + status = cpaCySetAddressTranslation(config->inst_handle, + sampleVirtToPhys); + + } + + pthread_cond_signal(&config->ready); + pthread_mutex_unlock(&config->mutex); + if (CPA_STATUS_SUCCESS != status) + pthread_exit(NULL); + // Start QAT instance and start polling pthread_t polling_thread; if (pthread_create(&polling_thread, config->attr, @@ -191,7 +209,10 @@ void *start_perform_op(void *_inst_config) HE_QAT_TaskRequest *request = NULL; // (HE_QAT_TaskRequest *) read_request(config->he_qat_buffer); - if (!request) continue; + if (NULL == request) { + pthread_cond_signal(&config->ready); + continue; + } unsigned retry = 0; do { @@ -214,6 +235,8 @@ void *start_perform_op(void *_inst_config) } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); + pthread_cond_signal(&config->ready); + // Update the status of the request //request->op_status = status; //if (CPA_STATUS_SUCCESS != status) @@ -226,26 +249,41 @@ void *start_perform_op(void *_inst_config) void stop_perform_op(HE_QAT_InstConfig *config, unsigned num_inst) { + //if () { // Stop runnning and polling instances - for (unsigned i = 0; i < num_inst; i++) { - config[i].polling = 0; - config[i].running = 0; - OS_SLEEP(10); - printf("Stopping instance #%d\n",i); - //stop_inst_polling(&config[i]); - } - // Release QAT instances handles + if (NULL == config) return ; + CpaStatus status = CPA_STATUS_FAIL; for (unsigned i = 0; i < num_inst; i++) { - if (config[i].inst_handle == NULL) continue; - printf("cpaCyStopInstance\n"); - status = cpaCyStopInstance(config[i].inst_handle); - if (CPA_STATUS_SUCCESS != status) { - printf("Failed to stop QAT instance #%d\n",i); - //return HE_QAT_STATUS_FAIL; - } + //if (config[i].polling || config[i].running) { + pthread_mutex_lock(&config[i].mutex); + printf("Try stopping instance #%d.\n",i); + while (0 == config[i].active) { + printf("STUCK\n"); + pthread_cond_wait(&config[i].ready, &config[i].mutex); + } + if (CPA_STATUS_SUCCESS == config[i].status && config[i].active) { + printf("Stopping polling and running instance #%d\n",i); + config[i].polling = 0; + config[i].running = 0; + OS_SLEEP(10); + printf("Stopping instance #%d\n",i); + if (config[i].inst_handle == NULL) continue; + printf("cpaCyStopInstance\n"); + status = cpaCyStopInstance(config[i].inst_handle); + if (CPA_STATUS_SUCCESS != status) { + printf("Failed to stop QAT instance #%d\n",i); + //return HE_QAT_STATUS_FAIL; + } + } + printf("Passed once\n"); + pthread_cond_signal(&config[i].ready); + pthread_mutex_unlock(&config[i].mutex); + //} } + //} + return ; } diff --git a/he_qat_context.c b/he_qat_context.c index a1abcd4..ebbf01a 100644 --- a/he_qat_context.c +++ b/he_qat_context.c @@ -28,6 +28,9 @@ extern HE_QAT_RequestBuffer he_qat_buffer; extern void *start_perform_op(void *_inst_config); extern void stop_perform_op(void *_inst_config, unsigned num_inst); + +CpaInstanceHandle handle = NULL; + /// @brief /// @function acquire_qat_devices /// Acquire QAT instances and set up QAT execution environment. @@ -59,8 +62,13 @@ HE_QAT_STATUS acquire_qat_devices() // Potential out-of-scope hazard for segmentation fault CpaInstanceHandle _inst_handle = NULL; // TODO: @fdiasmor Create a CyGetInstance that retrieves more than one. - sampleCyGetInstance(&_inst_handle); - if (_inst_handle == NULL) { + //sampleCyGetInstance(&_inst_handle); + //if (_inst_handle == NULL) { + // printf("Failed to find QAT endpoints.\n"); + // return HE_QAT_STATUS_FAIL; + //} + sampleCyGetInstance(&handle); + if (handle == NULL) { printf("Failed to find QAT endpoints.\n"); return HE_QAT_STATUS_FAIL; } @@ -91,9 +99,15 @@ HE_QAT_STATUS acquire_qat_devices() //HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) // malloc(sizeof(QATInstConfig)); //if (config == NULL) return HE_QAT_FAIL; - he_qat_inst_config[i].polling = 0; + he_qat_inst_config[i].active = 1; // HE_QAT_STATUS_INACTIVE + he_qat_inst_config[i].polling = 0; // HE_QAT_STATUS_INACTIVE he_qat_inst_config[i].running = 0; - he_qat_inst_config[i].inst_handle = _inst_handle; + he_qat_inst_config[i].status = CPA_STATUS_FAIL; +// he_qat_inst_config[i].mutex = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_init(&he_qat_inst_config[i].mutex,NULL); +// he_qat_inst_config[i].ready = PTHREAD_COND_INITIALIZER; + pthread_cond_init(&he_qat_inst_config[i].ready,NULL); + he_qat_inst_config[i].inst_handle = handle; //_inst_handle[i]; he_qat_inst_config[i].attr = &he_qat_inst_attr[i]; pthread_create(&he_qat_instances[i], he_qat_inst_config[i].attr, start_perform_op, (void *) &he_qat_inst_config[i]); diff --git a/he_qat_types.h b/he_qat_types.h index b27e8c0..d6b5d5f 100644 --- a/he_qat_types.h +++ b/he_qat_types.h @@ -45,8 +45,12 @@ typedef struct { CpaInstanceHandle inst_handle; pthread_attr_t *attr; HE_QAT_RequestBuffer *he_qat_buffer; + pthread_mutex_t mutex; + pthread_cond_t ready; + volatile int active; volatile int polling; volatile int running; + CpaStatus status; } HE_QAT_InstConfig; #endif From e0bbbb2cf12648c90ee09953f4f371445aed9b3a Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Sun, 27 Feb 2022 17:18:08 -0800 Subject: [PATCH 037/364] Fix synchronization issue between acquire and release. --- he_qat_bn_ops.c | 94 +++++++++++++++++++++++++++++++++--------------- he_qat_context.c | 22 +++++++++--- he_qat_types.h | 4 +++ 3 files changed, 88 insertions(+), 32 deletions(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index b06c103..45802ab 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -14,6 +14,7 @@ // Global buffer for the runtime environment HE_QAT_RequestBuffer he_qat_buffer; +//he_qat_buffer.count = 0; /// @brief /// @function @@ -129,14 +130,7 @@ static void *start_inst_polling (void *_inst_config) HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) _inst_config; - if (!config->inst_handle) return NULL; - - CpaStatus status = CPA_STATUS_FAIL; - status = cpaCyStartInstance(config->inst_handle); - if (CPA_STATUS_SUCCESS == status) { - status = cpaCySetAddressTranslation(config->inst_handle, - sampleVirtToPhys); - } + if (NULL == config->inst_handle) return NULL; // What is harmful for polling without performing any operation? config->polling = 1; @@ -164,14 +158,38 @@ static void stop_inst_polling(HE_QAT_InstConfig *config) /// @param[in] HE_QAT_InstConfig *: contains the handle to CPA instance, pointer the global buffer of requests. void *start_perform_op(void *_inst_config) { - CpaStatus status = CPA_STATUS_FAIL; - HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) _inst_config; - - if (NULL == config) { + if (NULL == _inst_config) { printf("Failed in start_perform_op: _inst_config is NULL.\n"); pthread_exit(NULL); } + + HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) _inst_config; + + CpaStatus status = CPA_STATUS_FAIL; + + // If called again, wait + pthread_mutex_lock(&config->mutex); + while (config->active) + pthread_cond_wait(&config->ready, &config->mutex); + + //assert(0 == config->active); + //assert(NULL == config->inst_handle); + + status = cpaCyStartInstance(config->inst_handle); + config->status = status; + if (CPA_STATUS_SUCCESS == status) { + printf("Cpa CyInstance has successfully started.\n "); + status = cpaCySetAddressTranslation(config->inst_handle, + sampleVirtToPhys); + + } + + pthread_cond_signal(&config->ready); + pthread_mutex_unlock(&config->mutex); + if (CPA_STATUS_SUCCESS != status) + pthread_exit(NULL); + // Start QAT instance and start polling pthread_t polling_thread; if (pthread_create(&polling_thread, config->attr, @@ -191,7 +209,10 @@ void *start_perform_op(void *_inst_config) HE_QAT_TaskRequest *request = NULL; // (HE_QAT_TaskRequest *) read_request(config->he_qat_buffer); - if (!request) continue; + if (NULL == request) { + pthread_cond_signal(&config->ready); + continue; + } unsigned retry = 0; do { @@ -214,6 +235,8 @@ void *start_perform_op(void *_inst_config) } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); + pthread_cond_signal(&config->ready); + // Update the status of the request //request->op_status = status; //if (CPA_STATUS_SUCCESS != status) @@ -226,26 +249,41 @@ void *start_perform_op(void *_inst_config) void stop_perform_op(HE_QAT_InstConfig *config, unsigned num_inst) { + //if () { // Stop runnning and polling instances - for (unsigned i = 0; i < num_inst; i++) { - config[i].polling = 0; - config[i].running = 0; - OS_SLEEP(10); - printf("Stopping instance #%d\n",i); - //stop_inst_polling(&config[i]); - } - // Release QAT instances handles + if (NULL == config) return ; + CpaStatus status = CPA_STATUS_FAIL; for (unsigned i = 0; i < num_inst; i++) { - if (config[i].inst_handle == NULL) continue; - printf("cpaCyStopInstance\n"); - status = cpaCyStopInstance(config[i].inst_handle); - if (CPA_STATUS_SUCCESS != status) { - printf("Failed to stop QAT instance #%d\n",i); - //return HE_QAT_STATUS_FAIL; - } + //if (config[i].polling || config[i].running) { + pthread_mutex_lock(&config[i].mutex); + printf("Try stopping instance #%d.\n",i); + while (0 == config[i].active) { + printf("STUCK\n"); + pthread_cond_wait(&config[i].ready, &config[i].mutex); + } + if (CPA_STATUS_SUCCESS == config[i].status && config[i].active) { + printf("Stopping polling and running instance #%d\n",i); + config[i].polling = 0; + config[i].running = 0; + OS_SLEEP(10); + printf("Stopping instance #%d\n",i); + if (config[i].inst_handle == NULL) continue; + printf("cpaCyStopInstance\n"); + status = cpaCyStopInstance(config[i].inst_handle); + if (CPA_STATUS_SUCCESS != status) { + printf("Failed to stop QAT instance #%d\n",i); + //return HE_QAT_STATUS_FAIL; + } + } + printf("Passed once\n"); + pthread_cond_signal(&config[i].ready); + pthread_mutex_unlock(&config[i].mutex); + //} } + //} + return ; } diff --git a/he_qat_context.c b/he_qat_context.c index a1abcd4..ebbf01a 100644 --- a/he_qat_context.c +++ b/he_qat_context.c @@ -28,6 +28,9 @@ extern HE_QAT_RequestBuffer he_qat_buffer; extern void *start_perform_op(void *_inst_config); extern void stop_perform_op(void *_inst_config, unsigned num_inst); + +CpaInstanceHandle handle = NULL; + /// @brief /// @function acquire_qat_devices /// Acquire QAT instances and set up QAT execution environment. @@ -59,8 +62,13 @@ HE_QAT_STATUS acquire_qat_devices() // Potential out-of-scope hazard for segmentation fault CpaInstanceHandle _inst_handle = NULL; // TODO: @fdiasmor Create a CyGetInstance that retrieves more than one. - sampleCyGetInstance(&_inst_handle); - if (_inst_handle == NULL) { + //sampleCyGetInstance(&_inst_handle); + //if (_inst_handle == NULL) { + // printf("Failed to find QAT endpoints.\n"); + // return HE_QAT_STATUS_FAIL; + //} + sampleCyGetInstance(&handle); + if (handle == NULL) { printf("Failed to find QAT endpoints.\n"); return HE_QAT_STATUS_FAIL; } @@ -91,9 +99,15 @@ HE_QAT_STATUS acquire_qat_devices() //HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) // malloc(sizeof(QATInstConfig)); //if (config == NULL) return HE_QAT_FAIL; - he_qat_inst_config[i].polling = 0; + he_qat_inst_config[i].active = 1; // HE_QAT_STATUS_INACTIVE + he_qat_inst_config[i].polling = 0; // HE_QAT_STATUS_INACTIVE he_qat_inst_config[i].running = 0; - he_qat_inst_config[i].inst_handle = _inst_handle; + he_qat_inst_config[i].status = CPA_STATUS_FAIL; +// he_qat_inst_config[i].mutex = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_init(&he_qat_inst_config[i].mutex,NULL); +// he_qat_inst_config[i].ready = PTHREAD_COND_INITIALIZER; + pthread_cond_init(&he_qat_inst_config[i].ready,NULL); + he_qat_inst_config[i].inst_handle = handle; //_inst_handle[i]; he_qat_inst_config[i].attr = &he_qat_inst_attr[i]; pthread_create(&he_qat_instances[i], he_qat_inst_config[i].attr, start_perform_op, (void *) &he_qat_inst_config[i]); diff --git a/he_qat_types.h b/he_qat_types.h index b27e8c0..d6b5d5f 100644 --- a/he_qat_types.h +++ b/he_qat_types.h @@ -45,8 +45,12 @@ typedef struct { CpaInstanceHandle inst_handle; pthread_attr_t *attr; HE_QAT_RequestBuffer *he_qat_buffer; + pthread_mutex_t mutex; + pthread_cond_t ready; + volatile int active; volatile int polling; volatile int running; + CpaStatus status; } HE_QAT_InstConfig; #endif From f0578156afd525708450fd239949a42ba0eaf807 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Sun, 27 Feb 2022 17:31:28 -0800 Subject: [PATCH 038/364] Real fix to sync issue between acquire and release. --- he_qat_bn_ops.c | 1 + he_qat_context.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index 45802ab..92b10d7 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -204,6 +204,7 @@ void *start_perform_op(void *_inst_config) } config->running = 1; + config->active = 1; while (config->running) { // Try consume data from butter to perform requested operation HE_QAT_TaskRequest *request = NULL; diff --git a/he_qat_context.c b/he_qat_context.c index ebbf01a..9bdd385 100644 --- a/he_qat_context.c +++ b/he_qat_context.c @@ -99,7 +99,7 @@ HE_QAT_STATUS acquire_qat_devices() //HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) // malloc(sizeof(QATInstConfig)); //if (config == NULL) return HE_QAT_FAIL; - he_qat_inst_config[i].active = 1; // HE_QAT_STATUS_INACTIVE + he_qat_inst_config[i].active = 0; // HE_QAT_STATUS_INACTIVE he_qat_inst_config[i].polling = 0; // HE_QAT_STATUS_INACTIVE he_qat_inst_config[i].running = 0; he_qat_inst_config[i].status = CPA_STATUS_FAIL; From 78b0b76553825dbe28c495d07aa00fbb11eb33f6 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Sun, 27 Feb 2022 17:31:28 -0800 Subject: [PATCH 039/364] Real fix to sync issue between acquire and release. --- he_qat_bn_ops.c | 1 + he_qat_context.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index 45802ab..92b10d7 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -204,6 +204,7 @@ void *start_perform_op(void *_inst_config) } config->running = 1; + config->active = 1; while (config->running) { // Try consume data from butter to perform requested operation HE_QAT_TaskRequest *request = NULL; diff --git a/he_qat_context.c b/he_qat_context.c index ebbf01a..9bdd385 100644 --- a/he_qat_context.c +++ b/he_qat_context.c @@ -99,7 +99,7 @@ HE_QAT_STATUS acquire_qat_devices() //HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) // malloc(sizeof(QATInstConfig)); //if (config == NULL) return HE_QAT_FAIL; - he_qat_inst_config[i].active = 1; // HE_QAT_STATUS_INACTIVE + he_qat_inst_config[i].active = 0; // HE_QAT_STATUS_INACTIVE he_qat_inst_config[i].polling = 0; // HE_QAT_STATUS_INACTIVE he_qat_inst_config[i].running = 0; he_qat_inst_config[i].status = CPA_STATUS_FAIL; From c97b168e31352010a7fc9a674a0063e57b59a2b2 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Sun, 27 Feb 2022 17:31:28 -0800 Subject: [PATCH 040/364] Real fix to sync issue between acquire and release. --- he_qat_bn_ops.c | 1 + he_qat_context.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index 45802ab..92b10d7 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -204,6 +204,7 @@ void *start_perform_op(void *_inst_config) } config->running = 1; + config->active = 1; while (config->running) { // Try consume data from butter to perform requested operation HE_QAT_TaskRequest *request = NULL; diff --git a/he_qat_context.c b/he_qat_context.c index ebbf01a..9bdd385 100644 --- a/he_qat_context.c +++ b/he_qat_context.c @@ -99,7 +99,7 @@ HE_QAT_STATUS acquire_qat_devices() //HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) // malloc(sizeof(QATInstConfig)); //if (config == NULL) return HE_QAT_FAIL; - he_qat_inst_config[i].active = 1; // HE_QAT_STATUS_INACTIVE + he_qat_inst_config[i].active = 0; // HE_QAT_STATUS_INACTIVE he_qat_inst_config[i].polling = 0; // HE_QAT_STATUS_INACTIVE he_qat_inst_config[i].running = 0; he_qat_inst_config[i].status = CPA_STATUS_FAIL; From 4e1a3eb4afc460d899a06de2e4de67250effd43b Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Sun, 27 Feb 2022 17:38:03 -0800 Subject: [PATCH 041/364] Switch CpaInstanceHandle to a local variable. --- he_qat_context.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/he_qat_context.c b/he_qat_context.c index 9bdd385..fdeb649 100644 --- a/he_qat_context.c +++ b/he_qat_context.c @@ -62,16 +62,16 @@ HE_QAT_STATUS acquire_qat_devices() // Potential out-of-scope hazard for segmentation fault CpaInstanceHandle _inst_handle = NULL; // TODO: @fdiasmor Create a CyGetInstance that retrieves more than one. - //sampleCyGetInstance(&_inst_handle); - //if (_inst_handle == NULL) { - // printf("Failed to find QAT endpoints.\n"); - // return HE_QAT_STATUS_FAIL; - //} - sampleCyGetInstance(&handle); - if (handle == NULL) { + sampleCyGetInstance(&_inst_handle); + if (_inst_handle == NULL) { printf("Failed to find QAT endpoints.\n"); return HE_QAT_STATUS_FAIL; } + //sampleCyGetInstance(&handle); + //if (handle == NULL) { + // printf("Failed to find QAT endpoints.\n"); + // return HE_QAT_STATUS_FAIL; + //} #ifdef _DESTINY_DEBUG_VERBOSE printf("Found QAT endpoints.\n"); #endif @@ -107,7 +107,7 @@ HE_QAT_STATUS acquire_qat_devices() pthread_mutex_init(&he_qat_inst_config[i].mutex,NULL); // he_qat_inst_config[i].ready = PTHREAD_COND_INITIALIZER; pthread_cond_init(&he_qat_inst_config[i].ready,NULL); - he_qat_inst_config[i].inst_handle = handle; //_inst_handle[i]; + he_qat_inst_config[i].inst_handle = _inst_handle; he_qat_inst_config[i].attr = &he_qat_inst_attr[i]; pthread_create(&he_qat_instances[i], he_qat_inst_config[i].attr, start_perform_op, (void *) &he_qat_inst_config[i]); From 97284b79e87487dcd82f04e3ce53f654b0c604e5 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 28 Feb 2022 09:07:03 -0800 Subject: [PATCH 042/364] Add debugging traces in stop_perform_op. --- he_qat_bn_ops.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index 92b10d7..2b506c0 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -236,6 +236,7 @@ void *start_perform_op(void *_inst_config) } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); + // Signal any calls to stop_perform_op that now it is safe to shutdown instances pthread_cond_signal(&config->ready); // Update the status of the request @@ -248,6 +249,11 @@ void *start_perform_op(void *_inst_config) pthread_exit(NULL); } +/// @brief +/// @function +/// Stop first 'num_inst' number of cpaCyInstance(s), including their polling and running threads. +/// @param[in] HE_QAT_InstConfig config Vector of created instances with their configuration setup. +/// @param[in] num_inst Unsigned integer number indicating first number of instances to be terminated. void stop_perform_op(HE_QAT_InstConfig *config, unsigned num_inst) { //if () { @@ -257,34 +263,35 @@ void stop_perform_op(HE_QAT_InstConfig *config, unsigned num_inst) CpaStatus status = CPA_STATUS_FAIL; for (unsigned i = 0; i < num_inst; i++) { - //if (config[i].polling || config[i].running) { pthread_mutex_lock(&config[i].mutex); - printf("Try stopping instance #%d.\n",i); +#ifdef _DESTINY_DEBUG_VERBOSE + printf("Try teardown HE QAT instance #%d.\n",i); +#endif while (0 == config[i].active) { - printf("STUCK\n"); pthread_cond_wait(&config[i].ready, &config[i].mutex); } if (CPA_STATUS_SUCCESS == config[i].status && config[i].active) { - printf("Stopping polling and running instance #%d\n",i); - config[i].polling = 0; +#ifdef _DESTINY_DEBUG_VERBOSE + printf("Stop polling and running threads #%d\n",i); +#endif + config[i].polling = 0; config[i].running = 0; OS_SLEEP(10); - printf("Stopping instance #%d\n",i); - if (config[i].inst_handle == NULL) continue; +#ifdef _DESTINY_DEBUG_VERBOSE + printf("Stop cpaCyInstance #%d\n",i); +#endif + if (config[i].inst_handle == NULL) continue; +#ifdef _DESTINY_DEBUG_VERBOSE printf("cpaCyStopInstance\n"); - status = cpaCyStopInstance(config[i].inst_handle); +#endif + status = cpaCyStopInstance(config[i].inst_handle); if (CPA_STATUS_SUCCESS != status) { printf("Failed to stop QAT instance #%d\n",i); - //return HE_QAT_STATUS_FAIL; } } - printf("Passed once\n"); pthread_cond_signal(&config[i].ready); pthread_mutex_unlock(&config[i].mutex); - //} } - //} - return ; } From 923272dd8c83aff4fa4089e9430dfcbb8227f379 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 28 Feb 2022 13:55:43 -0800 Subject: [PATCH 043/364] Non-tested impl of single-threaded synchronous bnModExpPerformOp. --- he_qat_bn_ops.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++-- he_qat_bn_ops.h | 27 ++++++---- 2 files changed, 148 insertions(+), 14 deletions(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index d90672b..f5683b0 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -102,6 +102,9 @@ static HE_QAT_TaskRequest *read_request(HE_QAT_RequestBuffer *_buffer) //printf("[%02d]:",_buffer->next_data_slot); item = _buffer->data[_buffer->next_data_slot++]; + + // make copy of request so that the buffer can be reused + _buffer->next_data_slot %= HE_QAT_BUFFER_SIZE; _buffer->count--; @@ -224,7 +227,7 @@ void *start_perform_op(void *_inst_config) status = cpaCyLnModExp(config->inst_handle, lnModExpCallback, (void *) request, - &request->op_data, + (CpaCyLnModExpOpData *) request->op_data, &request->op_output); retry++; break; @@ -300,10 +303,132 @@ void stop_perform_op(HE_QAT_InstConfig *config, unsigned num_inst) HE_QAT_STATUS bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits) { - // Unpack data and copy to QAT friendly memory space - // Pack it as a QAT Task Request - // + // Unpack data and copy to QAT friendly memory space + int len = nbits / 8; + + Cpa8U *pBase = NULL; + Cpa8U *pModulus = NULL; + Cpa8U *pExponent = NULL; + + HE_QAT_TaskRequest *request = (HE_QAT_TaskRequest *) calloc(1,sizeof(HE_QAT_TaskRequest)); + if (NULL == request) { + printf("HE_QAT_TaskRequest memory allocation failed in bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + + // TODO: @fdiasmor Try it with 8-byte alignment. + CpaStatus status = PHYS_CONTIG_ALLOC(&pBase, len); + if (CPA_STATUS_SUCCESS == status && NULL != pBase) { + unsigned char *bin = (unsigned char *) calloc(len, sizeof(unsigned char)); + if (BN_bn2binpad(b, bin, len)) { + memcpy(pBase, bin, len); + } else { + printf("BN_bn2binpad failed in bnModExpPerformOp.\n"); + PHYS_CONTIG_FREE(pBase); + free(bin); + bin = NULL; + return HE_QAT_STATUS_FAIL; + } + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + status = PHYS_CONTIG_ALLOC(&pExponent, len); + if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { + unsigned char *bin = (unsigned char *) calloc(len, sizeof(unsigned char)); + if (BN_bn2binpad(e, bin, len)) { + memcpy(pExponent, bin, len); + } else { + printf("BN_bn2binpad failed in bnModExpPerformOp.\n"); + PHYS_CONTIG_FREE(pExponent); + free(bin); + bin = NULL; + return HE_QAT_STATUS_FAIL; + } + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + status = PHYS_CONTIG_ALLOC(&pModulus, len); + if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { + unsigned char *bin = (unsigned char *) calloc(len, sizeof(unsigned char)); + if (BN_bn2binpad(m, bin, len)) { + memcpy(pModulus, bin, len); + } else { + printf("BN_bn2binpad failed in bnModExpPerformOp.\n"); + free(bin); + bin = NULL; + return HE_QAT_STATUS_FAIL; + } + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } - return HE_QAT_STATUS_SUCCESS; + // Pack it as a QAT Task Request + CpaCyLnModExpOpData *op_data = (CpaCyLnModExpOpData *) calloc(1, sizeof(CpaCyLnModExpOpData)); + if (NULL == op_data) { + printf("Cpa memory allocation failed in bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + op_data->base.pData = pBase; + op_data->base.dataLenInBytes = len; + op_data->exponent.pData = pExponent; + op_data->exponent.dataLenInBytes = len; + op_data->modulus.pData = pModulus; + op_data->modulus.dataLenInBytes = len; + request->op_data = (void *) op_data; + + status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); + if (CPA_STATUS_SUCCESS == status && NULL != request->op_result.pData) { + request->op_result.dataLenInBytes = len; + } else { + printf("CpaFlatBuffer.pData memory allocation failed in bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + + request->op_status = status; + request->op_output = (void *) r; + + // Submit request using producer function + submit_request(&he_qat_buffer, (void *) request); + + return HE_QAT_STATUS_SUCCESS; +} + +// Maybe it will be useful to pass the number of requests to retrieve +// Pass post-processing function as argument to bring output to expected type +void getBnModExpRequest() +{ + unsigned int finish = 0; + unsigned int index = 0; + // TODO: @fdiasmor Introduce global variable that record at which upcoming request it currently is + while (0 == finish) { + finish = 1; + for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE && finish; i++) { + HE_QAT_TaskRequest *task = (HE_QAT_TaskRequest *) he_qat_buffer.data[i]; + // TODO: @fdiasmor Check if not NULL before read. + finish = (HE_QAT_READY == task->request_status); + if (finish) { // ? 1 : 0; + // Set output results to original format + BIGNUM *r = BN_bin2bn(task->op_result.pData, task->op_result.dataLenInBytes, + (BIGNUM *) task->op_output); + + // Free up QAT temporary memory + CpaCyLnModExpOpData *op_data = (CpaCyLnModExpOpData *) task->op_data; + if (op_data) { + PHYS_CONTIG_FREE(op_data->base.pData); + PHYS_CONTIG_FREE(op_data->exponent.pData); + PHYS_CONTIG_FREE(op_data->modulus.pData); + } + if (task->op_result) { + PHYS_CONTIG_FREE(task->op_result.pData); + } + } + } + } + return ; } diff --git a/he_qat_bn_ops.h b/he_qat_bn_ops.h index 158c878..65308a7 100644 --- a/he_qat_bn_ops.h +++ b/he_qat_bn_ops.h @@ -24,9 +24,10 @@ typedef struct { struct COMPLETION_STRUCT callback; HE_QAT_OP op_type; CpaStatus op_status; - CpaFlatBuffer op_output; - CpaCyLnModExpOpData op_data; - //void *op_data; + CpaFlatBuffer op_result; + //CpaCyLnModExpOpData op_data; + void *op_data; + void *op_output; HE_QAT_STATUS request_status; } HE_QAT_TaskRequest; @@ -35,11 +36,15 @@ typedef struct { /// @function /// Perform big number modular exponentiation for input data in /// OpenSSL's BIGNUM format. -/// @param[out] Remainder number of the modular exponentiation operation. -/// @param[in] Base number of the modular exponentiation operation. -/// @param[in] Exponent number of the modular exponentiation operation. -/// @param[in] Modulus number of the modular exponentiation operation. -/// @param[in] Number of bits (bit precision) of input/output big numbers. +/// @details +/// Create private buffer for code section. Create QAT contiguous memory space. +/// Copy data and package into a request and call producer function to submit +/// request into qat buffer. +/// @param r [out] Remainder number of the modular exponentiation operation. +/// @param b [in] Base number of the modular exponentiation operation. +/// @param e [in] Exponent number of the modular exponentiation operation. +/// @param m [in] Modulus number of the modular exponentiation operation. +/// @param nbits[in] Number of bits (bit precision) of input/output big numbers. HE_QAT_STATUS bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits); /// @brief @@ -51,12 +56,16 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int /// @brief /// @function getModExpRequest() /// Monitor outstanding request to be complete and then deallocate buffer holding outstanding request; +/// @details +/// Releasing QAT temporary memory. + +// wait for all outstanding requests to complete +void getBnModExpRequest() /// thus, releasing temporary memory. // create private buffer for code section // create QAT contiguous memory space // copy data and package into a request // use producer to place request into qat buffer // wait for all outstanding requests to complete -//getModExpRequest() #endif From 51a0d87ab2126faadfe094fab00bc78dae3d182b Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 28 Feb 2022 14:17:06 -0800 Subject: [PATCH 044/364] Make every call to perform operation a blocking call. --- he_qat_bn_ops.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index f5683b0..4e2c7c5 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -218,6 +218,8 @@ void *start_perform_op(void *_inst_config) continue; } + COMPLETION_INIT(&request->callback); + unsigned retry = 0; do { // Realize the type of operation from data @@ -239,7 +241,19 @@ void *start_perform_op(void *_inst_config) } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); - // Signal any calls to stop_perform_op that now it is safe to shutdown instances + // Ensure every call to perform operation is blocking for each endpoint + if (CPA_STATUS_SUCCESS == status) { + // Wait until the callback function has been called + if (0 != COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { + request->op_status = CPA_STATUS_FAIL; + request->request_status = HE_QAT_STATUS_FAIL; // Review it + //request->request_status = HE_QAT_STATUS_INCOMPLETE; + } + } + + + // Wake up any blocked call to stop_perform_op, signaling that now it is + // safe to terminate running instances. Check if this detereorate performance. pthread_cond_signal(&config->ready); // Update the status of the request @@ -426,6 +440,9 @@ void getBnModExpRequest() if (task->op_result) { PHYS_CONTIG_FREE(task->op_result.pData); } + + // Destroy synchronization object + COMPLETION_DESTROY(&task->callback); } } } From a0a8c637e849513624194deb4a82fd58b9ff172b Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 28 Feb 2022 14:26:17 -0800 Subject: [PATCH 045/364] Fix compilation errors in he_qat_bn_ops.* for bnModExpPerformOp. --- he_qat_bn_ops.c | 4 ++-- he_qat_bn_ops.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index 4e2c7c5..deeb1cc 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -230,7 +230,7 @@ void *start_perform_op(void *_inst_config) lnModExpCallback, (void *) request, (CpaCyLnModExpOpData *) request->op_data, - &request->op_output); + &request->op_result); retry++; break; case HE_QAT_NO_OP: @@ -437,7 +437,7 @@ void getBnModExpRequest() PHYS_CONTIG_FREE(op_data->exponent.pData); PHYS_CONTIG_FREE(op_data->modulus.pData); } - if (task->op_result) { + if (task->op_result.pData) { PHYS_CONTIG_FREE(task->op_result.pData); } diff --git a/he_qat_bn_ops.h b/he_qat_bn_ops.h index 65308a7..5204b55 100644 --- a/he_qat_bn_ops.h +++ b/he_qat_bn_ops.h @@ -60,7 +60,7 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int /// Releasing QAT temporary memory. // wait for all outstanding requests to complete -void getBnModExpRequest() +void getBnModExpRequest(); /// thus, releasing temporary memory. // create private buffer for code section // create QAT contiguous memory space From 5450cb3e741fee4f7fc4da5bae76c712f7eb68de Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 28 Feb 2022 14:27:30 -0800 Subject: [PATCH 046/364] Remove unused variables in getBnModExpRequest. --- he_qat_bn_ops.c | 1 - 1 file changed, 1 deletion(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index deeb1cc..f7f5ee1 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -417,7 +417,6 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int void getBnModExpRequest() { unsigned int finish = 0; - unsigned int index = 0; // TODO: @fdiasmor Introduce global variable that record at which upcoming request it currently is while (0 == finish) { finish = 1; From 5c0d4248b133418035e73e423eb3d214ac563176 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Mon, 28 Feb 2022 14:49:25 -0800 Subject: [PATCH 047/364] Address issue #10 - complete (#11) --- ipcl/bignum.cpp | 19 ++++++++++--------- ipcl/include/ipcl/bignum.h | 10 ++++------ 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/ipcl/bignum.cpp b/ipcl/bignum.cpp index d8ea436..537ca1d 100644 --- a/ipcl/bignum.cpp +++ b/ipcl/bignum.cpp @@ -24,6 +24,7 @@ // BigNumber // ////////////////////////////////////////////////////////////////////// + BigNumber::~BigNumber() { delete[](Ipp8u*) m_pBN; } bool BigNumber::create(const Ipp32u* pData, int length, IppsBigNumSGN sgn) { @@ -405,11 +406,11 @@ bool BigNumber::TestBit(int index) const { int BigNumber::LSB() const { if (*this == BigNumber::Zero()) return 0; - vector v; + std::vector v; num2vec(v); int lsb = 0; - vector::iterator i; + std::vector::iterator i; for (i = v.begin(); i != v.end(); i++) { Ipp32u x = *i; if (0 == x) @@ -428,11 +429,11 @@ int BigNumber::LSB() const { int BigNumber::MSB() const { if (*this == BigNumber::Zero()) return 0; - vector v; + std::vector v; num2vec(v); int msb = (int)v.size() * 32 - 1; - vector::reverse_iterator i; + std::vector::reverse_iterator i; for (i = v.rbegin(); i != v.rend(); i++) { Ipp32u x = *i; if (0 == x) @@ -448,14 +449,14 @@ int BigNumber::MSB() const { return msb; } -int Bit(const vector& v, int n) { +int Bit(const std::vector& v, int n) { return 0 != (v[n >> 5] & (1 << (n & 0x1F))); } // // conversions and output // -void BigNumber::num2vec(vector& v) const { +void BigNumber::num2vec(std::vector& v) const { int bnBitLen; Ipp32u* bnData; ippsRef_BN(nullptr, &bnBitLen, &bnData, *this); @@ -465,7 +466,7 @@ void BigNumber::num2vec(vector& v) const { for (int n = 0; n < len; n++) v.push_back(bnData[n]); } -void BigNumber::num2hex(string& s) const { +void BigNumber::num2hex(std::string& s) const { IppsBigNumSGN bnSgn; int bnBitLen; Ipp32u* bnData; @@ -491,8 +492,8 @@ void BigNumber::num2hex(string& s) const { } } -ostream& operator<<(ostream& os, const BigNumber& a) { - string s; +std::ostream& operator<<(std::ostream& os, const BigNumber& a) { + std::string s; a.num2hex(s); os << s; return os; diff --git a/ipcl/include/ipcl/bignum.h b/ipcl/include/ipcl/bignum.h index 9fa2f7d..8645bef 100644 --- a/ipcl/include/ipcl/bignum.h +++ b/ipcl/include/ipcl/bignum.h @@ -22,8 +22,6 @@ #include #include -using namespace std; - class BigNumber { public: BigNumber(Ipp32u value = 0); @@ -114,12 +112,12 @@ class BigNumber { int LSB() const; int BitSize() const { return MSB() + 1; } int DwordSize() const { return (BitSize() + 31) >> 5; } - friend int Bit(const vector& v, int n); + friend int Bit(const std::vector& v, int n); // conversion and output - void num2hex(string& s) const; // convert to hex string - void num2vec(vector& v) const; // convert to 32-bit word vector - friend ostream& operator<<(ostream& os, const BigNumber& a); + void num2hex(std::string& s) const; // convert to hex string + void num2vec(std::vector& v) const; // convert to 32-bit word vector + friend std::ostream& operator<<(std::ostream& os, const BigNumber& a); protected: bool create(const Ipp32u* pData, int length, From a6268ce8fc233e3b9d8033e5bee7f13c8b9c1149 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Mon, 28 Feb 2022 15:16:25 -0800 Subject: [PATCH 048/364] Minor fixes - License update - added 0 multiply case to unit-test --- .clang-format | 2 +- .github/workflows/github-ci.yml | 2 +- .gitignore | 2 +- .pre-commit-config.yaml | 2 +- CMakeLists.txt | 2 +- CODEOWNERS | 2 +- LICENSE | 2 +- benchmark/CMakeLists.txt | 2 +- benchmark/bench_cryptography.cpp | 2 +- benchmark/bench_ops.cpp | 2 +- benchmark/main.cpp | 2 +- cmake/gbenchmark.cmake | 2 +- cmake/gtest.cmake | 2 +- cmake/ipcl/IPCLConfig.cmake.in | 2 +- cmake/ipcl/ipcl-util.cmake | 2 +- cmake/ippcrypto.cmake | 2 +- docs/CMakeLists.txt | 2 +- docs/Doxyfile.in | 2 +- docs/index.rst | 2 +- ipcl/CMakeLists.txt | 2 +- ipcl/include/ipcl/key_pair.hpp | 2 +- ipcl/include/ipcl/paillier_ops.hpp | 2 +- ipcl/include/ipcl/pri_key.hpp | 2 +- ipcl/include/ipcl/pub_key.hpp | 2 +- ipcl/key_pair.cpp | 2 +- ipcl/paillier_ops.cpp | 2 +- ipcl/paillier_pri.cpp | 2 +- ipcl/paillier_pub.cpp | 6 +-- test/CMakeLists.txt | 2 +- test/main.cpp | 2 +- test/test_cryptography.cpp | 2 +- test/test_ops.cpp | 81 ++++++++++++++++++++++-------- 32 files changed, 93 insertions(+), 54 deletions(-) diff --git a/.clang-format b/.clang-format index c2b1851..49d6b8c 100644 --- a/.clang-format +++ b/.clang-format @@ -1,4 +1,4 @@ -# Copyright (C) 2021-2022 Intel Corporation +# Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 BasedOnStyle: Google diff --git a/.github/workflows/github-ci.yml b/.github/workflows/github-ci.yml index 0bd1552..846f840 100644 --- a/.github/workflows/github-ci.yml +++ b/.github/workflows/github-ci.yml @@ -1,4 +1,4 @@ -# Copyright (C) 2021-2022 Intel Corporation +# Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 name: ipcl_internal diff --git a/.gitignore b/.gitignore index f88e0c0..4a6b67b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -# Copyright (C) 2021-2022 Intel Corporation +# Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 .vscode/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b194bad..e13a70f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,4 @@ -# Copyright (C) 2021-2022 Intel Corporation +# Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 exclude: 'docs/doxygen/' diff --git a/CMakeLists.txt b/CMakeLists.txt index f6e4891..80bd6da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2021-2022 Intel Corporation +# Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 cmake_minimum_required(VERSION 3.15.1) diff --git a/CODEOWNERS b/CODEOWNERS index 702e633..bff7bbc 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,4 +1,4 @@ -# Copyright (C) 2021-2022 Intel Corporation +# Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 # Default codeowner for all files diff --git a/LICENSE b/LICENSE index 3aa303a..a2b9587 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2021-2022 Intel Corporation + Copyright 2021 Intel Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index e4f4a19..7fcd633 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2021-2022 Intel Corporation +# Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 set(IPCL_BENCH_SRC main.cpp diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index ed17ec7..f669ecf 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index e705174..1f2d8e3 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include diff --git a/benchmark/main.cpp b/benchmark/main.cpp index dcdcd17..da89895 100644 --- a/benchmark/main.cpp +++ b/benchmark/main.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include diff --git a/cmake/gbenchmark.cmake b/cmake/gbenchmark.cmake index 9849666..67025aa 100644 --- a/cmake/gbenchmark.cmake +++ b/cmake/gbenchmark.cmake @@ -1,4 +1,4 @@ -# Copyright (C) 2021-2022 Intel Corporation +# Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 include(ExternalProject) diff --git a/cmake/gtest.cmake b/cmake/gtest.cmake index a844452..7678d59 100644 --- a/cmake/gtest.cmake +++ b/cmake/gtest.cmake @@ -1,4 +1,4 @@ -# Copyright (C) 2021-2022 Intel Corporation +# Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 include(ExternalProject) diff --git a/cmake/ipcl/IPCLConfig.cmake.in b/cmake/ipcl/IPCLConfig.cmake.in index 510eb69..be0c1d8 100644 --- a/cmake/ipcl/IPCLConfig.cmake.in +++ b/cmake/ipcl/IPCLConfig.cmake.in @@ -1,4 +1,4 @@ -# Copyright (C) 2021-2022 Intel Corporation +# Copyright (C) 2021 Intel Corporation @PACKAGE_INIT@ diff --git a/cmake/ipcl/ipcl-util.cmake b/cmake/ipcl/ipcl-util.cmake index e56dfe8..e9d2cfe 100644 --- a/cmake/ipcl/ipcl-util.cmake +++ b/cmake/ipcl/ipcl-util.cmake @@ -1,4 +1,4 @@ -# Copyright (C) 2021-2022 Intel Corporation +# Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 # Add dependency to the target archive diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake index b5657f1..a12ad08 100644 --- a/cmake/ippcrypto.cmake +++ b/cmake/ippcrypto.cmake @@ -1,4 +1,4 @@ -# Copyright (C) 2021-2022 Intel Corporation +# Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 include(ExternalProject) diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 05f813e..1d2abbd 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2021-2022 Intel Corporation +# Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 # Build Doxygen documentation diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in index a0815a3..66c046a 100644 --- a/docs/Doxyfile.in +++ b/docs/Doxyfile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2021-2022 Intel Corporation +# Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 PROJECT_NAME = "Intel Paillier Cryptosystem Library" diff --git a/docs/index.rst b/docs/index.rst index 3aaefde..d7f32b0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,4 +1,4 @@ -.. Copyright (C) 2021-2022 Intel Corporation +.. Copyright (C) 2021 Intel Corporation .. SPDX-License-Identifier: Apache-2.0 IPCL Documentation diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 5ecf54c..0beed37 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2021-2022 Intel Corporation +# Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 set(IPCL_SRCS paillier_pri.cpp diff --git a/ipcl/include/ipcl/key_pair.hpp b/ipcl/include/ipcl/key_pair.hpp index 67e98bb..e59726b 100644 --- a/ipcl/include/ipcl/key_pair.hpp +++ b/ipcl/include/ipcl/key_pair.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifndef IPCL_INCLUDE_IPCL_KEY_PAIR_HPP_ diff --git a/ipcl/include/ipcl/paillier_ops.hpp b/ipcl/include/ipcl/paillier_ops.hpp index cf90aa7..65de662 100644 --- a/ipcl/include/ipcl/paillier_ops.hpp +++ b/ipcl/include/ipcl/paillier_ops.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifndef IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ diff --git a/ipcl/include/ipcl/pri_key.hpp b/ipcl/include/ipcl/pri_key.hpp index 27f0609..3b5e1fd 100644 --- a/ipcl/include/ipcl/pri_key.hpp +++ b/ipcl/include/ipcl/pri_key.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifndef IPCL_INCLUDE_IPCL_PRI_KEY_HPP_ diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp index 6eafbcf..3fd0caa 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #ifndef IPCL_INCLUDE_IPCL_PUB_KEY_HPP_ diff --git a/ipcl/key_pair.cpp b/ipcl/key_pair.cpp index 5ba75e3..c1549b4 100644 --- a/ipcl/key_pair.cpp +++ b/ipcl/key_pair.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "ipcl/key_pair.hpp" diff --git a/ipcl/paillier_ops.cpp b/ipcl/paillier_ops.cpp index 651641b..600a0b2 100644 --- a/ipcl/paillier_ops.cpp +++ b/ipcl/paillier_ops.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "ipcl/paillier_ops.hpp" diff --git a/ipcl/paillier_pri.cpp b/ipcl/paillier_pri.cpp index 2a2f91a..64f6750 100644 --- a/ipcl/paillier_pri.cpp +++ b/ipcl/paillier_pri.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include diff --git a/ipcl/paillier_pub.cpp b/ipcl/paillier_pub.cpp index ee2a9c8..9026c72 100644 --- a/ipcl/paillier_pub.cpp +++ b/ipcl/paillier_pub.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include @@ -24,9 +24,9 @@ PaillierPublicKey::PaillierPublicKey(const BigNumber& n, int bits, m_bits(bits), m_dwords(BITSIZE_DWORD(bits * 2)), m_init_seed(randomUniformUnsignedInt()), - m_enable_DJN(false) { + m_enable_DJN(false), + m_testv(false) { if (enableDJN_) this->enableDJN(); // this sets m_enable_DJN - m_testv = false; } // array of 32-bit random, using rand() from stdlib diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e5808c3..759ad04 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2021-2022 Intel Corporation +# Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 # Unit tests diff --git a/test/main.cpp b/test/main.cpp index bdb4542..0ec6f12 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index cdc4709..c47d905 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include diff --git a/test/test_ops.cpp b/test/test_ops.cpp index 4d7dbb5..19e232b 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2022 Intel Corporation +// Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include @@ -106,7 +106,7 @@ TEST(OperationTest, CtPlusCtTest) { key.priv_key->decrypt(dt, res); for (int i = 0; i < 8; i++) { - vector v; + std::vector v; dt[i].num2vec(v); uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; @@ -147,7 +147,7 @@ TEST(OperationTest, CtPlusCtArrayTest) { key.priv_key->decrypt(dt, res); for (int i = 0; i < 8; i++) { - vector v; + std::vector v; dt[i].num2vec(v); uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; @@ -186,7 +186,7 @@ TEST(OperationTest, CtPlusPtTest) { key.priv_key->decrypt(dt, res); for (int i = 0; i < 8; i++) { - vector v; + std::vector v; dt[i].num2vec(v); uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; @@ -226,7 +226,7 @@ TEST(OperationTest, CtPlusPtArrayTest) { key.priv_key->decrypt(dt, res); for (int i = 0; i < 8; i++) { - vector v; + std::vector v; dt[i].num2vec(v); uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; @@ -265,7 +265,46 @@ TEST(OperationTest, CtMultiplyPtTest) { key.priv_key->decrypt(dt, res); for (int i = 0; i < 8; i++) { - vector v; + std::vector v; + dt[i].num2vec(v); + + uint64_t v_pp = (uint64_t)pt1[i] * (uint64_t)pt2[i]; + uint64_t v_dp = v[0]; + if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + + EXPECT_EQ(v_dp, v_pp); + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, CtMultiplyZeroPtTest) { + keyPair key = generateKeypair(2048); + + BigNumber ct1[8], ct2[8]; + BigNumber dt[8], res[8]; + + uint32_t pt1[8], pt2[8]; + BigNumber ptbn1[8]; + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < 8; i++) { + pt1[i] = dist(rng); + pt2[i] = 0; + ptbn1[i] = pt1[i]; + } + + key.pub_key->encrypt(ct1, ptbn1); + + CtMultiplyPt(res, ct1, pt2, key); + + key.priv_key->decrypt(dt, res); + + for (int i = 0; i < 8; i++) { + std::vector v; dt[i].num2vec(v); uint64_t v_pp = (uint64_t)pt1[i] * (uint64_t)pt2[i]; @@ -305,7 +344,7 @@ TEST(OperationTest, CtMultiplyPtArrayTest) { key.priv_key->decrypt(dt, res); for (int i = 0; i < 8; i++) { - vector v; + std::vector v; dt[i].num2vec(v); uint64_t v_pp = (uint64_t)pt1[i] * (uint64_t)pt2[i]; @@ -345,7 +384,7 @@ TEST(OperationTest, AddSubTest) { key.priv_key->decrypt(dt, res); for (int i = 0; i < 8; i++) { - vector v; + std::vector v; dt[i].num2vec(v); uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i] * 3; @@ -360,8 +399,8 @@ TEST(OperationTest, AddSubTest) { } #ifdef IPCL_UNITTEST_OMP -void CtPlusCt_OMP(int num_threads, vector v_sum, - vector v_ct1, vector v_ct2, +void CtPlusCt_OMP(int num_threads, std::vector v_sum, + std::vector v_ct1, std::vector v_ct2, keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { @@ -374,8 +413,8 @@ void CtPlusCt_OMP(int num_threads, vector v_sum, } } -void CtPlusPt_OMP(int num_threads, vector v_sum, - vector v_ct1, vector v_pt2, +void CtPlusPt_OMP(int num_threads, std::vector v_sum, + std::vector v_ct1, std::vector v_pt2, keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { @@ -388,9 +427,9 @@ void CtPlusPt_OMP(int num_threads, vector v_sum, } } -void CtPlusPtArray_OMP(int num_threads, vector v_sum, - vector v_ct1, vector v_pt2, - keyPair key) { +void CtPlusPtArray_OMP(int num_threads, std::vector v_sum, + std::vector v_ct1, + std::vector v_pt2, keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); @@ -403,9 +442,9 @@ void CtPlusPtArray_OMP(int num_threads, vector v_sum, } } -void CtMultiplyPt_OMP(int num_threads, vector v_product, - vector v_ct1, vector v_pt2, - keyPair key) { +void CtMultiplyPt_OMP(int num_threads, std::vector v_product, + std::vector v_ct1, + std::vector v_pt2, keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { @@ -417,9 +456,9 @@ void CtMultiplyPt_OMP(int num_threads, vector v_product, } } -void CtMultiplyPtArray_OMP(int num_threads, vector v_product, - vector v_ct1, vector v_pt2, - keyPair key) { +void CtMultiplyPtArray_OMP(int num_threads, std::vector v_product, + std::vector v_ct1, + std::vector v_pt2, keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); From 92e69b974052d108f765ed93128f409060ef6fc7 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Mon, 28 Feb 2022 15:23:13 -0800 Subject: [PATCH 049/364] Fixed std missing portions --- cmake/gbenchmark.cmake | 1 + ipcl/key_pair.cpp | 8 ++++---- test/test_cryptography.cpp | 16 ++++++++-------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/cmake/gbenchmark.cmake b/cmake/gbenchmark.cmake index 67025aa..efd03fb 100644 --- a/cmake/gbenchmark.cmake +++ b/cmake/gbenchmark.cmake @@ -26,6 +26,7 @@ ExternalProject_Add( BUILD_BYPRODUCTS ${GBENCHMARK_PATHS} # Skip updates UPDATE_COMMAND "" + EXCLUDE_FROM_ALL TRUE ) add_library(libgbenchmark INTERFACE) diff --git a/ipcl/key_pair.cpp b/ipcl/key_pair.cpp index c1549b4..53dbb9a 100644 --- a/ipcl/key_pair.cpp +++ b/ipcl/key_pair.cpp @@ -7,7 +7,7 @@ #include #include -static inline void rand32u(vector& addr) { +static inline void rand32u(std::vector& addr) { std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -17,7 +17,7 @@ static inline void rand32u(vector& addr) { BigNumber getPrimeBN(int maxBitSize) { int PrimeSize; ippsPrimeGetSize(maxBitSize, &PrimeSize); - auto primeGen = vector(PrimeSize); + auto primeGen = std::vector(PrimeSize); ippsPrimeInit(maxBitSize, reinterpret_cast(primeGen.data())); // define Pseudo Random Generator (default settings) @@ -25,10 +25,10 @@ BigNumber getPrimeBN(int maxBitSize) { int seedSize = BITSIZE_WORD(seedBitSize); ippsPRNGGetSize(&PrimeSize); - auto rand = vector(PrimeSize); + auto rand = std::vector(PrimeSize); ippsPRNGInit(seedBitSize, reinterpret_cast(rand.data())); - auto seed = vector(seedSize); + auto seed = std::vector(seedSize); rand32u(seed); BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index c47d905..1d2f691 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -15,7 +15,7 @@ #include "ipcl/paillier_ops.hpp" TEST(CryptoTest, CryptoTest) { - keyPair key = generateKeypair(2048); + keyPair key = generateKeypair(2048, true); BigNumber ct[8]; BigNumber dt[8]; @@ -35,7 +35,7 @@ TEST(CryptoTest, CryptoTest) { key.priv_key->decrypt(dt, ct); for (int i = 0; i < 8; i++) { - vector v; + std::vector v; dt[i].num2vec(v); EXPECT_EQ(v[0], pt[i]); } @@ -45,16 +45,16 @@ TEST(CryptoTest, CryptoTest) { } #ifdef IPCL_UNITTEST_OMP -void Encryption(int num_threads, vector v_ct, - vector v_ptbn, keyPair key) { +void Encryption(int num_threads, std::vector v_ct, + std::vector v_ptbn, keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { key.pub_key->encrypt(v_ct[i], v_ptbn[i]); } } -void Decryption(int num_threads, vector v_dt, - vector v_ct, keyPair key) { +void Decryption(int num_threads, std::vector v_dt, + std::vector v_ct, keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { key.priv_key->decrypt(v_dt[i], v_ct[i]); @@ -63,7 +63,7 @@ void Decryption(int num_threads, vector v_dt, TEST(CryptoTest, CryptoTest_OMP) { // use one keypair to do several encryption/decryption - keyPair key = generateKeypair(2048); + keyPair key = generateKeypair(2048, true); size_t num_threads = omp_get_max_threads(); // std::cout << "available threads: " << num_threads << std::endl; @@ -235,7 +235,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { key.priv_key->decrypt(dt, ct); key.priv_key->decrypt(dt12, ct12); - string str1, str2; + std::string str1, str2; c1.num2hex(str1); ct[0].num2hex(str2); From 34688a369c4b89ae1380f2b514786eb884838b8d Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Mon, 28 Feb 2022 15:33:17 -0800 Subject: [PATCH 050/364] Updated filenames - header and source file name match - Updated CMakelists per change - benchmark/unittest includes accordingly --- benchmark/bench_cryptography.cpp | 2 +- benchmark/bench_ops.cpp | 2 +- ipcl/CMakeLists.txt | 6 +++--- .../include/ipcl/{key_pair.hpp => paillier_keygen.hpp} | 10 +++++----- ipcl/include/ipcl/paillier_ops.hpp | 2 +- ipcl/include/ipcl/{pri_key.hpp => paillier_prikey.hpp} | 8 +++----- ipcl/include/ipcl/{pub_key.hpp => paillier_pubkey.hpp} | 6 +++--- ipcl/{key_pair.cpp => paillier_keygen.cpp} | 2 +- ipcl/{paillier_pri.cpp => paillier_prikey.cpp} | 4 ++-- ipcl/{paillier_pub.cpp => paillier_pubkey.cpp} | 4 ++-- test/test_cryptography.cpp | 2 +- test/test_ops.cpp | 2 +- 12 files changed, 24 insertions(+), 26 deletions(-) rename ipcl/include/ipcl/{key_pair.hpp => paillier_keygen.hpp} (74%) rename ipcl/include/ipcl/{pri_key.hpp => paillier_prikey.hpp} (94%) rename ipcl/include/ipcl/{pub_key.hpp => paillier_pubkey.hpp} (96%) rename ipcl/{key_pair.cpp => paillier_keygen.cpp} (98%) rename ipcl/{paillier_pri.cpp => paillier_prikey.cpp} (99%) rename ipcl/{paillier_pub.cpp => paillier_pubkey.cpp} (99%) diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index f669ecf..c59cae4 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -8,7 +8,7 @@ #include #endif -#include "ipcl/key_pair.hpp" +#include "ipcl/paillier_keygen.hpp" static void BM_KeyGen(benchmark::State& state) { int64_t n_length = state.range(0); diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index 1f2d8e3..542ed0d 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -9,7 +9,7 @@ #endif #include -#include "ipcl/key_pair.hpp" +#include "ipcl/paillier_keygen.hpp" #include "ipcl/paillier_ops.hpp" static void BM_Add_CTCT(benchmark::State& state) { diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 0beed37..540cde2 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -1,10 +1,10 @@ # Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -set(IPCL_SRCS paillier_pri.cpp - paillier_pub.cpp +set(IPCL_SRCS paillier_prikey.cpp + paillier_pubkey.cpp paillier_ops.cpp - key_pair.cpp + paillier_keygen.cpp bignum.cpp ) diff --git a/ipcl/include/ipcl/key_pair.hpp b/ipcl/include/ipcl/paillier_keygen.hpp similarity index 74% rename from ipcl/include/ipcl/key_pair.hpp rename to ipcl/include/ipcl/paillier_keygen.hpp index e59726b..3358957 100644 --- a/ipcl/include/ipcl/key_pair.hpp +++ b/ipcl/include/ipcl/paillier_keygen.hpp @@ -1,11 +1,11 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#ifndef IPCL_INCLUDE_IPCL_KEY_PAIR_HPP_ -#define IPCL_INCLUDE_IPCL_KEY_PAIR_HPP_ +#ifndef IPCL_INCLUDE_IPCL_PAILLIER_KEYGEN_HPP_ +#define IPCL_INCLUDE_IPCL_PAILLIER_KEYGEN_HPP_ -#include "ipcl/pri_key.hpp" -#include "ipcl/pub_key.hpp" +#include "ipcl/paillier_prikey.hpp" +#include "ipcl/paillier_pubkey.hpp" /** * Paillier key structure contains a public key and private key @@ -30,4 +30,4 @@ BigNumber getPrimeBN(int maxBitSize); */ keyPair generateKeypair(int64_t n_length, bool enable_DJN = true); -#endif // IPCL_INCLUDE_IPCL_KEY_PAIR_HPP_ +#endif // IPCL_INCLUDE_IPCL_PAILLIER_KEYGEN_HPP_ diff --git a/ipcl/include/ipcl/paillier_ops.hpp b/ipcl/include/ipcl/paillier_ops.hpp index 65de662..06ce3d7 100644 --- a/ipcl/include/ipcl/paillier_ops.hpp +++ b/ipcl/include/ipcl/paillier_ops.hpp @@ -6,7 +6,7 @@ #include -#include "ipcl/pub_key.hpp" +#include "ipcl/paillier_pubkey.hpp" class PaillierEncryptedNumber { public: diff --git a/ipcl/include/ipcl/pri_key.hpp b/ipcl/include/ipcl/paillier_prikey.hpp similarity index 94% rename from ipcl/include/ipcl/pri_key.hpp rename to ipcl/include/ipcl/paillier_prikey.hpp index 3b5e1fd..ededde7 100644 --- a/ipcl/include/ipcl/pri_key.hpp +++ b/ipcl/include/ipcl/paillier_prikey.hpp @@ -1,12 +1,10 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#ifndef IPCL_INCLUDE_IPCL_PRI_KEY_HPP_ -#define IPCL_INCLUDE_IPCL_PRI_KEY_HPP_ +#ifndef IPCL_INCLUDE_IPCL_PAILLIER_PRIKEY_HPP_ +#define IPCL_INCLUDE_IPCL_PAILLIER_PRIKEY_HPP_ -#include "ipcl/bignum.h" #include "ipcl/paillier_ops.hpp" -#include "ipcl/pub_key.hpp" class PaillierPrivateKey { public: @@ -130,4 +128,4 @@ class PaillierPrivateKey { void decryptCRT(BigNumber plaintext[8], const BigNumber ciphertext[8]); }; -#endif // IPCL_INCLUDE_IPCL_PRI_KEY_HPP_ +#endif // IPCL_INCLUDE_IPCL_PAILLIER_PRIKEY_HPP_ diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/paillier_pubkey.hpp similarity index 96% rename from ipcl/include/ipcl/pub_key.hpp rename to ipcl/include/ipcl/paillier_pubkey.hpp index 3fd0caa..054f1b1 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/paillier_pubkey.hpp @@ -1,8 +1,8 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#ifndef IPCL_INCLUDE_IPCL_PUB_KEY_HPP_ -#define IPCL_INCLUDE_IPCL_PUB_KEY_HPP_ +#ifndef IPCL_INCLUDE_IPCL_PAILLIER_PUBKEY_HPP_ +#define IPCL_INCLUDE_IPCL_PAILLIER_PUBKEY_HPP_ #include "ipcl/bignum.h" @@ -153,4 +153,4 @@ class PaillierPublicKey { BigNumber getRandom(int length); }; -#endif // IPCL_INCLUDE_IPCL_PUB_KEY_HPP_ +#endif // IPCL_INCLUDE_IPCL_PAILLIER_PUBKEY_HPP_ diff --git a/ipcl/key_pair.cpp b/ipcl/paillier_keygen.cpp similarity index 98% rename from ipcl/key_pair.cpp rename to ipcl/paillier_keygen.cpp index 53dbb9a..3acddbf 100644 --- a/ipcl/key_pair.cpp +++ b/ipcl/paillier_keygen.cpp @@ -1,7 +1,7 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include "ipcl/key_pair.hpp" +#include "ipcl/paillier_keygen.hpp" #include #include diff --git a/ipcl/paillier_pri.cpp b/ipcl/paillier_prikey.cpp similarity index 99% rename from ipcl/paillier_pri.cpp rename to ipcl/paillier_prikey.cpp index 64f6750..bcce535 100644 --- a/ipcl/paillier_pri.cpp +++ b/ipcl/paillier_prikey.cpp @@ -1,12 +1,12 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 +#include "ipcl/paillier_prikey.hpp" + #include #include -#include "ipcl/pri_key.hpp" - /** * Compute lcm for p and q * @param[in] p p - 1 of private key diff --git a/ipcl/paillier_pub.cpp b/ipcl/paillier_pubkey.cpp similarity index 99% rename from ipcl/paillier_pub.cpp rename to ipcl/paillier_pubkey.cpp index 9026c72..f0c3a3f 100644 --- a/ipcl/paillier_pub.cpp +++ b/ipcl/paillier_pubkey.cpp @@ -1,14 +1,14 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 +#include "ipcl/paillier_pubkey.hpp" + #include #include #include #include -#include "ipcl/pub_key.hpp" - static inline auto randomUniformUnsignedInt() { std::random_device dev; std::mt19937 rng(dev()); diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index 1d2f691..e6631a1 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -11,7 +11,7 @@ #endif #include "gtest/gtest.h" -#include "ipcl/key_pair.hpp" +#include "ipcl/paillier_keygen.hpp" #include "ipcl/paillier_ops.hpp" TEST(CryptoTest, CryptoTest) { diff --git a/test/test_ops.cpp b/test/test_ops.cpp index 19e232b..b9b9dcf 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -11,7 +11,7 @@ #endif #include "gtest/gtest.h" -#include "ipcl/key_pair.hpp" +#include "ipcl/paillier_keygen.hpp" #include "ipcl/paillier_ops.hpp" void CtPlusCt(BigNumber res[8], BigNumber ct1[8], BigNumber ct2[8], From 49b8dc37c27e89dbb3529c50d12476238e18082e Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Mon, 28 Feb 2022 15:52:57 -0800 Subject: [PATCH 051/364] Docstring typo fix --- ipcl/include/ipcl/paillier_keygen.hpp | 8 +++---- ipcl/include/ipcl/paillier_ops.hpp | 34 +++++++++++++-------------- ipcl/include/ipcl/paillier_prikey.hpp | 26 ++++++++++---------- ipcl/include/ipcl/paillier_pubkey.hpp | 22 ++++++++--------- 4 files changed, 45 insertions(+), 45 deletions(-) diff --git a/ipcl/include/ipcl/paillier_keygen.hpp b/ipcl/include/ipcl/paillier_keygen.hpp index 3358957..8a70c5b 100644 --- a/ipcl/include/ipcl/paillier_keygen.hpp +++ b/ipcl/include/ipcl/paillier_keygen.hpp @@ -18,15 +18,15 @@ struct keyPair { }; /** - * Generate Prime Big Number - * @param[in] maxBitSize Maxmuim bit length of generated Prime + * Generate prime number + * @param[in] maxBitSize Maximum bit length of to be generated prime number */ BigNumber getPrimeBN(int maxBitSize); /** - * Generate a pair of key + * Generate a public/private key pair * @param[in] n_length Bit length of key size - * @param[in] enable_DJN Default enabled DJN + * @param[in] enable_DJN Enable DJN (default=true) */ keyPair generateKeypair(int64_t n_length, bool enable_DJN = true); diff --git a/ipcl/include/ipcl/paillier_ops.hpp b/ipcl/include/ipcl/paillier_ops.hpp index 06ce3d7..b2971e4 100644 --- a/ipcl/include/ipcl/paillier_ops.hpp +++ b/ipcl/include/ipcl/paillier_ops.hpp @@ -11,27 +11,26 @@ class PaillierEncryptedNumber { public: /** - * PaillierEncryptedNumber construct function + * PaillierEncryptedNumber constructor * @param[in] pub_key paillier public key - * @param[in] bn ciphtext encrypted by paillier + * @param[in] bn ciphertext encrypted by paillier public key */ PaillierEncryptedNumber(PaillierPublicKey* pub_key, const BigNumber& bn); /** - * PaillierEncryptedNumber construct function + * PaillierEncryptedNumber constructor * @param[in] pub_key paillier public key - * @param[in] bn array of ciphtext encrypted by paillier - * @param[in] length elements of array + * @param[in] bn array of ciphertexts encrypted by paillier public key + * @param[in] length size of array */ PaillierEncryptedNumber(PaillierPublicKey* pub_key, const BigNumber bn[8], size_t length = 8); /** - * PaillierEncryptedNumber construct function + * PaillierEncryptedNumber constructor * @param[in] pub_key paillier public key - * @param[in] scalar array of scalar - * integer) - * @param[in] length elements of array + * @param[in] scalar array of integer scalars + * @param[in] length size of array */ PaillierEncryptedNumber(PaillierPublicKey* pub_key, const uint32_t scalar[8], size_t length = 8); @@ -67,8 +66,8 @@ class PaillierEncryptedNumber { PaillierEncryptedNumber operator*(const BigNumber& other) const; /** - * Apply obfuscator for ciphertext, obfuscated needed only when the result is - * shared to untrusted parties + * Apply obfuscator for ciphertext, obfuscated needed only when the ciphertext + * is exposed */ void apply_obfuscator() { b_isObfuscator = true; @@ -81,8 +80,8 @@ class PaillierEncryptedNumber { } /** - * Get output of Arithmetic operators - * @param[in] idx index of output array + * Return ciphertext + * @param[in] idx index of ciphertext stored in PaillierEncryptedNumber */ BigNumber getBN(size_t idx = 0) const { if (m_available == 1 && idx > 0) @@ -92,28 +91,29 @@ class PaillierEncryptedNumber { } /** - * Get public key for python wrapper + * Get public key */ PaillierPublicKey getPK() const { return *m_pubkey; } /** * Rotate PaillierEncryptedNumber + * @param[in] shift rotate length */ PaillierEncryptedNumber rotate(int shift); /** - * Get array output of Arithmetic operators + * Return entire ciphertext array * @param[out] bn output array */ void getArrayBN(BigNumber bn[8]) const { std::copy_n(m_bn, 8, bn); } /** - * Element in PaillierEncryptedNumber is single + * Check if element in PaillierEncryptedNumber is single */ bool isSingle() const { return m_available == 1; } /** - * Elements in PaillierEncryptedNumber + * Get size of array in PaillierEncryptedNumber */ size_t getLength() const { return m_length; } diff --git a/ipcl/include/ipcl/paillier_prikey.hpp b/ipcl/include/ipcl/paillier_prikey.hpp index ededde7..44c6021 100644 --- a/ipcl/include/ipcl/paillier_prikey.hpp +++ b/ipcl/include/ipcl/paillier_prikey.hpp @@ -9,29 +9,29 @@ class PaillierPrivateKey { public: /** - * PaillierPrivateKey construct function + * PaillierPrivateKey constructor * @param[in] public_key paillier public key - * @param[in] p p of private key in paillier paper - * @param[in] q q of private key in paillier paper + * @param[in] p p of private key in paillier scheme + * @param[in] q q of private key in paillier scheme */ PaillierPrivateKey(PaillierPublicKey* public_key, const BigNumber& p, const BigNumber& q); /** - * Chinese-remaindering enabling - * @param[in] crt Apply Chinese remaindering theorem + * Enable Chinese Remainder Theorem + * @param[in] crt Apply Chinese Remainder Theorem */ void enableCRT(bool crt) { m_enable_crt = crt; } /** - * Decrypt ciphtext + * Decrypt ciphertext * @param[out] plaintext output of the decryption * @param[in] ciphertext ciphertext to be decrypted */ void decrypt(BigNumber plaintext[8], const BigNumber ciphertext[8]); /** - * Decrypt ciphtext + * Decrypt ciphertext * @param[out] plaintext output of the decryption * @param[in] ciphertext PaillierEncryptedNumber to be decrypted */ @@ -41,17 +41,17 @@ class PaillierPrivateKey { const void* addr = static_cast(this); /** - * Get N of public key in paillier paper + * Get N of public key in paillier scheme */ BigNumber getN() const { return m_n; } /** - * Get p of private key in paillier paper + * Get p of private key in paillier scheme */ BigNumber getP() const { return m_p; } /** - * Get q of private key in paillier paper + * Get q of private key in paillier scheme */ BigNumber getQ() const { return m_q; } @@ -93,21 +93,21 @@ class PaillierPrivateKey { bool m_enable_crt; /** - * Compute L function in paillier paper + * Compute L function in paillier scheme * @param[in] a input a * @param[in] b input b */ BigNumber computeLfun(const BigNumber& a, const BigNumber& b); /** - * Compute H function in paillier paper + * Compute H function in paillier scheme * @param[in] a input a * @param[in] b input b */ BigNumber computeHfun(const BigNumber& a, const BigNumber& b); /** - * Compute CRT function in paillier paper + * Compute CRT function in paillier scheme * @param[in] mp input mp * @param[in] mq input mq */ diff --git a/ipcl/include/ipcl/paillier_pubkey.hpp b/ipcl/include/ipcl/paillier_pubkey.hpp index 054f1b1..f8ca988 100644 --- a/ipcl/include/ipcl/paillier_pubkey.hpp +++ b/ipcl/include/ipcl/paillier_pubkey.hpp @@ -9,8 +9,8 @@ class PaillierPublicKey { public: /** - * PaillierPublicKey construct function - * @param[in] n n of public key in paillier paper + * PaillierPublicKey constructor + * @param[in] n n of public key in paillier scheme * @param[in] bits bit length of public key * @param[in] enableDJN_ enables DJN scheme */ @@ -18,8 +18,8 @@ class PaillierPublicKey { bool enableDJN_ = false); /** - * PaillierPublicKey construct function - * @param[in] n n of public key in paillier paper + * PaillierPublicKey constructor + * @param[in] n n of public key in paillier scheme * @param[in] bits bit length of public key * @param[in] enableDJN_ enables DJN scheme */ @@ -35,7 +35,7 @@ class PaillierPublicKey { /** * Encrypt plaintext * @param[out] ciphertext output of the encryption - * @param[in] value array plaintext need to be encrypted + * @param[in] value array of plaintext to be encrypted * @param[in] make_secure apply obfuscator */ void encrypt(BigNumber ciphertext[8], const BigNumber value[8], @@ -44,7 +44,7 @@ class PaillierPublicKey { /** * Encrypt plaintext * @param[out] ciphertext output of the encryption - * @param[in] value plaintext need to be encrypted + * @param[in] value plaintext to be encrypted */ void encrypt(BigNumber& ciphertext, const BigNumber& value); @@ -75,17 +75,17 @@ class PaillierPublicKey { BigNumber IPP_invert(BigNumber a, BigNumber b); /** - * Get N of public key in paillier paper + * Get N of public key in paillier scheme */ BigNumber getN() const { return m_n; } /** - * Get NSQ of public key in paillier paper + * Get NSQ of public key in paillier scheme */ BigNumber getNSQ() const { return m_nsquare; } /** - * Get G of public key in paillier paper + * Get G of public key in paillier scheme */ BigNumber getG() const { return m_g; } @@ -140,7 +140,7 @@ class PaillierPublicKey { /** * Raw encrypt function * @param[out] ciphertext array output of the encryption - * @param[in] plaintext array plaintext need to be encrypted + * @param[in] plaintext plaintext array to be encrypted * @param[in] make_secure apply obfuscator */ void raw_encrypt(BigNumber ciphertext[8], const BigNumber plaintext[8], @@ -148,7 +148,7 @@ class PaillierPublicKey { /** * Get random value - * @param[in] length bit length of random + * @param[in] length bit length */ BigNumber getRandom(int length); }; From 03a8980b6e80a56d6a8af9fbe37139825be19ac6 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 28 Feb 2022 22:49:48 -0800 Subject: [PATCH 052/364] Initialize context with local CpaInstanceHandle variable (reverting to original impl). --- he_qat_context.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/he_qat_context.c b/he_qat_context.c index 1d859ec..5b9f7d3 100644 --- a/he_qat_context.c +++ b/he_qat_context.c @@ -41,7 +41,7 @@ HE_QAT_STATUS acquire_qat_devices() // Initialize QAT memory pool allocator status = qaeMemInit(); if (CPA_STATUS_SUCCESS != status) { - printf("Failed to initialized QAT memory.\n"); + printf("Failed to initialized memory driver.\n"); return HE_QAT_STATUS_FAIL; // HEQAT_STATUS_ERROR } #ifdef _DESTINY_DEBUG_VERBOSE @@ -62,16 +62,12 @@ HE_QAT_STATUS acquire_qat_devices() // Potential out-of-scope hazard for segmentation fault CpaInstanceHandle _inst_handle = NULL; // TODO: @fdiasmor Create a CyGetInstance that retrieves more than one. - //sampleCyGetInstance(&_inst_handle); - //if (_inst_handle == NULL) { - // printf("Failed to find QAT endpoints.\n"); - // return HE_QAT_STATUS_FAIL; - //} - sampleCyGetInstance(&handle); - if (handle == NULL) { + sampleCyGetInstance(&_inst_handle); + if (_inst_handle == NULL) { printf("Failed to find QAT endpoints.\n"); return HE_QAT_STATUS_FAIL; } + //sampleCyGetInstance(&handle); //if (handle == NULL) { // printf("Failed to find QAT endpoints.\n"); @@ -107,12 +103,12 @@ HE_QAT_STATUS acquire_qat_devices() he_qat_inst_config[i].active = 0; // HE_QAT_STATUS_INACTIVE he_qat_inst_config[i].polling = 0; // HE_QAT_STATUS_INACTIVE he_qat_inst_config[i].running = 0; - he_qat_inst_config[i].status = CPA_STATUS_FAIL; + he_qat_inst_config[i].status = CPA_STATUS_FAIL; // he_qat_inst_config[i].mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_init(&he_qat_inst_config[i].mutex,NULL); // he_qat_inst_config[i].ready = PTHREAD_COND_INITIALIZER; pthread_cond_init(&he_qat_inst_config[i].ready,NULL); - he_qat_inst_config[i].inst_handle = _inst_handle; + he_qat_inst_config[i].inst_handle = _inst_handle; he_qat_inst_config[i].attr = &he_qat_inst_attr[i]; pthread_create(&he_qat_instances[i], he_qat_inst_config[i].attr, start_perform_op, (void *) &he_qat_inst_config[i]); From 03371bde216e5dcac2abfd743ad5526ce9df0e05 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 28 Feb 2022 22:51:53 -0800 Subject: [PATCH 053/364] Add synchronous and blocking calls of variable batch size (default=1). --- he_qat_bn_ops.c | 75 ++++++++++++++++++++++++++++++++++--------------- he_qat_bn_ops.h | 6 +++- 2 files changed, 57 insertions(+), 24 deletions(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index f7f5ee1..b9b8c78 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -14,7 +14,6 @@ // Global buffer for the runtime environment HE_QAT_RequestBuffer he_qat_buffer; -//he_qat_buffer.count = 0; /// @brief /// @function @@ -27,29 +26,30 @@ static void lnModExpCallback(void *pCallbackTag, // This type can be variable { HE_QAT_TaskRequest *request = NULL; - //if (CPA_STATUS_SUCCESS != status) { - // // Update request status as an error (in pOpData) - // - // return ; - //} - // Check if input data for the op is available and do something if (NULL != pCallbackTag) { // Read request data request = (HE_QAT_TaskRequest *) pCallbackTag; // Collect the device output in pOut - request->op_status = status; - if (pOpData == &request->op_data) - // Mark request as complete or ready to be used - request->request_status = HE_QAT_READY; - else + if (CPA_STATUS_SUCCESS == status) { + if (pOpData == request->op_data) { +// printf("pOpData is same as input\n"); + // Mark request as complete or ready to be used + request->request_status = HE_QAT_READY; + + BIGNUM *r = BN_bin2bn(request->op_result.pData, request->op_result.dataLenInBytes, + (BIGNUM *) request->op_output); + } else { +// printf("pOpData is NOT same as input\n"); request->request_status = HE_QAT_STATUS_FAIL; - + } + } + // Make it synchronous and blocking + pthread_cond_signal(&request->ready); COMPLETE((struct COMPLETION_STRUCT *)&request->callback); } - // Asynchronous call needs to send wake-up signal to semaphore // if (NULL != pCallbackTag) { // COMPLETE((struct COMPLETION_STRUCT *)pCallbackTag); @@ -103,7 +103,7 @@ static HE_QAT_TaskRequest *read_request(HE_QAT_RequestBuffer *_buffer) //printf("[%02d]:",_buffer->next_data_slot); item = _buffer->data[_buffer->next_data_slot++]; - // make copy of request so that the buffer can be reused + // Asynchronous mode: Make copy of request so that the buffer can be reused _buffer->next_data_slot %= HE_QAT_BUFFER_SIZE; _buffer->count--; @@ -210,8 +210,7 @@ void *start_perform_op(void *_inst_config) config->active = 1; while (config->running) { // Try consume data from butter to perform requested operation - HE_QAT_TaskRequest *request = NULL; - // (HE_QAT_TaskRequest *) read_request(config->he_qat_buffer); + HE_QAT_TaskRequest *request = (HE_QAT_TaskRequest *) read_request(&he_qat_buffer); if (NULL == request) { pthread_cond_signal(&config->ready); @@ -226,6 +225,7 @@ void *start_perform_op(void *_inst_config) switch (request->op_type) { // Select appropriate action case HE_QAT_MODEXP: + // printf("Perform HE_QAT_MODEXP\n"); status = cpaCyLnModExp(config->inst_handle, lnModExpCallback, (void *) request, @@ -235,6 +235,7 @@ void *start_perform_op(void *_inst_config) break; case HE_QAT_NO_OP: default: +// printf("HE_QAT_NO_OP\n"); retry = HE_QAT_MAX_RETRY; break; } @@ -243,19 +244,25 @@ void *start_perform_op(void *_inst_config) // Ensure every call to perform operation is blocking for each endpoint if (CPA_STATUS_SUCCESS == status) { + //printf("Success at submission\n"); // Wait until the callback function has been called - if (0 != COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { + if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { request->op_status = CPA_STATUS_FAIL; request->request_status = HE_QAT_STATUS_FAIL; // Review it + printf("Failed in COMPLETION WAIT\n"); //request->request_status = HE_QAT_STATUS_INCOMPLETE; - } + } //else printf("Completed ModExp.\n"); + + + // Destroy synchronization object + COMPLETION_DESTROY(&request->callback); } // Wake up any blocked call to stop_perform_op, signaling that now it is // safe to terminate running instances. Check if this detereorate performance. pthread_cond_signal(&config->ready); - + // printf("Wake up stop_perform_op\n"); // Update the status of the request //request->op_status = status; //if (CPA_STATUS_SUCCESS != status) @@ -403,10 +410,15 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int return HE_QAT_STATUS_FAIL; } + request->op_type = HE_QAT_MODEXP; request->op_status = status; request->op_output = (void *) r; + + pthread_mutex_init(&request->mutex, NULL); + pthread_cond_init(&request->ready, NULL); // Submit request using producer function + //printf("Submit request \n"); submit_request(&he_qat_buffer, (void *) request); return HE_QAT_STATUS_SUCCESS; @@ -414,8 +426,22 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int // Maybe it will be useful to pass the number of requests to retrieve // Pass post-processing function as argument to bring output to expected type -void getBnModExpRequest() +void getBnModExpRequest(unsigned int batch_size) { + static unsigned int block_at_index = 0; + unsigned int j = 0; + do { + HE_QAT_TaskRequest *task = (HE_QAT_TaskRequest *) he_qat_buffer.data[block_at_index]; + pthread_mutex_lock(&task->mutex); + while (HE_QAT_READY != task->request_status) + pthread_cond_wait(&task->ready,&task->mutex); + pthread_mutex_unlock(&task->mutex); + block_at_index = (block_at_index+1)%HE_QAT_BUFFER_SIZE; + } while (++j < batch_size); + return; +} + +/* unsigned int finish = 0; // TODO: @fdiasmor Introduce global variable that record at which upcoming request it currently is while (0 == finish) { @@ -423,6 +449,8 @@ void getBnModExpRequest() for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE && finish; i++) { HE_QAT_TaskRequest *task = (HE_QAT_TaskRequest *) he_qat_buffer.data[i]; // TODO: @fdiasmor Check if not NULL before read. + if (NULL == task) continue; + finish = (HE_QAT_READY == task->request_status); if (finish) { // ? 1 : 0; // Set output results to original format @@ -439,12 +467,13 @@ void getBnModExpRequest() if (task->op_result.pData) { PHYS_CONTIG_FREE(task->op_result.pData); } - + // Destroy synchronization object COMPLETION_DESTROY(&task->callback); } } + // printf("getBnModExpRequest end\n"); } return ; } - +*/ diff --git a/he_qat_bn_ops.h b/he_qat_bn_ops.h index 5204b55..f759772 100644 --- a/he_qat_bn_ops.h +++ b/he_qat_bn_ops.h @@ -10,6 +10,7 @@ #include "he_qat_types.h" #include "cpa_sample_utils.h" +#include //#include #include @@ -29,6 +30,8 @@ typedef struct { void *op_data; void *op_output; HE_QAT_STATUS request_status; + pthread_mutex_t mutex; + pthread_cond_t ready; } HE_QAT_TaskRequest; @@ -60,7 +63,8 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int /// Releasing QAT temporary memory. // wait for all outstanding requests to complete -void getBnModExpRequest(); +//void getBnModExpRequest(); +void getBnModExpRequest(unsigned int num_requests); /// thus, releasing temporary memory. // create private buffer for code section // create QAT contiguous memory space From c76b07459f8d2647324c30882c61b90fc3c02847 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 28 Feb 2022 22:53:04 -0800 Subject: [PATCH 054/364] Add unit test to validate synchronous blocking call to bnModExpPerformOp with batch support. --- CMakeLists.txt | 5 + test_bnModExpPerformOp.c | 193 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 198 insertions(+) create mode 100644 test_bnModExpPerformOp.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 73719cc..4c8309e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,11 @@ target_link_libraries(test_context PUBLIC cpa_sample_utils) target_link_libraries(test_context PUBLIC z pthread crypto ssl crypto qat_s usdm_drv_s) +add_executable(test_bnModExpPerformOp test_bnModExpPerformOp.c) +target_link_libraries(test_bnModExpPerformOp PUBLIC he_qat) +target_link_libraries(test_bnModExpPerformOp PUBLIC cpa_sample_utils) +target_link_libraries(test_bnModExpPerformOp PUBLIC z pthread crypto ssl crypto qat_s usdm_drv_s) + # Compile test case #add_subdirectory(ln_mod_exp) diff --git a/test_bnModExpPerformOp.c b/test_bnModExpPerformOp.c new file mode 100644 index 0000000..13bce48 --- /dev/null +++ b/test_bnModExpPerformOp.c @@ -0,0 +1,193 @@ + +#include "cpa_sample_utils.h" + +#include "he_qat_bn_ops.h" +#include "he_qat_context.h" + +#include +#include +#include +#include + +#define LEN_OF_1024_BITS 128 +#define LEN_OF_2048_BITS 256 +#define msb_CAN_BE_ZERO -1 +#define msb_IS_ONE 0 +#define EVEN_RND_NUM 0 +#define ODD_RND_NUM 1 +#define BATCH_SIZE 1 + +int gDebugParam = 1; + + +BIGNUM *generateTestBNData(int nbits) +{ + if (!RAND_status()) + return NULL; +#ifdef _DESTINY_DEBUG_VERBOSE + printf("PRNG properly seeded.\n"); +#endif + + BIGNUM *bn = BN_new(); + + if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { + BN_free(bn); + printf("Error while generating BN random number: %lu\n",ERR_get_error()); + return NULL; + } + + return bn; +} + +unsigned char *paddingZeros(BIGNUM *bn, int nbits) +{ + if (!bn) return NULL; + + // Returns same address if it fails + int num_bytes = BN_num_bytes(bn); + int bytes_left = nbits/8 - num_bytes; + if (bytes_left <= 0) return NULL; + + // Returns same address if it fails + unsigned char *bin = NULL; + int len = bytes_left + num_bytes; + if (!(bin = OPENSSL_zalloc(len))) return NULL; + +#ifdef _DESTINY_DEBUG_VERBOSE + printf("Padding bn with %d bytes to total %d bytes\n",bytes_left,len); +#endif + BN_bn2binpad(bn,bin,len); + if (ERR_get_error()) { + OPENSSL_free(bin); + return NULL; + } + + return bin; +} + +void showHexBN(BIGNUM *bn, int nbits) +{ + int len = nbits / 8; + unsigned char *bin = OPENSSL_zalloc(len); + if (!bin) return ; + if (BN_bn2binpad(bn,bin,len)) { + for (size_t i = 0; i < len; i++) + printf("%d",bin[i]); + printf("\n"); + } + OPENSSL_free(bin); + return ; +} + +void showHexBin(unsigned char *bin, int len) +{ + if (!bin) return ; + for (size_t i = 0; i < len; i++) + printf("%d",bin[i]); + printf("\n"); + return ; +} + +int main(int argc, const char **argv) +{ + const size_t num_trials = 100; + const int bit_length = 1024; + + // Set up QAT runtime environment + acquire_qat_devices(); + + // OpenSSL as baseline + BN_CTX *ctx = BN_CTX_new(); + BN_CTX_start(ctx); + + CpaStatus status = CPA_STATUS_SUCCESS; + + for (size_t mod = 0; mod < num_trials; mod++) { + printf("Trial #%0.3lu\t",mod+1); + + BIGNUM *bn_mod = generateTestBNData(bit_length); + + if (!bn_mod) continue; + + char *bn_str = BN_bn2hex(bn_mod); +#ifdef _DESTINY_DEBUG_VERBOSE + printf("Generated modulus: %s num_bytes: %d num_bits: %d\n", + bn_str,BN_num_bytes(bn_mod),BN_num_bits(bn_mod)); +#endif + // bn_exponent in [0..bn_mod] + BIGNUM *bn_exponent = BN_new(); + if (!BN_rand_range(bn_exponent, bn_mod)) { + BN_free(bn_mod); + continue; + } + + BIGNUM *bn_base = generateTestBNData(bit_length); + + BIGNUM *ssl_res = BN_new(); + clock_t start = clock(); + BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); + clock_t elapsed = clock() - start; + + + //if (BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx)) { + if (!ERR_get_error()) { + bn_str = BN_bn2hex(ssl_res); +#ifdef _DESTINY_DEBUG_VERBOSE + printf("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", + bn_str, BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); + showHexBN(ssl_res, bit_length); +#endif + } else { + printf("Modular exponentiation failed.\n"); + } + +#ifdef _DESTINY_DEBUG_VERBOSE + PRINT_DBG("\nStarting QAT bnModExp...\n"); +#endif + + printf("OpenSSL: %.1lfus\t", elapsed / (CLOCKS_PER_SEC / 1000000.0)); + + BIGNUM *qat_res = BN_new(); + HE_QAT_STATUS he_qat_status = HE_QAT_STATUS_FAIL; + start = clock(); + for (unsigned int j = 0; j < BATCH_SIZE; j++) + he_qat_status = bnModExpPerformOp(qat_res, bn_base, bn_exponent, bn_mod, bit_length); + getBnModExpRequest(BATCH_SIZE); + elapsed = clock() - start; + + printf("QAT: %.1lfus\t", elapsed / (CLOCKS_PER_SEC / 1000000.0)); + + if (HE_QAT_STATUS_SUCCESS != he_qat_status) { + PRINT_ERR("\nQAT bnModExpOp failed\n"); + } +#ifdef _DESTINY_DEBUG_VERBOSE + else { + PRINT_DBG("\nQAT bnModExpOp finished\n"); + } +#endif + +// icp_sal_userStop(); +// qaeMemDestroy(); + + if (BN_cmp(qat_res, ssl_res) != 0) + printf("\t** FAIL **\n"); + else + printf("\t** PASS **\n"); + + OPENSSL_free(bn_str); + + BN_free(ssl_res); + BN_free(qat_res); + + BN_free(bn_mod); + BN_free(bn_base); + BN_free(bn_exponent); + } + + BN_CTX_end(ctx); + + // Tear down QAT runtime environment + release_qat_devices(); + + return (int)status; +} From 0957686cc3cf4c96d444236312c7c778febaca6d Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Wed, 2 Mar 2022 01:32:33 +0800 Subject: [PATCH 055/364] Code clean/refactor/optimize (#16) * Paillier key generation: clean/optimize code - Modify doxygen document - Change getNormalBN & getDJNBN to static - Add N_BIT_SIZE_MAX macro definition * Paillier key operation: clean/optimize code - Modify doxygen document - Rewrite function raw_mul * Paillier public key: clean/optimize code - Modify doxygen document - Rewrite function: randIpp32u, getRandom, apply_obfuscator, ippMultiBuffExp, ippMontExp * Paillier private key: clean/optimize code - Modify doxygen document - Rewrite function: decrpytRAW, decrypt, decryptCRT * Add namespace(ipcl) to Intel Paillier Crypto Lib --- benchmark/bench_cryptography.cpp | 114 +++++----- benchmark/bench_ops.cpp | 296 ++++++++++++------------ ipcl/bignum.cpp | 4 + ipcl/include/ipcl/bignum.h | 3 + ipcl/include/ipcl/paillier_keygen.hpp | 5 + ipcl/include/ipcl/paillier_ops.hpp | 8 +- ipcl/include/ipcl/paillier_prikey.hpp | 6 + ipcl/include/ipcl/paillier_pubkey.hpp | 24 +- ipcl/paillier_keygen.cpp | 16 +- ipcl/paillier_ops.cpp | 8 +- ipcl/paillier_prikey.cpp | 75 +++---- ipcl/paillier_pubkey.cpp | 178 +++++++++------ test/test_cryptography.cpp | 74 +++--- test/test_ops.cpp | 310 +++++++++++++------------- 14 files changed, 597 insertions(+), 524 deletions(-) diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index c59cae4..9d9bf46 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -13,22 +13,22 @@ static void BM_KeyGen(benchmark::State& state) { int64_t n_length = state.range(0); for (auto _ : state) { - keyPair key = generateKeypair(n_length, true); + ipcl::keyPair key = ipcl::generateKeypair(n_length, true); } } BENCHMARK(BM_KeyGen)->Unit(benchmark::kMicrosecond)->Args({1024})->Args({2048}); static void BM_Encrypt(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** pt = new BigNumber*[dsize]; - BigNumber** ct = new BigNumber*[dsize]; + ipcl::BigNumber** pt = new ipcl::BigNumber*[dsize]; + ipcl::BigNumber** ct = new ipcl::BigNumber*[dsize]; for (size_t i = 0; i < dsize; ++i) { - pt[i] = new BigNumber[8]; - ct[i] = new BigNumber[8]; - pt[i][0] = BigNumber((unsigned int)i); + pt[i] = new ipcl::BigNumber[8]; + ct[i] = new ipcl::BigNumber[8]; + pt[i][0] = ipcl::BigNumber((unsigned int)i); } for (auto _ : state) { @@ -48,16 +48,16 @@ BENCHMARK(BM_Encrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); static void BM_Encrypt_buff8(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** pt = new BigNumber*[dsize / 8]; - BigNumber** ct = new BigNumber*[dsize / 8]; + ipcl::BigNumber** pt = new ipcl::BigNumber*[dsize / 8]; + ipcl::BigNumber** ct = new ipcl::BigNumber*[dsize / 8]; for (size_t i = 0; i < dsize / 8; ++i) { - pt[i] = new BigNumber[8]; - ct[i] = new BigNumber[8]; + pt[i] = new ipcl::BigNumber[8]; + ct[i] = new ipcl::BigNumber[8]; for (size_t j = 0; j < 8; ++j) - pt[i][j] = BigNumber((unsigned int)(i * 8 + j)); + pt[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } for (auto _ : state) { @@ -79,16 +79,16 @@ BENCHMARK(BM_Encrypt_buff8) static void BM_Decrypt(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** pt = new BigNumber*[dsize]; - BigNumber** ct = new BigNumber*[dsize]; - BigNumber** de_ct = new BigNumber*[dsize]; + ipcl::BigNumber** pt = new ipcl::BigNumber*[dsize]; + ipcl::BigNumber** ct = new ipcl::BigNumber*[dsize]; + ipcl::BigNumber** de_ct = new ipcl::BigNumber*[dsize]; for (size_t i = 0; i < dsize; ++i) { - pt[i] = new BigNumber[8]; - ct[i] = new BigNumber[8]; - de_ct[i] = new BigNumber[8]; - pt[i][0] = BigNumber((unsigned int)i); + pt[i] = new ipcl::BigNumber[8]; + ct[i] = new ipcl::BigNumber[8]; + de_ct[i] = new ipcl::BigNumber[8]; + pt[i][0] = ipcl::BigNumber((unsigned int)i); } for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -114,18 +114,18 @@ BENCHMARK(BM_Decrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); static void BM_Decrypt_buff8(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** pt = new BigNumber*[dsize / 8]; - BigNumber** ct = new BigNumber*[dsize / 8]; - BigNumber** de_ct = new BigNumber*[dsize / 8]; + ipcl::BigNumber** pt = new ipcl::BigNumber*[dsize / 8]; + ipcl::BigNumber** ct = new ipcl::BigNumber*[dsize / 8]; + ipcl::BigNumber** de_ct = new ipcl::BigNumber*[dsize / 8]; for (size_t i = 0; i < dsize / 8; ++i) { - pt[i] = new BigNumber[8]; - ct[i] = new BigNumber[8]; - de_ct[i] = new BigNumber[8]; + pt[i] = new ipcl::BigNumber[8]; + ct[i] = new ipcl::BigNumber[8]; + de_ct[i] = new ipcl::BigNumber[8]; for (size_t j = 0; j < 8; ++j) - pt[i][j] = BigNumber((unsigned int)(i * 8 + j)); + pt[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -153,15 +153,15 @@ BENCHMARK(BM_Decrypt_buff8) #ifdef IPCL_BENCHMARK_OMP static void BM_Encrypt_OMP(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** pt = new BigNumber*[dsize]; - BigNumber** ct = new BigNumber*[dsize]; + ipcl::BigNumber** pt = new ipcl::BigNumber*[dsize]; + ipcl::BigNumber** ct = new ipcl::BigNumber*[dsize]; for (size_t i = 0; i < dsize; ++i) { - pt[i] = new BigNumber[8]; - ct[i] = new BigNumber[8]; - pt[i][0] = BigNumber((unsigned int)i); + pt[i] = new ipcl::BigNumber[8]; + ct[i] = new ipcl::BigNumber[8]; + pt[i][0] = ipcl::BigNumber((unsigned int)i); } for (auto _ : state) { @@ -184,16 +184,16 @@ BENCHMARK(BM_Encrypt_OMP) static void BM_Encrypt_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** pt = new BigNumber*[dsize / 8]; - BigNumber** ct = new BigNumber*[dsize / 8]; + ipcl::BigNumber** pt = new ipcl::BigNumber*[dsize / 8]; + ipcl::BigNumber** ct = new ipcl::BigNumber*[dsize / 8]; for (size_t i = 0; i < dsize / 8; ++i) { - pt[i] = new BigNumber[8]; - ct[i] = new BigNumber[8]; + pt[i] = new ipcl::BigNumber[8]; + ct[i] = new ipcl::BigNumber[8]; for (size_t j = 0; j < 8; ++j) - pt[i][j] = BigNumber((unsigned int)(i * 8 + j)); + pt[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } for (auto _ : state) { @@ -216,16 +216,16 @@ BENCHMARK(BM_Encrypt_buff8_OMP) static void BM_Decrypt_OMP(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** pt = new BigNumber*[dsize]; - BigNumber** ct = new BigNumber*[dsize]; - BigNumber** de_ct = new BigNumber*[dsize]; + ipcl::BigNumber** pt = new ipcl::BigNumber*[dsize]; + ipcl::BigNumber** ct = new ipcl::BigNumber*[dsize]; + ipcl::BigNumber** de_ct = new ipcl::BigNumber*[dsize]; for (size_t i = 0; i < dsize; ++i) { - pt[i] = new BigNumber[8]; - ct[i] = new BigNumber[8]; - de_ct[i] = new BigNumber[8]; - pt[i][0] = BigNumber((unsigned int)i); + pt[i] = new ipcl::BigNumber[8]; + ct[i] = new ipcl::BigNumber[8]; + de_ct[i] = new ipcl::BigNumber[8]; + pt[i][0] = ipcl::BigNumber((unsigned int)i); } for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -255,18 +255,18 @@ BENCHMARK(BM_Decrypt_OMP) static void BM_Decrypt_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** pt = new BigNumber*[dsize / 8]; - BigNumber** ct = new BigNumber*[dsize / 8]; - BigNumber** de_ct = new BigNumber*[dsize / 8]; + ipcl::BigNumber** pt = new ipcl::BigNumber*[dsize / 8]; + ipcl::BigNumber** ct = new ipcl::BigNumber*[dsize / 8]; + ipcl::BigNumber** de_ct = new ipcl::BigNumber*[dsize / 8]; for (size_t i = 0; i < dsize / 8; ++i) { - pt[i] = new BigNumber[8]; - ct[i] = new BigNumber[8]; - de_ct[i] = new BigNumber[8]; + pt[i] = new ipcl::BigNumber[8]; + ct[i] = new ipcl::BigNumber[8]; + de_ct[i] = new ipcl::BigNumber[8]; for (size_t j = 0; j < 8; ++j) - pt[i][j] = BigNumber((unsigned int)(i * 8 + j)); + pt[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index 542ed0d..ed69e69 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -14,30 +14,30 @@ static void BM_Add_CTCT(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize]; - BigNumber** b = new BigNumber*[dsize]; - BigNumber** ct_a = new BigNumber*[dsize]; - BigNumber** ct_b = new BigNumber*[dsize]; + ipcl::BigNumber** a = new ipcl::BigNumber*[dsize]; + ipcl::BigNumber** b = new ipcl::BigNumber*[dsize]; + ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize]; + ipcl::BigNumber** ct_b = new ipcl::BigNumber*[dsize]; for (size_t i = 0; i < dsize; ++i) { - a[i] = new BigNumber[8]; - a[i][0] = BigNumber((unsigned int)i); - ct_a[i] = new BigNumber[8]; + a[i] = new ipcl::BigNumber[8]; + a[i][0] = ipcl::BigNumber((unsigned int)i); + ct_a[i] = new ipcl::BigNumber[8]; key.pub_key->encrypt(ct_a[i], a[i]); - b[i] = new BigNumber[8]; - b[i][0] = BigNumber((unsigned int)i); - ct_b[i] = new BigNumber[8]; + b[i] = new ipcl::BigNumber[8]; + b[i][0] = ipcl::BigNumber((unsigned int)i); + ct_b[i] = new ipcl::BigNumber[8]; key.pub_key->encrypt(ct_b[i], b[i]); } for (auto _ : state) { for (size_t i = 0; i < dsize; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); - PaillierEncryptedNumber sum = pen_a + pen_b; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); + ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; } } @@ -58,22 +58,22 @@ BENCHMARK(BM_Add_CTCT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); static void BM_Add_CTCT_buff8(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize / 8]; - BigNumber** b = new BigNumber*[dsize / 8]; - BigNumber** ct_a = new BigNumber*[dsize / 8]; - BigNumber** ct_b = new BigNumber*[dsize / 8]; + ipcl::BigNumber** a = new ipcl::BigNumber*[dsize / 8]; + ipcl::BigNumber** b = new ipcl::BigNumber*[dsize / 8]; + ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize / 8]; + ipcl::BigNumber** ct_b = new ipcl::BigNumber*[dsize / 8]; for (size_t i = 0; i < dsize / 8; ++i) { - a[i] = new BigNumber[8]; - ct_a[i] = new BigNumber[8]; + a[i] = new ipcl::BigNumber[8]; + ct_a[i] = new ipcl::BigNumber[8]; - b[i] = new BigNumber[8]; - ct_b[i] = new BigNumber[8]; + b[i] = new ipcl::BigNumber[8]; + ct_b[i] = new ipcl::BigNumber[8]; for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -82,9 +82,9 @@ static void BM_Add_CTCT_buff8(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize / 8; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); - PaillierEncryptedNumber sum = pen_a + pen_b; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); + ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; } } @@ -108,25 +108,25 @@ BENCHMARK(BM_Add_CTCT_buff8) static void BM_Add_CTPT(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize]; - BigNumber** ct_a = new BigNumber*[dsize]; - BigNumber** b = new BigNumber*[dsize]; + ipcl::BigNumber** a = new ipcl::BigNumber*[dsize]; + ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize]; + ipcl::BigNumber** b = new ipcl::BigNumber*[dsize]; for (size_t i = 0; i < dsize; ++i) { - a[i] = new BigNumber[8]; - a[i][0] = BigNumber((unsigned int)i); - ct_a[i] = new BigNumber[8]; - b[i] = new BigNumber[8]; - b[i][0] = BigNumber((unsigned int)i); + a[i] = new ipcl::BigNumber[8]; + a[i][0] = ipcl::BigNumber((unsigned int)i); + ct_a[i] = new ipcl::BigNumber[8]; + b[i] = new ipcl::BigNumber[8]; + b[i][0] = ipcl::BigNumber((unsigned int)i); key.pub_key->encrypt(ct_a[i], a[i]); } for (auto _ : state) { for (size_t i = 0; i < dsize; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber sum = pen_a + b[i]; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; } } @@ -145,20 +145,20 @@ BENCHMARK(BM_Add_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); static void BM_Add_CTPT_buff8(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize / 8]; - BigNumber** b = new BigNumber*[dsize / 8]; - BigNumber** ct_a = new BigNumber*[dsize / 8]; + ipcl::BigNumber** a = new ipcl::BigNumber*[dsize / 8]; + ipcl::BigNumber** b = new ipcl::BigNumber*[dsize / 8]; + ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize / 8]; for (size_t i = 0; i < dsize / 8; ++i) { - a[i] = new BigNumber[8]; - ct_a[i] = new BigNumber[8]; + a[i] = new ipcl::BigNumber[8]; + ct_a[i] = new ipcl::BigNumber[8]; - b[i] = new BigNumber[8]; + b[i] = new ipcl::BigNumber[8]; for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -166,8 +166,8 @@ static void BM_Add_CTPT_buff8(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize / 8; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber sum = pen_a + b[i]; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; } } @@ -189,26 +189,26 @@ BENCHMARK(BM_Add_CTPT_buff8) static void BM_Mul_CTPT(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize]; - BigNumber** ct_a = new BigNumber*[dsize]; - BigNumber** b = new BigNumber*[dsize]; + ipcl::BigNumber** a = new ipcl::BigNumber*[dsize]; + ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize]; + ipcl::BigNumber** b = new ipcl::BigNumber*[dsize]; for (size_t i = 0; i < dsize; ++i) { - a[i] = new BigNumber[8]; - a[i][0] = BigNumber((unsigned int)i); - ct_a[i] = new BigNumber[8]; - b[i] = new BigNumber[8]; - b[i][0] = BigNumber((unsigned int)i); + a[i] = new ipcl::BigNumber[8]; + a[i][0] = ipcl::BigNumber((unsigned int)i); + ct_a[i] = new ipcl::BigNumber[8]; + b[i] = new ipcl::BigNumber[8]; + b[i][0] = ipcl::BigNumber((unsigned int)i); key.pub_key->encrypt(ct_a[i], a[i]); } for (auto _ : state) { for (size_t i = 0; i < dsize; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber pen_b(key.pub_key, b[i]); - PaillierEncryptedNumber sum = pen_a * pen_b; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber pen_b(key.pub_key, b[i]); + ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; } } @@ -227,20 +227,20 @@ BENCHMARK(BM_Mul_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); static void BM_Mul_CTPT_buff8(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize / 8]; - BigNumber** b = new BigNumber*[dsize / 8]; - BigNumber** ct_a = new BigNumber*[dsize / 8]; + ipcl::BigNumber** a = new ipcl::BigNumber*[dsize / 8]; + ipcl::BigNumber** b = new ipcl::BigNumber*[dsize / 8]; + ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize / 8]; for (size_t i = 0; i < dsize / 8; ++i) { - a[i] = new BigNumber[8]; - ct_a[i] = new BigNumber[8]; + a[i] = new ipcl::BigNumber[8]; + ct_a[i] = new ipcl::BigNumber[8]; - b[i] = new BigNumber[8]; + b[i] = new ipcl::BigNumber[8]; for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -248,9 +248,9 @@ static void BM_Mul_CTPT_buff8(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize / 8; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber pen_b(key.pub_key, b[i]); - PaillierEncryptedNumber sum = pen_a * pen_b; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber pen_b(key.pub_key, b[i]); + ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; } } @@ -273,31 +273,31 @@ BENCHMARK(BM_Mul_CTPT_buff8) #ifdef IPCL_BENCHMARK_OMP static void BM_Add_CTCT_OMP(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize]; - BigNumber** b = new BigNumber*[dsize]; - BigNumber** ct_a = new BigNumber*[dsize]; - BigNumber** ct_b = new BigNumber*[dsize]; + ipcl::BigNumber** a = new ipcl::BigNumber*[dsize]; + ipcl::BigNumber** b = new ipcl::BigNumber*[dsize]; + ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize]; + ipcl::BigNumber** ct_b = new ipcl::BigNumber*[dsize]; for (size_t i = 0; i < dsize; ++i) { - a[i] = new BigNumber[8]; - a[i][0] = BigNumber((unsigned int)i); - ct_a[i] = new BigNumber[8]; + a[i] = new ipcl::BigNumber[8]; + a[i][0] = ipcl::BigNumber((unsigned int)i); + ct_a[i] = new ipcl::BigNumber[8]; key.pub_key->encrypt(ct_a[i], a[i]); - b[i] = new BigNumber[8]; - b[i][0] = BigNumber((unsigned int)i); - ct_b[i] = new BigNumber[8]; + b[i] = new ipcl::BigNumber[8]; + b[i][0] = ipcl::BigNumber((unsigned int)i); + ct_b[i] = new ipcl::BigNumber[8]; key.pub_key->encrypt(ct_b[i], b[i]); } for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); - PaillierEncryptedNumber sum = pen_a + pen_b; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); + ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; } } @@ -321,22 +321,22 @@ BENCHMARK(BM_Add_CTCT_OMP) static void BM_Add_CTCT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize / 8]; - BigNumber** b = new BigNumber*[dsize / 8]; - BigNumber** ct_a = new BigNumber*[dsize / 8]; - BigNumber** ct_b = new BigNumber*[dsize / 8]; + ipcl::BigNumber** a = new ipcl::BigNumber*[dsize / 8]; + ipcl::BigNumber** b = new ipcl::BigNumber*[dsize / 8]; + ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize / 8]; + ipcl::BigNumber** ct_b = new ipcl::BigNumber*[dsize / 8]; for (size_t i = 0; i < dsize / 8; ++i) { - a[i] = new BigNumber[8]; - ct_a[i] = new BigNumber[8]; + a[i] = new ipcl::BigNumber[8]; + ct_a[i] = new ipcl::BigNumber[8]; - b[i] = new BigNumber[8]; - ct_b[i] = new BigNumber[8]; + b[i] = new ipcl::BigNumber[8]; + ct_b[i] = new ipcl::BigNumber[8]; for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -346,9 +346,9 @@ static void BM_Add_CTCT_buff8_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize / 8; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); - PaillierEncryptedNumber sum = pen_a + pen_b; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); + ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; } } @@ -372,26 +372,26 @@ BENCHMARK(BM_Add_CTCT_buff8_OMP) static void BM_Add_CTPT_OMP(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize]; - BigNumber** ct_a = new BigNumber*[dsize]; - BigNumber** b = new BigNumber*[dsize]; + ipcl::BigNumber** a = new ipcl::BigNumber*[dsize]; + ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize]; + ipcl::BigNumber** b = new ipcl::BigNumber*[dsize]; for (size_t i = 0; i < dsize; ++i) { - a[i] = new BigNumber[8]; - a[i][0] = BigNumber((unsigned int)i); - ct_a[i] = new BigNumber[8]; - b[i] = new BigNumber[8]; - b[i][0] = BigNumber((unsigned int)i); + a[i] = new ipcl::BigNumber[8]; + a[i][0] = ipcl::BigNumber((unsigned int)i); + ct_a[i] = new ipcl::BigNumber[8]; + b[i] = new ipcl::BigNumber[8]; + b[i][0] = ipcl::BigNumber((unsigned int)i); key.pub_key->encrypt(ct_a[i], a[i]); } for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber sum = pen_a + b[i]; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; } } @@ -413,20 +413,20 @@ BENCHMARK(BM_Add_CTPT_OMP) static void BM_Add_CTPT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize / 8]; - BigNumber** b = new BigNumber*[dsize / 8]; - BigNumber** ct_a = new BigNumber*[dsize / 8]; + ipcl::BigNumber** a = new ipcl::BigNumber*[dsize / 8]; + ipcl::BigNumber** b = new ipcl::BigNumber*[dsize / 8]; + ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize / 8]; for (size_t i = 0; i < dsize / 8; ++i) { - a[i] = new BigNumber[8]; - ct_a[i] = new BigNumber[8]; + a[i] = new ipcl::BigNumber[8]; + ct_a[i] = new ipcl::BigNumber[8]; - b[i] = new BigNumber[8]; + b[i] = new ipcl::BigNumber[8]; for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -435,8 +435,8 @@ static void BM_Add_CTPT_buff8_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize / 8; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber sum = pen_a + b[i]; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; } } @@ -458,27 +458,27 @@ BENCHMARK(BM_Add_CTPT_buff8_OMP) static void BM_Mul_CTPT_OMP(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize]; - BigNumber** ct_a = new BigNumber*[dsize]; - BigNumber** b = new BigNumber*[dsize]; + ipcl::BigNumber** a = new ipcl::BigNumber*[dsize]; + ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize]; + ipcl::BigNumber** b = new ipcl::BigNumber*[dsize]; for (size_t i = 0; i < dsize; ++i) { - a[i] = new BigNumber[8]; - a[i][0] = BigNumber((unsigned int)i); - ct_a[i] = new BigNumber[8]; - b[i] = new BigNumber[8]; - b[i][0] = BigNumber((unsigned int)i); + a[i] = new ipcl::BigNumber[8]; + a[i][0] = ipcl::BigNumber((unsigned int)i); + ct_a[i] = new ipcl::BigNumber[8]; + b[i] = new ipcl::BigNumber[8]; + b[i][0] = ipcl::BigNumber((unsigned int)i); key.pub_key->encrypt(ct_a[i], a[i]); } for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber pen_b(key.pub_key, b[i]); - PaillierEncryptedNumber sum = pen_a * pen_b; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber pen_b(key.pub_key, b[i]); + ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; } } @@ -500,20 +500,20 @@ BENCHMARK(BM_Mul_CTPT_OMP) static void BM_Mul_CTPT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize / 8]; - BigNumber** b = new BigNumber*[dsize / 8]; - BigNumber** ct_a = new BigNumber*[dsize / 8]; + ipcl::BigNumber** a = new ipcl::BigNumber*[dsize / 8]; + ipcl::BigNumber** b = new ipcl::BigNumber*[dsize / 8]; + ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize / 8]; for (size_t i = 0; i < dsize / 8; ++i) { - a[i] = new BigNumber[8]; - ct_a[i] = new BigNumber[8]; + a[i] = new ipcl::BigNumber[8]; + ct_a[i] = new ipcl::BigNumber[8]; - b[i] = new BigNumber[8]; + b[i] = new ipcl::BigNumber[8]; for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -522,9 +522,9 @@ static void BM_Mul_CTPT_buff8_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize / 8; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber pen_b(key.pub_key, b[i]); - PaillierEncryptedNumber sum = pen_a * pen_b; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber pen_b(key.pub_key, b[i]); + ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; } } diff --git a/ipcl/bignum.cpp b/ipcl/bignum.cpp index 537ca1d..f121d98 100644 --- a/ipcl/bignum.cpp +++ b/ipcl/bignum.cpp @@ -25,6 +25,8 @@ // ////////////////////////////////////////////////////////////////////// +namespace ipcl { + BigNumber::~BigNumber() { delete[](Ipp8u*) m_pBN; } bool BigNumber::create(const Ipp32u* pData, int length, IppsBigNumSGN sgn) { @@ -498,3 +500,5 @@ std::ostream& operator<<(std::ostream& os, const BigNumber& a) { os << s; return os; } + +} // namespace ipcl diff --git a/ipcl/include/ipcl/bignum.h b/ipcl/include/ipcl/bignum.h index 8645bef..d2eadd4 100644 --- a/ipcl/include/ipcl/bignum.h +++ b/ipcl/include/ipcl/bignum.h @@ -22,6 +22,8 @@ #include #include +namespace ipcl { + class BigNumber { public: BigNumber(Ipp32u value = 0); @@ -131,4 +133,5 @@ class BigNumber { // Bin: convert bit size into 64-bit words #define BITSIZE_DWORD(n) ((((n) + 63) >> 6)) +} // namespace ipcl #endif // _BIGNUM_H_ diff --git a/ipcl/include/ipcl/paillier_keygen.hpp b/ipcl/include/ipcl/paillier_keygen.hpp index 8a70c5b..98f154c 100644 --- a/ipcl/include/ipcl/paillier_keygen.hpp +++ b/ipcl/include/ipcl/paillier_keygen.hpp @@ -7,6 +7,8 @@ #include "ipcl/paillier_prikey.hpp" #include "ipcl/paillier_pubkey.hpp" +namespace ipcl { + /** * Paillier key structure contains a public key and private key * pub_key: paillier public key @@ -20,6 +22,7 @@ struct keyPair { /** * Generate prime number * @param[in] maxBitSize Maximum bit length of to be generated prime number + * @return The function return a prime big number */ BigNumber getPrimeBN(int maxBitSize); @@ -27,7 +30,9 @@ BigNumber getPrimeBN(int maxBitSize); * Generate a public/private key pair * @param[in] n_length Bit length of key size * @param[in] enable_DJN Enable DJN (default=true) + * @return The function return the public and private key pair */ keyPair generateKeypair(int64_t n_length, bool enable_DJN = true); +} // namespace ipcl #endif // IPCL_INCLUDE_IPCL_PAILLIER_KEYGEN_HPP_ diff --git a/ipcl/include/ipcl/paillier_ops.hpp b/ipcl/include/ipcl/paillier_ops.hpp index b2971e4..9590579 100644 --- a/ipcl/include/ipcl/paillier_ops.hpp +++ b/ipcl/include/ipcl/paillier_ops.hpp @@ -8,6 +8,8 @@ #include "ipcl/paillier_pubkey.hpp" +namespace ipcl { + class PaillierEncryptedNumber { public: /** @@ -21,7 +23,7 @@ class PaillierEncryptedNumber { * PaillierEncryptedNumber constructor * @param[in] pub_key paillier public key * @param[in] bn array of ciphertexts encrypted by paillier public key - * @param[in] length size of array + * @param[in] length size of array(default value is 8) */ PaillierEncryptedNumber(PaillierPublicKey* pub_key, const BigNumber bn[8], size_t length = 8); @@ -30,7 +32,7 @@ class PaillierEncryptedNumber { * PaillierEncryptedNumber constructor * @param[in] pub_key paillier public key * @param[in] scalar array of integer scalars - * @param[in] length size of array + * @param[in] length size of array(default value is 8) */ PaillierEncryptedNumber(PaillierPublicKey* pub_key, const uint32_t scalar[8], size_t length = 8); @@ -82,6 +84,7 @@ class PaillierEncryptedNumber { /** * Return ciphertext * @param[in] idx index of ciphertext stored in PaillierEncryptedNumber + * @param[in] idx index of output array(default value is 0) */ BigNumber getBN(size_t idx = 0) const { if (m_available == 1 && idx > 0) @@ -131,4 +134,5 @@ class PaillierEncryptedNumber { void raw_mul(BigNumber res[8], BigNumber a[8], BigNumber b[8]); }; +} // namespace ipcl #endif // IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ diff --git a/ipcl/include/ipcl/paillier_prikey.hpp b/ipcl/include/ipcl/paillier_prikey.hpp index 44c6021..6794914 100644 --- a/ipcl/include/ipcl/paillier_prikey.hpp +++ b/ipcl/include/ipcl/paillier_prikey.hpp @@ -6,6 +6,8 @@ #include "ipcl/paillier_ops.hpp" +namespace ipcl { + class PaillierPrivateKey { public: /** @@ -96,6 +98,7 @@ class PaillierPrivateKey { * Compute L function in paillier scheme * @param[in] a input a * @param[in] b input b + * @return the L function result of type BigNumber */ BigNumber computeLfun(const BigNumber& a, const BigNumber& b); @@ -103,6 +106,7 @@ class PaillierPrivateKey { * Compute H function in paillier scheme * @param[in] a input a * @param[in] b input b + * @return the H function result of type BigNumber */ BigNumber computeHfun(const BigNumber& a, const BigNumber& b); @@ -110,6 +114,7 @@ class PaillierPrivateKey { * Compute CRT function in paillier scheme * @param[in] mp input mp * @param[in] mq input mq + * @return the CRT result of type BigNumber */ BigNumber computeCRT(const BigNumber& mp, const BigNumber& mq); @@ -128,4 +133,5 @@ class PaillierPrivateKey { void decryptCRT(BigNumber plaintext[8], const BigNumber ciphertext[8]); }; +} // namespace ipcl #endif // IPCL_INCLUDE_IPCL_PAILLIER_PRIKEY_HPP_ diff --git a/ipcl/include/ipcl/paillier_pubkey.hpp b/ipcl/include/ipcl/paillier_pubkey.hpp index f8ca988..d18a228 100644 --- a/ipcl/include/ipcl/paillier_pubkey.hpp +++ b/ipcl/include/ipcl/paillier_pubkey.hpp @@ -4,15 +4,19 @@ #ifndef IPCL_INCLUDE_IPCL_PAILLIER_PUBKEY_HPP_ #define IPCL_INCLUDE_IPCL_PAILLIER_PUBKEY_HPP_ +#include + #include "ipcl/bignum.h" +namespace ipcl { + class PaillierPublicKey { public: /** * PaillierPublicKey constructor * @param[in] n n of public key in paillier scheme - * @param[in] bits bit length of public key - * @param[in] enableDJN_ enables DJN scheme + * @param[in] bits bit length of public key(default value is 1024) + * @param[in] enableDJN_ enables DJN scheme(default value is false) */ explicit PaillierPublicKey(const BigNumber& n, int bits = 1024, bool enableDJN_ = false); @@ -20,8 +24,8 @@ class PaillierPublicKey { /** * PaillierPublicKey constructor * @param[in] n n of public key in paillier scheme - * @param[in] bits bit length of public key - * @param[in] enableDJN_ enables DJN scheme + * @param[in] bits bit length of public key(default value is 1024) + * @param[in] enableDJN_ enables DJN scheme(default value is false) */ explicit PaillierPublicKey(const Ipp32u n, int bits = 1024, bool enableDJN_ = false) @@ -36,7 +40,7 @@ class PaillierPublicKey { * Encrypt plaintext * @param[out] ciphertext output of the encryption * @param[in] value array of plaintext to be encrypted - * @param[in] make_secure apply obfuscator + * @param[in] make_secure apply obfuscator(default value is true) */ void encrypt(BigNumber ciphertext[8], const BigNumber value[8], bool make_secure = true); @@ -53,6 +57,7 @@ class PaillierPublicKey { * @param[in] base base of the exponentiation * @param[in] pow pow of the exponentiation * @param[in] m modular + * @return the modular exponentiation result of type BigNumber */ BigNumber ippMontExp(const BigNumber& base, const BigNumber& pow, const BigNumber& m); @@ -71,6 +76,7 @@ class PaillierPublicKey { * Invert function needed by encoder(float to integer) * @param[in] a input of a * @param[in] b input of b + * @return the invert result of type BigNumber */ BigNumber IPP_invert(BigNumber a, BigNumber b); @@ -132,16 +138,16 @@ class PaillierPublicKey { /** * Get random value - * @param[in] addr addr of random + * @param[in,out] addr addr of random * @param[in] size size of random */ - Ipp32u* randIpp32u(Ipp32u* addr, int size); + void randIpp32u(std::vector& addr, int size); /** * Raw encrypt function * @param[out] ciphertext array output of the encryption * @param[in] plaintext plaintext array to be encrypted - * @param[in] make_secure apply obfuscator + * @param[in] make_secure apply obfuscator(default value is true) */ void raw_encrypt(BigNumber ciphertext[8], const BigNumber plaintext[8], bool make_secure = true); @@ -149,8 +155,10 @@ class PaillierPublicKey { /** * Get random value * @param[in] length bit length + * @return the random value of type BigNumber */ BigNumber getRandom(int length); }; +} // namespace ipcl #endif // IPCL_INCLUDE_IPCL_PAILLIER_PUBKEY_HPP_ diff --git a/ipcl/paillier_keygen.cpp b/ipcl/paillier_keygen.cpp index 3acddbf..777c86c 100644 --- a/ipcl/paillier_keygen.cpp +++ b/ipcl/paillier_keygen.cpp @@ -7,6 +7,10 @@ #include #include +namespace ipcl { + +#define N_BIT_SIZE_MAX 2048 + static inline void rand32u(std::vector& addr) { std::random_device dev; std::mt19937 rng(dev()); @@ -46,8 +50,8 @@ BigNumber getPrimeBN(int maxBitSize) { return pBN; } -inline void getNormalBN(int64_t n_length, BigNumber& p, BigNumber& q, - BigNumber& n) { +static inline void getNormalBN(int64_t n_length, BigNumber& p, BigNumber& q, + BigNumber& n) { for (int64_t len = 0; len != n_length; len = n.BitSize()) { p = getPrimeBN(n_length / 2); q = p; @@ -58,8 +62,8 @@ inline void getNormalBN(int64_t n_length, BigNumber& p, BigNumber& q, } } -inline void getDJNBN(int64_t n_length, BigNumber& p, BigNumber& q, - BigNumber& n) { +static inline void getDJNBN(int64_t n_length, BigNumber& p, BigNumber& q, + BigNumber& n) { BigNumber gcd; do { do { @@ -83,7 +87,7 @@ keyPair generateKeypair(int64_t n_length, bool enable_DJN) { https://www.intel.com/content/www/us/en/develop/documentation/ipp-crypto-reference/top/multi-buffer-cryptography-functions/modular-exponentiation/mbx-exp-1024-2048-3072-4096-mb8.html modulus size = n * n (keySize * keySize ) */ - if (n_length > 2048) { + if (n_length > N_BIT_SIZE_MAX) { throw std::runtime_error( "modulus size in bits should belong to either 1Kb, 2Kb, " "3Kb or 4Kb range only, key size exceed the range!!!"); @@ -102,3 +106,5 @@ keyPair generateKeypair(int64_t n_length, bool enable_DJN) { return keyPair{public_key, private_key}; } + +} // namespace ipcl diff --git a/ipcl/paillier_ops.cpp b/ipcl/paillier_ops.cpp index 600a0b2..b3f69b1 100644 --- a/ipcl/paillier_ops.cpp +++ b/ipcl/paillier_ops.cpp @@ -5,6 +5,7 @@ #include +namespace ipcl { // constructors // PaillierEncryptedNumber::PaillierEncryptedNumber(PaillierPublicKey* pub_key, @@ -118,9 +119,8 @@ BigNumber PaillierEncryptedNumber::raw_add(const BigNumber& a, void PaillierEncryptedNumber::raw_mul(BigNumber res[8], BigNumber a[8], BigNumber b[8]) { - BigNumber sq[8]; - for (int i = 0; i < 8; i++) sq[i] = m_pubkey->getNSQ(); - m_pubkey->ippMultiBuffExp(res, a, b, sq); + std::vector sq(8, m_pubkey->getNSQ()); + m_pubkey->ippMultiBuffExp(res, a, b, sq.data()); } BigNumber PaillierEncryptedNumber::raw_mul(const BigNumber& a, @@ -149,3 +149,5 @@ PaillierEncryptedNumber PaillierEncryptedNumber::rotate(int shift) { std::rotate(std::begin(new_bn), std::begin(new_bn) + shift, std::end(new_bn)); return PaillierEncryptedNumber(m_pubkey, new_bn); } + +} // namespace ipcl diff --git a/ipcl/paillier_prikey.cpp b/ipcl/paillier_prikey.cpp index bcce535..464e4fd 100644 --- a/ipcl/paillier_prikey.cpp +++ b/ipcl/paillier_prikey.cpp @@ -7,10 +7,12 @@ #include +namespace ipcl { /** * Compute lcm for p and q * @param[in] p p - 1 of private key * @param[in] q q - 1 of private key + * @return the lcm result of type BigNumber */ static inline BigNumber lcm(const BigNumber& p, const BigNumber& q) { BigNumber gcd(p); @@ -56,54 +58,56 @@ void PaillierPrivateKey::decryptRAW(BigNumber plaintext[8], const BigNumber ciphertext[8]) { mbx_status st = MBX_STATUS_OK; - Ipp64u* out_m[8]; - int64u* cip_array[8]; - - int bufferLen; - Ipp8u* pBuffer; - // setup buffer for mbx_exp - bufferLen = mbx_exp_BufferSize(m_bits * 2); - pBuffer = reinterpret_cast(alloca(bufferLen)); - if (nullptr == pBuffer) throw std::runtime_error("error alloc memory"); + int bufferLen = mbx_exp_BufferSize(m_bits * 2); + auto pBuffer = std::vector(bufferLen); + std::vector out_m(8), cip_array(8); int length = m_dwords * sizeof(int64u); + for (int i = 0; i < 8; i++) { out_m[i] = reinterpret_cast(alloca(length)); cip_array[i] = reinterpret_cast(alloca(length)); - if (nullptr == out_m[i] || nullptr == cip_array[i]) - throw std::runtime_error("error alloc memory"); - } + if (out_m[i] == nullptr || cip_array[i] == nullptr) + throw std::runtime_error("decryptRAW: alloc memory for error"); - for (int i = 0; i < 8; i++) memset(cip_array[i], 0, m_dwords * 8); + memset(out_m[i], 0, length); + memset(cip_array[i], 0, length); + } // TODO(bwang30): add multi-buffered modular exponentiation - Ipp32u *pow_c[8], *pow_lambda[8], *pow_nsquare[8], *pow_qsquare[8]; + std::vector pow_c(8), pow_nsquare(8), pow_lambda(8); + int cBitLen, lBitLen, nsqBitLen; BigNumber lambda = m_lambda; + for (int i = 0; i < 8; i++) { - ippsRef_BN(nullptr, &cBitLen, &pow_c[i], ciphertext[i]); + ippsRef_BN(nullptr, &cBitLen, reinterpret_cast(&pow_c[i]), + ciphertext[i]); ippsRef_BN(nullptr, &lBitLen, &pow_lambda[i], lambda); ippsRef_BN(nullptr, &nsqBitLen, &pow_nsquare[i], m_nsquare); memcpy(cip_array[i], pow_c[i], BITSIZE_WORD(cBitLen) * 4); } - st = mbx_exp_mb8(out_m, cip_array, reinterpret_cast(pow_lambda), - lBitLen, reinterpret_cast(pow_nsquare), nsqBitLen, - pBuffer, bufferLen); + st = mbx_exp_mb8(out_m.data(), cip_array.data(), + reinterpret_cast(pow_lambda.data()), lBitLen, + reinterpret_cast(pow_nsquare.data()), nsqBitLen, + pBuffer.data(), bufferLen); for (int i = 0; i < 8; i++) { if (MBX_STATUS_OK != MBX_GET_STS(st, i)) throw std::runtime_error( - std::string("error multi buffered exp modules, error code = ") + + std::string( + "decryptRAW: error multi buffered exp modules, error code = ") + std::to_string(MBX_GET_STS(st, i))); } BigNumber ipp_res(m_nsquare); BigNumber nn = m_n; BigNumber xx = m_x; + for (int i = 0; i < 8; i++) { ipp_res.Set(reinterpret_cast(out_m[i]), BITSIZE_WORD(nsqBitLen), IppsBigNumPOS); @@ -125,41 +129,32 @@ void PaillierPrivateKey::decrypt(BigNumber plaintext[8], const PaillierEncryptedNumber ciphertext) { // check key match if (ciphertext.getPK().getN() != m_pubkey->getN()) - throw std::runtime_error("public key mismatch error."); + throw std::runtime_error("decrypt: public key mismatch error."); - BigNumber res[8]; - ciphertext.getArrayBN(res); + std::vector res(8); + ciphertext.getArrayBN(res.data()); if (m_enable_crt) - decryptCRT(plaintext, res); + decryptCRT(plaintext, res.data()); else - decryptRAW(plaintext, res); + decryptRAW(plaintext, res.data()); } // CRT to calculate base^exp mod n^2 void PaillierPrivateKey::decryptCRT(BigNumber plaintext[8], const BigNumber ciphertext[8]) { - BigNumber resp[8]; - BigNumber resq[8]; - - BigNumber pm1[8]; - BigNumber qm1[8]; - - BigNumber psq[8], qsq[8]; - BigNumber basep[8], baseq[8]; + std::vector resp(8), resq(8); + std::vector basep(8), baseq(8); + std::vector pm1(8, m_pminusone), qm1(8, m_qminusone); + std::vector psq(8, m_psquare), qsq(8, m_qsquare); for (int i = 0; i < 8; i++) { - psq[i] = m_psquare; - qsq[i] = m_qsquare; - pm1[i] = m_pminusone; - qm1[i] = m_qminusone; - basep[i] = ciphertext[i] % psq[i]; baseq[i] = ciphertext[i] % qsq[i]; } // Based on the fact a^b mod n = (a mod n)^b mod n - m_pubkey->ippMultiBuffExp(resp, basep, pm1, psq); - m_pubkey->ippMultiBuffExp(resq, baseq, qm1, qsq); + m_pubkey->ippMultiBuffExp(resp.data(), basep.data(), pm1.data(), psq.data()); + m_pubkey->ippMultiBuffExp(resq.data(), baseq.data(), qm1.data(), qsq.data()); for (int i = 0; i < 8; i++) { BigNumber dp = computeLfun(resp[i], m_p) * m_hp % m_p; @@ -188,3 +183,5 @@ BigNumber PaillierPrivateKey::computeHfun(const BigNumber& a, BigNumber lcrt = computeLfun(pm, a); return a.InverseMul(lcrt); } + +} // namespace ipcl diff --git a/ipcl/paillier_pubkey.cpp b/ipcl/paillier_pubkey.cpp index f0c3a3f..403bd71 100644 --- a/ipcl/paillier_pubkey.cpp +++ b/ipcl/paillier_pubkey.cpp @@ -9,6 +9,8 @@ #include #include +namespace ipcl { + static inline auto randomUniformUnsignedInt() { std::random_device dev; std::mt19937 rng(dev()); @@ -30,39 +32,57 @@ PaillierPublicKey::PaillierPublicKey(const BigNumber& n, int bits, } // array of 32-bit random, using rand() from stdlib -Ipp32u* PaillierPublicKey::randIpp32u(Ipp32u* addr, int size) { - for (int i = 0; i < size; i++) - addr[i] = (rand_r(&m_init_seed) << 16) + rand_r(&m_init_seed); - return addr; +void PaillierPublicKey::randIpp32u(std::vector& addr, int size) { + for (auto& a : addr) a = (rand_r(&m_init_seed) << 16) + rand_r(&m_init_seed); } // length is Arbitery BigNumber PaillierPublicKey::getRandom(int length) { + IppStatus stat; int size; int seedBitSize = 160; int seedSize = BITSIZE_WORD(seedBitSize); - Ipp32u* seed = reinterpret_cast(alloca(seedSize * sizeof(Ipp32u))); - if (nullptr == seed) throw std::runtime_error("error alloc memory"); - ippsPRNGGetSize(&size); - IppsPRNGState* pRand = reinterpret_cast(alloca(size)); - if (nullptr == pRand) throw std::runtime_error("error alloc memory"); - ippsPRNGInit(seedBitSize, pRand); - Ipp32u* addr = randIpp32u(seed, seedSize); - BigNumber bseed(addr, seedSize, IppsBigNumPOS); + auto seed = std::vector(seedSize); + + stat = ippsPRNGGetSize(&size); + if (stat != ippStsNoErr) + throw std::runtime_error("getRandom: get IppsPRNGState context error."); + + auto pRand = std::vector(size); + + stat = + ippsPRNGInit(seedBitSize, reinterpret_cast(pRand.data())); + if (stat != ippStsNoErr) + throw std::runtime_error("getRandom: init rand context error."); - ippsPRNGSetSeed(BN(bseed), pRand); + randIpp32u(seed, seedSize); + BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); + + stat = ippsPRNGSetSeed(BN(bseed), + reinterpret_cast(pRand.data())); + if (stat != ippStsNoErr) + throw std::runtime_error("getRandom: set up seed value error."); // define length Big Numbers int bn_size = BITSIZE_WORD(length); - ippsBigNumGetSize(bn_size, &size); + stat = ippsBigNumGetSize(bn_size, &size); + if (stat != ippStsNoErr) + throw std::runtime_error("getRandom: get IppsBigNumState context error."); + IppsBigNumState* pBN = reinterpret_cast(alloca(size)); - if (nullptr == pBN) throw std::runtime_error("error alloc memory"); - ippsBigNumInit(bn_size, pBN); + if (nullptr == pBN) + throw std::runtime_error("getRandom: big number alloca error"); + + stat = ippsBigNumInit(bn_size, pBN); + if (stat != ippStsNoErr) + throw std::runtime_error("getRandom: init big number context error."); int bnBitSize = length; - ippsPRNGenRDRAND_BN(pBN, bnBitSize, pRand); + ippsPRNGenRDRAND_BN(pBN, bnBitSize, + reinterpret_cast(pRand.data())); BigNumber rand(pBN); + return rand; } @@ -86,19 +106,16 @@ void PaillierPublicKey::enableDJN() { } void PaillierPublicKey::apply_obfuscator(BigNumber obfuscator[8]) { - BigNumber r[8]; - BigNumber pown[8]; - BigNumber base[8]; - BigNumber sq[8]; + std::vector r(8); + std::vector pown(8, m_n); + std::vector base(8, m_hs); + std::vector sq(8, m_nsquare); if (m_enable_DJN) { - for (int i = 0; i < 8; i++) { - r[i] = getRandom(m_randbits); - base[i] = m_hs; - sq[i] = m_nsquare; + for (auto& r_ : r) { + r_ = getRandom(m_randbits); } - - ippMultiBuffExp(obfuscator, base, r, sq); + ippMultiBuffExp(obfuscator, base.data(), r.data(), sq.data()); } else { for (int i = 0; i < 8; i++) { if (m_testv) { @@ -110,7 +127,7 @@ void PaillierPublicKey::apply_obfuscator(BigNumber obfuscator[8]) { pown[i] = m_n; sq[i] = m_nsquare; } - ippMultiBuffExp(obfuscator, r, pown, sq); + ippMultiBuffExp(obfuscator, r.data(), pown.data(), sq.data()); } } @@ -155,49 +172,47 @@ void PaillierPublicKey::ippMultiBuffExp(BigNumber res[8], BigNumber base[8], const BigNumber pow[8], BigNumber m[8]) { mbx_status st = MBX_STATUS_OK; - - // Memory used for multi-buffered modular exponentiation - Ipp64u* out_x[8]; - - int64u* b_array[8]; - int64u* p_array[8]; - - int bufferLen; - Ipp8u* pBuffer; - - // setup buffer for mbx_exp int bits = m[0].BitSize(); int dwords = BITSIZE_DWORD(bits); - bufferLen = mbx_exp_BufferSize(bits); - pBuffer = reinterpret_cast(alloca(bufferLen)); - if (nullptr == pBuffer) throw std::runtime_error("error alloc memory"); + int bufferLen = mbx_exp_BufferSize(bits); + auto pBuffer = std::vector(bufferLen); + std::vector out_x(8), b_array(8), p_array(8); int length = dwords * sizeof(int64u); + for (int i = 0; i < 8; i++) { out_x[i] = reinterpret_cast(alloca(length)); - b_array[i] = reinterpret_cast(alloca(length)); p_array[i] = reinterpret_cast(alloca(length)); - if (nullptr == out_x[i] || nullptr == b_array[i] || nullptr == p_array[i]) - throw std::runtime_error("error alloc memory"); - } + if (out_x[i] == nullptr || b_array[i] == nullptr || p_array[i] == nullptr) + throw std::runtime_error("ippMultiBuffExp: alloc memory for error"); - for (int i = 0; i < 8; i++) { - memset(b_array[i], 0, dwords * 8); - memset(p_array[i], 0, dwords * 8); + memset(out_x[i], 0, length); + memset(b_array[i], 0, length); + memset(p_array[i], 0, length); } - Ipp32u *pow_b[8], *pow_p[8], *pow_nsquare[8]; + /* + * These two intermediate variables pow_b & pow_p are necessary + * because if they are not used, the length returned from ippsRef_BN + * will be inconsistent with the length allocated by b_array/p_array, + * resulting in data errors. + */ + std::vector pow_b(8), pow_p(8), pow_nsquare(8); int bBitLen, pBitLen, nsqBitLen; int expBitLen = 0; + for (int i = 0; i < 8; i++) { - ippsRef_BN(nullptr, &bBitLen, &pow_b[i], base[i]); - ippsRef_BN(nullptr, &pBitLen, &pow_p[i], pow[i]); + ippsRef_BN(nullptr, &bBitLen, reinterpret_cast(&pow_b[i]), + base[i]); + ippsRef_BN(nullptr, &pBitLen, reinterpret_cast(&pow_p[i]), + pow[i]); ippsRef_BN(nullptr, &nsqBitLen, &pow_nsquare[i], m[i]); memcpy(b_array[i], pow_b[i], BITSIZE_WORD(bBitLen) * 4); memcpy(p_array[i], pow_p[i], BITSIZE_WORD(pBitLen) * 4); + if (expBitLen < pBitLen) expBitLen = pBitLen; } @@ -206,9 +221,9 @@ void PaillierPublicKey::ippMultiBuffExp(BigNumber res[8], BigNumber base[8], *to maximum size of the actual module in bit size and extend all the modules *with zero bits */ - st = mbx_exp_mb8(out_x, b_array, p_array, expBitLen, - reinterpret_cast(pow_nsquare), nsqBitLen, pBuffer, - bufferLen); + st = mbx_exp_mb8(out_x.data(), b_array.data(), p_array.data(), expBitLen, + reinterpret_cast(pow_nsquare.data()), nsqBitLen, + reinterpret_cast(pBuffer.data()), bufferLen); for (int i = 0; i < 8; i++) { if (MBX_STATUS_OK != MBX_GET_STS(st, i)) @@ -219,10 +234,10 @@ void PaillierPublicKey::ippMultiBuffExp(BigNumber res[8], BigNumber base[8], // It is important to hold a copy of nsquare for thread-safe purpose BigNumber bn_c(m[0]); + for (int i = 0; i < 8; i++) { bn_c.Set(reinterpret_cast(out_x[i]), BITSIZE_WORD(nsqBitLen), IppsBigNumPOS); - res[i] = bn_c; } } @@ -230,7 +245,7 @@ void PaillierPublicKey::ippMultiBuffExp(BigNumber res[8], BigNumber base[8], BigNumber PaillierPublicKey::ippMontExp(const BigNumber& base, const BigNumber& pow, const BigNumber& m) { - IppStatus st = ippStsNoErr; + IppStatus stat = ippStsNoErr; // It is important to declear res * bform bit length refer to ipp-crypto spec: // R should not be less than the data length of the modulus m BigNumber res(m); @@ -242,32 +257,51 @@ BigNumber PaillierPublicKey::ippMontExp(const BigNumber& base, int size; // define and initialize Montgomery Engine over Modulus N - ippsMontGetSize(IppsBinaryMethod, nlen, &size); - IppsMontState* pMont = reinterpret_cast(new Ipp8u[size]); - if (nullptr == pMont) throw std::runtime_error("error alloc memory"); - ippsMontInit(IppsBinaryMethod, nlen, pMont); - ippsMontSet(pow_m, nlen, pMont); + stat = ippsMontGetSize(IppsBinaryMethod, nlen, &size); + if (stat != ippStsNoErr) + throw std::runtime_error( + "ippMontExp: get the size of IppsMontState context error."); + + auto pMont = std::vector(size); + + stat = ippsMontInit(IppsBinaryMethod, nlen, + reinterpret_cast(pMont.data())); + if (stat != ippStsNoErr) + throw std::runtime_error("ippMontExp: init Mont context error."); + + stat = + ippsMontSet(pow_m, nlen, reinterpret_cast(pMont.data())); + if (stat != ippStsNoErr) + throw std::runtime_error("ippMontExp: set Mont input error."); // encode base into Montfomery form BigNumber bform(m); - ippsMontForm(BN(base), pMont, BN(bform)); + stat = ippsMontForm(BN(base), reinterpret_cast(pMont.data()), + BN(bform)); + if (stat != ippStsNoErr) + throw std::runtime_error( + "ippMontExp: convet big number into Mont form error."); // compute R = base^pow mod N - st = ippsMontExp(BN(bform), BN(pow), pMont, BN(res)); - if (ippStsNoErr != st) - throw std::runtime_error(std::string("ippsMontExp error code = ") + - std::to_string(st)); + stat = ippsMontExp(BN(bform), BN(pow), + reinterpret_cast(pMont.data()), BN(res)); + if (stat != ippStsNoErr) + throw std::runtime_error(std::string("ippsMontExp: error code = ") + + std::to_string(stat)); BigNumber one(1); - st = ippsMontMul(BN(res), BN(one), pMont, BN(res)); // R = MontMul(R,1) - if (ippStsNoErr != st) - throw std::runtime_error(std::string("ippsMontMul error code = ") + - std::to_string(st)); + // R = MontMul(R,1) + stat = ippsMontMul(BN(res), BN(one), + reinterpret_cast(pMont.data()), BN(res)); + if (stat != ippStsNoErr) + throw std::runtime_error(std::string("ippsMontMul: error code = ") + + std::to_string(stat)); - delete[] reinterpret_cast(pMont); return res; } BigNumber PaillierPublicKey::IPP_invert(BigNumber a, BigNumber b) { return b.InverseMul(a); } + +} // namespace ipcl diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index e6631a1..10bdf6c 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -15,13 +15,13 @@ #include "ipcl/paillier_ops.hpp" TEST(CryptoTest, CryptoTest) { - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber ct[8]; - BigNumber dt[8]; + ipcl::BigNumber ct[8]; + ipcl::BigNumber dt[8]; uint32_t pt[8]; - BigNumber ptbn[8]; + ipcl::BigNumber ptbn[8]; std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -45,16 +45,16 @@ TEST(CryptoTest, CryptoTest) { } #ifdef IPCL_UNITTEST_OMP -void Encryption(int num_threads, std::vector v_ct, - std::vector v_ptbn, keyPair key) { +void Encryption(int num_threads, std::vector v_ct, + std::vector v_ptbn, ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { key.pub_key->encrypt(v_ct[i], v_ptbn[i]); } } -void Decryption(int num_threads, std::vector v_dt, - std::vector v_ct, keyPair key) { +void Decryption(int num_threads, std::vector v_dt, + std::vector v_ct, ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { key.priv_key->decrypt(v_dt[i], v_ct[i]); @@ -63,25 +63,25 @@ void Decryption(int num_threads, std::vector v_dt, TEST(CryptoTest, CryptoTest_OMP) { // use one keypair to do several encryption/decryption - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); size_t num_threads = omp_get_max_threads(); // std::cout << "available threads: " << num_threads << std::endl; - std::vector v_ct(num_threads); - std::vector v_dt(num_threads); + std::vector v_ct(num_threads); + std::vector v_dt(num_threads); std::vector v_pt(num_threads); - std::vector v_ptbn(num_threads); + std::vector v_ptbn(num_threads); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { - v_ct[i] = new BigNumber[8]; - v_dt[i] = new BigNumber[8]; + v_ct[i] = new ipcl::BigNumber[8]; + v_dt[i] = new ipcl::BigNumber[8]; v_pt[i] = new uint32_t[8]; - v_ptbn[i] = new BigNumber[8]; + v_ptbn[i] = new ipcl::BigNumber[8]; // for each threads, generated different rand testing value for (int j = 0; j < 8; j++) { @@ -115,31 +115,33 @@ TEST(CryptoTest, CryptoTest_OMP) { #endif TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { - BigNumber p = + ipcl::BigNumber p = "0xff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c" "8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b4" "0a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff76" "4dd8b091f11a0943a2dd2b983b0df02f4c4d00b413"; - BigNumber q = + ipcl::BigNumber q = "0xdacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d" "9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de70" "72a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49b" "aa0f610bad100cdf47cc86e5034e2a0b2179e04ec7"; - BigNumber n = p * q; + ipcl::BigNumber n = p * q; int n_length = n.BitSize(); - PaillierPublicKey* public_key = new PaillierPublicKey(n, n_length); - PaillierPrivateKey* private_key = new PaillierPrivateKey(public_key, p, q); + ipcl::PaillierPublicKey* public_key = + new ipcl::PaillierPublicKey(n, n_length); + ipcl::PaillierPrivateKey* private_key = + new ipcl::PaillierPrivateKey(public_key, p, q); - keyPair key = {public_key, private_key}; + ipcl::keyPair key = {public_key, private_key}; - BigNumber ptbn[8]; - BigNumber ct[8]; - BigNumber dt[8]; - BigNumber ir[8]; + ipcl::BigNumber ptbn[8]; + ipcl::BigNumber ct[8]; + ipcl::BigNumber dt[8]; + ipcl::BigNumber ir[8]; - BigNumber c1 = + ipcl::BigNumber c1 = "0x1fb7f08a42deb47876e4cbdc3f0b172c033563a696ad7a7c76fa5971b793fa488dcdd6" "bd65c7c5440d67d847cb89ccca468b2c96763fff5a5ece8330251112d65e59b7da94cfe9" "309f441ccc8f59c67dec75113d37b1ee929c8d4ce6b5e561a30a91104b0526de892e4eff" @@ -156,7 +158,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "b98ccb676367b7b3b269c670cd0210edf70ad9cb337f766af75fe06d18b3f7f7c2eae656" "5ff2815c2c09b1a1f5"; - BigNumber c2 = + ipcl::BigNumber c2 = "0x61803645f2798c06f2c08fc254eee612c55542051c8777d6ce69ede9c84a179afb2081" "167494dee727488ae5e9b56d98f4fcf132514616859fc854fbd3acf6aecd97324ac3f2af" "fa9f44864a9afc505754aa3b564b4617e887d6aa1f88095bccf6b47f458566f9d85e80fc" @@ -173,7 +175,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "d6f1d6864f1fd3e2e3937e00d391ad330b443aec85528571740ed5538188c32caab27c7b" "f437df2bb97cb90e02"; - BigNumber c1c2 = + ipcl::BigNumber c1c2 = "0x309f6e614d875e3bb0a77eedeb8895e7c6f297f161f576aef4f8b72bb5b81ef78b831a" "af134b09fe8697159cfd678c49920cb790e36580c5201a96848d7242fceb025808dd26b5" "0ff573ffca3f65e51b3b9fe85c7e44f5c8df0a9e524f64a5acc5c62cba7475978eb55e08" @@ -190,9 +192,9 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "a6d47f9af6e68e18960fa5916cc48994334354d6303312b8e96602766bec337a8a92c596" "b21b6038828a6c9744"; - BigNumber m1m2 = "0x616263646566676869606a6b6c6d6e6f"; + ipcl::BigNumber m1m2 = "0x616263646566676869606a6b6c6d6e6f"; - BigNumber r0 = + ipcl::BigNumber r0 = "0x57fb19590c31dc7c034b2a889cf4037ce3db799909c1eb0adb6199d8e96791daca9018" "891f34309daff32dced4af7d793d16734d055e28023acab7295956bfbfdf62bf0ccb2ed3" "1d5d176ca8b404e93007565fb6b72c33a512b4dc4f719231d62e27e34c3733929af32247" @@ -201,7 +203,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "27991c44a43750c24ed0825718ad14cfb9c6b40b78ff3d25f71741f2def1c9d420d4b0fa" "1e0a02e7851b5ec6a81133a368b80d1500b0f28fc653d2e6ff4366236dbf80ae3b4beae3" "5e04579f2c"; - BigNumber r1 = + ipcl::BigNumber r1 = "0x6ee8ed76227672a7bcaa1e7f152c2ea39f2fa225f0713f58210c59b2270b110e38b650" "69aaedbeffc713c021336cc12f65227cc0357ca531c07c706e7224c2c11c3145bc0a05b1" "64f426ec03350820f9f416377e8720ddb577843cae929178bfe5772e2cc1e9b94e8fce81" @@ -222,12 +224,12 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { key.pub_key->encrypt(ct, ptbn); - PaillierEncryptedNumber a(key.pub_key, ct[0]); - PaillierEncryptedNumber b(key.pub_key, ct[1]); - PaillierEncryptedNumber sum = a + b; - BigNumber res = sum.getBN(); + ipcl::PaillierEncryptedNumber a(key.pub_key, ct[0]); + ipcl::PaillierEncryptedNumber b(key.pub_key, ct[1]); + ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::BigNumber res = sum.getBN(); - BigNumber ct12[8], dt12[8]; + ipcl::BigNumber ct12[8], dt12[8]; for (int i = 0; i < 8; i++) { ct12[i] = res; } diff --git a/test/test_ops.cpp b/test/test_ops.cpp index b9b9dcf..f19852d 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -14,79 +14,80 @@ #include "ipcl/paillier_keygen.hpp" #include "ipcl/paillier_ops.hpp" -void CtPlusCt(BigNumber res[8], BigNumber ct1[8], BigNumber ct2[8], - keyPair key) { +void CtPlusCt(ipcl::BigNumber res[8], ipcl::BigNumber ct1[8], + ipcl::BigNumber ct2[8], ipcl::keyPair key) { for (int i = 0; i < 8; i++) { - PaillierEncryptedNumber a(key.pub_key, ct1[i]); - PaillierEncryptedNumber b(key.pub_key, ct2[i]); - PaillierEncryptedNumber sum = a + b; + ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); + ipcl::PaillierEncryptedNumber b(key.pub_key, ct2[i]); + ipcl::PaillierEncryptedNumber sum = a + b; res[i] = sum.getBN(); } } -void CtPlusCtArray(BigNumber res[8], BigNumber ct1[8], BigNumber ct2[8], - keyPair key) { - PaillierEncryptedNumber a(key.pub_key, ct1); - PaillierEncryptedNumber b(key.pub_key, ct2); - PaillierEncryptedNumber sum = a + b; +void CtPlusCtArray(ipcl::BigNumber res[8], ipcl::BigNumber ct1[8], + ipcl::BigNumber ct2[8], ipcl::keyPair key) { + ipcl::PaillierEncryptedNumber a(key.pub_key, ct1); + ipcl::PaillierEncryptedNumber b(key.pub_key, ct2); + ipcl::PaillierEncryptedNumber sum = a + b; sum.getArrayBN(res); } -void CtPlusPt(BigNumber res[8], BigNumber ct1[8], uint32_t pt2[8], - keyPair key) { +void CtPlusPt(ipcl::BigNumber res[8], ipcl::BigNumber ct1[8], uint32_t pt2[8], + ipcl::keyPair key) { for (int i = 0; i < 8; i++) { - PaillierEncryptedNumber a(key.pub_key, ct1[i]); - BigNumber b = pt2[i]; - PaillierEncryptedNumber sum = a + b; + ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); + ipcl::BigNumber b = pt2[i]; + ipcl::PaillierEncryptedNumber sum = a + b; res[i] = sum.getBN(); } } -void CtPlusPtArray(BigNumber res[8], BigNumber ct1[8], BigNumber ptbn2[8], - keyPair key) { - BigNumber stmp[8]; - PaillierEncryptedNumber a(key.pub_key, ct1); - PaillierEncryptedNumber sum = a + ptbn2; +void CtPlusPtArray(ipcl::BigNumber res[8], ipcl::BigNumber ct1[8], + ipcl::BigNumber ptbn2[8], ipcl::keyPair key) { + ipcl::BigNumber stmp[8]; + ipcl::PaillierEncryptedNumber a(key.pub_key, ct1); + ipcl::PaillierEncryptedNumber sum = a + ptbn2; sum.getArrayBN(res); } -void CtMultiplyPt(BigNumber res[8], BigNumber ct1[8], uint32_t pt2[8], - keyPair key) { +void CtMultiplyPt(ipcl::BigNumber res[8], ipcl::BigNumber ct1[8], + uint32_t pt2[8], ipcl::keyPair key) { for (int i = 0; i < 8; i++) { - PaillierEncryptedNumber a(key.pub_key, ct1[i]); - PaillierEncryptedNumber b(key.pub_key, pt2[i]); - PaillierEncryptedNumber sum = a * b; + ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); + ipcl::PaillierEncryptedNumber b(key.pub_key, pt2[i]); + ipcl::PaillierEncryptedNumber sum = a * b; res[i] = sum.getBN(); } } -void CtMultiplyPtArray(BigNumber res[8], BigNumber ct1[8], uint32_t pt2[8], - keyPair key) { - PaillierEncryptedNumber a(key.pub_key, ct1); - PaillierEncryptedNumber b(key.pub_key, pt2); - PaillierEncryptedNumber sum = a * b; +void CtMultiplyPtArray(ipcl::BigNumber res[8], ipcl::BigNumber ct1[8], + uint32_t pt2[8], ipcl::keyPair key) { + ipcl::PaillierEncryptedNumber a(key.pub_key, ct1); + ipcl::PaillierEncryptedNumber b(key.pub_key, pt2); + ipcl::PaillierEncryptedNumber sum = a * b; sum.getArrayBN(res); } -void AddSub(BigNumber res[8], BigNumber ct1[8], BigNumber ct2[8], keyPair key) { +void AddSub(ipcl::BigNumber res[8], ipcl::BigNumber ct1[8], + ipcl::BigNumber ct2[8], ipcl::keyPair key) { for (int i = 0; i < 8; i++) { - PaillierEncryptedNumber a(key.pub_key, ct1[i]); - PaillierEncryptedNumber b(key.pub_key, ct2[i]); - BigNumber m1(2); + ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); + ipcl::PaillierEncryptedNumber b(key.pub_key, ct2[i]); + ipcl::BigNumber m1(2); a = a + b * m1; - PaillierEncryptedNumber sum = a + b; + ipcl::PaillierEncryptedNumber sum = a + b; res[i] = sum.getBN(); } } TEST(OperationTest, CtPlusCtTest) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); - BigNumber ct1[8], ct2[8]; - BigNumber dt[8], res[8]; + ipcl::BigNumber ct1[8], ct2[8]; + ipcl::BigNumber dt[8], res[8]; uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8], ptbn2[8]; + ipcl::BigNumber ptbn1[8], ptbn2[8]; std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -121,13 +122,13 @@ TEST(OperationTest, CtPlusCtTest) { } TEST(OperationTest, CtPlusCtArrayTest) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); - BigNumber ct1[8], ct2[8]; - BigNumber dt[8], res[8]; + ipcl::BigNumber ct1[8], ct2[8]; + ipcl::BigNumber dt[8], res[8]; uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8], ptbn2[8]; + ipcl::BigNumber ptbn1[8], ptbn2[8]; std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -162,13 +163,13 @@ TEST(OperationTest, CtPlusCtArrayTest) { } TEST(OperationTest, CtPlusPtTest) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); - BigNumber ct1[8], ct2[8]; - BigNumber dt[8], res[8]; + ipcl::BigNumber ct1[8], ct2[8]; + ipcl::BigNumber dt[8], res[8]; uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8]; + ipcl::BigNumber ptbn1[8]; std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -201,13 +202,13 @@ TEST(OperationTest, CtPlusPtTest) { } TEST(OperationTest, CtPlusPtArrayTest) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); - BigNumber ct1[8], ct2[8]; - BigNumber dt[8], res[8]; + ipcl::BigNumber ct1[8], ct2[8]; + ipcl::BigNumber dt[8], res[8]; uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8], ptbn2[8]; + ipcl::BigNumber ptbn1[8], ptbn2[8]; std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -241,13 +242,13 @@ TEST(OperationTest, CtPlusPtArrayTest) { } TEST(OperationTest, CtMultiplyPtTest) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); - BigNumber ct1[8], ct2[8]; - BigNumber dt[8], res[8]; + ipcl::BigNumber ct1[8], ct2[8]; + ipcl::BigNumber dt[8], res[8]; uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8]; + ipcl::BigNumber ptbn1[8]; std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -280,13 +281,13 @@ TEST(OperationTest, CtMultiplyPtTest) { } TEST(OperationTest, CtMultiplyZeroPtTest) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); - BigNumber ct1[8], ct2[8]; - BigNumber dt[8], res[8]; + ipcl::BigNumber ct1[8], ct2[8]; + ipcl::BigNumber dt[8], res[8]; uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8]; + ipcl::BigNumber ptbn1[8]; std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -319,13 +320,13 @@ TEST(OperationTest, CtMultiplyZeroPtTest) { } TEST(OperationTest, CtMultiplyPtArrayTest) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); - BigNumber ct1[8]; - BigNumber dt[8], res[8]; + ipcl::BigNumber ct1[8]; + ipcl::BigNumber dt[8], res[8]; uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8], ptbn2[8]; + ipcl::BigNumber ptbn1[8], ptbn2[8]; std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -359,13 +360,13 @@ TEST(OperationTest, CtMultiplyPtArrayTest) { } TEST(OperationTest, AddSubTest) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); - BigNumber ct1[8], ct2[8]; - BigNumber dt[8], res[8]; + ipcl::BigNumber ct1[8], ct2[8]; + ipcl::BigNumber dt[8], res[8]; uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8], ptbn2[8]; + ipcl::BigNumber ptbn1[8], ptbn2[8]; std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -399,101 +400,102 @@ TEST(OperationTest, AddSubTest) { } #ifdef IPCL_UNITTEST_OMP -void CtPlusCt_OMP(int num_threads, std::vector v_sum, - std::vector v_ct1, std::vector v_ct2, - keyPair key) { +void CtPlusCt_OMP(int num_threads, std::vector v_sum, + std::vector v_ct1, + std::vector v_ct2, ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { - PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); - PaillierEncryptedNumber b(key.pub_key, v_ct2[i][j]); - PaillierEncryptedNumber sum = a + b; + ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); + ipcl::PaillierEncryptedNumber b(key.pub_key, v_ct2[i][j]); + ipcl::PaillierEncryptedNumber sum = a + b; v_sum[i][j] = sum.getBN(); } } } -void CtPlusPt_OMP(int num_threads, std::vector v_sum, - std::vector v_ct1, std::vector v_pt2, - keyPair key) { +void CtPlusPt_OMP(int num_threads, std::vector v_sum, + std::vector v_ct1, + std::vector v_pt2, ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { - BigNumber b = v_pt2[i][j]; - PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); - PaillierEncryptedNumber sum = a + b; + ipcl::BigNumber b = v_pt2[i][j]; + ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); + ipcl::PaillierEncryptedNumber sum = a + b; v_sum[i][j] = sum.getBN(); } } } -void CtPlusPtArray_OMP(int num_threads, std::vector v_sum, - std::vector v_ct1, - std::vector v_pt2, keyPair key) { +void CtPlusPtArray_OMP(int num_threads, std::vector v_sum, + std::vector v_ct1, + std::vector v_pt2, ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); - BigNumber b[8]; + ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); + ipcl::BigNumber b[8]; for (int j = 0; j < 8; j++) { b[j] = v_pt2[i][j]; } - PaillierEncryptedNumber sum = a + b; + ipcl::PaillierEncryptedNumber sum = a + b; sum.getArrayBN(v_sum[i]); } } -void CtMultiplyPt_OMP(int num_threads, std::vector v_product, - std::vector v_ct1, - std::vector v_pt2, keyPair key) { +void CtMultiplyPt_OMP(int num_threads, std::vector v_product, + std::vector v_ct1, + std::vector v_pt2, ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { - PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); - BigNumber b = v_pt2[i][j]; - PaillierEncryptedNumber product = a * b; + ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); + ipcl::BigNumber b = v_pt2[i][j]; + ipcl::PaillierEncryptedNumber product = a * b; v_product[i][j] = product.getBN(); } } } -void CtMultiplyPtArray_OMP(int num_threads, std::vector v_product, - std::vector v_ct1, - std::vector v_pt2, keyPair key) { +void CtMultiplyPtArray_OMP(int num_threads, + std::vector v_product, + std::vector v_ct1, + std::vector v_pt2, ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); - PaillierEncryptedNumber b(key.pub_key, v_pt2[i]); - PaillierEncryptedNumber product = a * b; + ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); + ipcl::PaillierEncryptedNumber b(key.pub_key, v_pt2[i]); + ipcl::PaillierEncryptedNumber product = a * b; product.getArrayBN(v_product[i]); } } TEST(OperationTest, CtPlusCtTest_OMP) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); size_t num_threads = omp_get_max_threads(); - std::vector v_ct1(num_threads); - std::vector v_ct2(num_threads); - std::vector v_dt(num_threads); - std::vector v_sum(num_threads); + std::vector v_ct1(num_threads); + std::vector v_ct2(num_threads); + std::vector v_dt(num_threads); + std::vector v_sum(num_threads); std::vector v_pt1(num_threads); std::vector v_pt2(num_threads); - std::vector v_ptbn1(num_threads); - std::vector v_ptbn2(num_threads); + std::vector v_ptbn1(num_threads); + std::vector v_ptbn2(num_threads); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { - v_ct1[i] = new BigNumber[8]; - v_ct2[i] = new BigNumber[8]; - v_dt[i] = new BigNumber[8]; - v_sum[i] = new BigNumber[8]; + v_ct1[i] = new ipcl::BigNumber[8]; + v_ct2[i] = new ipcl::BigNumber[8]; + v_dt[i] = new ipcl::BigNumber[8]; + v_sum[i] = new ipcl::BigNumber[8]; v_pt1[i] = new uint32_t[8]; v_pt2[i] = new uint32_t[8]; - v_ptbn1[i] = new BigNumber[8]; - v_ptbn2[i] = new BigNumber[8]; + v_ptbn1[i] = new ipcl::BigNumber[8]; + v_ptbn2[i] = new ipcl::BigNumber[8]; // for each threads, generated different rand testing value for (int j = 0; j < 8; j++) { @@ -547,29 +549,29 @@ TEST(OperationTest, CtPlusCtTest_OMP) { } TEST(OperationTest, CtPlusPtTest_OMP) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); size_t num_threads = omp_get_max_threads(); - std::vector v_ct1(num_threads); - std::vector v_dt(num_threads); - std::vector v_sum(num_threads); + std::vector v_ct1(num_threads); + std::vector v_dt(num_threads); + std::vector v_sum(num_threads); std::vector v_pt1(num_threads); std::vector v_pt2(num_threads); - std::vector v_ptbn1(num_threads); - std::vector v_ptbn2(num_threads); + std::vector v_ptbn1(num_threads); + std::vector v_ptbn2(num_threads); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { - v_ct1[i] = new BigNumber[8]; - v_dt[i] = new BigNumber[8]; - v_sum[i] = new BigNumber[8]; + v_ct1[i] = new ipcl::BigNumber[8]; + v_dt[i] = new ipcl::BigNumber[8]; + v_sum[i] = new ipcl::BigNumber[8]; v_pt1[i] = new uint32_t[8]; v_pt2[i] = new uint32_t[8]; - v_ptbn1[i] = new BigNumber[8]; - v_ptbn2[i] = new BigNumber[8]; + v_ptbn1[i] = new ipcl::BigNumber[8]; + v_ptbn2[i] = new ipcl::BigNumber[8]; // for each threads, generated different rand testing value for (int j = 0; j < 8; j++) { @@ -621,29 +623,29 @@ TEST(OperationTest, CtPlusPtTest_OMP) { } TEST(OperationTest, CtPlusPtArrayTest_OMP) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); size_t num_threads = omp_get_max_threads(); - std::vector v_ct1(num_threads); - std::vector v_dt(num_threads); - std::vector v_sum(num_threads); + std::vector v_ct1(num_threads); + std::vector v_dt(num_threads); + std::vector v_sum(num_threads); std::vector v_pt1(num_threads); std::vector v_pt2(num_threads); - std::vector v_ptbn1(num_threads); - std::vector v_ptbn2(num_threads); + std::vector v_ptbn1(num_threads); + std::vector v_ptbn2(num_threads); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { - v_ct1[i] = new BigNumber[8]; - v_dt[i] = new BigNumber[8]; - v_sum[i] = new BigNumber[8]; + v_ct1[i] = new ipcl::BigNumber[8]; + v_dt[i] = new ipcl::BigNumber[8]; + v_sum[i] = new ipcl::BigNumber[8]; v_pt1[i] = new uint32_t[8]; v_pt2[i] = new uint32_t[8]; - v_ptbn1[i] = new BigNumber[8]; - v_ptbn2[i] = new BigNumber[8]; + v_ptbn1[i] = new ipcl::BigNumber[8]; + v_ptbn2[i] = new ipcl::BigNumber[8]; // for each threads, generated different rand testing value for (int j = 0; j < 8; j++) { @@ -695,30 +697,30 @@ TEST(OperationTest, CtPlusPtArrayTest_OMP) { } TEST(OperationTest, CtMultiplyPtTest_OMP) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); size_t num_threads = omp_get_max_threads(); - std::vector v_ct1(num_threads); - std::vector v_dt(num_threads); - std::vector v_product(num_threads); + std::vector v_ct1(num_threads); + std::vector v_dt(num_threads); + std::vector v_product(num_threads); std::vector v_pt1(num_threads); std::vector v_pt2(num_threads); - std::vector v_ptbn1(num_threads); - std::vector v_ptbn2(num_threads); + std::vector v_ptbn1(num_threads); + std::vector v_ptbn2(num_threads); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { - v_ct1[i] = new BigNumber[8]; - v_dt[i] = new BigNumber[8]; - v_product[i] = new BigNumber[8]; + v_ct1[i] = new ipcl::BigNumber[8]; + v_dt[i] = new ipcl::BigNumber[8]; + v_product[i] = new ipcl::BigNumber[8]; v_pt1[i] = new uint32_t[8]; v_pt2[i] = new uint32_t[8]; - v_ptbn1[i] = new BigNumber[8]; - v_ptbn2[i] = new BigNumber[8]; + v_ptbn1[i] = new ipcl::BigNumber[8]; + v_ptbn2[i] = new ipcl::BigNumber[8]; // for each threads, generated different rand testing value for (int j = 0; j < 8; j++) { @@ -769,30 +771,30 @@ TEST(OperationTest, CtMultiplyPtTest_OMP) { } TEST(OperationTest, CtMultiplyPtArrayTest_OMP) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); size_t num_threads = omp_get_max_threads(); - std::vector v_ct1(num_threads); - std::vector v_dt(num_threads); - std::vector v_product(num_threads); + std::vector v_ct1(num_threads); + std::vector v_dt(num_threads); + std::vector v_product(num_threads); std::vector v_pt1(num_threads); std::vector v_pt2(num_threads); - std::vector v_ptbn1(num_threads); - std::vector v_ptbn2(num_threads); + std::vector v_ptbn1(num_threads); + std::vector v_ptbn2(num_threads); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { - v_ct1[i] = new BigNumber[8]; - v_dt[i] = new BigNumber[8]; - v_product[i] = new BigNumber[8]; + v_ct1[i] = new ipcl::BigNumber[8]; + v_dt[i] = new ipcl::BigNumber[8]; + v_product[i] = new ipcl::BigNumber[8]; v_pt1[i] = new uint32_t[8]; v_pt2[i] = new uint32_t[8]; - v_ptbn1[i] = new BigNumber[8]; - v_ptbn2[i] = new BigNumber[8]; + v_ptbn1[i] = new ipcl::BigNumber[8]; + v_ptbn2[i] = new ipcl::BigNumber[8]; // for each threads, generated different rand testing value From c800584d9d9a5e36b7532082bad7ec9b7da85e89 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 1 Mar 2022 10:45:55 -0800 Subject: [PATCH 056/364] Source code grooming with clang-format. --- he_qat_bn_ops.c | 462 +++++++++++++++++++-------------------- he_qat_bn_ops.h | 39 ++-- he_qat_context.c | 92 ++++---- he_qat_context.h | 6 +- he_qat_types.h | 42 ++-- test_bnModExpPerformOp.c | 176 +++++++-------- test_context.c | 11 +- 7 files changed, 406 insertions(+), 422 deletions(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index b9b8c78..e29329f 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -15,58 +15,56 @@ // Global buffer for the runtime environment HE_QAT_RequestBuffer he_qat_buffer; -/// @brief -/// @function -/// Callback function for lnModExpPerformOp. It performs any data processing +/// @brief +/// @function +/// Callback function for lnModExpPerformOp. It performs any data processing /// required after the modular exponentiation. -static void lnModExpCallback(void *pCallbackTag, // This type can be variable - CpaStatus status, - void *pOpData, // This is fixed -- please swap it - CpaFlatBuffer *pOut) -{ - HE_QAT_TaskRequest *request = NULL; +static void lnModExpCallback(void* pCallbackTag, // This type can be variable + CpaStatus status, + void* pOpData, // This is fixed -- please swap it + CpaFlatBuffer* pOut) { + HE_QAT_TaskRequest* request = NULL; // Check if input data for the op is available and do something if (NULL != pCallbackTag) { // Read request data - request = (HE_QAT_TaskRequest *) pCallbackTag; + request = (HE_QAT_TaskRequest*)pCallbackTag; // Collect the device output in pOut request->op_status = status; - if (CPA_STATUS_SUCCESS == status) { - if (pOpData == request->op_data) { -// printf("pOpData is same as input\n"); - // Mark request as complete or ready to be used - request->request_status = HE_QAT_READY; - - BIGNUM *r = BN_bin2bn(request->op_result.pData, request->op_result.dataLenInBytes, - (BIGNUM *) request->op_output); - } else { -// printf("pOpData is NOT same as input\n"); - request->request_status = HE_QAT_STATUS_FAIL; - } - } - // Make it synchronous and blocking - pthread_cond_signal(&request->ready); - COMPLETE((struct COMPLETION_STRUCT *)&request->callback); + if (CPA_STATUS_SUCCESS == status) { + if (pOpData == request->op_data) { + // printf("pOpData is same as input\n"); + // Mark request as complete or ready to be used + request->request_status = HE_QAT_READY; + + BIGNUM* r = BN_bin2bn(request->op_result.pData, + request->op_result.dataLenInBytes, + (BIGNUM*)request->op_output); + } else { + // printf("pOpData is NOT same as input\n"); + request->request_status = HE_QAT_STATUS_FAIL; + } + } + // Make it synchronous and blocking + pthread_cond_signal(&request->ready); + COMPLETE((struct COMPLETION_STRUCT*)&request->callback); } - // Asynchronous call needs to send wake-up signal to semaphore - // if (NULL != pCallbackTag) { - // COMPLETE((struct COMPLETION_STRUCT *)pCallbackTag); - // } + // Asynchronous call needs to send wake-up signal to semaphore + // if (NULL != pCallbackTag) { + // COMPLETE((struct COMPLETION_STRUCT *)pCallbackTag); + // } - return ; + return; } - /// @brief /// @function /// Thread-safe producer implementation for the shared request buffer. /// Stores requests in a buffer that will be offload to QAT devices. -static void submit_request(HE_QAT_RequestBuffer *_buffer, void *args) -{ +static void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { pthread_mutex_lock(&_buffer->mutex); - + while (_buffer->count >= HE_QAT_BUFFER_SIZE) pthread_cond_wait(&_buffer->any_free_slot, &_buffer->mutex); @@ -91,16 +89,15 @@ static void submit_request(HE_QAT_RequestBuffer *_buffer, void *args) /// @function /// Thread-safe consumer implementation for the shared request buffer. /// Read requests from a buffer to finally offload the work to QAT devices. -static HE_QAT_TaskRequest *read_request(HE_QAT_RequestBuffer *_buffer) -{ - void *item = NULL; +static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) { + void* item = NULL; pthread_mutex_lock(&_buffer->mutex); - while(_buffer->count <= 0) + while (_buffer->count <= 0) pthread_cond_wait(&_buffer->any_more_data, &_buffer->mutex); assert(_buffer->count > 0); - //printf("[%02d]:",_buffer->next_data_slot); + // printf("[%02d]:",_buffer->next_data_slot); item = _buffer->data[_buffer->next_data_slot++]; // Asynchronous mode: Make copy of request so that the buffer can be reused @@ -117,21 +114,21 @@ static HE_QAT_TaskRequest *read_request(HE_QAT_RequestBuffer *_buffer) pthread_cond_signal(&_buffer->any_free_slot); pthread_mutex_unlock(&_buffer->mutex); - return (HE_QAT_TaskRequest *) (item); + return (HE_QAT_TaskRequest*)(item); } -/// @brief +/// @brief /// @function start_inst_polling /// @param[in] HE_QAT_InstConfig Parameter values to start and poll instances. -/// -static void *start_inst_polling (void *_inst_config) -{ +/// +static void* start_inst_polling(void* _inst_config) { if (NULL == _inst_config) { - printf("Failed at start_inst_polling: argument is NULL."); //,__FUNC__); + printf( + "Failed at start_inst_polling: argument is NULL."); //,__FUNC__); pthread_exit(NULL); } - HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) _inst_config; + HE_QAT_InstConfig* config = (HE_QAT_InstConfig*)_inst_config; if (NULL == config->inst_handle) return NULL; @@ -139,66 +136,63 @@ static void *start_inst_polling (void *_inst_config) config->polling = 1; while (config->polling) { icp_sal_CyPollInstance(config->inst_handle, 0); - OS_SLEEP(10); + OS_SLEEP(10); } pthread_exit(NULL); } -/// @brief This function +/// @brief This function /// @function stop_inst_polling -/// Stop polling instances and halt polling thread. -static void stop_inst_polling(HE_QAT_InstConfig *config) -{ +/// Stop polling instances and halt polling thread. +static void stop_inst_polling(HE_QAT_InstConfig* config) { config->polling = 0; OS_SLEEP(10); - return ; + return; } -/// @brief +/// @brief /// @function perform_op -/// Offload operation to QAT endpoints; for example, large number modular exponentiation. -/// @param[in] HE_QAT_InstConfig *: contains the handle to CPA instance, pointer the global buffer of requests. -void *start_perform_op(void *_inst_config) -{ +/// Offload operation to QAT endpoints; for example, large number modular +/// exponentiation. +/// @param[in] HE_QAT_InstConfig *: contains the handle to CPA instance, pointer +/// the global buffer of requests. +void* start_perform_op(void* _inst_config) { if (NULL == _inst_config) { printf("Failed in start_perform_op: _inst_config is NULL.\n"); pthread_exit(NULL); } - HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) _inst_config; + HE_QAT_InstConfig* config = (HE_QAT_InstConfig*)_inst_config; CpaStatus status = CPA_STATUS_FAIL; // If called again, wait pthread_mutex_lock(&config->mutex); - while (config->active) - pthread_cond_wait(&config->ready, &config->mutex); + while (config->active) pthread_cond_wait(&config->ready, &config->mutex); - //assert(0 == config->active); - //assert(NULL == config->inst_handle); + // assert(0 == config->active); + // assert(NULL == config->inst_handle); status = cpaCyStartInstance(config->inst_handle); config->status = status; if (CPA_STATUS_SUCCESS == status) { - printf("Cpa CyInstance has successfully started.\n "); - status = cpaCySetAddressTranslation(config->inst_handle, - sampleVirtToPhys); - - } + printf("Cpa CyInstance has successfully started.\n "); + status = + cpaCySetAddressTranslation(config->inst_handle, sampleVirtToPhys); + } pthread_cond_signal(&config->ready); pthread_mutex_unlock(&config->mutex); - - if (CPA_STATUS_SUCCESS != status) - pthread_exit(NULL); + + if (CPA_STATUS_SUCCESS != status) pthread_exit(NULL); // Start QAT instance and start polling pthread_t polling_thread; - if (pthread_create(&polling_thread, config->attr, - start_inst_polling, (void *) config) != 0) { + if (pthread_create(&polling_thread, config->attr, start_inst_polling, + (void*)config) != 0) { printf("Failed at creating and starting polling thread.\n"); - pthread_exit(NULL); + pthread_exit(NULL); } if (pthread_detach(polling_thread) != 0) { @@ -209,10 +203,11 @@ void *start_perform_op(void *_inst_config) config->running = 1; config->active = 1; while (config->running) { - // Try consume data from butter to perform requested operation - HE_QAT_TaskRequest *request = (HE_QAT_TaskRequest *) read_request(&he_qat_buffer); + // Try consume data from butter to perform requested operation + HE_QAT_TaskRequest* request = + (HE_QAT_TaskRequest*)read_request(&he_qat_buffer); - if (NULL == request) { + if (NULL == request) { pthread_cond_signal(&config->ready); continue; } @@ -221,178 +216,181 @@ void *start_perform_op(void *_inst_config) unsigned retry = 0; do { - // Realize the type of operation from data - switch (request->op_type) { - // Select appropriate action - case HE_QAT_MODEXP: - // printf("Perform HE_QAT_MODEXP\n"); - status = cpaCyLnModExp(config->inst_handle, - lnModExpCallback, - (void *) request, - (CpaCyLnModExpOpData *) request->op_data, - &request->op_result); - retry++; - break; - case HE_QAT_NO_OP: - default: -// printf("HE_QAT_NO_OP\n"); - retry = HE_QAT_MAX_RETRY; - break; - } - + // Realize the type of operation from data + switch (request->op_type) { + // Select appropriate action + case HE_QAT_MODEXP: + // printf("Perform HE_QAT_MODEXP\n"); + status = cpaCyLnModExp(config->inst_handle, lnModExpCallback, + (void*)request, + (CpaCyLnModExpOpData*)request->op_data, + &request->op_result); + retry++; + break; + case HE_QAT_NO_OP: + default: + // printf("HE_QAT_NO_OP\n"); + retry = HE_QAT_MAX_RETRY; + break; + } + } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); - // Ensure every call to perform operation is blocking for each endpoint + // Ensure every call to perform operation is blocking for each endpoint if (CPA_STATUS_SUCCESS == status) { - //printf("Success at submission\n"); + // printf("Success at submission\n"); // Wait until the callback function has been called - if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { + if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { request->op_status = CPA_STATUS_FAIL; - request->request_status = HE_QAT_STATUS_FAIL; // Review it - printf("Failed in COMPLETION WAIT\n"); - //request->request_status = HE_QAT_STATUS_INCOMPLETE; - } //else printf("Completed ModExp.\n"); - - - // Destroy synchronization object - COMPLETION_DESTROY(&request->callback); - } + request->request_status = HE_QAT_STATUS_FAIL; // Review it + printf("Failed in COMPLETION WAIT\n"); + // request->request_status = HE_QAT_STATUS_INCOMPLETE; + } // else printf("Completed ModExp.\n"); + // Destroy synchronization object + COMPLETION_DESTROY(&request->callback); + } - // Wake up any blocked call to stop_perform_op, signaling that now it is - // safe to terminate running instances. Check if this detereorate performance. + // Wake up any blocked call to stop_perform_op, signaling that now it is + // safe to terminate running instances. Check if this detereorate + // performance. pthread_cond_signal(&config->ready); - // printf("Wake up stop_perform_op\n"); - // Update the status of the request - //request->op_status = status; - //if (CPA_STATUS_SUCCESS != status) + // printf("Wake up stop_perform_op\n"); + // Update the status of the request + // request->op_status = status; + // if (CPA_STATUS_SUCCESS != status) // request->request_status = HE_QAT_FAIL; - //else + // else // request->request_status = HE_QAT_READY; } pthread_exit(NULL); } -/// @brief +/// @brief /// @function -/// Stop first 'num_inst' number of cpaCyInstance(s), including their polling and running threads. -/// @param[in] HE_QAT_InstConfig config Vector of created instances with their configuration setup. -/// @param[in] num_inst Unsigned integer number indicating first number of instances to be terminated. -void stop_perform_op(HE_QAT_InstConfig *config, unsigned num_inst) -{ - //if () { +/// Stop first 'num_inst' number of cpaCyInstance(s), including their polling +/// and running threads. +/// @param[in] HE_QAT_InstConfig config Vector of created instances with their +/// configuration setup. +/// @param[in] num_inst Unsigned integer number indicating first number of +/// instances to be terminated. +void stop_perform_op(HE_QAT_InstConfig* config, unsigned num_inst) { + // if () { // Stop runnning and polling instances // Release QAT instances handles - if (NULL == config) return ; + if (NULL == config) return; CpaStatus status = CPA_STATUS_FAIL; for (unsigned i = 0; i < num_inst; i++) { - pthread_mutex_lock(&config[i].mutex); + pthread_mutex_lock(&config[i].mutex); #ifdef _DESTINY_DEBUG_VERBOSE - printf("Try teardown HE QAT instance #%d.\n",i); + printf("Try teardown HE QAT instance #%d.\n", i); #endif - while (0 == config[i].active) { - pthread_cond_wait(&config[i].ready, &config[i].mutex); - } - if (CPA_STATUS_SUCCESS == config[i].status && config[i].active) { + while (0 == config[i].active) { + pthread_cond_wait(&config[i].ready, &config[i].mutex); + } + if (CPA_STATUS_SUCCESS == config[i].status && config[i].active) { #ifdef _DESTINY_DEBUG_VERBOSE - printf("Stop polling and running threads #%d\n",i); + printf("Stop polling and running threads #%d\n", i); #endif - config[i].polling = 0; - config[i].running = 0; - OS_SLEEP(10); + config[i].polling = 0; + config[i].running = 0; + OS_SLEEP(10); #ifdef _DESTINY_DEBUG_VERBOSE - printf("Stop cpaCyInstance #%d\n",i); + printf("Stop cpaCyInstance #%d\n", i); #endif - if (config[i].inst_handle == NULL) continue; + if (config[i].inst_handle == NULL) continue; #ifdef _DESTINY_DEBUG_VERBOSE - printf("cpaCyStopInstance\n"); + printf("cpaCyStopInstance\n"); #endif - status = cpaCyStopInstance(config[i].inst_handle); - if (CPA_STATUS_SUCCESS != status) { - printf("Failed to stop QAT instance #%d\n",i); - } - } - pthread_cond_signal(&config[i].ready); - pthread_mutex_unlock(&config[i].mutex); + status = cpaCyStopInstance(config[i].inst_handle); + if (CPA_STATUS_SUCCESS != status) { + printf("Failed to stop QAT instance #%d\n", i); + } + } + pthread_cond_signal(&config[i].ready); + pthread_mutex_unlock(&config[i].mutex); } //} - - return ; + return; } -HE_QAT_STATUS bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits) -{ +HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, + int nbits) { // Unpack data and copy to QAT friendly memory space int len = nbits / 8; - Cpa8U *pBase = NULL; - Cpa8U *pModulus = NULL; - Cpa8U *pExponent = NULL; + Cpa8U* pBase = NULL; + Cpa8U* pModulus = NULL; + Cpa8U* pExponent = NULL; - HE_QAT_TaskRequest *request = (HE_QAT_TaskRequest *) calloc(1,sizeof(HE_QAT_TaskRequest)); + HE_QAT_TaskRequest* request = + (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); if (NULL == request) { - printf("HE_QAT_TaskRequest memory allocation failed in bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; + printf( + "HE_QAT_TaskRequest memory allocation failed in " + "bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; } - + // TODO: @fdiasmor Try it with 8-byte alignment. CpaStatus status = PHYS_CONTIG_ALLOC(&pBase, len); if (CPA_STATUS_SUCCESS == status && NULL != pBase) { - unsigned char *bin = (unsigned char *) calloc(len, sizeof(unsigned char)); - if (BN_bn2binpad(b, bin, len)) { - memcpy(pBase, bin, len); - } else { - printf("BN_bn2binpad failed in bnModExpPerformOp.\n"); - PHYS_CONTIG_FREE(pBase); - free(bin); - bin = NULL; - return HE_QAT_STATUS_FAIL; - } + unsigned char* bin = (unsigned char*)calloc(len, sizeof(unsigned char)); + if (BN_bn2binpad(b, bin, len)) { + memcpy(pBase, bin, len); + } else { + printf("BN_bn2binpad failed in bnModExpPerformOp.\n"); + PHYS_CONTIG_FREE(pBase); + free(bin); + bin = NULL; + return HE_QAT_STATUS_FAIL; + } } else { printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; + return HE_QAT_STATUS_FAIL; } status = PHYS_CONTIG_ALLOC(&pExponent, len); if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { - unsigned char *bin = (unsigned char *) calloc(len, sizeof(unsigned char)); - if (BN_bn2binpad(e, bin, len)) { - memcpy(pExponent, bin, len); - } else { - printf("BN_bn2binpad failed in bnModExpPerformOp.\n"); - PHYS_CONTIG_FREE(pExponent); - free(bin); - bin = NULL; - return HE_QAT_STATUS_FAIL; - } + unsigned char* bin = (unsigned char*)calloc(len, sizeof(unsigned char)); + if (BN_bn2binpad(e, bin, len)) { + memcpy(pExponent, bin, len); + } else { + printf("BN_bn2binpad failed in bnModExpPerformOp.\n"); + PHYS_CONTIG_FREE(pExponent); + free(bin); + bin = NULL; + return HE_QAT_STATUS_FAIL; + } } else { printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; + return HE_QAT_STATUS_FAIL; } status = PHYS_CONTIG_ALLOC(&pModulus, len); if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { - unsigned char *bin = (unsigned char *) calloc(len, sizeof(unsigned char)); - if (BN_bn2binpad(m, bin, len)) { - memcpy(pModulus, bin, len); - } else { - printf("BN_bn2binpad failed in bnModExpPerformOp.\n"); - free(bin); - bin = NULL; - return HE_QAT_STATUS_FAIL; - } + unsigned char* bin = (unsigned char*)calloc(len, sizeof(unsigned char)); + if (BN_bn2binpad(m, bin, len)) { + memcpy(pModulus, bin, len); + } else { + printf("BN_bn2binpad failed in bnModExpPerformOp.\n"); + free(bin); + bin = NULL; + return HE_QAT_STATUS_FAIL; + } } else { printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; + return HE_QAT_STATUS_FAIL; } - // Pack it as a QAT Task Request - CpaCyLnModExpOpData *op_data = (CpaCyLnModExpOpData *) calloc(1, sizeof(CpaCyLnModExpOpData)); + // Pack it as a QAT Task Request + CpaCyLnModExpOpData* op_data = + (CpaCyLnModExpOpData*)calloc(1, sizeof(CpaCyLnModExpOpData)); if (NULL == op_data) { - printf("Cpa memory allocation failed in bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; + printf("Cpa memory allocation failed in bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; } op_data->base.pData = pBase; op_data->base.dataLenInBytes = len; @@ -400,77 +398,77 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int op_data->exponent.dataLenInBytes = len; op_data->modulus.pData = pModulus; op_data->modulus.dataLenInBytes = len; - request->op_data = (void *) op_data; - + request->op_data = (void*)op_data; + status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); if (CPA_STATUS_SUCCESS == status && NULL != request->op_result.pData) { request->op_result.dataLenInBytes = len; } else { - printf("CpaFlatBuffer.pData memory allocation failed in bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; + printf( + "CpaFlatBuffer.pData memory allocation failed in " + "bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; } request->op_type = HE_QAT_MODEXP; request->op_status = status; - request->op_output = (void *) r; - + request->op_output = (void*)r; + pthread_mutex_init(&request->mutex, NULL); pthread_cond_init(&request->ready, NULL); // Submit request using producer function - //printf("Submit request \n"); - submit_request(&he_qat_buffer, (void *) request); + // printf("Submit request \n"); + submit_request(&he_qat_buffer, (void*)request); - return HE_QAT_STATUS_SUCCESS; + return HE_QAT_STATUS_SUCCESS; } // Maybe it will be useful to pass the number of requests to retrieve // Pass post-processing function as argument to bring output to expected type -void getBnModExpRequest(unsigned int batch_size) -{ +void getBnModExpRequest(unsigned int batch_size) { static unsigned int block_at_index = 0; unsigned int j = 0; do { - HE_QAT_TaskRequest *task = (HE_QAT_TaskRequest *) he_qat_buffer.data[block_at_index]; - pthread_mutex_lock(&task->mutex); + HE_QAT_TaskRequest* task = + (HE_QAT_TaskRequest*)he_qat_buffer.data[block_at_index]; + pthread_mutex_lock(&task->mutex); while (HE_QAT_READY != task->request_status) - pthread_cond_wait(&task->ready,&task->mutex); - pthread_mutex_unlock(&task->mutex); - block_at_index = (block_at_index+1)%HE_QAT_BUFFER_SIZE; + pthread_cond_wait(&task->ready, &task->mutex); + pthread_mutex_unlock(&task->mutex); + block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; } while (++j < batch_size); - return; + return; } /* - unsigned int finish = 0; - // TODO: @fdiasmor Introduce global variable that record at which upcoming request it currently is - while (0 == finish) { - finish = 1; - for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE && finish; i++) { - HE_QAT_TaskRequest *task = (HE_QAT_TaskRequest *) he_qat_buffer.data[i]; - // TODO: @fdiasmor Check if not NULL before read. + unsigned int finish = 0; + // TODO: @fdiasmor Introduce global variable that record at which upcoming +request it currently is while (0 == finish) { finish = 1; for (unsigned int i = +0; i < HE_QAT_BUFFER_SIZE && finish; i++) { HE_QAT_TaskRequest *task = +(HE_QAT_TaskRequest *) he_qat_buffer.data[i]; + // TODO: @fdiasmor Check if not NULL before read. if (NULL == task) continue; - finish = (HE_QAT_READY == task->request_status); + finish = (HE_QAT_READY == task->request_status); if (finish) { // ? 1 : 0; - // Set output results to original format - BIGNUM *r = BN_bin2bn(task->op_result.pData, task->op_result.dataLenInBytes, - (BIGNUM *) task->op_output); - - // Free up QAT temporary memory - CpaCyLnModExpOpData *op_data = (CpaCyLnModExpOpData *) task->op_data; - if (op_data) { - PHYS_CONTIG_FREE(op_data->base.pData); + // Set output results to original format + BIGNUM *r = BN_bin2bn(task->op_result.pData, +task->op_result.dataLenInBytes, (BIGNUM *) task->op_output); + + // Free up QAT temporary memory + CpaCyLnModExpOpData *op_data = (CpaCyLnModExpOpData *) +task->op_data; if (op_data) { PHYS_CONTIG_FREE(op_data->base.pData); PHYS_CONTIG_FREE(op_data->exponent.pData); - PHYS_CONTIG_FREE(op_data->modulus.pData); - } - if (task->op_result.pData) { - PHYS_CONTIG_FREE(task->op_result.pData); - } - - // Destroy synchronization object - COMPLETION_DESTROY(&task->callback); - } + PHYS_CONTIG_FREE(op_data->modulus.pData); + } + if (task->op_result.pData) { + PHYS_CONTIG_FREE(task->op_result.pData); + } + + // Destroy synchronization object + COMPLETION_DESTROY(&task->callback); + } } // printf("getBnModExpRequest end\n"); } diff --git a/he_qat_bn_ops.h b/he_qat_bn_ops.h index f759772..66fe8a1 100644 --- a/he_qat_bn_ops.h +++ b/he_qat_bn_ops.h @@ -9,61 +9,64 @@ #include "cpa_cy_ln.h" #include "he_qat_types.h" -#include "cpa_sample_utils.h" +#include "cpa_sample_utils.h" #include //#include #include -// #include "bignum.h" or create a standard interface +// #include "bignum.h" or create a standard interface #define HE_QAT_MAX_RETRY 100 // One for each consumer typedef struct { - //sem_t callback; + // sem_t callback; struct COMPLETION_STRUCT callback; HE_QAT_OP op_type; CpaStatus op_status; CpaFlatBuffer op_result; - //CpaCyLnModExpOpData op_data; - void *op_data; - void *op_output; + // CpaCyLnModExpOpData op_data; + void* op_data; + void* op_output; HE_QAT_STATUS request_status; pthread_mutex_t mutex; pthread_cond_t ready; } HE_QAT_TaskRequest; - /// @brief /// @function -/// Perform big number modular exponentiation for input data in +/// Perform big number modular exponentiation for input data in /// OpenSSL's BIGNUM format. /// @details /// Create private buffer for code section. Create QAT contiguous memory space. -/// Copy data and package into a request and call producer function to submit +/// Copy data and package into a request and call producer function to submit /// request into qat buffer. -/// @param r [out] Remainder number of the modular exponentiation operation. +/// @param r [out] Remainder number of the modular exponentiation operation. /// @param b [in] Base number of the modular exponentiation operation. /// @param e [in] Exponent number of the modular exponentiation operation. /// @param m [in] Modulus number of the modular exponentiation operation. /// @param nbits[in] Number of bits (bit precision) of input/output big numbers. -HE_QAT_STATUS bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits); +HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, + int nbits); /// @brief /// @function setModExpRequest(unsigned worksize) -/// Allocate buffer to hold and monitor up to 'worksize' number of outstanding requests. -/// @param[in] worksize Total number of modular exponentiation to perform in the next code section. -//void setModExpRequest(unsigned worksize) +/// Allocate buffer to hold and monitor up to 'worksize' number of outstanding +/// requests. +/// @param[in] worksize Total number of modular exponentiation to perform in the +/// next code section. +// void setModExpRequest(unsigned worksize) /// @brief /// @function getModExpRequest() -/// Monitor outstanding request to be complete and then deallocate buffer holding outstanding request; -/// @details +/// Monitor outstanding request to be complete and then deallocate buffer +/// holding outstanding request; +/// @details /// Releasing QAT temporary memory. // wait for all outstanding requests to complete -//void getBnModExpRequest(); +// void getBnModExpRequest(); void getBnModExpRequest(unsigned int num_requests); /// thus, releasing temporary memory. // create private buffer for code section @@ -72,4 +75,4 @@ void getBnModExpRequest(unsigned int num_requests); // use producer to place request into qat buffer // wait for all outstanding requests to complete -#endif +#endif diff --git a/he_qat_context.c b/he_qat_context.c index 5b9f7d3..ecfccc8 100644 --- a/he_qat_context.c +++ b/he_qat_context.c @@ -19,41 +19,40 @@ #include "icp_sal_poll.h" // Global variable declarations -HE_QAT_Inst he_qat_instances [HE_QAT_MAX_NUM_INST]; -pthread_attr_t he_qat_inst_attr [HE_QAT_MAX_NUM_INST]; -HE_QAT_InstConfig he_qat_inst_config [HE_QAT_MAX_NUM_INST]; -//HE_QAT_RequestBuffer he_qat_buffer; +HE_QAT_Inst he_qat_instances[HE_QAT_MAX_NUM_INST]; +pthread_attr_t he_qat_inst_attr[HE_QAT_MAX_NUM_INST]; +HE_QAT_InstConfig he_qat_inst_config[HE_QAT_MAX_NUM_INST]; +// HE_QAT_RequestBuffer he_qat_buffer; extern HE_QAT_RequestBuffer he_qat_buffer; -extern void *start_perform_op(void *_inst_config); -extern void stop_perform_op(void *_inst_config, unsigned num_inst); - +extern void* start_perform_op(void* _inst_config); +extern void stop_perform_op(void* _inst_config, unsigned num_inst); CpaInstanceHandle handle = NULL; -/// @brief +/// @brief /// @function acquire_qat_devices /// Acquire QAT instances and set up QAT execution environment. -HE_QAT_STATUS acquire_qat_devices() -{ +HE_QAT_STATUS acquire_qat_devices() { CpaStatus status = CPA_STATUS_FAIL; // Initialize QAT memory pool allocator status = qaeMemInit(); if (CPA_STATUS_SUCCESS != status) { printf("Failed to initialized memory driver.\n"); - return HE_QAT_STATUS_FAIL; // HEQAT_STATUS_ERROR + return HE_QAT_STATUS_FAIL; // HEQAT_STATUS_ERROR } #ifdef _DESTINY_DEBUG_VERBOSE printf("QAT memory successfully initialized.\n"); #endif - // Not sure if for multiple instances the id will need to be specified, e.g. "SSL1" + // Not sure if for multiple instances the id will need to be specified, e.g. + // "SSL1" status = icp_sal_userStartMultiProcess("SSL", CPA_FALSE); if (CPA_STATUS_SUCCESS != status) { printf("Failed to start SAL user process SSL\n"); qaeMemDestroy(); - return HE_QAT_STATUS_FAIL; // HEQAT_STATUS_ERROR + return HE_QAT_STATUS_FAIL; // HEQAT_STATUS_ERROR } #ifdef _DESTINY_DEBUG_VERBOSE printf("SAL user process successfully started.\n"); @@ -66,17 +65,17 @@ HE_QAT_STATUS acquire_qat_devices() if (_inst_handle == NULL) { printf("Failed to find QAT endpoints.\n"); return HE_QAT_STATUS_FAIL; - } - - //sampleCyGetInstance(&handle); - //if (handle == NULL) { + } + + // sampleCyGetInstance(&handle); + // if (handle == NULL) { // printf("Failed to find QAT endpoints.\n"); // return HE_QAT_STATUS_FAIL; - //} + //} #ifdef _DESTINY_DEBUG_VERBOSE printf("Found QAT endpoints.\n"); #endif - + // Initialize QAT buffer synchronization attributes he_qat_buffer.count = 0; he_qat_buffer.next_free_slot = 0; @@ -92,26 +91,27 @@ HE_QAT_STATUS acquire_qat_devices() cpu_set_t cpus; for (int i = 0; i < HE_QAT_SYNC; i++) { CPU_ZERO(&cpus); - CPU_SET(i, &cpus); + CPU_SET(i, &cpus); pthread_attr_init(&he_qat_inst_attr[i]); - pthread_attr_setaffinity_np(&he_qat_inst_attr[i], sizeof(cpu_set_t), &cpus); + pthread_attr_setaffinity_np(&he_qat_inst_attr[i], sizeof(cpu_set_t), + &cpus); // configure thread - //HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) + // HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) // malloc(sizeof(QATInstConfig)); - //if (config == NULL) return HE_QAT_FAIL; - he_qat_inst_config[i].active = 0; // HE_QAT_STATUS_INACTIVE - he_qat_inst_config[i].polling = 0; // HE_QAT_STATUS_INACTIVE - he_qat_inst_config[i].running = 0; + // if (config == NULL) return HE_QAT_FAIL; + he_qat_inst_config[i].active = 0; // HE_QAT_STATUS_INACTIVE + he_qat_inst_config[i].polling = 0; // HE_QAT_STATUS_INACTIVE + he_qat_inst_config[i].running = 0; he_qat_inst_config[i].status = CPA_STATUS_FAIL; - // he_qat_inst_config[i].mutex = PTHREAD_MUTEX_INITIALIZER; - pthread_mutex_init(&he_qat_inst_config[i].mutex,NULL); - // he_qat_inst_config[i].ready = PTHREAD_COND_INITIALIZER; - pthread_cond_init(&he_qat_inst_config[i].ready,NULL); + // he_qat_inst_config[i].mutex = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_init(&he_qat_inst_config[i].mutex, NULL); + // he_qat_inst_config[i].ready = PTHREAD_COND_INITIALIZER; + pthread_cond_init(&he_qat_inst_config[i].ready, NULL); he_qat_inst_config[i].inst_handle = _inst_handle; - he_qat_inst_config[i].attr = &he_qat_inst_attr[i]; - pthread_create(&he_qat_instances[i], he_qat_inst_config[i].attr, - start_perform_op, (void *) &he_qat_inst_config[i]); + he_qat_inst_config[i].attr = &he_qat_inst_attr[i]; + pthread_create(&he_qat_instances[i], he_qat_inst_config[i].attr, + start_perform_op, (void*)&he_qat_inst_config[i]); } #ifdef _DESTINY_DEBUG_VERBOSE printf("Created processing threads.\n"); @@ -131,21 +131,20 @@ HE_QAT_STATUS acquire_qat_devices() /// @brief /// @function release_qat_devices /// Release QAT instances and tear down QAT execution environment. -HE_QAT_STATUS release_qat_devices() -{ +HE_QAT_STATUS release_qat_devices() { CpaStatus status = CPA_STATUS_FAIL; // signal all qat instance to stop polling -// stop_inst_polling(); -// -// // Release QAT instances handles -// for (int i = 0; i < HE_QAT_MAX_NUM_INST; i++) { -// status = cpaCyStopInstance(he_qat_inst_config[i].inst_handle); -// if (CPA_STATUS_SUCCESS != status) { -// printf("Failed to stop QAT instance #%d\n",i); -// return HE_QAT_STATUS_FAIL; -// } -// } + // stop_inst_polling(); + // + // // Release QAT instances handles + // for (int i = 0; i < HE_QAT_MAX_NUM_INST; i++) { + // status = cpaCyStopInstance(he_qat_inst_config[i].inst_handle); + // if (CPA_STATUS_SUCCESS != status) { + // printf("Failed to stop QAT instance #%d\n",i); + // return HE_QAT_STATUS_FAIL; + // } + // } stop_perform_op(he_qat_inst_config, HE_QAT_SYNC); #ifdef _DESTINY_DEBUG_VERBOSE @@ -160,7 +159,7 @@ HE_QAT_STATUS release_qat_devices() printf("Stopped SAL user process.\n"); #endif - // Release QAT allocated memory + // Release QAT allocated memory qaeMemDestroy(); #ifdef _DESTINY_DEBUG_VERBOSE printf("Release QAT memory.\n"); @@ -168,4 +167,3 @@ HE_QAT_STATUS release_qat_devices() return HE_QAT_STATUS_SUCCESS; } - diff --git a/he_qat_context.h b/he_qat_context.h index bcf833a..0dc6686 100644 --- a/he_qat_context.h +++ b/he_qat_context.h @@ -8,14 +8,14 @@ #include #define HE_QAT_MAX_NUM_INST 8 -//const unsigned HE_QAT_MAX_NUM_INST = 8 +// const unsigned HE_QAT_MAX_NUM_INST = 8 -/// @brief +/// @brief /// @function acquire_qat_devices /// Configure and initialize QAT runtime environment. HE_QAT_STATUS acquire_qat_devices(); -/// @brief +/// @brief /// @function release_qat_devices /// Configure and initialize QAT runtime environment. HE_QAT_STATUS release_qat_devices(); diff --git a/he_qat_types.h b/he_qat_types.h index d6b5d5f..617f863 100644 --- a/he_qat_types.h +++ b/he_qat_types.h @@ -10,41 +10,36 @@ #include #define HE_QAT_BUFFER_SIZE 4 -//const unsigned HE_QAT_BUFFER_SIZE = 4; +// const unsigned HE_QAT_BUFFER_SIZE = 4; // Type definitions -typedef enum { - HE_QAT_SYNC = 1, - HE_QAT_ASYNC = 2 -} HE_QAT_EXEC_MODE; - -typedef enum { - HE_QAT_READY = 1, - HE_QAT_STATUS_SUCCESS = 0, - HE_QAT_STATUS_FAIL = -1 +typedef enum { HE_QAT_SYNC = 1, HE_QAT_ASYNC = 2 } HE_QAT_EXEC_MODE; + +typedef enum { + HE_QAT_READY = 1, + HE_QAT_STATUS_SUCCESS = 0, + HE_QAT_STATUS_FAIL = -1 } HE_QAT_STATUS; -typedef enum { - HE_QAT_NO_OP = 0, - HE_QAT_MODEXP = 1 -} HE_QAT_OP; +typedef enum { HE_QAT_NO_OP = 0, HE_QAT_MODEXP = 1 } HE_QAT_OP; typedef pthread_t HE_QAT_Inst; typedef struct { - void *data[HE_QAT_BUFFER_SIZE]; // + void* data[HE_QAT_BUFFER_SIZE]; // int count; // occupied track number of buffer enties - int next_free_slot; // nextin index of the next free slot to accommodate a request - int next_data_slot; // nextout index of next request to be processed - pthread_mutex_t mutex; // - pthread_cond_t any_more_data; // more - pthread_cond_t any_free_slot; // less + int next_free_slot; // nextin index of the next free slot to accommodate a + // request + int next_data_slot; // nextout index of next request to be processed + pthread_mutex_t mutex; // + pthread_cond_t any_more_data; // more + pthread_cond_t any_free_slot; // less } HE_QAT_RequestBuffer; -typedef struct { +typedef struct { CpaInstanceHandle inst_handle; - pthread_attr_t *attr; - HE_QAT_RequestBuffer *he_qat_buffer; + pthread_attr_t* attr; + HE_QAT_RequestBuffer* he_qat_buffer; pthread_mutex_t mutex; pthread_cond_t ready; volatile int active; @@ -54,4 +49,3 @@ typedef struct { } HE_QAT_InstConfig; #endif - diff --git a/test_bnModExpPerformOp.c b/test_bnModExpPerformOp.c index 13bce48..d0fa50a 100644 --- a/test_bnModExpPerformOp.c +++ b/test_bnModExpPerformOp.c @@ -9,87 +9,79 @@ #include #include -#define LEN_OF_1024_BITS 128 -#define LEN_OF_2048_BITS 256 -#define msb_CAN_BE_ZERO -1 -#define msb_IS_ONE 0 -#define EVEN_RND_NUM 0 -#define ODD_RND_NUM 1 -#define BATCH_SIZE 1 +#define LEN_OF_1024_BITS 128 +#define LEN_OF_2048_BITS 256 +#define msb_CAN_BE_ZERO -1 +#define msb_IS_ONE 0 +#define EVEN_RND_NUM 0 +#define ODD_RND_NUM 1 +#define BATCH_SIZE 1 int gDebugParam = 1; - -BIGNUM *generateTestBNData(int nbits) -{ - if (!RAND_status()) - return NULL; +BIGNUM* generateTestBNData(int nbits) { + if (!RAND_status()) return NULL; #ifdef _DESTINY_DEBUG_VERBOSE printf("PRNG properly seeded.\n"); #endif - BIGNUM *bn = BN_new(); + BIGNUM* bn = BN_new(); if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { BN_free(bn); - printf("Error while generating BN random number: %lu\n",ERR_get_error()); + printf("Error while generating BN random number: %lu\n", + ERR_get_error()); return NULL; } - return bn; + return bn; } -unsigned char *paddingZeros(BIGNUM *bn, int nbits) -{ +unsigned char* paddingZeros(BIGNUM* bn, int nbits) { if (!bn) return NULL; // Returns same address if it fails int num_bytes = BN_num_bytes(bn); - int bytes_left = nbits/8 - num_bytes; - if (bytes_left <= 0) return NULL; + int bytes_left = nbits / 8 - num_bytes; + if (bytes_left <= 0) return NULL; // Returns same address if it fails - unsigned char *bin = NULL; + unsigned char* bin = NULL; int len = bytes_left + num_bytes; if (!(bin = OPENSSL_zalloc(len))) return NULL; #ifdef _DESTINY_DEBUG_VERBOSE - printf("Padding bn with %d bytes to total %d bytes\n",bytes_left,len); + printf("Padding bn with %d bytes to total %d bytes\n", bytes_left, len); #endif - BN_bn2binpad(bn,bin,len); + BN_bn2binpad(bn, bin, len); if (ERR_get_error()) { OPENSSL_free(bin); - return NULL; + return NULL; } return bin; } -void showHexBN(BIGNUM *bn, int nbits) -{ +void showHexBN(BIGNUM* bn, int nbits) { int len = nbits / 8; - unsigned char *bin = OPENSSL_zalloc(len); - if (!bin) return ; - if (BN_bn2binpad(bn,bin,len)) { - for (size_t i = 0; i < len; i++) - printf("%d",bin[i]); + unsigned char* bin = OPENSSL_zalloc(len); + if (!bin) return; + if (BN_bn2binpad(bn, bin, len)) { + for (size_t i = 0; i < len; i++) printf("%d", bin[i]); printf("\n"); } OPENSSL_free(bin); - return ; + return; } -void showHexBin(unsigned char *bin, int len) -{ - if (!bin) return ; - for (size_t i = 0; i < len; i++) - printf("%d",bin[i]); +void showHexBin(unsigned char* bin, int len) { + if (!bin) return; + for (size_t i = 0; i < len; i++) printf("%d", bin[i]); printf("\n"); - return ; + return; } -int main(int argc, const char **argv) -{ +int main(int argc, const char** argv) { const size_t num_trials = 100; const int bit_length = 1024; @@ -97,96 +89,96 @@ int main(int argc, const char **argv) acquire_qat_devices(); // OpenSSL as baseline - BN_CTX *ctx = BN_CTX_new(); + BN_CTX* ctx = BN_CTX_new(); BN_CTX_start(ctx); - + CpaStatus status = CPA_STATUS_SUCCESS; - + for (size_t mod = 0; mod < num_trials; mod++) { - printf("Trial #%0.3lu\t",mod+1); - - BIGNUM *bn_mod = generateTestBNData(bit_length); + printf("Trial #%0.3lu\t", mod + 1); + + BIGNUM* bn_mod = generateTestBNData(bit_length); if (!bn_mod) continue; - char *bn_str = BN_bn2hex(bn_mod); + char* bn_str = BN_bn2hex(bn_mod); #ifdef _DESTINY_DEBUG_VERBOSE - printf("Generated modulus: %s num_bytes: %d num_bits: %d\n", - bn_str,BN_num_bytes(bn_mod),BN_num_bits(bn_mod)); + printf("Generated modulus: %s num_bytes: %d num_bits: %d\n", bn_str, + BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); #endif - // bn_exponent in [0..bn_mod] - BIGNUM *bn_exponent = BN_new(); - if (!BN_rand_range(bn_exponent, bn_mod)) { + // bn_exponent in [0..bn_mod] + BIGNUM* bn_exponent = BN_new(); + if (!BN_rand_range(bn_exponent, bn_mod)) { BN_free(bn_mod); - continue; - } + continue; + } - BIGNUM *bn_base = generateTestBNData(bit_length); + BIGNUM* bn_base = generateTestBNData(bit_length); - BIGNUM *ssl_res = BN_new(); - clock_t start = clock(); + BIGNUM* ssl_res = BN_new(); + clock_t start = clock(); BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); - clock_t elapsed = clock() - start; + clock_t elapsed = clock() - start; - - //if (BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx)) { - if (!ERR_get_error()) { - bn_str = BN_bn2hex(ssl_res); + // if (BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx)) { + if (!ERR_get_error()) { + bn_str = BN_bn2hex(ssl_res); #ifdef _DESTINY_DEBUG_VERBOSE - printf("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", - bn_str, BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); - showHexBN(ssl_res, bit_length); + printf("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", bn_str, + BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); + showHexBN(ssl_res, bit_length); #endif - } else { - printf("Modular exponentiation failed.\n"); - } + } else { + printf("Modular exponentiation failed.\n"); + } #ifdef _DESTINY_DEBUG_VERBOSE PRINT_DBG("\nStarting QAT bnModExp...\n"); #endif printf("OpenSSL: %.1lfus\t", elapsed / (CLOCKS_PER_SEC / 1000000.0)); - - BIGNUM *qat_res = BN_new(); - HE_QAT_STATUS he_qat_status = HE_QAT_STATUS_FAIL; - start = clock(); - for (unsigned int j = 0; j < BATCH_SIZE; j++) - he_qat_status = bnModExpPerformOp(qat_res, bn_base, bn_exponent, bn_mod, bit_length); - getBnModExpRequest(BATCH_SIZE); + + BIGNUM* qat_res = BN_new(); + HE_QAT_STATUS he_qat_status = HE_QAT_STATUS_FAIL; + start = clock(); + for (unsigned int j = 0; j < BATCH_SIZE; j++) + he_qat_status = bnModExpPerformOp(qat_res, bn_base, bn_exponent, + bn_mod, bit_length); + getBnModExpRequest(BATCH_SIZE); elapsed = clock() - start; - printf("QAT: %.1lfus\t", elapsed / (CLOCKS_PER_SEC / 1000000.0)); + printf("QAT: %.1lfus\t", elapsed / (CLOCKS_PER_SEC / 1000000.0)); - if (HE_QAT_STATUS_SUCCESS != he_qat_status) { + if (HE_QAT_STATUS_SUCCESS != he_qat_status) { PRINT_ERR("\nQAT bnModExpOp failed\n"); - } + } #ifdef _DESTINY_DEBUG_VERBOSE - else { + else { PRINT_DBG("\nQAT bnModExpOp finished\n"); } #endif -// icp_sal_userStop(); -// qaeMemDestroy(); + // icp_sal_userStop(); + // qaeMemDestroy(); if (BN_cmp(qat_res, ssl_res) != 0) printf("\t** FAIL **\n"); - else - printf("\t** PASS **\n"); - - OPENSSL_free(bn_str); - - BN_free(ssl_res); - BN_free(qat_res); - - BN_free(bn_mod); - BN_free(bn_base); - BN_free(bn_exponent); + else + printf("\t** PASS **\n"); + + OPENSSL_free(bn_str); + + BN_free(ssl_res); + BN_free(qat_res); + + BN_free(bn_mod); + BN_free(bn_base); + BN_free(bn_exponent); } BN_CTX_end(ctx); - // Tear down QAT runtime environment + // Tear down QAT runtime environment release_qat_devices(); return (int)status; diff --git a/test_context.c b/test_context.c index cfdb129..e640e8b 100644 --- a/test_context.c +++ b/test_context.c @@ -3,14 +3,13 @@ #include "cpa_sample_utils.h" #include "he_qat_context.h" -int main() -{ +int main() { HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; status = acquire_qat_devices(); if (HE_QAT_STATUS_SUCCESS == status) { printf("Completed acquire_qat_devices() successfully.\n"); - } else { + } else { printf("acquire_qat_devices() failed.\n"); exit(1); } @@ -20,10 +19,10 @@ int main() status = release_qat_devices(); if (HE_QAT_STATUS_SUCCESS == status) { printf("Completed release_qat_devices() successfully.\n"); - } else { + } else { printf("release_qat_devices() failed.\n"); exit(1); - } - + } + return 0; } From b6beba171b8f0004f4fef6c4bc89e2972c6cea45 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 1 Mar 2022 12:42:02 -0800 Subject: [PATCH 057/364] Reduce and free allocated memory for requests. --- he_qat_bn_ops.c | 71 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 19 deletions(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index e29329f..62193a2 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -335,18 +335,23 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, } // TODO: @fdiasmor Try it with 8-byte alignment. - CpaStatus status = PHYS_CONTIG_ALLOC(&pBase, len); + CpaStatus status = CPA_STATUS_FAIL; + status = PHYS_CONTIG_ALLOC(&pBase, len); if (CPA_STATUS_SUCCESS == status && NULL != pBase) { - unsigned char* bin = (unsigned char*)calloc(len, sizeof(unsigned char)); - if (BN_bn2binpad(b, bin, len)) { - memcpy(pBase, bin, len); + //{ + // unsigned char* bin = (unsigned char*)calloc(len, sizeof(unsigned + // char)); if (BN_bn2binpad(b, bin, len)) { + if (BN_bn2binpad(b, pBase, len)) { + // memcpy(pBase, bin, len); + // pBase = (Cpa8U*)bin; } else { - printf("BN_bn2binpad failed in bnModExpPerformOp.\n"); + printf("BN_bn2binpad (base) failed in bnModExpPerformOp.\n"); PHYS_CONTIG_FREE(pBase); - free(bin); - bin = NULL; + // free(bin); + // bin = NULL; return HE_QAT_STATUS_FAIL; } + //} } else { printf("Contiguous memory allocation failed for pBase.\n"); return HE_QAT_STATUS_FAIL; @@ -354,16 +359,20 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, status = PHYS_CONTIG_ALLOC(&pExponent, len); if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { - unsigned char* bin = (unsigned char*)calloc(len, sizeof(unsigned char)); - if (BN_bn2binpad(e, bin, len)) { - memcpy(pExponent, bin, len); + //{ + // unsigned char* bin = (unsigned char*)calloc(len, sizeof(unsigned + // char)); if (BN_bn2binpad(e, bin, len)) { + if (BN_bn2binpad(e, pExponent, len)) { + // memcpy(pExponent, bin, len); + // pExponent = (Cpa8U*)bin; } else { - printf("BN_bn2binpad failed in bnModExpPerformOp.\n"); + printf("BN_bn2binpad (exponent) failed in bnModExpPerformOp.\n"); PHYS_CONTIG_FREE(pExponent); - free(bin); - bin = NULL; + // free(bin); + // bin = NULL; return HE_QAT_STATUS_FAIL; } + //} } else { printf("Contiguous memory allocation failed for pBase.\n"); return HE_QAT_STATUS_FAIL; @@ -371,15 +380,20 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, status = PHYS_CONTIG_ALLOC(&pModulus, len); if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { - unsigned char* bin = (unsigned char*)calloc(len, sizeof(unsigned char)); - if (BN_bn2binpad(m, bin, len)) { - memcpy(pModulus, bin, len); + //{ + // unsigned char* bin = (unsigned char*)calloc(len, sizeof(unsigned + // char)); if (BN_bn2binpad(m, bin, len)) { + if (BN_bn2binpad(m, pModulus, len)) { + // memcpy(pModulus, bin, len); + // pModulus = (Cpa8U*)bin; } else { printf("BN_bn2binpad failed in bnModExpPerformOp.\n"); - free(bin); - bin = NULL; + PHYS_CONTIG_FREE(pModulus); + // free(bin); + // bin = NULL; return HE_QAT_STATUS_FAIL; } + //} } else { printf("Contiguous memory allocation failed for pBase.\n"); return HE_QAT_STATUS_FAIL; @@ -414,6 +428,7 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, request->op_status = status; request->op_output = (void*)r; + // Ensure calls are synchronous and blocking pthread_mutex_init(&request->mutex, NULL); pthread_cond_init(&request->ready, NULL); @@ -430,11 +445,29 @@ void getBnModExpRequest(unsigned int batch_size) { static unsigned int block_at_index = 0; unsigned int j = 0; do { + // Buffer read may be safe for single-threaded blocking calls only. + // Note: Not tested on multithreaded environment. HE_QAT_TaskRequest* task = (HE_QAT_TaskRequest*)he_qat_buffer.data[block_at_index]; - pthread_mutex_lock(&task->mutex); + // Block and synchronize: Wait for the most recently offloaded request + // to complete processing + pthread_mutex_lock( + &task->mutex); // mutex only needed for the conditional variable while (HE_QAT_READY != task->request_status) pthread_cond_wait(&task->ready, &task->mutex); + // Free up QAT temporary memory + CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; + if (op_data) { + PHYS_CONTIG_FREE(op_data->base.pData); + PHYS_CONTIG_FREE(op_data->exponent.pData); + PHYS_CONTIG_FREE(op_data->modulus.pData); + } + free(task->op_data); + task->op_data = NULL; + if (task->op_result.pData) { + PHYS_CONTIG_FREE(task->op_result.pData); + } + // Move forward to wait for the next request that will be offloaded pthread_mutex_unlock(&task->mutex); block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; } while (++j < batch_size); From a21d945b0d9111788e167ad599a4a7c69e0736da Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 1 Mar 2022 12:59:04 -0800 Subject: [PATCH 058/364] Fix memory leak due to mem alloc of requests. --- he_qat_bn_ops.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index 62193a2..9b07ab6 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -467,6 +467,8 @@ void getBnModExpRequest(unsigned int batch_size) { if (task->op_result.pData) { PHYS_CONTIG_FREE(task->op_result.pData); } + free(he_qat_buffer.data[block_at_index]); + he_qat_buffer.data[block_at_index] = NULL; // Move forward to wait for the next request that will be offloaded pthread_mutex_unlock(&task->mutex); block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; From 9e0f56ad3768a10f8dcd990aa7a37fead8bf0f27 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 1 Mar 2022 13:00:21 -0800 Subject: [PATCH 059/364] Fix mem leak due to string from BN_bn2hex. --- test_bnModExpPerformOp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test_bnModExpPerformOp.c b/test_bnModExpPerformOp.c index d0fa50a..1d7b738 100644 --- a/test_bnModExpPerformOp.c +++ b/test_bnModExpPerformOp.c @@ -101,10 +101,11 @@ int main(int argc, const char** argv) { if (!bn_mod) continue; - char* bn_str = BN_bn2hex(bn_mod); #ifdef _DESTINY_DEBUG_VERBOSE + char* bn_str = BN_bn2hex(bn_mod); printf("Generated modulus: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); + OPENSSL_free(bn_str); #endif // bn_exponent in [0..bn_mod] BIGNUM* bn_exponent = BN_new(); @@ -122,11 +123,12 @@ int main(int argc, const char** argv) { // if (BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx)) { if (!ERR_get_error()) { - bn_str = BN_bn2hex(ssl_res); #ifdef _DESTINY_DEBUG_VERBOSE + bn_str = BN_bn2hex(ssl_res); printf("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); showHexBN(ssl_res, bit_length); + OPENSSL_free(bn_str); #endif } else { printf("Modular exponentiation failed.\n"); @@ -166,8 +168,6 @@ int main(int argc, const char** argv) { else printf("\t** PASS **\n"); - OPENSSL_free(bn_str); - BN_free(ssl_res); BN_free(qat_res); From 24a4fabaa11e5d7fb4e32afa12fb46dd11abef3c Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Tue, 1 Mar 2022 13:21:02 -0800 Subject: [PATCH 060/364] Add const keyword (#18) - applied constant protection to all member functions and needed arguments - public key member is const in both paillier_prikey and paillier_ops --- ipcl/include/ipcl/paillier_ops.hpp | 22 ++++++++++++---------- ipcl/include/ipcl/paillier_prikey.hpp | 22 +++++++++++----------- ipcl/include/ipcl/paillier_pubkey.hpp | 18 +++++++++--------- ipcl/paillier_ops.cpp | 24 +++++++++++------------- ipcl/paillier_prikey.cpp | 18 +++++++++--------- ipcl/paillier_pubkey.cpp | 25 +++++++++++++++---------- 6 files changed, 67 insertions(+), 62 deletions(-) diff --git a/ipcl/include/ipcl/paillier_ops.hpp b/ipcl/include/ipcl/paillier_ops.hpp index 9590579..029100c 100644 --- a/ipcl/include/ipcl/paillier_ops.hpp +++ b/ipcl/include/ipcl/paillier_ops.hpp @@ -17,7 +17,8 @@ class PaillierEncryptedNumber { * @param[in] pub_key paillier public key * @param[in] bn ciphertext encrypted by paillier public key */ - PaillierEncryptedNumber(PaillierPublicKey* pub_key, const BigNumber& bn); + PaillierEncryptedNumber(const PaillierPublicKey* pub_key, + const BigNumber& bn); /** * PaillierEncryptedNumber constructor @@ -25,8 +26,8 @@ class PaillierEncryptedNumber { * @param[in] bn array of ciphertexts encrypted by paillier public key * @param[in] length size of array(default value is 8) */ - PaillierEncryptedNumber(PaillierPublicKey* pub_key, const BigNumber bn[8], - size_t length = 8); + PaillierEncryptedNumber(const PaillierPublicKey* pub_key, + const BigNumber bn[8], size_t length = 8); /** * PaillierEncryptedNumber constructor @@ -34,8 +35,8 @@ class PaillierEncryptedNumber { * @param[in] scalar array of integer scalars * @param[in] length size of array(default value is 8) */ - PaillierEncryptedNumber(PaillierPublicKey* pub_key, const uint32_t scalar[8], - size_t length = 8); + PaillierEncryptedNumber(const PaillierPublicKey* pub_key, + const uint32_t scalar[8], size_t length = 8); /** * Arithmetic addition operator @@ -102,7 +103,7 @@ class PaillierEncryptedNumber { * Rotate PaillierEncryptedNumber * @param[in] shift rotate length */ - PaillierEncryptedNumber rotate(int shift); + PaillierEncryptedNumber rotate(int shift) const; /** * Return entire ciphertext array @@ -125,13 +126,14 @@ class PaillierEncryptedNumber { private: bool b_isObfuscator; int m_available; - PaillierPublicKey* m_pubkey; + const PaillierPublicKey* m_pubkey; size_t m_length; BigNumber m_bn[8]; - BigNumber raw_add(const BigNumber& a, const BigNumber& b); - BigNumber raw_mul(const BigNumber& a, const BigNumber& b); - void raw_mul(BigNumber res[8], BigNumber a[8], BigNumber b[8]); + BigNumber raw_add(const BigNumber& a, const BigNumber& b) const; + BigNumber raw_mul(const BigNumber& a, const BigNumber& b) const; + void raw_mul(BigNumber res[8], const BigNumber a[8], + const BigNumber b[8]) const; }; } // namespace ipcl diff --git a/ipcl/include/ipcl/paillier_prikey.hpp b/ipcl/include/ipcl/paillier_prikey.hpp index 6794914..a695366 100644 --- a/ipcl/include/ipcl/paillier_prikey.hpp +++ b/ipcl/include/ipcl/paillier_prikey.hpp @@ -16,7 +16,7 @@ class PaillierPrivateKey { * @param[in] p p of private key in paillier scheme * @param[in] q q of private key in paillier scheme */ - PaillierPrivateKey(PaillierPublicKey* public_key, const BigNumber& p, + PaillierPrivateKey(const PaillierPublicKey* public_key, const BigNumber& p, const BigNumber& q); /** @@ -30,7 +30,7 @@ class PaillierPrivateKey { * @param[out] plaintext output of the decryption * @param[in] ciphertext ciphertext to be decrypted */ - void decrypt(BigNumber plaintext[8], const BigNumber ciphertext[8]); + void decrypt(BigNumber plaintext[8], const BigNumber ciphertext[8]) const; /** * Decrypt ciphertext @@ -38,7 +38,7 @@ class PaillierPrivateKey { * @param[in] ciphertext PaillierEncryptedNumber to be decrypted */ void decrypt(BigNumber plaintext[8], - const PaillierEncryptedNumber ciphertext); + const PaillierEncryptedNumber ciphertext) const; const void* addr = static_cast(this); @@ -65,17 +65,17 @@ class PaillierPrivateKey { /** * Get public key */ - PaillierPublicKey* getPubKey() const { return m_pubkey; } + const PaillierPublicKey* getPubKey() const { return m_pubkey; } /** * @brief Support function for ISO/IEC 18033-6 compliance check * * @return BigNumber */ - BigNumber getLambda() { return m_lambda; } + BigNumber getLambda() const { return m_lambda; } private: - PaillierPublicKey* m_pubkey; + const PaillierPublicKey* m_pubkey; BigNumber m_n; BigNumber m_nsquare; BigNumber m_g; @@ -100,7 +100,7 @@ class PaillierPrivateKey { * @param[in] b input b * @return the L function result of type BigNumber */ - BigNumber computeLfun(const BigNumber& a, const BigNumber& b); + BigNumber computeLfun(const BigNumber& a, const BigNumber& b) const; /** * Compute H function in paillier scheme @@ -108,7 +108,7 @@ class PaillierPrivateKey { * @param[in] b input b * @return the H function result of type BigNumber */ - BigNumber computeHfun(const BigNumber& a, const BigNumber& b); + BigNumber computeHfun(const BigNumber& a, const BigNumber& b) const; /** * Compute CRT function in paillier scheme @@ -116,21 +116,21 @@ class PaillierPrivateKey { * @param[in] mq input mq * @return the CRT result of type BigNumber */ - BigNumber computeCRT(const BigNumber& mp, const BigNumber& mq); + BigNumber computeCRT(const BigNumber& mp, const BigNumber& mq) const; /** * Raw decryption function without CRT optimization * @param[out] plaintext output plaintext * @param[in] ciphertext input ciphertext */ - void decryptRAW(BigNumber plaintext[8], const BigNumber ciphertext[8]); + void decryptRAW(BigNumber plaintext[8], const BigNumber ciphertext[8]) const; /** * Raw decryption function with CRT optimization * @param[out] plaintext output plaintext * @param[in] ciphertext input ciphertext */ - void decryptCRT(BigNumber plaintext[8], const BigNumber ciphertext[8]); + void decryptCRT(BigNumber plaintext[8], const BigNumber ciphertext[8]) const; }; } // namespace ipcl diff --git a/ipcl/include/ipcl/paillier_pubkey.hpp b/ipcl/include/ipcl/paillier_pubkey.hpp index d18a228..5be1807 100644 --- a/ipcl/include/ipcl/paillier_pubkey.hpp +++ b/ipcl/include/ipcl/paillier_pubkey.hpp @@ -43,14 +43,14 @@ class PaillierPublicKey { * @param[in] make_secure apply obfuscator(default value is true) */ void encrypt(BigNumber ciphertext[8], const BigNumber value[8], - bool make_secure = true); + bool make_secure = true) const; /** * Encrypt plaintext * @param[out] ciphertext output of the encryption * @param[in] value plaintext to be encrypted */ - void encrypt(BigNumber& ciphertext, const BigNumber& value); + void encrypt(BigNumber& ciphertext, const BigNumber& value) const; /** * Modular exponentiation @@ -60,7 +60,7 @@ class PaillierPublicKey { * @return the modular exponentiation result of type BigNumber */ BigNumber ippMontExp(const BigNumber& base, const BigNumber& pow, - const BigNumber& m); + const BigNumber& m) const; /** * Multi-buffered modular exponentiation @@ -69,8 +69,8 @@ class PaillierPublicKey { * @param[in] pow arrya pow of the exponentiation * @param[in] m arrayodular */ - void ippMultiBuffExp(BigNumber res[8], BigNumber base[8], - const BigNumber pow[8], BigNumber m[8]); + void ippMultiBuffExp(BigNumber res[8], const BigNumber base[8], + const BigNumber pow[8], const BigNumber m[8]) const; /** * Invert function needed by encoder(float to integer) @@ -109,7 +109,7 @@ class PaillierPublicKey { * Apply obfuscator for ciphertext * @param[out] obfuscator output of obfuscator with random value */ - void apply_obfuscator(BigNumber obfuscator[8]); + void apply_obfuscator(BigNumber obfuscator[8]) const; /** * @brief Set the Random object for ISO/IEC 18033-6 compliance check @@ -141,7 +141,7 @@ class PaillierPublicKey { * @param[in,out] addr addr of random * @param[in] size size of random */ - void randIpp32u(std::vector& addr, int size); + void randIpp32u(std::vector& addr, int size) const; /** * Raw encrypt function @@ -150,14 +150,14 @@ class PaillierPublicKey { * @param[in] make_secure apply obfuscator(default value is true) */ void raw_encrypt(BigNumber ciphertext[8], const BigNumber plaintext[8], - bool make_secure = true); + bool make_secure = true) const; /** * Get random value * @param[in] length bit length * @return the random value of type BigNumber */ - BigNumber getRandom(int length); + BigNumber getRandom(int length) const; }; } // namespace ipcl diff --git a/ipcl/paillier_ops.cpp b/ipcl/paillier_ops.cpp index b3f69b1..0955260 100644 --- a/ipcl/paillier_ops.cpp +++ b/ipcl/paillier_ops.cpp @@ -8,8 +8,8 @@ namespace ipcl { // constructors // -PaillierEncryptedNumber::PaillierEncryptedNumber(PaillierPublicKey* pub_key, - const BigNumber& bn) +PaillierEncryptedNumber::PaillierEncryptedNumber( + const PaillierPublicKey* pub_key, const BigNumber& bn) : b_isObfuscator(false), m_available(1), m_pubkey(pub_key), @@ -17,18 +17,16 @@ PaillierEncryptedNumber::PaillierEncryptedNumber(PaillierPublicKey* pub_key, m_bn{bn} // m_bn[0] {} -PaillierEncryptedNumber::PaillierEncryptedNumber(PaillierPublicKey* pub_key, - const BigNumber bn[8], - size_t length) +PaillierEncryptedNumber::PaillierEncryptedNumber( + const PaillierPublicKey* pub_key, const BigNumber bn[8], size_t length) : b_isObfuscator(false), m_pubkey(pub_key), m_available(8), m_length(length), m_bn{bn[0], bn[1], bn[2], bn[3], bn[4], bn[5], bn[6], bn[7]} {} -PaillierEncryptedNumber::PaillierEncryptedNumber(PaillierPublicKey* pub_key, - const uint32_t scalar[8], - size_t length) +PaillierEncryptedNumber::PaillierEncryptedNumber( + const PaillierPublicKey* pub_key, const uint32_t scalar[8], size_t length) : b_isObfuscator(false), m_pubkey(pub_key), m_available(8), @@ -111,25 +109,25 @@ PaillierEncryptedNumber PaillierEncryptedNumber::operator*( } BigNumber PaillierEncryptedNumber::raw_add(const BigNumber& a, - const BigNumber& b) { + const BigNumber& b) const { // Hold a copy of nsquare for multi-threaded BigNumber sq = m_pubkey->getNSQ(); return a * b % sq; } -void PaillierEncryptedNumber::raw_mul(BigNumber res[8], BigNumber a[8], - BigNumber b[8]) { +void PaillierEncryptedNumber::raw_mul(BigNumber res[8], const BigNumber a[8], + const BigNumber b[8]) const { std::vector sq(8, m_pubkey->getNSQ()); m_pubkey->ippMultiBuffExp(res, a, b, sq.data()); } BigNumber PaillierEncryptedNumber::raw_mul(const BigNumber& a, - const BigNumber& b) { + const BigNumber& b) const { BigNumber sq = m_pubkey->getNSQ(); return m_pubkey->ippMontExp(a, b, sq); } -PaillierEncryptedNumber PaillierEncryptedNumber::rotate(int shift) { +PaillierEncryptedNumber PaillierEncryptedNumber::rotate(int shift) const { if (m_available == 1) throw std::invalid_argument("Cannot rotate single PaillierEncryptedNumber"); if (shift > 8 || shift < -8) diff --git a/ipcl/paillier_prikey.cpp b/ipcl/paillier_prikey.cpp index 464e4fd..85aea0a 100644 --- a/ipcl/paillier_prikey.cpp +++ b/ipcl/paillier_prikey.cpp @@ -20,7 +20,7 @@ static inline BigNumber lcm(const BigNumber& p, const BigNumber& q) { return p * q / gcd; } -PaillierPrivateKey::PaillierPrivateKey(PaillierPublicKey* public_key, +PaillierPrivateKey::PaillierPrivateKey(const PaillierPublicKey* public_key, const BigNumber& p, const BigNumber& q) : m_pubkey(public_key), m_n(m_pubkey->getN()), @@ -55,7 +55,7 @@ PaillierPrivateKey::PaillierPrivateKey(PaillierPublicKey* public_key, } void PaillierPrivateKey::decryptRAW(BigNumber plaintext[8], - const BigNumber ciphertext[8]) { + const BigNumber ciphertext[8]) const { mbx_status st = MBX_STATUS_OK; // setup buffer for mbx_exp @@ -118,15 +118,15 @@ void PaillierPrivateKey::decryptRAW(BigNumber plaintext[8], } void PaillierPrivateKey::decrypt(BigNumber plaintext[8], - const BigNumber ciphertext[8]) { + const BigNumber ciphertext[8]) const { if (m_enable_crt) decryptCRT(plaintext, ciphertext); else decryptRAW(plaintext, ciphertext); } -void PaillierPrivateKey::decrypt(BigNumber plaintext[8], - const PaillierEncryptedNumber ciphertext) { +void PaillierPrivateKey::decrypt( + BigNumber plaintext[8], const PaillierEncryptedNumber ciphertext) const { // check key match if (ciphertext.getPK().getN() != m_pubkey->getN()) throw std::runtime_error("decrypt: public key mismatch error."); @@ -141,7 +141,7 @@ void PaillierPrivateKey::decrypt(BigNumber plaintext[8], // CRT to calculate base^exp mod n^2 void PaillierPrivateKey::decryptCRT(BigNumber plaintext[8], - const BigNumber ciphertext[8]) { + const BigNumber ciphertext[8]) const { std::vector resp(8), resq(8); std::vector basep(8), baseq(8); std::vector pm1(8, m_pminusone), qm1(8, m_qminusone); @@ -164,18 +164,18 @@ void PaillierPrivateKey::decryptCRT(BigNumber plaintext[8], } BigNumber PaillierPrivateKey::computeCRT(const BigNumber& mp, - const BigNumber& mq) { + const BigNumber& mq) const { BigNumber u = (mq - mp) * m_pinverse % m_q; return mp + (u * m_p); } BigNumber PaillierPrivateKey::computeLfun(const BigNumber& a, - const BigNumber& b) { + const BigNumber& b) const { return (a - 1) / b; } BigNumber PaillierPrivateKey::computeHfun(const BigNumber& a, - const BigNumber& b) { + const BigNumber& b) const { // Based on the fact a^b mod n = (a mod n)^b mod n BigNumber xm = a - 1; BigNumber base = m_g % b; diff --git a/ipcl/paillier_pubkey.cpp b/ipcl/paillier_pubkey.cpp index 403bd71..623d1d3 100644 --- a/ipcl/paillier_pubkey.cpp +++ b/ipcl/paillier_pubkey.cpp @@ -32,12 +32,14 @@ PaillierPublicKey::PaillierPublicKey(const BigNumber& n, int bits, } // array of 32-bit random, using rand() from stdlib -void PaillierPublicKey::randIpp32u(std::vector& addr, int size) { - for (auto& a : addr) a = (rand_r(&m_init_seed) << 16) + rand_r(&m_init_seed); +void PaillierPublicKey::randIpp32u(std::vector& addr, int size) const { + // TODO(skmono): check if copy of m_init_seed is needed for const + unsigned int init_seed = m_init_seed; + for (auto& a : addr) a = (rand_r(&init_seed) << 16) + rand_r(&init_seed); } // length is Arbitery -BigNumber PaillierPublicKey::getRandom(int length) { +BigNumber PaillierPublicKey::getRandom(int length) const { IppStatus stat; int size; int seedBitSize = 160; @@ -105,7 +107,7 @@ void PaillierPublicKey::enableDJN() { m_enable_DJN = true; } -void PaillierPublicKey::apply_obfuscator(BigNumber obfuscator[8]) { +void PaillierPublicKey::apply_obfuscator(BigNumber obfuscator[8]) const { std::vector r(8); std::vector pown(8, m_n); std::vector base(8, m_hs); @@ -133,7 +135,7 @@ void PaillierPublicKey::apply_obfuscator(BigNumber obfuscator[8]) { void PaillierPublicKey::raw_encrypt(BigNumber ciphertext[8], const BigNumber plaintext[8], - bool make_secure) { + bool make_secure) const { // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 BigNumber sq = m_nsquare; for (int i = 0; i < 8; i++) { @@ -151,12 +153,14 @@ void PaillierPublicKey::raw_encrypt(BigNumber ciphertext[8], } void PaillierPublicKey::encrypt(BigNumber ciphertext[8], - const BigNumber value[8], bool make_secure) { + const BigNumber value[8], + bool make_secure) const { raw_encrypt(ciphertext, value, make_secure); } // Used for CT+PT, where PT do not need to add obfuscator -void PaillierPublicKey::encrypt(BigNumber& ciphertext, const BigNumber& value) { +void PaillierPublicKey::encrypt(BigNumber& ciphertext, + const BigNumber& value) const { // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 BigNumber bn = value; BigNumber sq = m_nsquare; @@ -168,9 +172,10 @@ void PaillierPublicKey::encrypt(BigNumber& ciphertext, const BigNumber& value) { ---------------------------------------------------------- */ } -void PaillierPublicKey::ippMultiBuffExp(BigNumber res[8], BigNumber base[8], +void PaillierPublicKey::ippMultiBuffExp(BigNumber res[8], + const BigNumber base[8], const BigNumber pow[8], - BigNumber m[8]) { + const BigNumber m[8]) const { mbx_status st = MBX_STATUS_OK; int bits = m[0].BitSize(); int dwords = BITSIZE_DWORD(bits); @@ -244,7 +249,7 @@ void PaillierPublicKey::ippMultiBuffExp(BigNumber res[8], BigNumber base[8], BigNumber PaillierPublicKey::ippMontExp(const BigNumber& base, const BigNumber& pow, - const BigNumber& m) { + const BigNumber& m) const { IppStatus stat = ippStsNoErr; // It is important to declear res * bform bit length refer to ipp-crypto spec: // R should not be less than the data length of the modulus m From 09da3cdeba717608e24d7f90472449868cc9a052 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 1 Mar 2022 17:25:39 -0800 Subject: [PATCH 061/364] Unset debugging macro. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c8309e..ebfd96a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,7 +49,7 @@ target_link_directories(he_qat PUBLIC /opt/openssl/lib) target_link_libraries(he_qat PRIVATE cpa_sample_utils) target_link_libraries(he_qat PUBLIC z pthread crypto ssl crypto qat_s usdm_drv_s) -add_definitions(-D_DESTINY_DEBUG_VERBOSE) +#add_definitions(-D_DESTINY_DEBUG_VERBOSE) add_executable(test_context test_context.c) target_link_libraries(test_context PUBLIC he_qat) From 1768da2d326bdf1acb1f4dfbc47055b380a907e3 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 1 Mar 2022 17:49:38 -0800 Subject: [PATCH 062/364] Fix potential mem leak due to requests. --- he_qat_bn_ops.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index 9b07ab6..c60de75 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -177,7 +177,7 @@ void* start_perform_op(void* _inst_config) { status = cpaCyStartInstance(config->inst_handle); config->status = status; if (CPA_STATUS_SUCCESS == status) { - printf("Cpa CyInstance has successfully started.\n "); + printf("Cpa CyInstance has successfully started.\n"); status = cpaCySetAddressTranslation(config->inst_handle, sampleVirtToPhys); } @@ -435,6 +435,7 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, // Submit request using producer function // printf("Submit request \n"); submit_request(&he_qat_buffer, (void*)request); + // printf("Submitted\n"); return HE_QAT_STATUS_SUCCESS; } @@ -442,7 +443,7 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, // Maybe it will be useful to pass the number of requests to retrieve // Pass post-processing function as argument to bring output to expected type void getBnModExpRequest(unsigned int batch_size) { - static unsigned int block_at_index = 0; + static unsigned long block_at_index = 0; unsigned int j = 0; do { // Buffer read may be safe for single-threaded blocking calls only. @@ -467,8 +468,8 @@ void getBnModExpRequest(unsigned int batch_size) { if (task->op_result.pData) { PHYS_CONTIG_FREE(task->op_result.pData); } - free(he_qat_buffer.data[block_at_index]); - he_qat_buffer.data[block_at_index] = NULL; + free(he_qat_buffer.data[block_at_index]); + he_qat_buffer.data[block_at_index] = NULL; // Move forward to wait for the next request that will be offloaded pthread_mutex_unlock(&task->mutex); block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; From e4fd76feaa416f6b89a999dad5b5822825416099 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 1 Mar 2022 17:57:23 -0800 Subject: [PATCH 063/364] Fix for batch size up to 16. --- he_qat_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/he_qat_types.h b/he_qat_types.h index 617f863..f274b56 100644 --- a/he_qat_types.h +++ b/he_qat_types.h @@ -9,7 +9,7 @@ #include -#define HE_QAT_BUFFER_SIZE 4 +#define HE_QAT_BUFFER_SIZE 16 // const unsigned HE_QAT_BUFFER_SIZE = 4; // Type definitions From 12b26548bb998e997a1ddd1e7d6482de93de8dc7 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 1 Mar 2022 17:59:01 -0800 Subject: [PATCH 064/364] Format performance test to show average times and speed-ups. --- test_bnModExpPerformOp.c | 70 +++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/test_bnModExpPerformOp.c b/test_bnModExpPerformOp.c index 1d7b738..a139a5a 100644 --- a/test_bnModExpPerformOp.c +++ b/test_bnModExpPerformOp.c @@ -17,7 +17,7 @@ #define ODD_RND_NUM 1 #define BATCH_SIZE 1 -int gDebugParam = 1; +//int gDebugParam = 1; BIGNUM* generateTestBNData(int nbits) { if (!RAND_status()) return NULL; @@ -82,21 +82,27 @@ void showHexBin(unsigned char* bin, int len) { } int main(int argc, const char** argv) { + const int bit_length = 4096; //1024; const size_t num_trials = 100; - const int bit_length = 1024; - // Set up QAT runtime environment + double avg_speed_up = 0.0; + double ssl_avg_time = 0.0; + double qat_avg_time = 0.0; + + clock_t start = CLOCKS_PER_SEC; + clock_t ssl_elapsed = CLOCKS_PER_SEC; + clock_t qat_elapsed = CLOCKS_PER_SEC; + + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + // Set up QAT runtime context acquire_qat_devices(); - // OpenSSL as baseline + // Set up OpenSSL context (as baseline) BN_CTX* ctx = BN_CTX_new(); BN_CTX_start(ctx); - CpaStatus status = CPA_STATUS_SUCCESS; - for (size_t mod = 0; mod < num_trials; mod++) { - printf("Trial #%0.3lu\t", mod + 1); - BIGNUM* bn_mod = generateTestBNData(bit_length); if (!bn_mod) continue; @@ -116,12 +122,12 @@ int main(int argc, const char** argv) { BIGNUM* bn_base = generateTestBNData(bit_length); + // Perform OpenSSL ModExp Op BIGNUM* ssl_res = BN_new(); - clock_t start = clock(); + start = clock(); BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); - clock_t elapsed = clock() - start; + ssl_elapsed = clock() - start; - // if (BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx)) { if (!ERR_get_error()) { #ifdef _DESTINY_DEBUG_VERBOSE bn_str = BN_bn2hex(ssl_res); @@ -138,20 +144,40 @@ int main(int argc, const char** argv) { PRINT_DBG("\nStarting QAT bnModExp...\n"); #endif - printf("OpenSSL: %.1lfus\t", elapsed / (CLOCKS_PER_SEC / 1000000.0)); + // printf("OpenSSL: %.1lfus\t", ssl_elapsed / (CLOCKS_PER_SEC / + // 1000000.0)); + // Perform QAT ModExp Op BIGNUM* qat_res = BN_new(); - HE_QAT_STATUS he_qat_status = HE_QAT_STATUS_FAIL; start = clock(); for (unsigned int j = 0; j < BATCH_SIZE; j++) - he_qat_status = bnModExpPerformOp(qat_res, bn_base, bn_exponent, + status = bnModExpPerformOp(qat_res, bn_base, bn_exponent, bn_mod, bit_length); getBnModExpRequest(BATCH_SIZE); - elapsed = clock() - start; - - printf("QAT: %.1lfus\t", elapsed / (CLOCKS_PER_SEC / 1000000.0)); - - if (HE_QAT_STATUS_SUCCESS != he_qat_status) { + qat_elapsed = clock() - start; + + ssl_avg_time = (mod * ssl_avg_time + + (ssl_elapsed / (CLOCKS_PER_SEC / 1000000.0))) / + (mod + 1); + qat_avg_time = + (mod * qat_avg_time + + (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0)) / BATCH_SIZE) / + (mod + 1); + avg_speed_up = + (mod * avg_speed_up + + (ssl_elapsed / (CLOCKS_PER_SEC / 1000000.0)) / + ((qat_elapsed / (CLOCKS_PER_SEC / 1000000.0)) / BATCH_SIZE)) / + (mod + 1); + + printf("Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", + (mod+1), ssl_avg_time, qat_avg_time, avg_speed_up); + + // printf("QAT: %.1lfus\t", qat_elapsed / (CLOCKS_PER_SEC / + // 1000000.0)); printf("Speed Up: %.1lfx\t", (ssl_elapsed / + // (CLOCKS_PER_SEC / 1000000.0) / BATCH_SIZE) / (qat_elapsed / + // (CLOCKS_PER_SEC / 1000000.0) / BATCH_SIZE) ); + + if (HE_QAT_STATUS_SUCCESS != status) { PRINT_ERR("\nQAT bnModExpOp failed\n"); } #ifdef _DESTINY_DEBUG_VERBOSE @@ -160,9 +186,6 @@ int main(int argc, const char** argv) { } #endif - // icp_sal_userStop(); - // qaeMemDestroy(); - if (BN_cmp(qat_res, ssl_res) != 0) printf("\t** FAIL **\n"); else @@ -176,9 +199,10 @@ int main(int argc, const char** argv) { BN_free(bn_exponent); } + // Tear down OpenSSL context BN_CTX_end(ctx); - // Tear down QAT runtime environment + // Tear down QAT runtime context release_qat_devices(); return (int)status; From 93ae52975cee31dbed956dae0addb774847a5858 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Tue, 1 Mar 2022 18:25:49 -0800 Subject: [PATCH 065/364] Refactoring (#19) * Refactoring - Replaced all pointers and arrays with std::vector - resolves #14 - Changed multi-buffered PaillierEncryptedNumber::raw_mul to return std::vector - resolves #15 - Changed multi-buffered modular exponentation PaillierPublicKey::ippMultiBuffExp to return std::vector - resolves #15 - Applied changes to unit-test and benchmark accordingly - Applied const keywords to test and benchmark functions for keyPair * Bug fix on BM_Mul_CTPT_OMP in benchmark * Updated README - updated unittest_omp per changes to IPCL_ENABLE_OMP flag * Updated README * Removed unused header --- CMakeLists.txt | 2 +- README.md | 24 +- benchmark/bench_cryptography.cpp | 149 +++-------- benchmark/bench_ops.cpp | 294 ++++++--------------- ipcl/include/ipcl/paillier_ops.hpp | 19 +- ipcl/include/ipcl/paillier_prikey.hpp | 13 +- ipcl/include/ipcl/paillier_pubkey.hpp | 24 +- ipcl/paillier_ops.cpp | 28 +- ipcl/paillier_prikey.cpp | 30 ++- ipcl/paillier_pubkey.cpp | 43 ++-- test/test_cryptography.cpp | 56 ++-- test/test_ops.cpp | 357 ++++++++++++-------------- 12 files changed, 404 insertions(+), 635 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 80bd6da..94b5e15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,7 +102,7 @@ include(ipcl-util) include(cmake/ippcrypto.cmake) -if(IPCL_TEST OR IPCL_OMP_TEST) +if(IPCL_TEST) include(cmake/gtest.cmake) endif() if(IPCL_BENCHMARK) diff --git a/README.md b/README.md index 5c61789..ffd5067 100644 --- a/README.md +++ b/README.md @@ -70,13 +70,13 @@ cmake --build build -j It is possible to pass additional options to enable more features. The following table contains the current CMake options, default values are in bold. -| CMake options | Values | Default | Comments | -|-------------------------|-----------|---------|------------------------------| -|`IPCL_TEST` | ON/OFF | ON | unit-test | -|`IPCL_TEST_OMP` | ON/OFF | ON | unit-test w/ OpenMP | -|`IPCL_BENCHMARK` | ON/OFF | ON | benchmark | -|`IPCL_DOCS` | ON/OFF | OFF | build doxygen documentation | -|`IPCL_SHARED` | ON/OFF | ON | build shared library | +| CMake options | Values | Default | Comments | +|-------------------------|-----------|---------|-------------------------------------| +|`IPCL_TEST` | ON/OFF | ON | unit-test | +|`IPCL_BENCHMARK` | ON/OFF | ON | benchmark | +|`IPCL_ENABLE_OMP` | ON/OFF | ON | enables OMP unit-test and benchmark | +|`IPCL_DOCS` | ON/OFF | OFF | build doxygen documentation | +|`IPCL_SHARED` | ON/OFF | ON | build shared library | ## Testing and Benchmarking To run a set of unit tests via [Googletest](https://github.com/google/googletest), configure and build library with `-DIPCL_TEST=ON` (see [Instructions](#instructions)). @@ -84,23 +84,19 @@ Then, run ```bash cmake --build build --target unittest ``` -For OpenMP testing, configure and build with `-DIPCL_TEST_OMP=ON`, and run -```bash -cmake --build build --target unittest_omp -``` For running benchmark via [Google Benchmark](https://github.com/google/benchmark), configure and build library with `-DIPCL_BENCHMARK=ON` (see [Instructions](#instructions)). Then, run ```bash cmake --build build --target benchmark ``` -OpenMP benchmarks will automatically be applied if `-DIPCL_TEST_OMP=ON` is set. +OpenMP unit-tests and benchmarks will automatically be applied if `-DIPCL_ENABLE_OMP=ON` is set. -The unit-test executable itself is located at `${IPCL_DIR}/build/test/unit-test`, `${IPCL_DIR}/build/test/unit-test_omp` and `${IPCL_DIR}/build/benchmark/bench_ipcl`. +The executables are located at `${IPCL_DIR}/build/test/unittest_ipcl` and `${IPCL_DIR}/build/benchmark/bench_ipcl`. # Standardization This library is in compliance with the homomorphic encryption standards [ISO/IEC 18033-6](https://www.iso.org/standard/67740.html). -The compliance test is included in the [unit-test](test/test_cryptography.cpp#L117-L258). +The compliance test is included in the [unit-test](test/test_cryptography.cpp#L112-L256). # Contributors Main contributors to this project, sorted by alphabetical order of last name are: diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index 9d9bf46..ec92562 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -22,26 +22,18 @@ static void BM_Encrypt(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber** pt = new ipcl::BigNumber*[dsize]; - ipcl::BigNumber** ct = new ipcl::BigNumber*[dsize]; + std::vector> pt(dsize, + std::vector(8)); + std::vector> ct(dsize, + std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - pt[i] = new ipcl::BigNumber[8]; - ct[i] = new ipcl::BigNumber[8]; pt[i][0] = ipcl::BigNumber((unsigned int)i); } for (auto _ : state) { for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); } - - for (size_t i = 0; i < dsize; ++i) { - delete[] pt[i]; - delete[] ct[i]; - } - - delete[] pt; - delete[] ct; } BENCHMARK(BM_Encrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); @@ -50,12 +42,12 @@ static void BM_Encrypt_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber** pt = new ipcl::BigNumber*[dsize / 8]; - ipcl::BigNumber** ct = new ipcl::BigNumber*[dsize / 8]; + std::vector> pt(dsize / 8, + std::vector(8)); + std::vector> ct(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { - pt[i] = new ipcl::BigNumber[8]; - ct[i] = new ipcl::BigNumber[8]; for (size_t j = 0; j < 8; ++j) pt[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } @@ -63,13 +55,6 @@ static void BM_Encrypt_buff8(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); } - - for (size_t i = 0; i < dsize / 8; ++i) { - delete[] pt[i]; - delete[] ct[i]; - } - delete[] pt; - delete[] ct; } BENCHMARK(BM_Encrypt_buff8) @@ -81,13 +66,14 @@ static void BM_Decrypt(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber** pt = new ipcl::BigNumber*[dsize]; - ipcl::BigNumber** ct = new ipcl::BigNumber*[dsize]; - ipcl::BigNumber** de_ct = new ipcl::BigNumber*[dsize]; + std::vector> pt(dsize, + std::vector(8)); + std::vector> ct(dsize, + std::vector(8)); + std::vector> de_ct( + dsize, std::vector(8)); + for (size_t i = 0; i < dsize; ++i) { - pt[i] = new ipcl::BigNumber[8]; - ct[i] = new ipcl::BigNumber[8]; - de_ct[i] = new ipcl::BigNumber[8]; pt[i][0] = ipcl::BigNumber((unsigned int)i); } @@ -98,16 +84,6 @@ static void BM_Decrypt(benchmark::State& state) { key.priv_key->decrypt(de_ct[i], ct[i]); } } - - for (size_t i = 0; i < dsize; ++i) { - delete[] pt[i]; - delete[] ct[i]; - delete[] de_ct[i]; - } - - delete[] pt; - delete[] ct; - delete[] de_ct; } BENCHMARK(BM_Decrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); @@ -116,14 +92,14 @@ static void BM_Decrypt_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber** pt = new ipcl::BigNumber*[dsize / 8]; - ipcl::BigNumber** ct = new ipcl::BigNumber*[dsize / 8]; - ipcl::BigNumber** de_ct = new ipcl::BigNumber*[dsize / 8]; + std::vector> pt(dsize / 8, + std::vector(8)); + std::vector> ct(dsize / 8, + std::vector(8)); + std::vector> de_ct( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { - pt[i] = new ipcl::BigNumber[8]; - ct[i] = new ipcl::BigNumber[8]; - de_ct[i] = new ipcl::BigNumber[8]; for (size_t j = 0; j < 8; ++j) pt[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } @@ -134,15 +110,6 @@ static void BM_Decrypt_buff8(benchmark::State& state) { for (size_t i = 0; i < dsize / 8; ++i) key.priv_key->decrypt(de_ct[i], ct[i]); } - - for (size_t i = 0; i < dsize / 8; ++i) { - delete[] pt[i]; - delete[] ct[i]; - delete[] de_ct[i]; - } - delete[] pt; - delete[] ct; - delete[] de_ct; } BENCHMARK(BM_Decrypt_buff8) @@ -155,12 +122,12 @@ static void BM_Encrypt_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber** pt = new ipcl::BigNumber*[dsize]; - ipcl::BigNumber** ct = new ipcl::BigNumber*[dsize]; + std::vector> pt(dsize, + std::vector(8)); + std::vector> ct(dsize, + std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - pt[i] = new ipcl::BigNumber[8]; - ct[i] = new ipcl::BigNumber[8]; pt[i][0] = ipcl::BigNumber((unsigned int)i); } @@ -168,14 +135,6 @@ static void BM_Encrypt_OMP(benchmark::State& state) { #pragma omp parallel for for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); } - - for (size_t i = 0; i < dsize; ++i) { - delete[] pt[i]; - delete[] ct[i]; - } - - delete[] pt; - delete[] ct; } BENCHMARK(BM_Encrypt_OMP) ->Unit(benchmark::kMicrosecond) @@ -186,12 +145,12 @@ static void BM_Encrypt_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber** pt = new ipcl::BigNumber*[dsize / 8]; - ipcl::BigNumber** ct = new ipcl::BigNumber*[dsize / 8]; + std::vector> pt(dsize / 8, + std::vector(8)); + std::vector> ct(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { - pt[i] = new ipcl::BigNumber[8]; - ct[i] = new ipcl::BigNumber[8]; for (size_t j = 0; j < 8; ++j) pt[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } @@ -200,13 +159,6 @@ static void BM_Encrypt_buff8_OMP(benchmark::State& state) { #pragma omp parallel for for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); } - - for (size_t i = 0; i < dsize / 8; ++i) { - delete[] pt[i]; - delete[] ct[i]; - } - delete[] pt; - delete[] ct; } BENCHMARK(BM_Encrypt_buff8_OMP) @@ -218,13 +170,13 @@ static void BM_Decrypt_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber** pt = new ipcl::BigNumber*[dsize]; - ipcl::BigNumber** ct = new ipcl::BigNumber*[dsize]; - ipcl::BigNumber** de_ct = new ipcl::BigNumber*[dsize]; + std::vector> pt(dsize, + std::vector(8)); + std::vector> ct(dsize, + std::vector(8)); + std::vector> de_ct( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - pt[i] = new ipcl::BigNumber[8]; - ct[i] = new ipcl::BigNumber[8]; - de_ct[i] = new ipcl::BigNumber[8]; pt[i][0] = ipcl::BigNumber((unsigned int)i); } @@ -236,16 +188,6 @@ static void BM_Decrypt_OMP(benchmark::State& state) { key.priv_key->decrypt(de_ct[i], ct[i]); } } - - for (size_t i = 0; i < dsize; ++i) { - delete[] pt[i]; - delete[] ct[i]; - delete[] de_ct[i]; - } - - delete[] pt; - delete[] ct; - delete[] de_ct; } BENCHMARK(BM_Decrypt_OMP) @@ -257,14 +199,14 @@ static void BM_Decrypt_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber** pt = new ipcl::BigNumber*[dsize / 8]; - ipcl::BigNumber** ct = new ipcl::BigNumber*[dsize / 8]; - ipcl::BigNumber** de_ct = new ipcl::BigNumber*[dsize / 8]; + std::vector> pt(dsize / 8, + std::vector(8)); + std::vector> ct(dsize / 8, + std::vector(8)); + std::vector> de_ct( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { - pt[i] = new ipcl::BigNumber[8]; - ct[i] = new ipcl::BigNumber[8]; - de_ct[i] = new ipcl::BigNumber[8]; for (size_t j = 0; j < 8; ++j) pt[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } @@ -276,15 +218,6 @@ static void BM_Decrypt_buff8_OMP(benchmark::State& state) { for (size_t i = 0; i < dsize / 8; ++i) key.priv_key->decrypt(de_ct[i], ct[i]); } - - for (size_t i = 0; i < dsize / 8; ++i) { - delete[] pt[i]; - delete[] ct[i]; - delete[] de_ct[i]; - } - delete[] pt; - delete[] ct; - delete[] de_ct; } BENCHMARK(BM_Decrypt_buff8_OMP) diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index ed69e69..f13b271 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -16,20 +16,20 @@ static void BM_Add_CTCT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber** a = new ipcl::BigNumber*[dsize]; - ipcl::BigNumber** b = new ipcl::BigNumber*[dsize]; - ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize]; - ipcl::BigNumber** ct_b = new ipcl::BigNumber*[dsize]; + std::vector> a(dsize, + std::vector(8)); + std::vector> b(dsize, + std::vector(8)); + std::vector> ct_a( + dsize, std::vector(8)); + std::vector> ct_b( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i] = new ipcl::BigNumber[8]; a[i][0] = ipcl::BigNumber((unsigned int)i); - ct_a[i] = new ipcl::BigNumber[8]; key.pub_key->encrypt(ct_a[i], a[i]); - b[i] = new ipcl::BigNumber[8]; b[i][0] = ipcl::BigNumber((unsigned int)i); - ct_b[i] = new ipcl::BigNumber[8]; key.pub_key->encrypt(ct_b[i], b[i]); } @@ -40,18 +40,6 @@ static void BM_Add_CTCT(benchmark::State& state) { ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; } } - - for (size_t i = 0; i < dsize; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - delete[] ct_b[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; - delete[] ct_b; } BENCHMARK(BM_Add_CTCT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); @@ -60,17 +48,16 @@ static void BM_Add_CTCT_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber** a = new ipcl::BigNumber*[dsize / 8]; - ipcl::BigNumber** b = new ipcl::BigNumber*[dsize / 8]; - ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize / 8]; - ipcl::BigNumber** ct_b = new ipcl::BigNumber*[dsize / 8]; + std::vector> a(dsize / 8, + std::vector(8)); + std::vector> b(dsize / 8, + std::vector(8)); + std::vector> ct_a( + dsize / 8, std::vector(8)); + std::vector> ct_b( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { - a[i] = new ipcl::BigNumber[8]; - ct_a[i] = new ipcl::BigNumber[8]; - - b[i] = new ipcl::BigNumber[8]; - ct_b[i] = new ipcl::BigNumber[8]; for (size_t j = 0; j < 8; ++j) { a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); @@ -87,18 +74,6 @@ static void BM_Add_CTCT_buff8(benchmark::State& state) { ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; } } - - for (size_t i = 0; i < dsize / 8; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - delete[] ct_b[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; - delete[] ct_b; } BENCHMARK(BM_Add_CTCT_buff8) @@ -110,15 +85,15 @@ static void BM_Add_CTPT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber** a = new ipcl::BigNumber*[dsize]; - ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize]; - ipcl::BigNumber** b = new ipcl::BigNumber*[dsize]; + std::vector> a(dsize, + std::vector(8)); + std::vector> b(dsize, + std::vector(8)); + std::vector> ct_a( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i] = new ipcl::BigNumber[8]; a[i][0] = ipcl::BigNumber((unsigned int)i); - ct_a[i] = new ipcl::BigNumber[8]; - b[i] = new ipcl::BigNumber[8]; b[i][0] = ipcl::BigNumber((unsigned int)i); key.pub_key->encrypt(ct_a[i], a[i]); } @@ -129,16 +104,6 @@ static void BM_Add_CTPT(benchmark::State& state) { ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; } } - - for (size_t i = 0; i < dsize; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; } BENCHMARK(BM_Add_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); @@ -147,15 +112,14 @@ static void BM_Add_CTPT_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber** a = new ipcl::BigNumber*[dsize / 8]; - ipcl::BigNumber** b = new ipcl::BigNumber*[dsize / 8]; - ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize / 8]; + std::vector> a(dsize / 8, + std::vector(8)); + std::vector> b(dsize / 8, + std::vector(8)); + std::vector> ct_a( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { - a[i] = new ipcl::BigNumber[8]; - ct_a[i] = new ipcl::BigNumber[8]; - - b[i] = new ipcl::BigNumber[8]; for (size_t j = 0; j < 8; ++j) { a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); @@ -170,16 +134,6 @@ static void BM_Add_CTPT_buff8(benchmark::State& state) { ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; } } - - for (size_t i = 0; i < dsize / 8; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; } BENCHMARK(BM_Add_CTPT_buff8) @@ -191,15 +145,15 @@ static void BM_Mul_CTPT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber** a = new ipcl::BigNumber*[dsize]; - ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize]; - ipcl::BigNumber** b = new ipcl::BigNumber*[dsize]; + std::vector> a(dsize, + std::vector(8)); + std::vector> b(dsize, + std::vector(8)); + std::vector> ct_a( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i] = new ipcl::BigNumber[8]; a[i][0] = ipcl::BigNumber((unsigned int)i); - ct_a[i] = new ipcl::BigNumber[8]; - b[i] = new ipcl::BigNumber[8]; b[i][0] = ipcl::BigNumber((unsigned int)i); key.pub_key->encrypt(ct_a[i], a[i]); } @@ -211,16 +165,6 @@ static void BM_Mul_CTPT(benchmark::State& state) { ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; } } - - for (size_t i = 0; i < dsize; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; } BENCHMARK(BM_Mul_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); @@ -229,15 +173,14 @@ static void BM_Mul_CTPT_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber** a = new ipcl::BigNumber*[dsize / 8]; - ipcl::BigNumber** b = new ipcl::BigNumber*[dsize / 8]; - ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize / 8]; + std::vector> a(dsize / 8, + std::vector(8)); + std::vector> b(dsize / 8, + std::vector(8)); + std::vector> ct_a( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { - a[i] = new ipcl::BigNumber[8]; - ct_a[i] = new ipcl::BigNumber[8]; - - b[i] = new ipcl::BigNumber[8]; for (size_t j = 0; j < 8; ++j) { a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); @@ -253,16 +196,6 @@ static void BM_Mul_CTPT_buff8(benchmark::State& state) { ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; } } - - for (size_t i = 0; i < dsize / 8; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; } BENCHMARK(BM_Mul_CTPT_buff8) @@ -275,20 +208,20 @@ static void BM_Add_CTCT_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber** a = new ipcl::BigNumber*[dsize]; - ipcl::BigNumber** b = new ipcl::BigNumber*[dsize]; - ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize]; - ipcl::BigNumber** ct_b = new ipcl::BigNumber*[dsize]; + std::vector> a(dsize, + std::vector(8)); + std::vector> b(dsize, + std::vector(8)); + std::vector> ct_a( + dsize, std::vector(8)); + std::vector> ct_b( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i] = new ipcl::BigNumber[8]; a[i][0] = ipcl::BigNumber((unsigned int)i); - ct_a[i] = new ipcl::BigNumber[8]; key.pub_key->encrypt(ct_a[i], a[i]); - b[i] = new ipcl::BigNumber[8]; b[i][0] = ipcl::BigNumber((unsigned int)i); - ct_b[i] = new ipcl::BigNumber[8]; key.pub_key->encrypt(ct_b[i], b[i]); } @@ -300,18 +233,6 @@ static void BM_Add_CTCT_OMP(benchmark::State& state) { ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; } } - - for (size_t i = 0; i < dsize; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - delete[] ct_b[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; - delete[] ct_b; } BENCHMARK(BM_Add_CTCT_OMP) @@ -323,17 +244,16 @@ static void BM_Add_CTCT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber** a = new ipcl::BigNumber*[dsize / 8]; - ipcl::BigNumber** b = new ipcl::BigNumber*[dsize / 8]; - ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize / 8]; - ipcl::BigNumber** ct_b = new ipcl::BigNumber*[dsize / 8]; + std::vector> a(dsize / 8, + std::vector(8)); + std::vector> b(dsize / 8, + std::vector(8)); + std::vector> ct_a( + dsize / 8, std::vector(8)); + std::vector> ct_b( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { - a[i] = new ipcl::BigNumber[8]; - ct_a[i] = new ipcl::BigNumber[8]; - - b[i] = new ipcl::BigNumber[8]; - ct_b[i] = new ipcl::BigNumber[8]; for (size_t j = 0; j < 8; ++j) { a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); @@ -351,18 +271,6 @@ static void BM_Add_CTCT_buff8_OMP(benchmark::State& state) { ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; } } - - for (size_t i = 0; i < dsize / 8; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - delete[] ct_b[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; - delete[] ct_b; } BENCHMARK(BM_Add_CTCT_buff8_OMP) @@ -374,15 +282,15 @@ static void BM_Add_CTPT_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber** a = new ipcl::BigNumber*[dsize]; - ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize]; - ipcl::BigNumber** b = new ipcl::BigNumber*[dsize]; + std::vector> a(dsize, + std::vector(8)); + std::vector> b(dsize, + std::vector(8)); + std::vector> ct_a( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i] = new ipcl::BigNumber[8]; a[i][0] = ipcl::BigNumber((unsigned int)i); - ct_a[i] = new ipcl::BigNumber[8]; - b[i] = new ipcl::BigNumber[8]; b[i][0] = ipcl::BigNumber((unsigned int)i); key.pub_key->encrypt(ct_a[i], a[i]); } @@ -394,16 +302,6 @@ static void BM_Add_CTPT_OMP(benchmark::State& state) { ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; } } - - for (size_t i = 0; i < dsize; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; } BENCHMARK(BM_Add_CTPT_OMP) @@ -415,15 +313,14 @@ static void BM_Add_CTPT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber** a = new ipcl::BigNumber*[dsize / 8]; - ipcl::BigNumber** b = new ipcl::BigNumber*[dsize / 8]; - ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize / 8]; + std::vector> a(dsize / 8, + std::vector(8)); + std::vector> b(dsize / 8, + std::vector(8)); + std::vector> ct_a( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { - a[i] = new ipcl::BigNumber[8]; - ct_a[i] = new ipcl::BigNumber[8]; - - b[i] = new ipcl::BigNumber[8]; for (size_t j = 0; j < 8; ++j) { a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); @@ -439,16 +336,6 @@ static void BM_Add_CTPT_buff8_OMP(benchmark::State& state) { ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; } } - - for (size_t i = 0; i < dsize / 8; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; } BENCHMARK(BM_Add_CTPT_buff8_OMP) @@ -460,15 +347,15 @@ static void BM_Mul_CTPT_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber** a = new ipcl::BigNumber*[dsize]; - ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize]; - ipcl::BigNumber** b = new ipcl::BigNumber*[dsize]; + std::vector> a(dsize, + std::vector(8)); + std::vector> b(dsize, + std::vector(8)); + std::vector> ct_a( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i] = new ipcl::BigNumber[8]; a[i][0] = ipcl::BigNumber((unsigned int)i); - ct_a[i] = new ipcl::BigNumber[8]; - b[i] = new ipcl::BigNumber[8]; b[i][0] = ipcl::BigNumber((unsigned int)i); key.pub_key->encrypt(ct_a[i], a[i]); } @@ -481,16 +368,6 @@ static void BM_Mul_CTPT_OMP(benchmark::State& state) { ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; } } - - for (size_t i = 0; i < dsize; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; } BENCHMARK(BM_Mul_CTPT_OMP) @@ -502,15 +379,14 @@ static void BM_Mul_CTPT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber** a = new ipcl::BigNumber*[dsize / 8]; - ipcl::BigNumber** b = new ipcl::BigNumber*[dsize / 8]; - ipcl::BigNumber** ct_a = new ipcl::BigNumber*[dsize / 8]; + std::vector> a(dsize / 8, + std::vector(8)); + std::vector> b(dsize / 8, + std::vector(8)); + std::vector> ct_a( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { - a[i] = new ipcl::BigNumber[8]; - ct_a[i] = new ipcl::BigNumber[8]; - - b[i] = new ipcl::BigNumber[8]; for (size_t j = 0; j < 8; ++j) { a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); @@ -527,16 +403,6 @@ static void BM_Mul_CTPT_buff8_OMP(benchmark::State& state) { ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; } } - - for (size_t i = 0; i < dsize / 8; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; } BENCHMARK(BM_Mul_CTPT_buff8_OMP) diff --git a/ipcl/include/ipcl/paillier_ops.hpp b/ipcl/include/ipcl/paillier_ops.hpp index 029100c..98e774e 100644 --- a/ipcl/include/ipcl/paillier_ops.hpp +++ b/ipcl/include/ipcl/paillier_ops.hpp @@ -4,7 +4,7 @@ #ifndef IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ #define IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ -#include +#include #include "ipcl/paillier_pubkey.hpp" @@ -27,7 +27,7 @@ class PaillierEncryptedNumber { * @param[in] length size of array(default value is 8) */ PaillierEncryptedNumber(const PaillierPublicKey* pub_key, - const BigNumber bn[8], size_t length = 8); + const std::vector& bn, size_t length = 8); /** * PaillierEncryptedNumber constructor @@ -36,7 +36,8 @@ class PaillierEncryptedNumber { * @param[in] length size of array(default value is 8) */ PaillierEncryptedNumber(const PaillierPublicKey* pub_key, - const uint32_t scalar[8], size_t length = 8); + const std::vector& scalar, + size_t length = 8); /** * Arithmetic addition operator @@ -54,7 +55,7 @@ class PaillierEncryptedNumber { * Arithmetic addition operator * @param[in] other array of augend */ - PaillierEncryptedNumber operator+(const BigNumber other[8]) const; + PaillierEncryptedNumber operator+(const std::vector& other) const; /** * Arithmetic multiply operator @@ -74,7 +75,7 @@ class PaillierEncryptedNumber { */ void apply_obfuscator() { b_isObfuscator = true; - BigNumber obfuscator[8]; + std::vector obfuscator(8); m_pubkey->apply_obfuscator(obfuscator); BigNumber sq = m_pubkey->getNSQ(); @@ -109,7 +110,7 @@ class PaillierEncryptedNumber { * Return entire ciphertext array * @param[out] bn output array */ - void getArrayBN(BigNumber bn[8]) const { std::copy_n(m_bn, 8, bn); } + std::vector getArrayBN() const { return m_bn; } /** * Check if element in PaillierEncryptedNumber is single @@ -128,12 +129,12 @@ class PaillierEncryptedNumber { int m_available; const PaillierPublicKey* m_pubkey; size_t m_length; - BigNumber m_bn[8]; + std::vector m_bn; BigNumber raw_add(const BigNumber& a, const BigNumber& b) const; BigNumber raw_mul(const BigNumber& a, const BigNumber& b) const; - void raw_mul(BigNumber res[8], const BigNumber a[8], - const BigNumber b[8]) const; + std::vector raw_mul(const std::vector& a, + const std::vector& b) const; }; } // namespace ipcl diff --git a/ipcl/include/ipcl/paillier_prikey.hpp b/ipcl/include/ipcl/paillier_prikey.hpp index a695366..5ecfc3d 100644 --- a/ipcl/include/ipcl/paillier_prikey.hpp +++ b/ipcl/include/ipcl/paillier_prikey.hpp @@ -4,6 +4,8 @@ #ifndef IPCL_INCLUDE_IPCL_PAILLIER_PRIKEY_HPP_ #define IPCL_INCLUDE_IPCL_PAILLIER_PRIKEY_HPP_ +#include + #include "ipcl/paillier_ops.hpp" namespace ipcl { @@ -30,14 +32,15 @@ class PaillierPrivateKey { * @param[out] plaintext output of the decryption * @param[in] ciphertext ciphertext to be decrypted */ - void decrypt(BigNumber plaintext[8], const BigNumber ciphertext[8]) const; + void decrypt(std::vector& plaintext, + const std::vector& ciphertext) const; /** * Decrypt ciphertext * @param[out] plaintext output of the decryption * @param[in] ciphertext PaillierEncryptedNumber to be decrypted */ - void decrypt(BigNumber plaintext[8], + void decrypt(std::vector& plaintext, const PaillierEncryptedNumber ciphertext) const; const void* addr = static_cast(this); @@ -123,14 +126,16 @@ class PaillierPrivateKey { * @param[out] plaintext output plaintext * @param[in] ciphertext input ciphertext */ - void decryptRAW(BigNumber plaintext[8], const BigNumber ciphertext[8]) const; + void decryptRAW(std::vector& plaintext, + const std::vector& ciphertext) const; /** * Raw decryption function with CRT optimization * @param[out] plaintext output plaintext * @param[in] ciphertext input ciphertext */ - void decryptCRT(BigNumber plaintext[8], const BigNumber ciphertext[8]) const; + void decryptCRT(std::vector& plaintext, + const std::vector& ciphertext) const; }; } // namespace ipcl diff --git a/ipcl/include/ipcl/paillier_pubkey.hpp b/ipcl/include/ipcl/paillier_pubkey.hpp index 5be1807..7d90e63 100644 --- a/ipcl/include/ipcl/paillier_pubkey.hpp +++ b/ipcl/include/ipcl/paillier_pubkey.hpp @@ -42,7 +42,8 @@ class PaillierPublicKey { * @param[in] value array of plaintext to be encrypted * @param[in] make_secure apply obfuscator(default value is true) */ - void encrypt(BigNumber ciphertext[8], const BigNumber value[8], + void encrypt(std::vector& ciphertext, + const std::vector& value, bool make_secure = true) const; /** @@ -69,8 +70,9 @@ class PaillierPublicKey { * @param[in] pow arrya pow of the exponentiation * @param[in] m arrayodular */ - void ippMultiBuffExp(BigNumber res[8], const BigNumber base[8], - const BigNumber pow[8], const BigNumber m[8]) const; + std::vector ippMultiBuffExp(const std::vector& base, + const std::vector& pow, + const std::vector& m) const; /** * Invert function needed by encoder(float to integer) @@ -109,17 +111,14 @@ class PaillierPublicKey { * Apply obfuscator for ciphertext * @param[out] obfuscator output of obfuscator with random value */ - void apply_obfuscator(BigNumber obfuscator[8]) const; + void apply_obfuscator(std::vector& obfuscator) const; /** * @brief Set the Random object for ISO/IEC 18033-6 compliance check * * @param r */ - void setRandom(BigNumber r[8]) { - for (int i = 0; i < 8; i++) m_r[i] = r[i]; - m_testv = true; - } + void setRandom(const std::vector& r); const void* addr = static_cast(this); @@ -133,15 +132,15 @@ class PaillierPublicKey { int m_dwords; unsigned int m_init_seed; bool m_enable_DJN; - BigNumber m_r[8]; + std::vector m_r; bool m_testv; /** * Get random value - * @param[in,out] addr addr of random * @param[in] size size of random + * @return addr of random */ - void randIpp32u(std::vector& addr, int size) const; + std::vector randIpp32u(int size) const; /** * Raw encrypt function @@ -149,7 +148,8 @@ class PaillierPublicKey { * @param[in] plaintext plaintext array to be encrypted * @param[in] make_secure apply obfuscator(default value is true) */ - void raw_encrypt(BigNumber ciphertext[8], const BigNumber plaintext[8], + void raw_encrypt(std::vector& ciphertext, + const std::vector& plaintext, bool make_secure = true) const; /** diff --git a/ipcl/paillier_ops.cpp b/ipcl/paillier_ops.cpp index 0955260..1c66844 100644 --- a/ipcl/paillier_ops.cpp +++ b/ipcl/paillier_ops.cpp @@ -14,11 +14,11 @@ PaillierEncryptedNumber::PaillierEncryptedNumber( m_available(1), m_pubkey(pub_key), m_length(1), - m_bn{bn} // m_bn[0] -{} + m_bn{bn} {} PaillierEncryptedNumber::PaillierEncryptedNumber( - const PaillierPublicKey* pub_key, const BigNumber bn[8], size_t length) + const PaillierPublicKey* pub_key, const std::vector& bn, + size_t length) : b_isObfuscator(false), m_pubkey(pub_key), m_available(8), @@ -26,7 +26,8 @@ PaillierEncryptedNumber::PaillierEncryptedNumber( m_bn{bn[0], bn[1], bn[2], bn[3], bn[4], bn[5], bn[6], bn[7]} {} PaillierEncryptedNumber::PaillierEncryptedNumber( - const PaillierPublicKey* pub_key, const uint32_t scalar[8], size_t length) + const PaillierPublicKey* pub_key, const std::vector& scalar, + size_t length) : b_isObfuscator(false), m_pubkey(pub_key), m_available(8), @@ -48,7 +49,7 @@ PaillierEncryptedNumber PaillierEncryptedNumber::operator+( BigNumber sum = a.raw_add(a.m_bn[0], b.m_bn[0]); return PaillierEncryptedNumber(m_pubkey, sum); } else { - BigNumber sum[8]; + std::vector sum(8); for (int i = 0; i < m_available; i++) sum[i] = a.raw_add(a.m_bn[i], b.m_bn[i]); return PaillierEncryptedNumber(m_pubkey, sum); @@ -68,10 +69,11 @@ PaillierEncryptedNumber PaillierEncryptedNumber::operator+( // multi encrypted CT+PT PaillierEncryptedNumber PaillierEncryptedNumber::operator+( - const BigNumber other[8]) const { + const std::vector& other) const { PaillierEncryptedNumber a = *this; - BigNumber b[8], sum[8]; + std::vector b(8); + std::vector sum(8); a.m_pubkey->encrypt(b, other, false); for (int i = 0; i < 8; i++) sum[i] = a.raw_add(a.m_bn[i], b[i]); return PaillierEncryptedNumber(m_pubkey, sum); @@ -92,8 +94,7 @@ PaillierEncryptedNumber PaillierEncryptedNumber::operator*( BigNumber product = a.raw_mul(a.m_bn[0], b.m_bn[0]); return PaillierEncryptedNumber(m_pubkey, product); } else { - BigNumber product[8]; - a.raw_mul(product, a.m_bn, b.m_bn); + std::vector product = a.raw_mul(a.m_bn, b.m_bn); return PaillierEncryptedNumber(m_pubkey, product); } } @@ -115,10 +116,10 @@ BigNumber PaillierEncryptedNumber::raw_add(const BigNumber& a, return a * b % sq; } -void PaillierEncryptedNumber::raw_mul(BigNumber res[8], const BigNumber a[8], - const BigNumber b[8]) const { +std::vector PaillierEncryptedNumber::raw_mul( + const std::vector& a, const std::vector& b) const { std::vector sq(8, m_pubkey->getNSQ()); - m_pubkey->ippMultiBuffExp(res, a, b, sq.data()); + return m_pubkey->ippMultiBuffExp(a, b, sq); } BigNumber PaillierEncryptedNumber::raw_mul(const BigNumber& a, @@ -141,8 +142,7 @@ PaillierEncryptedNumber PaillierEncryptedNumber::rotate(int shift) const { else shift = -shift; - BigNumber new_bn[8]; - getArrayBN(new_bn); + std::vector new_bn = getArrayBN(); std::rotate(std::begin(new_bn), std::begin(new_bn) + shift, std::end(new_bn)); return PaillierEncryptedNumber(m_pubkey, new_bn); diff --git a/ipcl/paillier_prikey.cpp b/ipcl/paillier_prikey.cpp index 85aea0a..3ccc3e3 100644 --- a/ipcl/paillier_prikey.cpp +++ b/ipcl/paillier_prikey.cpp @@ -54,8 +54,9 @@ PaillierPrivateKey::PaillierPrivateKey(const PaillierPublicKey* public_key, } } -void PaillierPrivateKey::decryptRAW(BigNumber plaintext[8], - const BigNumber ciphertext[8]) const { +void PaillierPrivateKey::decryptRAW( + std::vector& plaintext, + const std::vector& ciphertext) const { mbx_status st = MBX_STATUS_OK; // setup buffer for mbx_exp @@ -117,8 +118,9 @@ void PaillierPrivateKey::decryptRAW(BigNumber plaintext[8], } } -void PaillierPrivateKey::decrypt(BigNumber plaintext[8], - const BigNumber ciphertext[8]) const { +void PaillierPrivateKey::decrypt( + std::vector& plaintext, + const std::vector& ciphertext) const { if (m_enable_crt) decryptCRT(plaintext, ciphertext); else @@ -126,23 +128,23 @@ void PaillierPrivateKey::decrypt(BigNumber plaintext[8], } void PaillierPrivateKey::decrypt( - BigNumber plaintext[8], const PaillierEncryptedNumber ciphertext) const { + std::vector& plaintext, + const PaillierEncryptedNumber ciphertext) const { // check key match if (ciphertext.getPK().getN() != m_pubkey->getN()) throw std::runtime_error("decrypt: public key mismatch error."); - std::vector res(8); - ciphertext.getArrayBN(res.data()); + std::vector res = ciphertext.getArrayBN(); if (m_enable_crt) - decryptCRT(plaintext, res.data()); + decryptCRT(plaintext, res); else - decryptRAW(plaintext, res.data()); + decryptRAW(plaintext, res); } // CRT to calculate base^exp mod n^2 -void PaillierPrivateKey::decryptCRT(BigNumber plaintext[8], - const BigNumber ciphertext[8]) const { - std::vector resp(8), resq(8); +void PaillierPrivateKey::decryptCRT( + std::vector& plaintext, + const std::vector& ciphertext) const { std::vector basep(8), baseq(8); std::vector pm1(8, m_pminusone), qm1(8, m_qminusone); std::vector psq(8, m_psquare), qsq(8, m_qsquare); @@ -153,8 +155,8 @@ void PaillierPrivateKey::decryptCRT(BigNumber plaintext[8], } // Based on the fact a^b mod n = (a mod n)^b mod n - m_pubkey->ippMultiBuffExp(resp.data(), basep.data(), pm1.data(), psq.data()); - m_pubkey->ippMultiBuffExp(resq.data(), baseq.data(), qm1.data(), qsq.data()); + std::vector resp = m_pubkey->ippMultiBuffExp(basep, pm1, psq); + std::vector resq = m_pubkey->ippMultiBuffExp(baseq, qm1, qsq); for (int i = 0; i < 8; i++) { BigNumber dp = computeLfun(resp[i], m_p) * m_hp % m_p; diff --git a/ipcl/paillier_pubkey.cpp b/ipcl/paillier_pubkey.cpp index 623d1d3..9718505 100644 --- a/ipcl/paillier_pubkey.cpp +++ b/ipcl/paillier_pubkey.cpp @@ -5,6 +5,7 @@ #include +#include #include #include #include @@ -28,14 +29,16 @@ PaillierPublicKey::PaillierPublicKey(const BigNumber& n, int bits, m_init_seed(randomUniformUnsignedInt()), m_enable_DJN(false), m_testv(false) { - if (enableDJN_) this->enableDJN(); // this sets m_enable_DJN + if (enableDJN_) this->enableDJN(); // sets m_enable_DJN } // array of 32-bit random, using rand() from stdlib -void PaillierPublicKey::randIpp32u(std::vector& addr, int size) const { +std::vector PaillierPublicKey::randIpp32u(int size) const { + std::vector addr(size); // TODO(skmono): check if copy of m_init_seed is needed for const unsigned int init_seed = m_init_seed; for (auto& a : addr) a = (rand_r(&init_seed) << 16) + rand_r(&init_seed); + return addr; } // length is Arbitery @@ -45,8 +48,6 @@ BigNumber PaillierPublicKey::getRandom(int length) const { int seedBitSize = 160; int seedSize = BITSIZE_WORD(seedBitSize); - auto seed = std::vector(seedSize); - stat = ippsPRNGGetSize(&size); if (stat != ippStsNoErr) throw std::runtime_error("getRandom: get IppsPRNGState context error."); @@ -58,7 +59,7 @@ BigNumber PaillierPublicKey::getRandom(int length) const { if (stat != ippStsNoErr) throw std::runtime_error("getRandom: init rand context error."); - randIpp32u(seed, seedSize); + auto seed = randIpp32u(seedSize); BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); stat = ippsPRNGSetSeed(BN(bseed), @@ -107,7 +108,8 @@ void PaillierPublicKey::enableDJN() { m_enable_DJN = true; } -void PaillierPublicKey::apply_obfuscator(BigNumber obfuscator[8]) const { +void PaillierPublicKey::apply_obfuscator( + std::vector& obfuscator) const { std::vector r(8); std::vector pown(8, m_n); std::vector base(8, m_hs); @@ -117,7 +119,7 @@ void PaillierPublicKey::apply_obfuscator(BigNumber obfuscator[8]) const { for (auto& r_ : r) { r_ = getRandom(m_randbits); } - ippMultiBuffExp(obfuscator, base.data(), r.data(), sq.data()); + obfuscator = ippMultiBuffExp(base, r, sq); } else { for (int i = 0; i < 8; i++) { if (m_testv) { @@ -129,12 +131,17 @@ void PaillierPublicKey::apply_obfuscator(BigNumber obfuscator[8]) const { pown[i] = m_n; sq[i] = m_nsquare; } - ippMultiBuffExp(obfuscator, r.data(), pown.data(), sq.data()); + obfuscator = ippMultiBuffExp(r, pown, sq); } } -void PaillierPublicKey::raw_encrypt(BigNumber ciphertext[8], - const BigNumber plaintext[8], +void PaillierPublicKey::setRandom(const std::vector& r) { + std::copy(r.begin(), r.end(), std::back_inserter(m_r)); + m_testv = true; +} + +void PaillierPublicKey::raw_encrypt(std::vector& ciphertext, + const std::vector& plaintext, bool make_secure) const { // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 BigNumber sq = m_nsquare; @@ -144,7 +151,7 @@ void PaillierPublicKey::raw_encrypt(BigNumber ciphertext[8], } if (make_secure) { - BigNumber obfuscator[8]; + std::vector obfuscator(8); apply_obfuscator(obfuscator); for (int i = 0; i < 8; i++) @@ -152,8 +159,8 @@ void PaillierPublicKey::raw_encrypt(BigNumber ciphertext[8], } } -void PaillierPublicKey::encrypt(BigNumber ciphertext[8], - const BigNumber value[8], +void PaillierPublicKey::encrypt(std::vector& ciphertext, + const std::vector& value, bool make_secure) const { raw_encrypt(ciphertext, value, make_secure); } @@ -172,11 +179,11 @@ void PaillierPublicKey::encrypt(BigNumber& ciphertext, ---------------------------------------------------------- */ } -void PaillierPublicKey::ippMultiBuffExp(BigNumber res[8], - const BigNumber base[8], - const BigNumber pow[8], - const BigNumber m[8]) const { +std::vector PaillierPublicKey::ippMultiBuffExp( + const std::vector& base, const std::vector& pow, + const std::vector& m) const { mbx_status st = MBX_STATUS_OK; + int bits = m[0].BitSize(); int dwords = BITSIZE_DWORD(bits); int bufferLen = mbx_exp_BufferSize(bits); @@ -240,11 +247,13 @@ void PaillierPublicKey::ippMultiBuffExp(BigNumber res[8], // It is important to hold a copy of nsquare for thread-safe purpose BigNumber bn_c(m[0]); + std::vector res(8, 0); for (int i = 0; i < 8; i++) { bn_c.Set(reinterpret_cast(out_x[i]), BITSIZE_WORD(nsqBitLen), IppsBigNumPOS); res[i] = bn_c; } + return res; } BigNumber PaillierPublicKey::ippMontExp(const BigNumber& base, diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index 10bdf6c..4575562 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -17,11 +17,11 @@ TEST(CryptoTest, CryptoTest) { ipcl::keyPair key = ipcl::generateKeypair(2048, true); - ipcl::BigNumber ct[8]; - ipcl::BigNumber dt[8]; + std::vector ct(8); + std::vector dt(8); - uint32_t pt[8]; - ipcl::BigNumber ptbn[8]; + std::vector pt(8); + std::vector ptbn(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -45,16 +45,20 @@ TEST(CryptoTest, CryptoTest) { } #ifdef IPCL_UNITTEST_OMP -void Encryption(int num_threads, std::vector v_ct, - std::vector v_ptbn, ipcl::keyPair key) { +void Encryption(int num_threads, + std::vector>& v_ct, + const std::vector>& v_ptbn, + const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { key.pub_key->encrypt(v_ct[i], v_ptbn[i]); } } -void Decryption(int num_threads, std::vector v_dt, - std::vector v_ct, ipcl::keyPair key) { +void Decryption(int num_threads, + std::vector>& v_dt, + const std::vector>& v_ct, + const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { key.priv_key->decrypt(v_dt[i], v_ct[i]); @@ -66,23 +70,21 @@ TEST(CryptoTest, CryptoTest_OMP) { ipcl::keyPair key = ipcl::generateKeypair(2048, true); size_t num_threads = omp_get_max_threads(); - // std::cout << "available threads: " << num_threads << std::endl; - std::vector v_ct(num_threads); - std::vector v_dt(num_threads); - std::vector v_pt(num_threads); - std::vector v_ptbn(num_threads); + std::vector> v_ct( + num_threads, std::vector(8)); + std::vector> v_dt( + num_threads, std::vector(8)); + std::vector> v_pt(num_threads, + std::vector(8)); + std::vector> v_ptbn( + num_threads, std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { - v_ct[i] = new ipcl::BigNumber[8]; - v_dt[i] = new ipcl::BigNumber[8]; - v_pt[i] = new uint32_t[8]; - v_ptbn[i] = new ipcl::BigNumber[8]; - // for each threads, generated different rand testing value for (int j = 0; j < 8; j++) { v_pt[i][j] = dist(rng); @@ -102,13 +104,6 @@ TEST(CryptoTest, CryptoTest_OMP) { } } - for (int i = 0; i < num_threads; i++) { - delete[] v_ct[i]; - delete[] v_dt[i]; - delete[] v_pt[i]; - delete[] v_ptbn[i]; - } - delete key.pub_key; delete key.priv_key; } @@ -136,10 +131,10 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { ipcl::keyPair key = {public_key, private_key}; - ipcl::BigNumber ptbn[8]; - ipcl::BigNumber ct[8]; - ipcl::BigNumber dt[8]; - ipcl::BigNumber ir[8]; + std::vector ptbn(8); + std::vector ct(8); + std::vector dt(8); + std::vector ir(8); ipcl::BigNumber c1 = "0x1fb7f08a42deb47876e4cbdc3f0b172c033563a696ad7a7c76fa5971b793fa488dcdd6" @@ -229,7 +224,8 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { ipcl::PaillierEncryptedNumber sum = a + b; ipcl::BigNumber res = sum.getBN(); - ipcl::BigNumber ct12[8], dt12[8]; + std::vector ct12(8); + std::vector dt12(8); for (int i = 0; i < 8; i++) { ct12[i] = res; } diff --git a/test/test_ops.cpp b/test/test_ops.cpp index f19852d..33aa802 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -14,8 +14,10 @@ #include "ipcl/paillier_keygen.hpp" #include "ipcl/paillier_ops.hpp" -void CtPlusCt(ipcl::BigNumber res[8], ipcl::BigNumber ct1[8], - ipcl::BigNumber ct2[8], ipcl::keyPair key) { +void CtPlusCt(std::vector& res, + const std::vector& ct1, + const std::vector& ct2, + const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); ipcl::PaillierEncryptedNumber b(key.pub_key, ct2[i]); @@ -24,16 +26,19 @@ void CtPlusCt(ipcl::BigNumber res[8], ipcl::BigNumber ct1[8], } } -void CtPlusCtArray(ipcl::BigNumber res[8], ipcl::BigNumber ct1[8], - ipcl::BigNumber ct2[8], ipcl::keyPair key) { +void CtPlusCtArray(std::vector& res, + const std::vector& ct1, + const std::vector& ct2, + const ipcl::keyPair key) { ipcl::PaillierEncryptedNumber a(key.pub_key, ct1); ipcl::PaillierEncryptedNumber b(key.pub_key, ct2); ipcl::PaillierEncryptedNumber sum = a + b; - sum.getArrayBN(res); + res = sum.getArrayBN(); } -void CtPlusPt(ipcl::BigNumber res[8], ipcl::BigNumber ct1[8], uint32_t pt2[8], - ipcl::keyPair key) { +void CtPlusPt(std::vector& res, + const std::vector& ct1, + const std::vector& pt2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); ipcl::BigNumber b = pt2[i]; @@ -42,16 +47,18 @@ void CtPlusPt(ipcl::BigNumber res[8], ipcl::BigNumber ct1[8], uint32_t pt2[8], } } -void CtPlusPtArray(ipcl::BigNumber res[8], ipcl::BigNumber ct1[8], - ipcl::BigNumber ptbn2[8], ipcl::keyPair key) { - ipcl::BigNumber stmp[8]; +void CtPlusPtArray(std::vector& res, + const std::vector& ct1, + const std::vector& ptbn2, + const ipcl::keyPair key) { ipcl::PaillierEncryptedNumber a(key.pub_key, ct1); ipcl::PaillierEncryptedNumber sum = a + ptbn2; - sum.getArrayBN(res); + res = sum.getArrayBN(); } -void CtMultiplyPt(ipcl::BigNumber res[8], ipcl::BigNumber ct1[8], - uint32_t pt2[8], ipcl::keyPair key) { +void CtMultiplyPt(std::vector& res, + const std::vector& ct1, + const std::vector& pt2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); ipcl::PaillierEncryptedNumber b(key.pub_key, pt2[i]); @@ -60,16 +67,19 @@ void CtMultiplyPt(ipcl::BigNumber res[8], ipcl::BigNumber ct1[8], } } -void CtMultiplyPtArray(ipcl::BigNumber res[8], ipcl::BigNumber ct1[8], - uint32_t pt2[8], ipcl::keyPair key) { +void CtMultiplyPtArray(std::vector& res, + const std::vector& ct1, + const std::vector& pt2, + const ipcl::keyPair key) { ipcl::PaillierEncryptedNumber a(key.pub_key, ct1); ipcl::PaillierEncryptedNumber b(key.pub_key, pt2); ipcl::PaillierEncryptedNumber sum = a * b; - sum.getArrayBN(res); + res = sum.getArrayBN(); } -void AddSub(ipcl::BigNumber res[8], ipcl::BigNumber ct1[8], - ipcl::BigNumber ct2[8], ipcl::keyPair key) { +void AddSub(std::vector& res, + const std::vector& ct1, + const std::vector& ct2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); ipcl::PaillierEncryptedNumber b(key.pub_key, ct2[i]); @@ -83,11 +93,11 @@ void AddSub(ipcl::BigNumber res[8], ipcl::BigNumber ct1[8], TEST(OperationTest, CtPlusCtTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - ipcl::BigNumber ct1[8], ct2[8]; - ipcl::BigNumber dt[8], res[8]; + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); - uint32_t pt1[8], pt2[8]; - ipcl::BigNumber ptbn1[8], ptbn2[8]; + std::vector pt1(8), pt2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -124,11 +134,11 @@ TEST(OperationTest, CtPlusCtTest) { TEST(OperationTest, CtPlusCtArrayTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - ipcl::BigNumber ct1[8], ct2[8]; - ipcl::BigNumber dt[8], res[8]; + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); - uint32_t pt1[8], pt2[8]; - ipcl::BigNumber ptbn1[8], ptbn2[8]; + std::vector pt1(8), pt2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -165,11 +175,11 @@ TEST(OperationTest, CtPlusCtArrayTest) { TEST(OperationTest, CtPlusPtTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - ipcl::BigNumber ct1[8], ct2[8]; - ipcl::BigNumber dt[8], res[8]; + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); - uint32_t pt1[8], pt2[8]; - ipcl::BigNumber ptbn1[8]; + std::vector pt1(8), pt2(8); + std::vector ptbn1(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -204,11 +214,11 @@ TEST(OperationTest, CtPlusPtTest) { TEST(OperationTest, CtPlusPtArrayTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - ipcl::BigNumber ct1[8], ct2[8]; - ipcl::BigNumber dt[8], res[8]; + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); - uint32_t pt1[8], pt2[8]; - ipcl::BigNumber ptbn1[8], ptbn2[8]; + std::vector pt1(8), pt2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -244,11 +254,11 @@ TEST(OperationTest, CtPlusPtArrayTest) { TEST(OperationTest, CtMultiplyPtTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - ipcl::BigNumber ct1[8], ct2[8]; - ipcl::BigNumber dt[8], res[8]; + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); - uint32_t pt1[8], pt2[8]; - ipcl::BigNumber ptbn1[8]; + std::vector pt1(8), pt2(8); + std::vector ptbn1(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -283,11 +293,11 @@ TEST(OperationTest, CtMultiplyPtTest) { TEST(OperationTest, CtMultiplyZeroPtTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - ipcl::BigNumber ct1[8], ct2[8]; - ipcl::BigNumber dt[8], res[8]; + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); - uint32_t pt1[8], pt2[8]; - ipcl::BigNumber ptbn1[8]; + std::vector pt1(8), pt2(8); + std::vector ptbn1(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -322,11 +332,11 @@ TEST(OperationTest, CtMultiplyZeroPtTest) { TEST(OperationTest, CtMultiplyPtArrayTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - ipcl::BigNumber ct1[8]; - ipcl::BigNumber dt[8], res[8]; + std::vector ct1(8); + std::vector dt(8), res(8); - uint32_t pt1[8], pt2[8]; - ipcl::BigNumber ptbn1[8], ptbn2[8]; + std::vector pt1(8), pt2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -362,11 +372,11 @@ TEST(OperationTest, CtMultiplyPtArrayTest) { TEST(OperationTest, AddSubTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - ipcl::BigNumber ct1[8], ct2[8]; - ipcl::BigNumber dt[8], res[8]; + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); - uint32_t pt1[8], pt2[8]; - ipcl::BigNumber ptbn1[8], ptbn2[8]; + std::vector pt1(8), pt2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -400,9 +410,11 @@ TEST(OperationTest, AddSubTest) { } #ifdef IPCL_UNITTEST_OMP -void CtPlusCt_OMP(int num_threads, std::vector v_sum, - std::vector v_ct1, - std::vector v_ct2, ipcl::keyPair key) { +void CtPlusCt_OMP(int num_threads, + std::vector>& v_sum, + const std::vector>& v_ct1, + const std::vector>& v_ct2, + const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { @@ -414,9 +426,11 @@ void CtPlusCt_OMP(int num_threads, std::vector v_sum, } } -void CtPlusPt_OMP(int num_threads, std::vector v_sum, - std::vector v_ct1, - std::vector v_pt2, ipcl::keyPair key) { +void CtPlusPt_OMP(int num_threads, + std::vector>& v_sum, + const std::vector>& v_ct1, + const std::vector>& v_pt2, + const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { @@ -428,24 +442,28 @@ void CtPlusPt_OMP(int num_threads, std::vector v_sum, } } -void CtPlusPtArray_OMP(int num_threads, std::vector v_sum, - std::vector v_ct1, - std::vector v_pt2, ipcl::keyPair key) { +void CtPlusPtArray_OMP(int num_threads, + std::vector>& v_sum, + const std::vector>& v_ct1, + const std::vector>& v_pt2, + const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); - ipcl::BigNumber b[8]; + std::vector b(8); for (int j = 0; j < 8; j++) { b[j] = v_pt2[i][j]; } ipcl::PaillierEncryptedNumber sum = a + b; - sum.getArrayBN(v_sum[i]); + v_sum[i] = sum.getArrayBN(); } } -void CtMultiplyPt_OMP(int num_threads, std::vector v_product, - std::vector v_ct1, - std::vector v_pt2, ipcl::keyPair key) { +void CtMultiplyPt_OMP(int num_threads, + std::vector>& v_product, + const std::vector>& v_ct1, + const std::vector>& v_pt2, + const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { @@ -457,16 +475,16 @@ void CtMultiplyPt_OMP(int num_threads, std::vector v_product, } } -void CtMultiplyPtArray_OMP(int num_threads, - std::vector v_product, - std::vector v_ct1, - std::vector v_pt2, ipcl::keyPair key) { +void CtMultiplyPtArray_OMP( + int num_threads, std::vector>& v_product, + const std::vector>& v_ct1, + const std::vector>& v_pt2, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); ipcl::PaillierEncryptedNumber b(key.pub_key, v_pt2[i]); ipcl::PaillierEncryptedNumber product = a * b; - product.getArrayBN(v_product[i]); + v_product[i] = product.getArrayBN(); } } @@ -475,28 +493,27 @@ TEST(OperationTest, CtPlusCtTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector v_ct1(num_threads); - std::vector v_ct2(num_threads); - std::vector v_dt(num_threads); - std::vector v_sum(num_threads); - std::vector v_pt1(num_threads); - std::vector v_pt2(num_threads); - std::vector v_ptbn1(num_threads); - std::vector v_ptbn2(num_threads); + std::vector> v_ct1( + num_threads, std::vector(8)); + std::vector> v_ct2( + num_threads, std::vector(8)); + std::vector> v_dt( + num_threads, std::vector(8)); + std::vector> v_sum( + num_threads, std::vector(8)); + std::vector> v_pt1(num_threads, + std::vector(8)); + std::vector> v_pt2(num_threads, + std::vector(8)); + std::vector> v_ptbn1( + num_threads, std::vector(8)); + std::vector> v_ptbn2( + num_threads, std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { - v_ct1[i] = new ipcl::BigNumber[8]; - v_ct2[i] = new ipcl::BigNumber[8]; - v_dt[i] = new ipcl::BigNumber[8]; - v_sum[i] = new ipcl::BigNumber[8]; - v_pt1[i] = new uint32_t[8]; - v_pt2[i] = new uint32_t[8]; - v_ptbn1[i] = new ipcl::BigNumber[8]; - v_ptbn2[i] = new ipcl::BigNumber[8]; - // for each threads, generated different rand testing value for (int j = 0; j < 8; j++) { v_pt1[i][j] = dist(rng); @@ -533,17 +550,6 @@ TEST(OperationTest, CtPlusCtTest_OMP) { } } - for (int i = 0; i < num_threads; i++) { - delete[] v_ct1[i]; - delete[] v_ct2[i]; - delete[] v_dt[i]; - delete[] v_pt1[i]; - delete[] v_pt2[i]; - delete[] v_ptbn1[i]; - delete[] v_ptbn2[i]; - delete[] v_sum[i]; - } - delete key.pub_key; delete key.priv_key; } @@ -553,26 +559,25 @@ TEST(OperationTest, CtPlusPtTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector v_ct1(num_threads); - std::vector v_dt(num_threads); - std::vector v_sum(num_threads); - std::vector v_pt1(num_threads); - std::vector v_pt2(num_threads); - std::vector v_ptbn1(num_threads); - std::vector v_ptbn2(num_threads); + std::vector> v_ct1( + num_threads, std::vector(8)); + std::vector> v_dt( + num_threads, std::vector(8)); + std::vector> v_sum( + num_threads, std::vector(8)); + std::vector> v_pt1(num_threads, + std::vector(8)); + std::vector> v_pt2(num_threads, + std::vector(8)); + std::vector> v_ptbn1( + num_threads, std::vector(8)); + std::vector> v_ptbn2( + num_threads, std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { - v_ct1[i] = new ipcl::BigNumber[8]; - v_dt[i] = new ipcl::BigNumber[8]; - v_sum[i] = new ipcl::BigNumber[8]; - v_pt1[i] = new uint32_t[8]; - v_pt2[i] = new uint32_t[8]; - v_ptbn1[i] = new ipcl::BigNumber[8]; - v_ptbn2[i] = new ipcl::BigNumber[8]; - // for each threads, generated different rand testing value for (int j = 0; j < 8; j++) { v_pt1[i][j] = dist(rng); @@ -608,16 +613,6 @@ TEST(OperationTest, CtPlusPtTest_OMP) { } } - for (int i = 0; i < num_threads; i++) { - delete[] v_ct1[i]; - delete[] v_dt[i]; - delete[] v_pt1[i]; - delete[] v_pt2[i]; - delete[] v_ptbn1[i]; - delete[] v_ptbn2[i]; - delete[] v_sum[i]; - } - delete key.pub_key; delete key.priv_key; } @@ -627,26 +622,25 @@ TEST(OperationTest, CtPlusPtArrayTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector v_ct1(num_threads); - std::vector v_dt(num_threads); - std::vector v_sum(num_threads); - std::vector v_pt1(num_threads); - std::vector v_pt2(num_threads); - std::vector v_ptbn1(num_threads); - std::vector v_ptbn2(num_threads); + std::vector> v_ct1( + num_threads, std::vector(8)); + std::vector> v_dt( + num_threads, std::vector(8)); + std::vector> v_sum( + num_threads, std::vector(8)); + std::vector> v_pt1(num_threads, + std::vector(8)); + std::vector> v_pt2(num_threads, + std::vector(8)); + std::vector> v_ptbn1( + num_threads, std::vector(8)); + std::vector> v_ptbn2( + num_threads, std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { - v_ct1[i] = new ipcl::BigNumber[8]; - v_dt[i] = new ipcl::BigNumber[8]; - v_sum[i] = new ipcl::BigNumber[8]; - v_pt1[i] = new uint32_t[8]; - v_pt2[i] = new uint32_t[8]; - v_ptbn1[i] = new ipcl::BigNumber[8]; - v_ptbn2[i] = new ipcl::BigNumber[8]; - // for each threads, generated different rand testing value for (int j = 0; j < 8; j++) { v_pt1[i][j] = dist(rng); @@ -682,16 +676,6 @@ TEST(OperationTest, CtPlusPtArrayTest_OMP) { } } - for (int i = 0; i < num_threads; i++) { - delete[] v_ct1[i]; - delete[] v_dt[i]; - delete[] v_pt1[i]; - delete[] v_pt2[i]; - delete[] v_ptbn1[i]; - delete[] v_ptbn2[i]; - delete[] v_sum[i]; - } - delete key.pub_key; delete key.priv_key; } @@ -701,27 +685,26 @@ TEST(OperationTest, CtMultiplyPtTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector v_ct1(num_threads); - std::vector v_dt(num_threads); - std::vector v_product(num_threads); - std::vector v_pt1(num_threads); - std::vector v_pt2(num_threads); - std::vector v_ptbn1(num_threads); - std::vector v_ptbn2(num_threads); + std::vector> v_ct1( + num_threads, std::vector(8)); + std::vector> v_dt( + num_threads, std::vector(8)); + std::vector> v_product( + num_threads, std::vector(8)); + std::vector> v_pt1(num_threads, + std::vector(8)); + std::vector> v_pt2(num_threads, + std::vector(8)); + std::vector> v_ptbn1( + num_threads, std::vector(8)); + std::vector> v_ptbn2( + num_threads, std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { - v_ct1[i] = new ipcl::BigNumber[8]; - v_dt[i] = new ipcl::BigNumber[8]; - v_product[i] = new ipcl::BigNumber[8]; - v_pt1[i] = new uint32_t[8]; - v_pt2[i] = new uint32_t[8]; - v_ptbn1[i] = new ipcl::BigNumber[8]; - v_ptbn2[i] = new ipcl::BigNumber[8]; - // for each threads, generated different rand testing value for (int j = 0; j < 8; j++) { v_pt1[i][j] = dist(rng); @@ -756,16 +739,6 @@ TEST(OperationTest, CtMultiplyPtTest_OMP) { } } - for (int i = 0; i < num_threads; i++) { - delete[] v_ct1[i]; - delete[] v_dt[i]; - delete[] v_pt1[i]; - delete[] v_pt2[i]; - delete[] v_ptbn1[i]; - delete[] v_ptbn2[i]; - delete[] v_product[i]; - } - delete key.pub_key; delete key.priv_key; } @@ -775,29 +748,27 @@ TEST(OperationTest, CtMultiplyPtArrayTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector v_ct1(num_threads); - std::vector v_dt(num_threads); - std::vector v_product(num_threads); - std::vector v_pt1(num_threads); - std::vector v_pt2(num_threads); - std::vector v_ptbn1(num_threads); - std::vector v_ptbn2(num_threads); + std::vector> v_ct1( + num_threads, std::vector(8)); + std::vector> v_dt( + num_threads, std::vector(8)); + std::vector> v_product( + num_threads, std::vector(8)); + std::vector> v_pt1(num_threads, + std::vector(8)); + std::vector> v_pt2(num_threads, + std::vector(8)); + std::vector> v_ptbn1( + num_threads, std::vector(8)); + std::vector> v_ptbn2( + num_threads, std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { - v_ct1[i] = new ipcl::BigNumber[8]; - v_dt[i] = new ipcl::BigNumber[8]; - v_product[i] = new ipcl::BigNumber[8]; - v_pt1[i] = new uint32_t[8]; - v_pt2[i] = new uint32_t[8]; - v_ptbn1[i] = new ipcl::BigNumber[8]; - v_ptbn2[i] = new ipcl::BigNumber[8]; - // for each threads, generated different rand testing value - for (int j = 0; j < 8; j++) { v_pt1[i][j] = dist(rng); v_pt2[i][j] = dist(rng); @@ -830,16 +801,6 @@ TEST(OperationTest, CtMultiplyPtArrayTest_OMP) { } } - for (int i = 0; i < num_threads; i++) { - delete[] v_ct1[i]; - delete[] v_dt[i]; - delete[] v_pt1[i]; - delete[] v_pt2[i]; - delete[] v_ptbn1[i]; - delete[] v_ptbn2[i]; - delete[] v_product[i]; - } - delete key.pub_key; delete key.priv_key; } From 1cade912ffe1b109b38026fe2e36812b12c14030 Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Thu, 3 Mar 2022 05:33:31 +0800 Subject: [PATCH 066/364] Add util function/macro (#24) * Add util function/macro * Minor modifications - Changed PARALLEL_PROCESS_NUM to IPCL_CRYPTO_MB_SIZE - Replaced BigNum macros (BITSIZE_WORD and BITSIZE_DWORD) with functions in BigNum Co-authored-by: Sejun Kim --- ipcl/bignum.cpp | 3 ++ ipcl/include/ipcl/bignum.h | 7 +-- ipcl/include/ipcl/common.hpp | 12 +++++ ipcl/include/ipcl/paillier_ops.hpp | 5 +- ipcl/include/ipcl/util.hpp | 42 +++++++++++++++++ ipcl/paillier_keygen.cpp | 11 +++-- ipcl/paillier_ops.cpp | 22 +++++---- ipcl/paillier_prikey.cpp | 35 +++++++------- ipcl/paillier_pubkey.cpp | 73 ++++++++++++++++-------------- 9 files changed, 137 insertions(+), 73 deletions(-) create mode 100644 ipcl/include/ipcl/common.hpp create mode 100644 ipcl/include/ipcl/util.hpp diff --git a/ipcl/bignum.cpp b/ipcl/bignum.cpp index f121d98..cff54b7 100644 --- a/ipcl/bignum.cpp +++ b/ipcl/bignum.cpp @@ -501,4 +501,7 @@ std::ostream& operator<<(std::ostream& os, const BigNumber& a) { return os; } +int BITSIZE_WORD(int n) { return (((n) + 31) >> 5); } +int BITSIZE_DWORD(int n) { return (((n) + 63) >> 6); } + } // namespace ipcl diff --git a/ipcl/include/ipcl/bignum.h b/ipcl/include/ipcl/bignum.h index d2eadd4..3f1684e 100644 --- a/ipcl/include/ipcl/bignum.h +++ b/ipcl/include/ipcl/bignum.h @@ -127,11 +127,8 @@ class BigNumber { IppsBigNumState* m_pBN; }; -// convert bit size into 32-bit words -#define BITSIZE_WORD(n) ((((n) + 31) >> 5)) - -// Bin: convert bit size into 64-bit words -#define BITSIZE_DWORD(n) ((((n) + 63) >> 6)) +int BITSIZE_WORD(int n); +int BITSIZE_DWORD(int n); } // namespace ipcl #endif // _BIGNUM_H_ diff --git a/ipcl/include/ipcl/common.hpp b/ipcl/include/ipcl/common.hpp new file mode 100644 index 0000000..fecc02d --- /dev/null +++ b/ipcl/include/ipcl/common.hpp @@ -0,0 +1,12 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IPCL_INCLUDE_IPCL_COMMON_HPP_ +#define IPCL_INCLUDE_IPCL_COMMON_HPP_ + +namespace ipcl { + +#define IPCL_CRYPTO_MB_SIZE 8 + +} // namespace ipcl +#endif // IPCL_INCLUDE_IPCL_COMMON_HPP_ diff --git a/ipcl/include/ipcl/paillier_ops.hpp b/ipcl/include/ipcl/paillier_ops.hpp index 98e774e..3679b59 100644 --- a/ipcl/include/ipcl/paillier_ops.hpp +++ b/ipcl/include/ipcl/paillier_ops.hpp @@ -7,6 +7,7 @@ #include #include "ipcl/paillier_pubkey.hpp" +#include "ipcl/util.hpp" namespace ipcl { @@ -89,8 +90,8 @@ class PaillierEncryptedNumber { * @param[in] idx index of output array(default value is 0) */ BigNumber getBN(size_t idx = 0) const { - if (m_available == 1 && idx > 0) - throw std::out_of_range("PaillierEncryptedNumber only has 1 BigNumber"); + ERROR_CHECK(m_available != 1 || idx <= 0, + "getBN: PaillierEncryptedNumber only has 1 BigNumber"); return m_bn[idx]; } diff --git a/ipcl/include/ipcl/util.hpp b/ipcl/include/ipcl/util.hpp new file mode 100644 index 0000000..b56cf50 --- /dev/null +++ b/ipcl/include/ipcl/util.hpp @@ -0,0 +1,42 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IPCL_INCLUDE_IPCL_UTIL_HPP_ +#define IPCL_INCLUDE_IPCL_UTIL_HPP_ + +#include +#include +#include + +#include "ipcl/common.hpp" + +namespace ipcl { + +static inline std::string build_log(const char* file, int line, + std::string msg) { + std::string log; + log = "\nFile: " + std::string(file); + log += "\nLine: " + std::to_string(line); + log += "\nError: " + msg; + + return log; +} + +#define ERROR_CHECK(e, ...) \ + do { \ + if (!(e)) \ + throw std::runtime_error(build_log(__FILE__, __LINE__, __VA_ARGS__)); \ + } while (0) + +template +inline void vec_size_check(const std::vector& v, const char* file, + int line) { + if (v.size() != IPCL_CRYPTO_MB_SIZE) + throw std::runtime_error(build_log( + file, line, "Vector size is NOT equal to IPCL_CRYPTO_MB_SIZE")); +} + +#define VEC_SIZE_CHECK(v) vec_size_check(v, __FILE__, __LINE__) + +} // namespace ipcl +#endif // IPCL_INCLUDE_IPCL_UTIL_HPP_ diff --git a/ipcl/paillier_keygen.cpp b/ipcl/paillier_keygen.cpp index 777c86c..22f0ce9 100644 --- a/ipcl/paillier_keygen.cpp +++ b/ipcl/paillier_keygen.cpp @@ -7,6 +7,8 @@ #include #include +#include "ipcl/util.hpp" + namespace ipcl { #define N_BIT_SIZE_MAX 2048 @@ -87,11 +89,10 @@ keyPair generateKeypair(int64_t n_length, bool enable_DJN) { https://www.intel.com/content/www/us/en/develop/documentation/ipp-crypto-reference/top/multi-buffer-cryptography-functions/modular-exponentiation/mbx-exp-1024-2048-3072-4096-mb8.html modulus size = n * n (keySize * keySize ) */ - if (n_length > N_BIT_SIZE_MAX) { - throw std::runtime_error( - "modulus size in bits should belong to either 1Kb, 2Kb, " - "3Kb or 4Kb range only, key size exceed the range!!!"); - } + ERROR_CHECK( + n_length <= N_BIT_SIZE_MAX, + "generateKeyPair: modulus size in bits should belong to either 1Kb, 2Kb, " + "3Kb or 4Kb range only, key size exceed the range!!!"); BigNumber p, q, n; diff --git a/ipcl/paillier_ops.cpp b/ipcl/paillier_ops.cpp index 1c66844..f7c05e0 100644 --- a/ipcl/paillier_ops.cpp +++ b/ipcl/paillier_ops.cpp @@ -5,6 +5,8 @@ #include +#include "ipcl/util.hpp" + namespace ipcl { // constructors // @@ -38,9 +40,8 @@ PaillierEncryptedNumber::PaillierEncryptedNumber( // CT+CT PaillierEncryptedNumber PaillierEncryptedNumber::operator+( const PaillierEncryptedNumber& other) const { - if (m_pubkey->getN() != other.m_pubkey->getN()) { - throw std::runtime_error("two different public keys detected!!"); - } + ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), + "operator+: two different public keys detected!!"); PaillierEncryptedNumber a = *this; PaillierEncryptedNumber b = other; @@ -70,6 +71,8 @@ PaillierEncryptedNumber PaillierEncryptedNumber::operator+( // multi encrypted CT+PT PaillierEncryptedNumber PaillierEncryptedNumber::operator+( const std::vector& other) const { + VEC_SIZE_CHECK(other); + PaillierEncryptedNumber a = *this; std::vector b(8); @@ -83,9 +86,8 @@ PaillierEncryptedNumber PaillierEncryptedNumber::operator+( // integer PaillierEncryptedNumber PaillierEncryptedNumber::operator*( const PaillierEncryptedNumber& other) const { - if (m_pubkey->getN() != other.m_pubkey->getN()) { - throw std::runtime_error("two different public keys detected!!"); - } + ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), + "operator*: two different public keys detected!!"); PaillierEncryptedNumber a = *this; PaillierEncryptedNumber b = other; @@ -129,10 +131,10 @@ BigNumber PaillierEncryptedNumber::raw_mul(const BigNumber& a, } PaillierEncryptedNumber PaillierEncryptedNumber::rotate(int shift) const { - if (m_available == 1) - throw std::invalid_argument("Cannot rotate single PaillierEncryptedNumber"); - if (shift > 8 || shift < -8) - throw std::invalid_argument("Cannot shift more than 8 or -8"); + ERROR_CHECK(m_available != 1, + "rotate: Cannot rotate single PaillierEncryptedNumber"); + ERROR_CHECK(shift >= -8 && shift <= 8, + "rotate: Cannot shift more than 8 or -8"); if (shift == 0 || shift == 8 || shift == -8) return PaillierEncryptedNumber(m_pubkey, m_bn); diff --git a/ipcl/paillier_prikey.cpp b/ipcl/paillier_prikey.cpp index 3ccc3e3..a4cb074 100644 --- a/ipcl/paillier_prikey.cpp +++ b/ipcl/paillier_prikey.cpp @@ -7,6 +7,8 @@ #include +#include "ipcl/util.hpp" + namespace ipcl { /** * Compute lcm for p and q @@ -45,13 +47,9 @@ PaillierPrivateKey::PaillierPrivateKey(const PaillierPublicKey* public_key, m_bits(m_pubkey->getBits()), m_dwords(m_pubkey->getDwords()), m_enable_crt(true) { - if (p * q != m_n) { - throw std::runtime_error("Public key does not match p * q."); - } - - if (p == q) { - throw std::runtime_error("p and q error."); - } + ERROR_CHECK(p * q == m_n, + "PaillierPrivateKey ctor: Public key does not match p * q."); + ERROR_CHECK(p != q, "PaillierPrivateKey ctor: p and q are same"); } void PaillierPrivateKey::decryptRAW( @@ -69,9 +67,8 @@ void PaillierPrivateKey::decryptRAW( for (int i = 0; i < 8; i++) { out_m[i] = reinterpret_cast(alloca(length)); cip_array[i] = reinterpret_cast(alloca(length)); - - if (out_m[i] == nullptr || cip_array[i] == nullptr) - throw std::runtime_error("decryptRAW: alloc memory for error"); + ERROR_CHECK(out_m[i] != nullptr && cip_array[i] != nullptr, + "decryptRAW: alloc memory for error"); memset(out_m[i], 0, length); memset(cip_array[i], 0, length); @@ -98,11 +95,11 @@ void PaillierPrivateKey::decryptRAW( pBuffer.data(), bufferLen); for (int i = 0; i < 8; i++) { - if (MBX_STATUS_OK != MBX_GET_STS(st, i)) - throw std::runtime_error( - std::string( - "decryptRAW: error multi buffered exp modules, error code = ") + - std::to_string(MBX_GET_STS(st, i))); + ERROR_CHECK( + MBX_STATUS_OK == MBX_GET_STS(st, i), + std::string( + "decryptRAW: error multi buffered exp modules, error code = ") + + std::to_string(MBX_GET_STS(st, i))); } BigNumber ipp_res(m_nsquare); @@ -121,6 +118,9 @@ void PaillierPrivateKey::decryptRAW( void PaillierPrivateKey::decrypt( std::vector& plaintext, const std::vector& ciphertext) const { + VEC_SIZE_CHECK(plaintext); + VEC_SIZE_CHECK(ciphertext); + if (m_enable_crt) decryptCRT(plaintext, ciphertext); else @@ -130,9 +130,10 @@ void PaillierPrivateKey::decrypt( void PaillierPrivateKey::decrypt( std::vector& plaintext, const PaillierEncryptedNumber ciphertext) const { + VEC_SIZE_CHECK(plaintext); // check key match - if (ciphertext.getPK().getN() != m_pubkey->getN()) - throw std::runtime_error("decrypt: public key mismatch error."); + ERROR_CHECK(ciphertext.getPK().getN() == m_pubkey->getN(), + "decrypt: public key mismatch error."); std::vector res = ciphertext.getArrayBN(); if (m_enable_crt) diff --git a/ipcl/paillier_pubkey.cpp b/ipcl/paillier_pubkey.cpp index 9718505..7afa08e 100644 --- a/ipcl/paillier_pubkey.cpp +++ b/ipcl/paillier_pubkey.cpp @@ -10,6 +10,8 @@ #include #include +#include "ipcl/util.hpp" + namespace ipcl { static inline auto randomUniformUnsignedInt() { @@ -49,37 +51,33 @@ BigNumber PaillierPublicKey::getRandom(int length) const { int seedSize = BITSIZE_WORD(seedBitSize); stat = ippsPRNGGetSize(&size); - if (stat != ippStsNoErr) - throw std::runtime_error("getRandom: get IppsPRNGState context error."); + ERROR_CHECK(stat == ippStsNoErr, + "getRandom: get IppsPRNGState context error."); auto pRand = std::vector(size); stat = ippsPRNGInit(seedBitSize, reinterpret_cast(pRand.data())); - if (stat != ippStsNoErr) - throw std::runtime_error("getRandom: init rand context error."); + ERROR_CHECK(stat == ippStsNoErr, "getRandom: init rand context error."); auto seed = randIpp32u(seedSize); BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); stat = ippsPRNGSetSeed(BN(bseed), reinterpret_cast(pRand.data())); - if (stat != ippStsNoErr) - throw std::runtime_error("getRandom: set up seed value error."); + ERROR_CHECK(stat == ippStsNoErr, "getRandom: set up seed value error."); // define length Big Numbers int bn_size = BITSIZE_WORD(length); stat = ippsBigNumGetSize(bn_size, &size); - if (stat != ippStsNoErr) - throw std::runtime_error("getRandom: get IppsBigNumState context error."); + ERROR_CHECK(stat == ippStsNoErr, + "getRandom: get IppsBigNumState context error."); IppsBigNumState* pBN = reinterpret_cast(alloca(size)); - if (nullptr == pBN) - throw std::runtime_error("getRandom: big number alloca error"); + ERROR_CHECK(pBN != nullptr, "getRandom: big number alloca error"); stat = ippsBigNumInit(bn_size, pBN); - if (stat != ippStsNoErr) - throw std::runtime_error("getRandom: init big number context error."); + ERROR_CHECK(stat == ippStsNoErr, "getRandom: init big number context error."); int bnBitSize = length; ippsPRNGenRDRAND_BN(pBN, bnBitSize, @@ -115,6 +113,8 @@ void PaillierPublicKey::apply_obfuscator( std::vector base(8, m_hs); std::vector sq(8, m_nsquare); + VEC_SIZE_CHECK(obfuscator); + if (m_enable_DJN) { for (auto& r_ : r) { r_ = getRandom(m_randbits); @@ -136,6 +136,8 @@ void PaillierPublicKey::apply_obfuscator( } void PaillierPublicKey::setRandom(const std::vector& r) { + VEC_SIZE_CHECK(r); + std::copy(r.begin(), r.end(), std::back_inserter(m_r)); m_testv = true; } @@ -162,6 +164,9 @@ void PaillierPublicKey::raw_encrypt(std::vector& ciphertext, void PaillierPublicKey::encrypt(std::vector& ciphertext, const std::vector& value, bool make_secure) const { + VEC_SIZE_CHECK(ciphertext); + VEC_SIZE_CHECK(value); + raw_encrypt(ciphertext, value, make_secure); } @@ -182,6 +187,10 @@ void PaillierPublicKey::encrypt(BigNumber& ciphertext, std::vector PaillierPublicKey::ippMultiBuffExp( const std::vector& base, const std::vector& pow, const std::vector& m) const { + VEC_SIZE_CHECK(base); + VEC_SIZE_CHECK(pow); + VEC_SIZE_CHECK(m); + mbx_status st = MBX_STATUS_OK; int bits = m[0].BitSize(); @@ -197,8 +206,9 @@ std::vector PaillierPublicKey::ippMultiBuffExp( b_array[i] = reinterpret_cast(alloca(length)); p_array[i] = reinterpret_cast(alloca(length)); - if (out_x[i] == nullptr || b_array[i] == nullptr || p_array[i] == nullptr) - throw std::runtime_error("ippMultiBuffExp: alloc memory for error"); + ERROR_CHECK( + out_x[i] != nullptr && b_array[i] != nullptr && p_array[i] != nullptr, + "ippMultiBuffExp: alloc memory for error"); memset(out_x[i], 0, length); memset(b_array[i], 0, length); @@ -238,10 +248,10 @@ std::vector PaillierPublicKey::ippMultiBuffExp( reinterpret_cast(pBuffer.data()), bufferLen); for (int i = 0; i < 8; i++) { - if (MBX_STATUS_OK != MBX_GET_STS(st, i)) - throw std::runtime_error( - std::string("error multi buffered exp modules, error code = ") + - std::to_string(MBX_GET_STS(st, i))); + ERROR_CHECK(MBX_STATUS_OK == MBX_GET_STS(st, i), + std::string("ippMultiBuffExp: error multi buffered exp " + "modules, error code = ") + + std::to_string(MBX_GET_STS(st, i))); } // It is important to hold a copy of nsquare for thread-safe purpose @@ -272,44 +282,39 @@ BigNumber PaillierPublicKey::ippMontExp(const BigNumber& base, int size; // define and initialize Montgomery Engine over Modulus N stat = ippsMontGetSize(IppsBinaryMethod, nlen, &size); - if (stat != ippStsNoErr) - throw std::runtime_error( - "ippMontExp: get the size of IppsMontState context error."); + ERROR_CHECK(stat == ippStsNoErr, + "ippMontExp: get the size of IppsMontState context error."); auto pMont = std::vector(size); stat = ippsMontInit(IppsBinaryMethod, nlen, reinterpret_cast(pMont.data())); - if (stat != ippStsNoErr) - throw std::runtime_error("ippMontExp: init Mont context error."); + ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: init Mont context error."); stat = ippsMontSet(pow_m, nlen, reinterpret_cast(pMont.data())); - if (stat != ippStsNoErr) - throw std::runtime_error("ippMontExp: set Mont input error."); + ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: set Mont input error."); // encode base into Montfomery form BigNumber bform(m); stat = ippsMontForm(BN(base), reinterpret_cast(pMont.data()), BN(bform)); - if (stat != ippStsNoErr) - throw std::runtime_error( - "ippMontExp: convet big number into Mont form error."); + ERROR_CHECK(stat == ippStsNoErr, + "ippMontExp: convet big number into Mont form error."); // compute R = base^pow mod N stat = ippsMontExp(BN(bform), BN(pow), reinterpret_cast(pMont.data()), BN(res)); - if (stat != ippStsNoErr) - throw std::runtime_error(std::string("ippsMontExp: error code = ") + - std::to_string(stat)); + ERROR_CHECK(stat == ippStsNoErr, + std::string("ippsMontExp: error code = ") + std::to_string(stat)); BigNumber one(1); // R = MontMul(R,1) stat = ippsMontMul(BN(res), BN(one), reinterpret_cast(pMont.data()), BN(res)); - if (stat != ippStsNoErr) - throw std::runtime_error(std::string("ippsMontMul: error code = ") + - std::to_string(stat)); + + ERROR_CHECK(stat == ippStsNoErr, + std::string("ippsMontMul: error code = ") + std::to_string(stat)); return res; } From 65a957e088ff2e6bde89fb224168a3feb27134d5 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Wed, 2 Mar 2022 15:58:44 -0800 Subject: [PATCH 067/364] Updated readme (#25) --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index ffd5067..188921c 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ Intel Paillier Cryptosystem Library is an open-source library which provides acc - [Dependencies](#dependencies) - [Instructions](#instructions) - [Testing and Benchmarking](#testing-and-benchmarking) +- [Python Extension](#python-extension) - [Standardization](#standardization) - [Contributors](#contributors) @@ -94,6 +95,9 @@ OpenMP unit-tests and benchmarks will automatically be applied if `-DIPCL_ENABLE The executables are located at `${IPCL_DIR}/build/test/unittest_ipcl` and `${IPCL_DIR}/build/benchmark/bench_ipcl`. +# Python Extension +Alongside the Intel Paillier Cryptosystem Library, we provide a Python extension package utilizing this library as a backend. For installation and usage detail, refer to [Intel Paillier Cryptosystem Library - Python](https://github.com/intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.pailliercryptolib-python). + # Standardization This library is in compliance with the homomorphic encryption standards [ISO/IEC 18033-6](https://www.iso.org/standard/67740.html). The compliance test is included in the [unit-test](test/test_cryptography.cpp#L112-L256). From 34629b2dafdad1f9cc0ffab97b716be9ebcc6f56 Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Fri, 4 Mar 2022 04:05:09 +0800 Subject: [PATCH 068/364] Add support for multi cpu architecture (#28) * Add support for multi cpu architecture(i.e. when cpu doesn't support avx512 instructions) * OpenMP enabling cleanup * Skmono/decrypt raw refactoring (#29) * Modified decryptRAW to use m_pubkey->ippMultiBuffExp * Replaced "avx512" with "avx512ifma" - mbx_exp_mb8 works only with ifma instructions * Removed testing code * Renamed OMP compiler flag to IPCL_USE_OMP * Renamed ippMultiBuffExp and ippMontExp - ippMultiBuffExp -> ippMBModExp - ippMontExp -> ippSBModExp - put both multi and single buffered mod exp to private - only expose ippModExp that will take care of any modular exponentiation * bugfix - updated remaining ippMontExp Co-authored-by: Sejun Kim --- CMakeLists.txt | 4 ++ benchmark/CMakeLists.txt | 1 - benchmark/bench_cryptography.cpp | 8 ++-- benchmark/bench_ops.cpp | 8 ++-- ipcl/CMakeLists.txt | 9 ++++ ipcl/include/ipcl/paillier_pubkey.hpp | 52 +++++++++++++++------- ipcl/paillier_ops.cpp | 4 +- ipcl/paillier_prikey.cpp | 63 ++++----------------------- ipcl/paillier_pubkey.cpp | 41 ++++++++++++++--- test/CMakeLists.txt | 1 - test/test_cryptography.cpp | 8 ++-- test/test_ops.cpp | 8 ++-- 12 files changed, 111 insertions(+), 96 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 94b5e15..7918c0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,10 @@ option(IPCL_ENABLE_OMP "Enable OpenMP testing/benchmarking" ON) option(IPCL_DOCS "Enable document building" OFF) option(IPCL_SHARED "Build shared library" ON) +if(IPCL_ENABLE_OMP) + add_compile_definitions(IPCL_USE_OMP) +endif() + if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(IPCL_DEBUG ON) else() diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 7fcd633..ae35824 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -18,6 +18,5 @@ target_link_libraries(bench_ipcl PRIVATE # enable OpenMP benchmarks if(IPCL_ENABLE_OMP) find_package(OpenMP REQUIRED) - add_compile_definitions(IPCL_BENCHMARK_OMP) target_link_libraries(bench_ipcl PRIVATE OpenMP::OpenMP_CXX) endif() diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index ec92562..06f28e2 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -4,9 +4,9 @@ #include #include -#ifdef IPCL_BENCHMARK_OMP +#ifdef IPCL_USE_OMP #include -#endif +#endif // IPCL_USE_OMP #include "ipcl/paillier_keygen.hpp" @@ -117,7 +117,7 @@ BENCHMARK(BM_Decrypt_buff8) ->Args({16}) ->Args({64}); -#ifdef IPCL_BENCHMARK_OMP +#ifdef IPCL_USE_OMP static void BM_Encrypt_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); @@ -224,4 +224,4 @@ BENCHMARK(BM_Decrypt_buff8_OMP) ->Unit(benchmark::kMicrosecond) ->Args({16}) ->Args({64}); -#endif +#endif // IPCL_USE_OMP diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index f13b271..a9a43d2 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -4,9 +4,9 @@ #include #include -#ifdef IPCL_BENCHMARK_OMP +#ifdef IPCL_USE_OMP #include -#endif +#endif // IPCL_USE_OMP #include #include "ipcl/paillier_keygen.hpp" @@ -203,7 +203,7 @@ BENCHMARK(BM_Mul_CTPT_buff8) ->Args({16}) ->Args({64}); -#ifdef IPCL_BENCHMARK_OMP +#ifdef IPCL_USE_OMP static void BM_Add_CTCT_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); @@ -409,4 +409,4 @@ BENCHMARK(BM_Mul_CTPT_buff8_OMP) ->Unit(benchmark::kMicrosecond) ->Args({16}) ->Args({64}); -#endif +#endif // IPCL_USE_OMP diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 540cde2..199ae28 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -53,6 +53,15 @@ else() target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) endif() +# check whether cpu support avx512 flag +set(CPU_AVX512_FLAG "avx512ifma") +execute_process(COMMAND lscpu COMMAND grep ${CPU_AVX512_FLAG} OUTPUT_VARIABLE CPU_ENABLE_AVX512) +if("${CPU_ENABLE_AVX512}" STREQUAL "") + message(STATUS "Support AVX512IFMA: False") +else() + message(STATUS "Support AVX512IFMA: True") + add_compile_definitions(IPCL_CRYPTO_MB_MOD_EXP) +endif() set_target_properties(ipcl PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(ipcl PROPERTIES VERSION ${IPCL_VERSION}) diff --git a/ipcl/include/ipcl/paillier_pubkey.hpp b/ipcl/include/ipcl/paillier_pubkey.hpp index 7d90e63..dccd407 100644 --- a/ipcl/include/ipcl/paillier_pubkey.hpp +++ b/ipcl/include/ipcl/paillier_pubkey.hpp @@ -60,19 +60,11 @@ class PaillierPublicKey { * @param[in] m modular * @return the modular exponentiation result of type BigNumber */ - BigNumber ippMontExp(const BigNumber& base, const BigNumber& pow, - const BigNumber& m) const; - - /** - * Multi-buffered modular exponentiation - * @param[out] res array result of the modular exponentiation - * @param[in] base array base of the exponentiation - * @param[in] pow arrya pow of the exponentiation - * @param[in] m arrayodular - */ - std::vector ippMultiBuffExp(const std::vector& base, - const std::vector& pow, - const std::vector& m) const; + std::vector ippModExp(const std::vector& base, + const std::vector& pow, + const std::vector& m) const; + BigNumber ippModExp(const BigNumber& base, const BigNumber& pow, + const BigNumber& m) const; /** * Invert function needed by encoder(float to integer) @@ -138,7 +130,7 @@ class PaillierPublicKey { /** * Get random value * @param[in] size size of random - * @return addr of random + * @return addr of random of type Ipp32u vector */ std::vector randIpp32u(int size) const; @@ -151,13 +143,43 @@ class PaillierPublicKey { void raw_encrypt(std::vector& ciphertext, const std::vector& plaintext, bool make_secure = true) const; - + // /** + // * Raw Multi-buffered modular exponentiation + // * @param[in] base array base of the exponentiation + // * @param[in] pow arrya pow of the exponentiation + // * @param[in] m arrayodular + // * @return result of the modular exponentiation of type BigNumber vector + // */ + // std::vector raw_ippMultiBuffExp( + // const std::vector& base, const std::vector& + // pow, const std::vector& m) const; /** * Get random value * @param[in] length bit length * @return the random value of type BigNumber */ BigNumber getRandom(int length) const; + + /** + * Single-buffered modular exponentiation + * @param[in] base base of the exponentiation + * @param[in] pow pow of the exponentiation + * @param[in] m modular + * @return the modular exponentiation result of type BigNumber + */ + BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, + const BigNumber& m) const; + + /** + * Multi-buffered modular exponentiation + * @param[in] base array base of the exponentiation + * @param[in] pow arrya pow of the exponentiation + * @param[in] m arrayodular + * @return result of the modular exponentiation of type BigNumber vector + */ + std::vector ippMBModExp(const std::vector& base, + const std::vector& pow, + const std::vector& m) const; }; } // namespace ipcl diff --git a/ipcl/paillier_ops.cpp b/ipcl/paillier_ops.cpp index f7c05e0..d555d28 100644 --- a/ipcl/paillier_ops.cpp +++ b/ipcl/paillier_ops.cpp @@ -121,13 +121,13 @@ BigNumber PaillierEncryptedNumber::raw_add(const BigNumber& a, std::vector PaillierEncryptedNumber::raw_mul( const std::vector& a, const std::vector& b) const { std::vector sq(8, m_pubkey->getNSQ()); - return m_pubkey->ippMultiBuffExp(a, b, sq); + return m_pubkey->ippModExp(a, b, sq); } BigNumber PaillierEncryptedNumber::raw_mul(const BigNumber& a, const BigNumber& b) const { BigNumber sq = m_pubkey->getNSQ(); - return m_pubkey->ippMontExp(a, b, sq); + return m_pubkey->ippModExp(a, b, sq); } PaillierEncryptedNumber PaillierEncryptedNumber::rotate(int shift) const { diff --git a/ipcl/paillier_prikey.cpp b/ipcl/paillier_prikey.cpp index a4cb074..288161a 100644 --- a/ipcl/paillier_prikey.cpp +++ b/ipcl/paillier_prikey.cpp @@ -42,7 +42,7 @@ PaillierPrivateKey::PaillierPrivateKey(const PaillierPublicKey* public_key, m_lambda(lcm(m_pminusone, m_qminusone)), // TODO(bwang30): check if ippsModInv_BN does the same thing with // mpz_invert - m_x(m_n.InverseMul(m_pubkey->ippMontExp(m_g, m_lambda, m_nsquare) - 1) / + m_x(m_n.InverseMul(m_pubkey->ippModExp(m_g, m_lambda, m_nsquare) - 1) / m_n), m_bits(m_pubkey->getBits()), m_dwords(m_pubkey->getDwords()), @@ -55,61 +55,16 @@ PaillierPrivateKey::PaillierPrivateKey(const PaillierPublicKey* public_key, void PaillierPrivateKey::decryptRAW( std::vector& plaintext, const std::vector& ciphertext) const { - mbx_status st = MBX_STATUS_OK; + std::vector pow_lambda(IPCL_CRYPTO_MB_SIZE, m_lambda); + std::vector modulo(IPCL_CRYPTO_MB_SIZE, m_nsquare); + std::vector res = + m_pubkey->ippModExp(ciphertext, pow_lambda, modulo); - // setup buffer for mbx_exp - int bufferLen = mbx_exp_BufferSize(m_bits * 2); - auto pBuffer = std::vector(bufferLen); - - std::vector out_m(8), cip_array(8); - int length = m_dwords * sizeof(int64u); - - for (int i = 0; i < 8; i++) { - out_m[i] = reinterpret_cast(alloca(length)); - cip_array[i] = reinterpret_cast(alloca(length)); - ERROR_CHECK(out_m[i] != nullptr && cip_array[i] != nullptr, - "decryptRAW: alloc memory for error"); - - memset(out_m[i], 0, length); - memset(cip_array[i], 0, length); - } - - // TODO(bwang30): add multi-buffered modular exponentiation - std::vector pow_c(8), pow_nsquare(8), pow_lambda(8); - - int cBitLen, lBitLen, nsqBitLen; - BigNumber lambda = m_lambda; - - for (int i = 0; i < 8; i++) { - ippsRef_BN(nullptr, &cBitLen, reinterpret_cast(&pow_c[i]), - ciphertext[i]); - ippsRef_BN(nullptr, &lBitLen, &pow_lambda[i], lambda); - ippsRef_BN(nullptr, &nsqBitLen, &pow_nsquare[i], m_nsquare); - - memcpy(cip_array[i], pow_c[i], BITSIZE_WORD(cBitLen) * 4); - } - - st = mbx_exp_mb8(out_m.data(), cip_array.data(), - reinterpret_cast(pow_lambda.data()), lBitLen, - reinterpret_cast(pow_nsquare.data()), nsqBitLen, - pBuffer.data(), bufferLen); - - for (int i = 0; i < 8; i++) { - ERROR_CHECK( - MBX_STATUS_OK == MBX_GET_STS(st, i), - std::string( - "decryptRAW: error multi buffered exp modules, error code = ") + - std::to_string(MBX_GET_STS(st, i))); - } - - BigNumber ipp_res(m_nsquare); BigNumber nn = m_n; BigNumber xx = m_x; for (int i = 0; i < 8; i++) { - ipp_res.Set(reinterpret_cast(out_m[i]), BITSIZE_WORD(nsqBitLen), - IppsBigNumPOS); - BigNumber m = (ipp_res - 1) / nn; + BigNumber m = (res[i] - 1) / nn; m = m * xx; plaintext[i] = m % nn; } @@ -156,8 +111,8 @@ void PaillierPrivateKey::decryptCRT( } // Based on the fact a^b mod n = (a mod n)^b mod n - std::vector resp = m_pubkey->ippMultiBuffExp(basep, pm1, psq); - std::vector resq = m_pubkey->ippMultiBuffExp(baseq, qm1, qsq); + std::vector resp = m_pubkey->ippModExp(basep, pm1, psq); + std::vector resq = m_pubkey->ippModExp(baseq, qm1, qsq); for (int i = 0; i < 8; i++) { BigNumber dp = computeLfun(resp[i], m_p) * m_hp % m_p; @@ -182,7 +137,7 @@ BigNumber PaillierPrivateKey::computeHfun(const BigNumber& a, // Based on the fact a^b mod n = (a mod n)^b mod n BigNumber xm = a - 1; BigNumber base = m_g % b; - BigNumber pm = m_pubkey->ippMontExp(base, xm, b); + BigNumber pm = m_pubkey->ippModExp(base, xm, b); BigNumber lcrt = computeLfun(pm, a); return a.InverseMul(lcrt); } diff --git a/ipcl/paillier_pubkey.cpp b/ipcl/paillier_pubkey.cpp index 7afa08e..30d2f8e 100644 --- a/ipcl/paillier_pubkey.cpp +++ b/ipcl/paillier_pubkey.cpp @@ -10,6 +10,10 @@ #include #include +#ifdef IPCL_CRYPTO_OMP +#include +#endif + #include "ipcl/util.hpp" namespace ipcl { @@ -100,7 +104,7 @@ void PaillierPublicKey::enableDJN() { BigNumber rmod_sq = rmod * rmod; BigNumber rmod_neg = rmod_sq * -1; BigNumber h = rmod_neg % m_n; - m_hs = ippMontExp(h, m_n, m_nsquare); + m_hs = ippSBModExp(h, m_n, m_nsquare); m_randbits = m_bits >> 1; // bits/2 m_enable_DJN = true; @@ -119,7 +123,7 @@ void PaillierPublicKey::apply_obfuscator( for (auto& r_ : r) { r_ = getRandom(m_randbits); } - obfuscator = ippMultiBuffExp(base, r, sq); + obfuscator = ippModExp(base, r, sq); } else { for (int i = 0; i < 8; i++) { if (m_testv) { @@ -131,7 +135,7 @@ void PaillierPublicKey::apply_obfuscator( pown[i] = m_n; sq[i] = m_nsquare; } - obfuscator = ippMultiBuffExp(r, pown, sq); + obfuscator = ippModExp(r, pown, sq); } } @@ -184,7 +188,30 @@ void PaillierPublicKey::encrypt(BigNumber& ciphertext, ---------------------------------------------------------- */ } -std::vector PaillierPublicKey::ippMultiBuffExp( +std::vector PaillierPublicKey::ippModExp( + const std::vector& base, const std::vector& pow, + const std::vector& m) const { +#ifdef IPCL_CRYPTO_MB_MOD_EXP + return ippMBModExp(base, pow, m); +#else + std::vector res(8); +#ifdef IPCL_USE_OMP +#pragma omp parallel for +#endif + for (int i = 0; i < 8; i++) { + res[i] = ippSBModExp(base[i], pow[i], m[i]); + } + return res; +#endif +} + +BigNumber PaillierPublicKey::ippModExp(const BigNumber& base, + const BigNumber& pow, + const BigNumber& m) const { + return ippSBModExp(base, pow, m); +} + +std::vector PaillierPublicKey::ippMBModExp( const std::vector& base, const std::vector& pow, const std::vector& m) const { VEC_SIZE_CHECK(base); @@ -266,9 +293,9 @@ std::vector PaillierPublicKey::ippMultiBuffExp( return res; } -BigNumber PaillierPublicKey::ippMontExp(const BigNumber& base, - const BigNumber& pow, - const BigNumber& m) const { +BigNumber PaillierPublicKey::ippSBModExp(const BigNumber& base, + const BigNumber& pow, + const BigNumber& m) const { IppStatus stat = ippStsNoErr; // It is important to declear res * bform bit length refer to ipp-crypto spec: // R should not be less than the data length of the modulus m diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 759ad04..bb24a5f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -18,6 +18,5 @@ target_link_libraries(unittest_ipcl PRIVATE # enable OpenMP unittests if(IPCL_ENABLE_OMP) find_package(OpenMP REQUIRED) - add_compile_definitions(IPCL_UNITTEST_OMP) target_link_libraries(unittest_ipcl PRIVATE OpenMP::OpenMP_CXX) endif() diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index 4575562..c0cfe75 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -6,9 +6,9 @@ #include #include -#ifdef IPCL_UNITTEST_OMP +#ifdef IPCL_USE_OMP #include -#endif +#endif // IPCL_USE_OMP #include "gtest/gtest.h" #include "ipcl/paillier_keygen.hpp" @@ -44,7 +44,7 @@ TEST(CryptoTest, CryptoTest) { delete key.priv_key; } -#ifdef IPCL_UNITTEST_OMP +#ifdef IPCL_USE_OMP void Encryption(int num_threads, std::vector>& v_ct, const std::vector>& v_ptbn, @@ -107,7 +107,7 @@ TEST(CryptoTest, CryptoTest_OMP) { delete key.pub_key; delete key.priv_key; } -#endif +#endif // IPCL_USE_OMP TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { ipcl::BigNumber p = diff --git a/test/test_ops.cpp b/test/test_ops.cpp index 33aa802..c2ab740 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -6,9 +6,9 @@ #include #include -#ifdef IPCL_UNITTEST_OMP +#ifdef IPCL_USE_OMP #include -#endif +#endif // IPCL_USE_OMP #include "gtest/gtest.h" #include "ipcl/paillier_keygen.hpp" @@ -409,7 +409,7 @@ TEST(OperationTest, AddSubTest) { delete key.priv_key; } -#ifdef IPCL_UNITTEST_OMP +#ifdef IPCL_USE_OMP void CtPlusCt_OMP(int num_threads, std::vector>& v_sum, const std::vector>& v_ct1, @@ -804,4 +804,4 @@ TEST(OperationTest, CtMultiplyPtArrayTest_OMP) { delete key.pub_key; delete key.priv_key; } -#endif +#endif // IPCL_USE_OMP From 60a23475f3e6f192eb952840731d5e4ef7e93b3e Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Thu, 3 Mar 2022 15:11:41 -0800 Subject: [PATCH 069/364] Updated README on flags (#32) --- README.md | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 188921c..e979632 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,9 @@ Intel Paillier Cryptosystem Library is an open-source library which provides acc - [Intel Paillier Cryptosystem Library](#intel-paillier-cryptosystem-library) - [Contents](#contents) - [Introduction](#introduction) + - [Performance](#performance) - [Building the Library](#building-the-library) - - [Requirements](#requirements) + - [Prerequisites](#prerequisites) - [Dependencies](#dependencies) - [Instructions](#instructions) - [Testing and Benchmarking](#testing-and-benchmarking) @@ -27,16 +28,21 @@ As a public key encryption scheme, Paillier cryptosystem has three stages: For increased security, typically the key length is at least 1024 bits, but recommendation is 2048 bits or larger. To handle such large size integers, conventional implementations of the Paillier cryptosystem utilizes the GNU Multiple Precision Arithmetic Library (GMP). The essential computation of the scheme relies on the modular exponentiation, and our library takes advantage of the multi-buffer modular exponentiation function (```mbx_exp_mb8```) of IPP-Crypto library, which is enabled in AVX512IFMA instruction sets supporting SKUs, such as Intel Icelake Xeon CPUs. +### Performance +To be added after P2CA review ## Building the Library -### Requirements -The hardware requirement to use the library is AVX512IFMA instruction sets enabled CPUs, as listed in Intel codenames: +### Prerequisites +For best performance, especially due to the multi-buffer modular exponentiation function, it is best to use the library on AVX512IFMA enabled systems, as listed below Intel CPU codenames: - Intel Cannon Lake - Intel Ice Lake -Note: We are planning to add support for more SKUs. +The library can be built and used without AVX512IFMA, as if the instruction set is not detected on the system, it will automatically switch to non multi-buffer modular exponentiation. -As for the operating systems, ehe library has been tested and confirmed to work on Ubuntu 18.04, 20.04 and RHEL 8.0. +The following operating systems have been tested and deemed to be fully functional. + - Ubuntu 18.04 and higher + - Red Hat Enterprise Linux 8.1 and higher +We will keep working on adding more supported operating systems. ### Dependencies Must have dependencies include: ``` @@ -46,7 +52,7 @@ pthread g++ >= 7.0 or clang >= 10.0 ``` -The following libraries are also required, +The following libraries and tools are also required, ``` nasm>=2.15 OpenSSL>=1.1.0 @@ -54,12 +60,12 @@ OpenSSL>=1.1.0 For ```nasm```, please refer to the [Netwide Assembler](https://nasm.us/) for installation details. -On Ubuntu, ```OpenSSL``` can be installed by: +On Ubuntu, ```OpenSSL``` can be installed with: ```bash sudo apt update sudo apt install libssl-dev ``` -On RHEL, it needs to be built and installed from source as the static libraries are not installed with package managers. Please refer to [OpenSSL Project](https://github.com/openssl/openssl) for installation details for static libraries. +For RHEL, ```OpenSSL``` needs to be built and installed from source as the static libraries are missing when installed through the package managers. Please refer to [OpenSSL Project](https://github.com/openssl/openssl) for installation details for static libraries. ### Instructions The library can be built using the following commands: @@ -75,7 +81,7 @@ It is possible to pass additional options to enable more features. The following |-------------------------|-----------|---------|-------------------------------------| |`IPCL_TEST` | ON/OFF | ON | unit-test | |`IPCL_BENCHMARK` | ON/OFF | ON | benchmark | -|`IPCL_ENABLE_OMP` | ON/OFF | ON | enables OMP unit-test and benchmark | +|`IPCL_ENABLE_OMP` | ON/OFF | ON | enables OpenMP functionalities | |`IPCL_DOCS` | ON/OFF | OFF | build doxygen documentation | |`IPCL_SHARED` | ON/OFF | ON | build shared library | @@ -91,7 +97,7 @@ Then, run ```bash cmake --build build --target benchmark ``` -OpenMP unit-tests and benchmarks will automatically be applied if `-DIPCL_ENABLE_OMP=ON` is set. +Setting the CMake flag ```-DIPCL_ENABLE_OMP=ON``` during configuration will automatically enable OpenMP unit-tests and benchmarks. The executables are located at `${IPCL_DIR}/build/test/unittest_ipcl` and `${IPCL_DIR}/build/benchmark/bench_ipcl`. From c2fe7f29e85bf5fe4d6f592c5538975ce960e537 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Thu, 3 Mar 2022 16:09:12 -0800 Subject: [PATCH 070/364] Updated README (#36) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e979632..29dcf69 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ For increased security, typically the key length is at least 1024 bits, but reco To be added after P2CA review ## Building the Library ### Prerequisites -For best performance, especially due to the multi-buffer modular exponentiation function, it is best to use the library on AVX512IFMA enabled systems, as listed below Intel CPU codenames: +For best performance, especially due to the multi-buffer modular exponentiation function, the library is to be used on AVX512IFMA enabled systems, as listed below in Intel CPU codenames: - Intel Cannon Lake - Intel Ice Lake From 11322e9ae915654c68ec45aea6659816200eac7d Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Sat, 5 Mar 2022 04:14:53 +0800 Subject: [PATCH 071/364] Fix decryptRAW incorrect result issue (#37) --- ipcl/paillier_prikey.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ipcl/paillier_prikey.cpp b/ipcl/paillier_prikey.cpp index 288161a..20de78f 100644 --- a/ipcl/paillier_prikey.cpp +++ b/ipcl/paillier_prikey.cpp @@ -42,8 +42,8 @@ PaillierPrivateKey::PaillierPrivateKey(const PaillierPublicKey* public_key, m_lambda(lcm(m_pminusone, m_qminusone)), // TODO(bwang30): check if ippsModInv_BN does the same thing with // mpz_invert - m_x(m_n.InverseMul(m_pubkey->ippModExp(m_g, m_lambda, m_nsquare) - 1) / - m_n), + m_x(m_n.InverseMul((m_pubkey->ippModExp(m_g, m_lambda, m_nsquare) - 1) / + m_n)), m_bits(m_pubkey->getBits()), m_dwords(m_pubkey->getDwords()), m_enable_crt(true) { From 5a805ea024e38d9b09d329ae667cc8133182b3ff Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Fri, 4 Mar 2022 18:54:24 -0800 Subject: [PATCH 072/364] Added support for Ipp8u vector retrieval of BigNumber for QAT integration (#38) --- ipcl/bignum.cpp | 8 ++++++++ ipcl/include/ipcl/bignum.h | 1 + 2 files changed, 9 insertions(+) diff --git a/ipcl/bignum.cpp b/ipcl/bignum.cpp index cff54b7..b0b578e 100644 --- a/ipcl/bignum.cpp +++ b/ipcl/bignum.cpp @@ -501,6 +501,14 @@ std::ostream& operator<<(std::ostream& os, const BigNumber& a) { return os; } +void BigNumber::num2char(std::vector& dest) const { + int bnBitLen; + unsigned char* bnData; + ippsRef_BN(nullptr, &bnBitLen, reinterpret_cast(&bnData), *this); + int len = (bnBitLen + 7) >> 3; + dest.assign(bnData, bnData + len); +} + int BITSIZE_WORD(int n) { return (((n) + 31) >> 5); } int BITSIZE_DWORD(int n) { return (((n) + 63) >> 6); } diff --git a/ipcl/include/ipcl/bignum.h b/ipcl/include/ipcl/bignum.h index 3f1684e..c150f5a 100644 --- a/ipcl/include/ipcl/bignum.h +++ b/ipcl/include/ipcl/bignum.h @@ -120,6 +120,7 @@ class BigNumber { void num2hex(std::string& s) const; // convert to hex string void num2vec(std::vector& v) const; // convert to 32-bit word vector friend std::ostream& operator<<(std::ostream& os, const BigNumber& a); + void num2char(std::vector& dest) const; protected: bool create(const Ipp32u* pData, int length, From 524fbad17aa29a145b0611f521e7943bf3b6a55e Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Tue, 8 Mar 2022 02:55:40 +0800 Subject: [PATCH 073/364] Move Mod Exp to seperate file (#39) * Move modular exponentation to seperate file * Remove unused function IPP_invert --- ipcl/CMakeLists.txt | 1 + ipcl/include/ipcl/mod_exp.hpp | 35 ++++++ ipcl/include/ipcl/paillier_pubkey.hpp | 31 ----- ipcl/mod_exp.cpp | 168 +++++++++++++++++++++++++ ipcl/paillier_ops.cpp | 5 +- ipcl/paillier_prikey.cpp | 12 +- ipcl/paillier_pubkey.cpp | 169 +------------------------- 7 files changed, 217 insertions(+), 204 deletions(-) create mode 100644 ipcl/include/ipcl/mod_exp.hpp create mode 100644 ipcl/mod_exp.cpp diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 199ae28..4ad679f 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -6,6 +6,7 @@ set(IPCL_SRCS paillier_prikey.cpp paillier_ops.cpp paillier_keygen.cpp bignum.cpp + mod_exp.cpp ) diff --git a/ipcl/include/ipcl/mod_exp.hpp b/ipcl/include/ipcl/mod_exp.hpp new file mode 100644 index 0000000..e3b3ac4 --- /dev/null +++ b/ipcl/include/ipcl/mod_exp.hpp @@ -0,0 +1,35 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IPCL_INCLUDE_IPCL_MOD_EXP_HPP_ +#define IPCL_INCLUDE_IPCL_MOD_EXP_HPP_ + +#include + +#include "ipcl/bignum.h" +#include "ipcl/util.hpp" + +namespace ipcl { +/** + * Modular exponentiation for multi buffer + * @param[in] base base of the exponentiation + * @param[in] pow pow of the exponentiation + * @param[in] m modular + * @return the modular exponentiation result of type BigNumber + */ +std::vector ippModExp(const std::vector& base, + const std::vector& pow, + const std::vector& m); + +/** + * Modular exponentiation for single buffer + * @param[in] base base of the exponentiation + * @param[in] pow pow of the exponentiation + * @param[in] m modular + * @return the modular exponentiation result of type BigNumber + */ +BigNumber ippModExp(const BigNumber& base, const BigNumber& pow, + const BigNumber& m); + +} // namespace ipcl +#endif // IPCL_INCLUDE_IPCL_MOD_EXP_HPP_ diff --git a/ipcl/include/ipcl/paillier_pubkey.hpp b/ipcl/include/ipcl/paillier_pubkey.hpp index dccd407..ef0301b 100644 --- a/ipcl/include/ipcl/paillier_pubkey.hpp +++ b/ipcl/include/ipcl/paillier_pubkey.hpp @@ -63,16 +63,6 @@ class PaillierPublicKey { std::vector ippModExp(const std::vector& base, const std::vector& pow, const std::vector& m) const; - BigNumber ippModExp(const BigNumber& base, const BigNumber& pow, - const BigNumber& m) const; - - /** - * Invert function needed by encoder(float to integer) - * @param[in] a input of a - * @param[in] b input of b - * @return the invert result of type BigNumber - */ - BigNumber IPP_invert(BigNumber a, BigNumber b); /** * Get N of public key in paillier scheme @@ -159,27 +149,6 @@ class PaillierPublicKey { * @return the random value of type BigNumber */ BigNumber getRandom(int length) const; - - /** - * Single-buffered modular exponentiation - * @param[in] base base of the exponentiation - * @param[in] pow pow of the exponentiation - * @param[in] m modular - * @return the modular exponentiation result of type BigNumber - */ - BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, - const BigNumber& m) const; - - /** - * Multi-buffered modular exponentiation - * @param[in] base array base of the exponentiation - * @param[in] pow arrya pow of the exponentiation - * @param[in] m arrayodular - * @return result of the modular exponentiation of type BigNumber vector - */ - std::vector ippMBModExp(const std::vector& base, - const std::vector& pow, - const std::vector& m) const; }; } // namespace ipcl diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp new file mode 100644 index 0000000..6cd11b9 --- /dev/null +++ b/ipcl/mod_exp.cpp @@ -0,0 +1,168 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/mod_exp.hpp" + +#include + +#include + +namespace ipcl { + +static std::vector ippMBModExp(const std::vector& base, + const std::vector& pow, + const std::vector& m) { + VEC_SIZE_CHECK(base); + VEC_SIZE_CHECK(pow); + VEC_SIZE_CHECK(m); + + mbx_status st = MBX_STATUS_OK; + + int bits = m[0].BitSize(); + int dwords = BITSIZE_DWORD(bits); + int bufferLen = mbx_exp_BufferSize(bits); + auto pBuffer = std::vector(bufferLen); + + std::vector out_x(8), b_array(8), p_array(8); + int length = dwords * sizeof(int64u); + + for (int i = 0; i < 8; i++) { + out_x[i] = reinterpret_cast(alloca(length)); + b_array[i] = reinterpret_cast(alloca(length)); + p_array[i] = reinterpret_cast(alloca(length)); + + ERROR_CHECK( + out_x[i] != nullptr && b_array[i] != nullptr && p_array[i] != nullptr, + "ippMultiBuffExp: alloc memory for error"); + + memset(out_x[i], 0, length); + memset(b_array[i], 0, length); + memset(p_array[i], 0, length); + } + + /* + * These two intermediate variables pow_b & pow_p are necessary + * because if they are not used, the length returned from ippsRef_BN + * will be inconsistent with the length allocated by b_array/p_array, + * resulting in data errors. + */ + std::vector pow_b(8), pow_p(8), pow_nsquare(8); + int bBitLen, pBitLen, nsqBitLen; + int expBitLen = 0; + + for (int i = 0; i < 8; i++) { + ippsRef_BN(nullptr, &bBitLen, reinterpret_cast(&pow_b[i]), + base[i]); + ippsRef_BN(nullptr, &pBitLen, reinterpret_cast(&pow_p[i]), + pow[i]); + ippsRef_BN(nullptr, &nsqBitLen, &pow_nsquare[i], m[i]); + + memcpy(b_array[i], pow_b[i], BITSIZE_WORD(bBitLen) * 4); + memcpy(p_array[i], pow_p[i], BITSIZE_WORD(pBitLen) * 4); + + if (expBitLen < pBitLen) expBitLen = pBitLen; + } + + /* + *Note: If actual sizes of exp are different, set the exp_bits parameter equal + *to maximum size of the actual module in bit size and extend all the modules + *with zero bits + */ + st = mbx_exp_mb8(out_x.data(), b_array.data(), p_array.data(), expBitLen, + reinterpret_cast(pow_nsquare.data()), nsqBitLen, + reinterpret_cast(pBuffer.data()), bufferLen); + + for (int i = 0; i < 8; i++) { + ERROR_CHECK(MBX_STATUS_OK == MBX_GET_STS(st, i), + std::string("ippMultiBuffExp: error multi buffered exp " + "modules, error code = ") + + std::to_string(MBX_GET_STS(st, i))); + } + + // It is important to hold a copy of nsquare for thread-safe purpose + BigNumber bn_c(m[0]); + + std::vector res(8, 0); + for (int i = 0; i < 8; i++) { + bn_c.Set(reinterpret_cast(out_x[i]), BITSIZE_WORD(nsqBitLen), + IppsBigNumPOS); + res[i] = bn_c; + } + return res; +} + +static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, + const BigNumber& m) { + IppStatus stat = ippStsNoErr; + // It is important to declear res * bform bit length refer to ipp-crypto spec: + // R should not be less than the data length of the modulus m + BigNumber res(m); + + int bnBitLen; + Ipp32u* pow_m; + ippsRef_BN(nullptr, &bnBitLen, &pow_m, BN(m)); + int nlen = BITSIZE_WORD(bnBitLen); + + int size; + // define and initialize Montgomery Engine over Modulus N + stat = ippsMontGetSize(IppsBinaryMethod, nlen, &size); + ERROR_CHECK(stat == ippStsNoErr, + "ippMontExp: get the size of IppsMontState context error."); + + auto pMont = std::vector(size); + + stat = ippsMontInit(IppsBinaryMethod, nlen, + reinterpret_cast(pMont.data())); + ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: init Mont context error."); + + stat = + ippsMontSet(pow_m, nlen, reinterpret_cast(pMont.data())); + ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: set Mont input error."); + + // encode base into Montfomery form + BigNumber bform(m); + stat = ippsMontForm(BN(base), reinterpret_cast(pMont.data()), + BN(bform)); + ERROR_CHECK(stat == ippStsNoErr, + "ippMontExp: convert big number into Mont form error."); + + // compute R = base^pow mod N + stat = ippsMontExp(BN(bform), BN(pow), + reinterpret_cast(pMont.data()), BN(res)); + ERROR_CHECK(stat == ippStsNoErr, + std::string("ippsMontExp: error code = ") + std::to_string(stat)); + + BigNumber one(1); + // R = MontMul(R,1) + stat = ippsMontMul(BN(res), BN(one), + reinterpret_cast(pMont.data()), BN(res)); + + ERROR_CHECK(stat == ippStsNoErr, + std::string("ippsMontMul: error code = ") + std::to_string(stat)); + + return res; +} + +std::vector ippModExp(const std::vector& base, + const std::vector& pow, + const std::vector& m) { +#ifdef IPCL_CRYPTO_MB_MOD_EXP + return ippMBModExp(base, pow, m); +#else + std::vector res(8); +#ifdef IPCL_USE_OMP +#pragma omp parallel for +#endif + for (int i = 0; i < 8; i++) { + res[i] = ippSBModExp(base[i], pow[i], m[i]); + } + return res; +#endif +} + +BigNumber ippModExp(const BigNumber& base, const BigNumber& pow, + const BigNumber& m) { + return ippSBModExp(base, pow, m); +} + +} // namespace ipcl diff --git a/ipcl/paillier_ops.cpp b/ipcl/paillier_ops.cpp index d555d28..e61f2b7 100644 --- a/ipcl/paillier_ops.cpp +++ b/ipcl/paillier_ops.cpp @@ -5,6 +5,7 @@ #include +#include "ipcl/mod_exp.hpp" #include "ipcl/util.hpp" namespace ipcl { @@ -121,13 +122,13 @@ BigNumber PaillierEncryptedNumber::raw_add(const BigNumber& a, std::vector PaillierEncryptedNumber::raw_mul( const std::vector& a, const std::vector& b) const { std::vector sq(8, m_pubkey->getNSQ()); - return m_pubkey->ippModExp(a, b, sq); + return ipcl::ippModExp(a, b, sq); } BigNumber PaillierEncryptedNumber::raw_mul(const BigNumber& a, const BigNumber& b) const { BigNumber sq = m_pubkey->getNSQ(); - return m_pubkey->ippModExp(a, b, sq); + return ipcl::ippModExp(a, b, sq); } PaillierEncryptedNumber PaillierEncryptedNumber::rotate(int shift) const { diff --git a/ipcl/paillier_prikey.cpp b/ipcl/paillier_prikey.cpp index 20de78f..645cc90 100644 --- a/ipcl/paillier_prikey.cpp +++ b/ipcl/paillier_prikey.cpp @@ -7,6 +7,7 @@ #include +#include "ipcl/mod_exp.hpp" #include "ipcl/util.hpp" namespace ipcl { @@ -42,7 +43,7 @@ PaillierPrivateKey::PaillierPrivateKey(const PaillierPublicKey* public_key, m_lambda(lcm(m_pminusone, m_qminusone)), // TODO(bwang30): check if ippsModInv_BN does the same thing with // mpz_invert - m_x(m_n.InverseMul((m_pubkey->ippModExp(m_g, m_lambda, m_nsquare) - 1) / + m_x(m_n.InverseMul((ipcl::ippModExp(m_g, m_lambda, m_nsquare) - 1) / m_n)), m_bits(m_pubkey->getBits()), m_dwords(m_pubkey->getDwords()), @@ -57,8 +58,7 @@ void PaillierPrivateKey::decryptRAW( const std::vector& ciphertext) const { std::vector pow_lambda(IPCL_CRYPTO_MB_SIZE, m_lambda); std::vector modulo(IPCL_CRYPTO_MB_SIZE, m_nsquare); - std::vector res = - m_pubkey->ippModExp(ciphertext, pow_lambda, modulo); + std::vector res = ipcl::ippModExp(ciphertext, pow_lambda, modulo); BigNumber nn = m_n; BigNumber xx = m_x; @@ -111,8 +111,8 @@ void PaillierPrivateKey::decryptCRT( } // Based on the fact a^b mod n = (a mod n)^b mod n - std::vector resp = m_pubkey->ippModExp(basep, pm1, psq); - std::vector resq = m_pubkey->ippModExp(baseq, qm1, qsq); + std::vector resp = ipcl::ippModExp(basep, pm1, psq); + std::vector resq = ipcl::ippModExp(baseq, qm1, qsq); for (int i = 0; i < 8; i++) { BigNumber dp = computeLfun(resp[i], m_p) * m_hp % m_p; @@ -137,7 +137,7 @@ BigNumber PaillierPrivateKey::computeHfun(const BigNumber& a, // Based on the fact a^b mod n = (a mod n)^b mod n BigNumber xm = a - 1; BigNumber base = m_g % b; - BigNumber pm = m_pubkey->ippModExp(base, xm, b); + BigNumber pm = ipcl::ippModExp(base, xm, b); BigNumber lcrt = computeLfun(pm, a); return a.InverseMul(lcrt); } diff --git a/ipcl/paillier_pubkey.cpp b/ipcl/paillier_pubkey.cpp index 30d2f8e..250b820 100644 --- a/ipcl/paillier_pubkey.cpp +++ b/ipcl/paillier_pubkey.cpp @@ -14,6 +14,7 @@ #include #endif +#include "ipcl/mod_exp.hpp" #include "ipcl/util.hpp" namespace ipcl { @@ -104,7 +105,7 @@ void PaillierPublicKey::enableDJN() { BigNumber rmod_sq = rmod * rmod; BigNumber rmod_neg = rmod_sq * -1; BigNumber h = rmod_neg % m_n; - m_hs = ippSBModExp(h, m_n, m_nsquare); + m_hs = ipcl::ippModExp(h, m_n, m_nsquare); m_randbits = m_bits >> 1; // bits/2 m_enable_DJN = true; @@ -123,7 +124,7 @@ void PaillierPublicKey::apply_obfuscator( for (auto& r_ : r) { r_ = getRandom(m_randbits); } - obfuscator = ippModExp(base, r, sq); + obfuscator = ipcl::ippModExp(base, r, sq); } else { for (int i = 0; i < 8; i++) { if (m_testv) { @@ -135,7 +136,7 @@ void PaillierPublicKey::apply_obfuscator( pown[i] = m_n; sq[i] = m_nsquare; } - obfuscator = ippModExp(r, pown, sq); + obfuscator = ipcl::ippModExp(r, pown, sq); } } @@ -188,166 +189,4 @@ void PaillierPublicKey::encrypt(BigNumber& ciphertext, ---------------------------------------------------------- */ } -std::vector PaillierPublicKey::ippModExp( - const std::vector& base, const std::vector& pow, - const std::vector& m) const { -#ifdef IPCL_CRYPTO_MB_MOD_EXP - return ippMBModExp(base, pow, m); -#else - std::vector res(8); -#ifdef IPCL_USE_OMP -#pragma omp parallel for -#endif - for (int i = 0; i < 8; i++) { - res[i] = ippSBModExp(base[i], pow[i], m[i]); - } - return res; -#endif -} - -BigNumber PaillierPublicKey::ippModExp(const BigNumber& base, - const BigNumber& pow, - const BigNumber& m) const { - return ippSBModExp(base, pow, m); -} - -std::vector PaillierPublicKey::ippMBModExp( - const std::vector& base, const std::vector& pow, - const std::vector& m) const { - VEC_SIZE_CHECK(base); - VEC_SIZE_CHECK(pow); - VEC_SIZE_CHECK(m); - - mbx_status st = MBX_STATUS_OK; - - int bits = m[0].BitSize(); - int dwords = BITSIZE_DWORD(bits); - int bufferLen = mbx_exp_BufferSize(bits); - auto pBuffer = std::vector(bufferLen); - - std::vector out_x(8), b_array(8), p_array(8); - int length = dwords * sizeof(int64u); - - for (int i = 0; i < 8; i++) { - out_x[i] = reinterpret_cast(alloca(length)); - b_array[i] = reinterpret_cast(alloca(length)); - p_array[i] = reinterpret_cast(alloca(length)); - - ERROR_CHECK( - out_x[i] != nullptr && b_array[i] != nullptr && p_array[i] != nullptr, - "ippMultiBuffExp: alloc memory for error"); - - memset(out_x[i], 0, length); - memset(b_array[i], 0, length); - memset(p_array[i], 0, length); - } - - /* - * These two intermediate variables pow_b & pow_p are necessary - * because if they are not used, the length returned from ippsRef_BN - * will be inconsistent with the length allocated by b_array/p_array, - * resulting in data errors. - */ - std::vector pow_b(8), pow_p(8), pow_nsquare(8); - int bBitLen, pBitLen, nsqBitLen; - int expBitLen = 0; - - for (int i = 0; i < 8; i++) { - ippsRef_BN(nullptr, &bBitLen, reinterpret_cast(&pow_b[i]), - base[i]); - ippsRef_BN(nullptr, &pBitLen, reinterpret_cast(&pow_p[i]), - pow[i]); - ippsRef_BN(nullptr, &nsqBitLen, &pow_nsquare[i], m[i]); - - memcpy(b_array[i], pow_b[i], BITSIZE_WORD(bBitLen) * 4); - memcpy(p_array[i], pow_p[i], BITSIZE_WORD(pBitLen) * 4); - - if (expBitLen < pBitLen) expBitLen = pBitLen; - } - - /* - *Note: If actual sizes of exp are different, set the exp_bits parameter equal - *to maximum size of the actual module in bit size and extend all the modules - *with zero bits - */ - st = mbx_exp_mb8(out_x.data(), b_array.data(), p_array.data(), expBitLen, - reinterpret_cast(pow_nsquare.data()), nsqBitLen, - reinterpret_cast(pBuffer.data()), bufferLen); - - for (int i = 0; i < 8; i++) { - ERROR_CHECK(MBX_STATUS_OK == MBX_GET_STS(st, i), - std::string("ippMultiBuffExp: error multi buffered exp " - "modules, error code = ") + - std::to_string(MBX_GET_STS(st, i))); - } - - // It is important to hold a copy of nsquare for thread-safe purpose - BigNumber bn_c(m[0]); - - std::vector res(8, 0); - for (int i = 0; i < 8; i++) { - bn_c.Set(reinterpret_cast(out_x[i]), BITSIZE_WORD(nsqBitLen), - IppsBigNumPOS); - res[i] = bn_c; - } - return res; -} - -BigNumber PaillierPublicKey::ippSBModExp(const BigNumber& base, - const BigNumber& pow, - const BigNumber& m) const { - IppStatus stat = ippStsNoErr; - // It is important to declear res * bform bit length refer to ipp-crypto spec: - // R should not be less than the data length of the modulus m - BigNumber res(m); - - int bnBitLen; - Ipp32u* pow_m; - ippsRef_BN(nullptr, &bnBitLen, &pow_m, BN(m)); - int nlen = BITSIZE_WORD(bnBitLen); - - int size; - // define and initialize Montgomery Engine over Modulus N - stat = ippsMontGetSize(IppsBinaryMethod, nlen, &size); - ERROR_CHECK(stat == ippStsNoErr, - "ippMontExp: get the size of IppsMontState context error."); - - auto pMont = std::vector(size); - - stat = ippsMontInit(IppsBinaryMethod, nlen, - reinterpret_cast(pMont.data())); - ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: init Mont context error."); - - stat = - ippsMontSet(pow_m, nlen, reinterpret_cast(pMont.data())); - ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: set Mont input error."); - - // encode base into Montfomery form - BigNumber bform(m); - stat = ippsMontForm(BN(base), reinterpret_cast(pMont.data()), - BN(bform)); - ERROR_CHECK(stat == ippStsNoErr, - "ippMontExp: convet big number into Mont form error."); - - // compute R = base^pow mod N - stat = ippsMontExp(BN(bform), BN(pow), - reinterpret_cast(pMont.data()), BN(res)); - ERROR_CHECK(stat == ippStsNoErr, - std::string("ippsMontExp: error code = ") + std::to_string(stat)); - - BigNumber one(1); - // R = MontMul(R,1) - stat = ippsMontMul(BN(res), BN(one), - reinterpret_cast(pMont.data()), BN(res)); - - ERROR_CHECK(stat == ippStsNoErr, - std::string("ippsMontMul: error code = ") + std::to_string(stat)); - - return res; -} - -BigNumber PaillierPublicKey::IPP_invert(BigNumber a, BigNumber b) { - return b.InverseMul(a); -} - } // namespace ipcl From cfb0f94d3a419cace69c04af98ed694cfb2ef834 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 7 Mar 2022 17:11:13 -0800 Subject: [PATCH 074/364] Add BigNumber utils. --- utils/CMakeLists.txt | 23 +++ utils/bignum.cpp | 437 +++++++++++++++++++++++++++++++++++++++++++ utils/bignum.h | 106 +++++++++++ utils/utils.cpp | 46 +++++ utils/utils.h | 34 ++++ 5 files changed, 646 insertions(+) create mode 100644 utils/CMakeLists.txt create mode 100644 utils/bignum.cpp create mode 100644 utils/bignum.h create mode 100644 utils/utils.cpp create mode 100644 utils/utils.h diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt new file mode 100644 index 0000000..c4ebb74 --- /dev/null +++ b/utils/CMakeLists.txt @@ -0,0 +1,23 @@ + +# Include directories +list(APPEND HE_QAT_UTILS_INC_DIR + ${CMAKE_CURRENT_LIST_DIR} + ${IPPCP_DIR}/include +) +message(STATUS "HE_QAT_UTILS_INC_DIR: ${HE_QAT_UTILS_INC_DIR}") + +# Source files +set(HE_QAT_UTILS_SRC ${CMAKE_CURRENT_LIST_DIR}/utils.cpp + ${CMAKE_CURRENT_LIST_DIR}/bignum.cpp +) + +add_library(he_qat_utils ${HE_QAT_UTILS_SRC}) +target_include_directories(he_qat_utils + PUBLIC $ # Public headers + PUBLIC $ # Public headers +) +target_link_directories(he_qat_utils PUBLIC ${IPPCP_DIR}/lib/intel64) +target_link_libraries(he_qat_utils PUBLIC ippcpmx crypto_mb) + +set(HE_QAT_UTILS_INC_DIR ${HE_QAT_UTILS_INC_DIR} PARENT_SCOPE) + diff --git a/utils/bignum.cpp b/utils/bignum.cpp new file mode 100644 index 0000000..57a372c --- /dev/null +++ b/utils/bignum.cpp @@ -0,0 +1,437 @@ +/******************************************************************************* +* Copyright 2019-2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#include "bignum.h" +#include +#include +#include "utils.h" + +////////////////////////////////////////////////////////////////////// +// +// BigNumber +// +////////////////////////////////////////////////////////////////////// +BigNumber::~BigNumber() +{ + delete [] (Ipp8u*)m_pBN; +} + +bool BigNumber::create(const Ipp32u* pData, int length, IppsBigNumSGN sgn) +{ + int size; + ippsBigNumGetSize(length, &size); + m_pBN = (IppsBigNumState*)( new Ipp8u[size] ); + if(!m_pBN) + return false; + ippsBigNumInit(length, m_pBN); + if (pData) + ippsSet_BN(sgn, length, pData, m_pBN); + return true; +} + +// +// constructors +// +BigNumber::BigNumber(Ipp32u value) +{ + create(&value, 1, IppsBigNumPOS); +} + +BigNumber::BigNumber(Ipp32s value) +{ + Ipp32s avalue = abs(value); + create((Ipp32u*)&avalue, 1, (value<0)? IppsBigNumNEG : IppsBigNumPOS); +} + +BigNumber::BigNumber(const IppsBigNumState* pBN) +{ + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, pBN); + + create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); +} + +BigNumber::BigNumber(const Ipp32u* pData, int length, IppsBigNumSGN sgn) +{ + create(pData, length, sgn); +} + +static char HexDigitList[] = "0123456789ABCDEF"; + +BigNumber::BigNumber(const char* s) +{ + bool neg = '-' == s[0]; + if(neg) s++; + bool hex = ('0'==s[0]) && (('x'==s[1]) || ('X'==s[1])); + + int dataLen; + Ipp32u base; + if(hex) { + s += 2; + base = 0x10; + dataLen = (int)(strlen_safe(s) + 7)/8; + } + else { + base = 10; + dataLen = (int)(strlen_safe(s) + 9)/10; + } + + create(0, dataLen); + *(this) = Zero(); + while(*s) { + char tmp[2] = {s[0],0}; + Ipp32u digit = (Ipp32u)strcspn(HexDigitList, tmp); + *this = (*this) * base + BigNumber( digit ); + s++; + } + + if(neg) + (*this) = Zero()- (*this); +} + +BigNumber::BigNumber(const BigNumber& bn) +{ + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); + + create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); +} + +// +// set value +// +void BigNumber::Set(const Ipp32u* pData, int length, IppsBigNumSGN sgn) +{ + ippsSet_BN(sgn, length, pData, BN(*this)); +} + +// +// constants +// +const BigNumber& BigNumber::Zero() +{ + static const BigNumber zero(0); + return zero; +} + +const BigNumber& BigNumber::One() +{ + static const BigNumber one(1); + return one; +} + +const BigNumber& BigNumber::Two() +{ + static const BigNumber two(2); + return two; +} + +// +// arithmetic operators +// +BigNumber& BigNumber::operator =(const BigNumber& bn) +{ + if(this != &bn) { // prevent self copy + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); + + delete [] (Ipp8u*)m_pBN; + create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); + } + return *this; +} + +BigNumber& BigNumber::operator += (const BigNumber& bn) +{ + int aBitLen; + ippsRef_BN(NULL, &aBitLen, NULL, *this); + int bBitLen; + ippsRef_BN(NULL, &bBitLen, NULL, bn); + int rBitLen = IPP_MAX(aBitLen, bBitLen) + 1; + + BigNumber result(0, BITSIZE_WORD(rBitLen)); + ippsAdd_BN(*this, bn, result); + *this = result; + return *this; +} + +BigNumber& BigNumber::operator -= (const BigNumber& bn) +{ + int aBitLen; + ippsRef_BN(NULL, &aBitLen, NULL, *this); + int bBitLen; + ippsRef_BN(NULL, &bBitLen, NULL, bn); + int rBitLen = IPP_MAX(aBitLen, bBitLen); + + BigNumber result(0, BITSIZE_WORD(rBitLen)); + ippsSub_BN(*this, bn, result); + *this = result; + return *this; +} + +BigNumber& BigNumber::operator *= (const BigNumber& bn) +{ + int aBitLen; + ippsRef_BN(NULL, &aBitLen, NULL, *this); + int bBitLen; + ippsRef_BN(NULL, &bBitLen, NULL, bn); + int rBitLen = aBitLen + bBitLen; + + BigNumber result(0, BITSIZE_WORD(rBitLen)); + ippsMul_BN(*this, bn, result); + *this = result; + return *this; +} + +BigNumber& BigNumber::operator *= (Ipp32u n) +{ + int aBitLen; + ippsRef_BN(NULL, &aBitLen, NULL, *this); + + BigNumber result(0, BITSIZE_WORD(aBitLen+32)); + BigNumber bn(n); + ippsMul_BN(*this, bn, result); + *this = result; + return *this; +} + +BigNumber& BigNumber::operator %= (const BigNumber& bn) +{ + BigNumber remainder(bn); + ippsMod_BN(BN(*this), BN(bn), BN(remainder)); + *this = remainder; + return *this; +} + +BigNumber& BigNumber::operator /= (const BigNumber& bn) +{ + BigNumber quotient(*this); + BigNumber remainder(bn); + ippsDiv_BN(BN(*this), BN(bn), BN(quotient), BN(remainder)); + *this = quotient; + return *this; +} + +BigNumber operator + (const BigNumber& a, const BigNumber& b ) +{ + BigNumber r(a); + return r += b; +} + +BigNumber operator - (const BigNumber& a, const BigNumber& b ) +{ + BigNumber r(a); + return r -= b; +} + +BigNumber operator * (const BigNumber& a, const BigNumber& b ) +{ + BigNumber r(a); + return r *= b; +} + +BigNumber operator * (const BigNumber& a, Ipp32u n) +{ + BigNumber r(a); + return r *= n; +} + +BigNumber operator / (const BigNumber& a, const BigNumber& b ) +{ + BigNumber q(a); + return q /= b; +} + +BigNumber operator % (const BigNumber& a, const BigNumber& b ) +{ + BigNumber r(b); + ippsMod_BN(BN(a), BN(b), BN(r)); + return r; +} + +// +// modulo arithmetic +// +BigNumber BigNumber::Modulo(const BigNumber& a) const +{ + return a % *this; +} + +BigNumber BigNumber::InverseAdd(const BigNumber& a) const +{ + BigNumber t = Modulo(a); + if(t==BigNumber::Zero()) + return t; + else + return *this - t; +} + +BigNumber BigNumber::InverseMul(const BigNumber& a) const +{ + BigNumber r(*this); + ippsModInv_BN(BN(a), BN(*this), BN(r)); + return r; +} + +BigNumber BigNumber::ModAdd(const BigNumber& a, const BigNumber& b) const +{ + BigNumber r = this->Modulo(a+b); + return r; +} + +BigNumber BigNumber::ModSub(const BigNumber& a, const BigNumber& b) const +{ + BigNumber r = this->Modulo(a + this->InverseAdd(b)); + return r; +} + +BigNumber BigNumber::ModMul(const BigNumber& a, const BigNumber& b) const +{ + BigNumber r = this->Modulo(a*b); + return r; +} + +// +// comparison +// +int BigNumber::compare(const BigNumber &bn) const +{ + Ipp32u result; + BigNumber tmp = *this - bn; + ippsCmpZero_BN(BN(tmp), &result); + return (result==IS_ZERO)? 0 : (result==GREATER_THAN_ZERO)? 1 : -1; +} + +bool operator < (const BigNumber &a, const BigNumber &b) { return a.compare(b) < 0; } +bool operator > (const BigNumber &a, const BigNumber &b) { return a.compare(b) > 0; } +bool operator == (const BigNumber &a, const BigNumber &b) { return 0 == a.compare(b);} +bool operator != (const BigNumber &a, const BigNumber &b) { return 0 != a.compare(b);} + +// easy tests +// +bool BigNumber::IsOdd() const +{ + Ipp32u* bnData; + ippsRef_BN(NULL, NULL, &bnData, *this); + return bnData[0]&1; +} + +// +// size of BigNumber +// +int BigNumber::LSB() const +{ + if( *this == BigNumber::Zero() ) + return 0; + + vector v; + num2vec(v); + + int lsb = 0; + vector::iterator i; + for(i=v.begin(); i!=v.end(); i++) { + Ipp32u x = *i; + if(0==x) + lsb += 32; + else { + while(0==(x&1)) { + lsb++; + x >>= 1; + } + break; + } + } + return lsb; +} + +int BigNumber::MSB() const +{ + if( *this == BigNumber::Zero() ) + return 0; + + vector v; + num2vec(v); + + int msb = (int)v.size()*32 -1; + vector::reverse_iterator i; + for(i=v.rbegin(); i!=v.rend(); i++) { + Ipp32u x = *i; + if(0==x) + msb -=32; + else { + while(!(x&0x80000000)) { + msb--; + x <<= 1; + } + break; + } + } + return msb; +} + +int Bit(const vector& v, int n) +{ + return 0 != ( v[n>>5] & (1<<(n&0x1F)) ); +} + +// +// conversions and output +// +void BigNumber::num2vec( vector& v ) const +{ + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(NULL, &bnBitLen, &bnData, *this); + + int len = BITSIZE_WORD(bnBitLen);; + for(int n=0; n0; n--) { + Ipp32u x = bnData[n-1]; + for(int nd=8; nd>0; nd--) { + char c = HexDigitList[(x>>(nd-1)*4)&0xF]; + s.append(1, c); + } + } +} + +ostream& operator << ( ostream &os, const BigNumber& a) +{ + string s; + a.num2hex(s); + os << s.c_str(); + return os; +} diff --git a/utils/bignum.h b/utils/bignum.h new file mode 100644 index 0000000..51696d1 --- /dev/null +++ b/utils/bignum.h @@ -0,0 +1,106 @@ +/******************************************************************************* +* Copyright 2019-2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#if !defined _BIGNUMBER_H_ +#define _BIGNUMBER_H_ + +#include "ippcp.h" + +#include +#include +#include + +using namespace std; + +class BigNumber +{ +public: + BigNumber(Ipp32u value=0); + BigNumber(Ipp32s value); + BigNumber(const IppsBigNumState* pBN); + BigNumber(const Ipp32u* pData, int length=1, IppsBigNumSGN sgn=IppsBigNumPOS); + BigNumber(const BigNumber& bn); + BigNumber(const char *s); + virtual ~BigNumber(); + + // set value + void Set(const Ipp32u* pData, int length=1, IppsBigNumSGN sgn=IppsBigNumPOS); + // conversion to IppsBigNumState + friend IppsBigNumState* BN(const BigNumber& bn) {return bn.m_pBN;} + operator IppsBigNumState* () const { return m_pBN; } + + // some useful constatns + static const BigNumber& Zero(); + static const BigNumber& One(); + static const BigNumber& Two(); + + // arithmetic operators probably need + BigNumber& operator = (const BigNumber& bn); + BigNumber& operator += (const BigNumber& bn); + BigNumber& operator -= (const BigNumber& bn); + BigNumber& operator *= (Ipp32u n); + BigNumber& operator *= (const BigNumber& bn); + BigNumber& operator /= (const BigNumber& bn); + BigNumber& operator %= (const BigNumber& bn); + friend BigNumber operator + (const BigNumber& a, const BigNumber& b); + friend BigNumber operator - (const BigNumber& a, const BigNumber& b); + friend BigNumber operator * (const BigNumber& a, const BigNumber& b); + friend BigNumber operator * (const BigNumber& a, Ipp32u); + friend BigNumber operator % (const BigNumber& a, const BigNumber& b); + friend BigNumber operator / (const BigNumber& a, const BigNumber& b); + + // modulo arithmetic + BigNumber Modulo(const BigNumber& a) const; + BigNumber ModAdd(const BigNumber& a, const BigNumber& b) const; + BigNumber ModSub(const BigNumber& a, const BigNumber& b) const; + BigNumber ModMul(const BigNumber& a, const BigNumber& b) const; + BigNumber InverseAdd(const BigNumber& a) const; + BigNumber InverseMul(const BigNumber& a) const; + + // comparisons + friend bool operator < (const BigNumber& a, const BigNumber& b); + friend bool operator > (const BigNumber& a, const BigNumber& b); + friend bool operator == (const BigNumber& a, const BigNumber& b); + friend bool operator != (const BigNumber& a, const BigNumber& b); + friend bool operator <= (const BigNumber& a, const BigNumber& b) {return !(a>b);} + friend bool operator >= (const BigNumber& a, const BigNumber& b) {return !(a>5;} + friend int Bit(const vector& v, int n); + + // conversion and output + void num2hex( string& s ) const; // convert to hex string + void num2vec( vector& v ) const; // convert to 32-bit word vector + friend ostream& operator << (ostream& os, const BigNumber& a); + +protected: + bool create(const Ipp32u* pData, int length, IppsBigNumSGN sgn=IppsBigNumPOS); + int compare(const BigNumber& ) const; + IppsBigNumState* m_pBN; +}; + +// convert bit size into 32-bit words +#define BITSIZE_WORD(n) ((((n)+31)>>5)) + +#endif // _BIGNUMBER_H_ diff --git a/utils/utils.cpp b/utils/utils.cpp new file mode 100644 index 0000000..a89e150 --- /dev/null +++ b/utils/utils.cpp @@ -0,0 +1,46 @@ +/******************************************************************************* +* Copyright 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + + +#include "utils.h" + +size_t strlen_safe(const char* dest, size_t dmax) { + size_t count; + + /* check null pointer */ + if (NULL == dest) { + return 0UL; + } + + /* check max equal zero */ + if (0UL == dmax) { + return 0UL; + } + + /* check dmax > 4Kb */ + if (dmax > RSIZE_MAX_STR) { + return 0UL; + } + + count = 0UL; + while (*dest && dmax) { + ++count; + --dmax; + ++dest; + } + + return count; +} diff --git a/utils/utils.h b/utils/utils.h new file mode 100644 index 0000000..6b1f079 --- /dev/null +++ b/utils/utils.h @@ -0,0 +1,34 @@ +/******************************************************************************* +* Copyright 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ +#ifndef _UTILS_H_ +#define _UTILS_H_ + +#include + +#define RSIZE_MAX_STR (4UL << 10) /* 4Kb */ + +/** + * \brief + * The strnlen_s function computes the length of the string pointed to by dest. + * \param[in] dest pointer to string + * \param[in] dmax restricted maximum length. (default 4Kb) + * \return size_t + * The function returns the string length, excluding the terminating + * null character. If dest is NULL, then strnlen_s returns 0. + */ +size_t strlen_safe(const char* dest, size_t dmax = RSIZE_MAX_STR); + +#endif // _UTILS_H_ From 1bb5aa3e4886061967aee46dcdcd4a2873b6be10 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 7 Mar 2022 17:12:03 -0800 Subject: [PATCH 075/364] Add preliminary README.md containing project description. --- README.md | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0be9277..0289325 100644 --- a/README.md +++ b/README.md @@ -1 +1,42 @@ -# libraries.security.cryptography.homomorphic-encryption.glade.he-qat \ No newline at end of file +# Intel Homomorphic Encryption (HE) Acceleration Library for Quick Assist Technology (QAT) +Intel Homomorphic Encryption Acceleration Library for QAT (HEQAT Lib) is an open-source library which provides accelerated performance for homomorphic encryption (HE) math functions involving multi-precision numbers and modular arithmetic. This library is written in C99. + +## Contents +- [Intel Paillier Cryptosystem Library](#intel-paillier-cryptosystem-library) + - [Contents](#contents) + - [Introduction](#introduction) + - [Building the Library](#building-the-library) + - [Requirements](#requirements) + - [Dependencies](#dependencies) + - [Instructions](#instructions) + - [Testing and Benchmarking](#testing-and-benchmarking) +- [Standardization](#standardization) +- [Contributors](#contributors) + +## Introduction + +This library is underconstruction and currently only offers acceleration of modular exponentiation of multi-precision numbers, ranging from 1024 to 8192-bit numbers. Current stage of implementation provides the big number modular exponentiation featuring OpenSSL BIGNUM data type and has the following characteristics: + - Synchronous: It means that calls will place a work request to be offloaded to the accelerator and processed in the order they are issued. + - Blocking: It means that the next buffered work request waits for completion of processing of the most recently request offloaded to the accelerator, when processing must be currently in progress. + - Batch Support: The internal buffer is set accommodate 16 request at once so that the maximum batch size is 16. Therefore, only up to 16 requests can exercised asynchronously from the application for any single `for loop` or code block along with a call to the `get` function that waits for completion of the requests. + - Single-Threaded: It is currently safer to use single-threaded, although multiple threading is partially supported (try it at your own risk). Multi-threading can only be supported so long as the internal buffer can fill all the requests submitted by multiple threads, otherwise it will hang (this feature will become reliable in later versions). + - Single instance: The library is configure to use only 1 single QAT endpoint at any time at the creation of the QAT runtime context. + +## Building the Library +### Requirements +The hardware requirement to use the library is the following: + - Intel Sapphire Rapids + - Intel C62XX acceleration card + +As for the operating systems, the library has been tested and confirmed to work on Ubuntu 20.04. + +### Dependencies +Required dependencies include: +``` +cmake >=3.15.1 +git +pthread +gcc >= 9.1 +qatlib +``` + From 6056d76182af0fd29dba19e4997163d7cc8d899c Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 7 Mar 2022 17:18:53 -0800 Subject: [PATCH 076/364] Add C++ compilation support and refactor custom types. --- he_qat_bn_ops.h | 22 ++++++++++++++++++++++ he_qat_context.h | 8 ++++++++ he_qat_types.h | 14 +++++++++++--- include/cpa_sample_cnv_utils.h | 9 +++++++++ include/cpa_sample_utils.h | 19 ++++++++++++++++--- 5 files changed, 66 insertions(+), 6 deletions(-) diff --git a/he_qat_bn_ops.h b/he_qat_bn_ops.h index 66fe8a1..ebdb061 100644 --- a/he_qat_bn_ops.h +++ b/he_qat_bn_ops.h @@ -5,6 +5,10 @@ #ifndef _HE_QAT_BN_OPS_H_ #define _HE_QAT_BN_OPS_H_ +#ifdef __cplusplus +extern "C" { +#endif + #include "cpa.h" #include "cpa_cy_ln.h" @@ -75,4 +79,22 @@ void getBnModExpRequest(unsigned int num_requests); // use producer to place request into qat buffer // wait for all outstanding requests to complete +/// @brief +/// @function +/// Generic big number modular exponentiation for input data in primitive type format (unsigned char *). +/// @details +/// Create private buffer for code section. Create QAT contiguous memory space. +/// Copy data and package into a request and call producer function to submit +/// request into qat buffer. +/// @param[out] r Remainder number of the modular exponentiation operation. +/// @param[in] b Base number of the modular exponentiation operation. +/// @param[in] e Exponent number of the modular exponentiation operation. +/// @param[in] m Modulus number of the modular exponentiation operation. +/// @param[in] nbits Number of bits (bit precision) of input/output big numbers. +HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, unsigned char* e, unsigned char* m, int nbits); + +#ifdef __cplusplus +} //extern "C" { +#endif + #endif diff --git a/he_qat_context.h b/he_qat_context.h index 0dc6686..3330403 100644 --- a/he_qat_context.h +++ b/he_qat_context.h @@ -4,6 +4,10 @@ #ifndef _HE_QAT_CONTEXT_H_ #define _HE_QAT_CONTEXT_H_ +#ifdef __cplusplus +extern "C" { +#endif + #include "he_qat_types.h" #include @@ -20,4 +24,8 @@ HE_QAT_STATUS acquire_qat_devices(); /// Configure and initialize QAT runtime environment. HE_QAT_STATUS release_qat_devices(); +#ifdef __cplusplus +} //extern "C" { +#endif + #endif diff --git a/he_qat_types.h b/he_qat_types.h index f274b56..fcc1da6 100644 --- a/he_qat_types.h +++ b/he_qat_types.h @@ -4,24 +4,28 @@ #ifndef _HE_QAT_TYPES_H_ #define _HE_QAT_TYPES_H_ +#ifdef __cplusplus +extern "C" { +#endif + #include "cpa.h" #include "cpa_cy_im.h" #include #define HE_QAT_BUFFER_SIZE 16 -// const unsigned HE_QAT_BUFFER_SIZE = 4; // Type definitions typedef enum { HE_QAT_SYNC = 1, HE_QAT_ASYNC = 2 } HE_QAT_EXEC_MODE; typedef enum { - HE_QAT_READY = 1, + HE_QAT_STATUS_INVALID_PARAM = 2, + HE_QAT_STATUS_READY = 1, HE_QAT_STATUS_SUCCESS = 0, HE_QAT_STATUS_FAIL = -1 } HE_QAT_STATUS; -typedef enum { HE_QAT_NO_OP = 0, HE_QAT_MODEXP = 1 } HE_QAT_OP; +typedef enum { HE_QAT_OP_NONE = 0, HE_QAT_OP_MODEXP = 1 } HE_QAT_OP; typedef pthread_t HE_QAT_Inst; @@ -48,4 +52,8 @@ typedef struct { CpaStatus status; } HE_QAT_InstConfig; +#ifdef __cplusplus +} // close the extern "C" { #endif + +#endif // _HE_QAT_TYPES_H_ diff --git a/include/cpa_sample_cnv_utils.h b/include/cpa_sample_cnv_utils.h index 322481f..dd3730e 100644 --- a/include/cpa_sample_cnv_utils.h +++ b/include/cpa_sample_cnv_utils.h @@ -78,6 +78,10 @@ #ifndef QAT_SAMPLE_CNV_UTILS_H_ #define QAT_SAMPLE_CNV_UTILS_H_ +#ifdef __cplusplus +extern "C" { +#endif + /* Common macro definitions */ #ifndef DC_API_VERSION_AT_LEAST #define DC_API_VERSION_AT_LEAST(major, minor) \ @@ -257,4 +261,9 @@ static CpaStatus getSampleDcCapabilities( return CPA_STATUS_SUCCESS; } + +#ifdef __cplusplus +} // close extern "C" { +#endif + #endif /* QAT_SAMPLE_CNV_UTILS_H_ */ diff --git a/include/cpa_sample_utils.h b/include/cpa_sample_utils.h index b82e666..72dbcce 100644 --- a/include/cpa_sample_utils.h +++ b/include/cpa_sample_utils.h @@ -78,6 +78,16 @@ #ifndef CPA_SAMPLE_UTILS_H #define CPA_SAMPLE_UTILS_H +#ifdef __cplusplus +#define HE_QAT_RESTRICT __restrict__ +#else +#define HE_QAT_RESTRICT restrict +#endif + +#ifdef __cplusplus +extern "C" { +#endif + #include "cpa.h" #include "cpa_cy_im.h" #include "cpa_dc.h" @@ -271,8 +281,8 @@ typedef struct task_struct *sampleThread; * @post * none *****************************************************************************/ -static inline void displayHexArray(const char *restrict pLabel, - const Cpa8U *restrict pBuff, +static inline void displayHexArray(const char *HE_QAT_RESTRICT pLabel, + const Cpa8U *HE_QAT_RESTRICT pBuff, Cpa32U len) { @@ -613,7 +623,10 @@ void sampleDcStartPolling(CpaInstanceHandle dcInstHandle); void sampleDcStopPolling(void); - +#ifdef __cplusplus +} //extern "C" { #endif +#endif + From d5fa36ef632e4c14aa171c228c6360847c60e56c Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 7 Mar 2022 17:21:19 -0800 Subject: [PATCH 077/364] Add modular exponentiation interface to support generic types. --- he_qat_bn_ops.c | 144 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 136 insertions(+), 8 deletions(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index c60de75..0af59b2 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -36,7 +36,7 @@ static void lnModExpCallback(void* pCallbackTag, // This type can be variable if (pOpData == request->op_data) { // printf("pOpData is same as input\n"); // Mark request as complete or ready to be used - request->request_status = HE_QAT_READY; + request->request_status = HE_QAT_STATUS_READY; BIGNUM* r = BN_bin2bn(request->op_result.pData, request->op_result.dataLenInBytes, @@ -167,7 +167,7 @@ void* start_perform_op(void* _inst_config) { CpaStatus status = CPA_STATUS_FAIL; - // If called again, wait + // Start from zero or restart after stop_perform_op pthread_mutex_lock(&config->mutex); while (config->active) pthread_cond_wait(&config->ready, &config->mutex); @@ -219,17 +219,15 @@ void* start_perform_op(void* _inst_config) { // Realize the type of operation from data switch (request->op_type) { // Select appropriate action - case HE_QAT_MODEXP: - // printf("Perform HE_QAT_MODEXP\n"); + case HE_QAT_OP_MODEXP: status = cpaCyLnModExp(config->inst_handle, lnModExpCallback, (void*)request, (CpaCyLnModExpOpData*)request->op_data, &request->op_result); retry++; break; - case HE_QAT_NO_OP: + case HE_QAT_OP_NONE: default: - // printf("HE_QAT_NO_OP\n"); retry = HE_QAT_MAX_RETRY; break; } @@ -424,7 +422,7 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, return HE_QAT_STATUS_FAIL; } - request->op_type = HE_QAT_MODEXP; + request->op_type = HE_QAT_OP_MODEXP; request->op_status = status; request->op_output = (void*)r; @@ -454,7 +452,7 @@ void getBnModExpRequest(unsigned int batch_size) { // to complete processing pthread_mutex_lock( &task->mutex); // mutex only needed for the conditional variable - while (HE_QAT_READY != task->request_status) + while (HE_QAT_STATUS_READY != task->request_status) pthread_cond_wait(&task->ready, &task->mutex); // Free up QAT temporary memory CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; @@ -511,3 +509,133 @@ task->op_data; if (op_data) { PHYS_CONTIG_FREE(op_data->base.pData); return ; } */ + +/// @brief +/// @function +/// Callback function for lnIppModExpPerformOp. It performs any data processing +/// required after the modular exponentiation. +static void HE_QAT_bnModExpCallback(void* pCallbackTag, // This type can be variable + CpaStatus status, + void* pOpData, // This is fixed -- please swap it + CpaFlatBuffer* pOut) { + HE_QAT_TaskRequest* request = NULL; + + // Check if input data for the op is available and do something + if (NULL != pCallbackTag) { + // Read request data + request = (HE_QAT_TaskRequest*)pCallbackTag; + + // Collect the device output in pOut + request->op_status = status; + if (CPA_STATUS_SUCCESS == status) { + if (pOpData == request->op_data) { + // printf("pOpData is same as input\n"); + // Mark request as complete or ready to be used + request->request_status = HE_QAT_STATUS_READY; + // Copy compute results to output destination + memcpy(request->op_output, request->op_result.pData, request->op_result.dataLenInBytes); + } else { + // printf("pOpData is NOT same as input\n"); + request->request_status = HE_QAT_STATUS_FAIL; + } + } + // Make it synchronous and blocking + pthread_cond_signal(&request->ready); + COMPLETE((struct COMPLETION_STRUCT*)&request->callback); + } + + return; +} + +HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, unsigned char* e, unsigned char* m, int nbits) { + // Unpack data and copy to QAT friendly memory space + int len = nbits / 8; + + if (NULL == r) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == b) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == e) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == m) return HE_QAT_STATUS_INVALID_PARAM; + + Cpa8U* pBase = NULL; + Cpa8U* pModulus = NULL; + Cpa8U* pExponent = NULL; + + + // TODO(fdiasmor): Try it with 8-byte alignment. + CpaStatus status = CPA_STATUS_FAIL; + status = PHYS_CONTIG_ALLOC(&pBase, len); + if (CPA_STATUS_SUCCESS == status && NULL != pBase) { + memcpy(pBase, b, len); + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + status = PHYS_CONTIG_ALLOC(&pExponent, len); + if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { + memcpy(pExponent, e, len); + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + status = PHYS_CONTIG_ALLOC(&pModulus, len); + if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { + memcpy(pModulus, m, len); + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + // HE_QAT_TaskRequest request = + // HE_QAT_PACK_MODEXP_REQUEST(pBase, pExponent, pModulus, r) + // Pack it as a QAT Task Request + HE_QAT_TaskRequest* request = + (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); + if (NULL == request) { + printf( + "HE_QAT_TaskRequest memory allocation failed in " + "bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + + CpaCyLnModExpOpData* op_data = + (CpaCyLnModExpOpData*)calloc(1, sizeof(CpaCyLnModExpOpData)); + if (NULL == op_data) { + printf("Cpa memory allocation failed in bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + op_data->base.pData = pBase; + op_data->base.dataLenInBytes = len; + op_data->exponent.pData = pExponent; + op_data->exponent.dataLenInBytes = len; + op_data->modulus.pData = pModulus; + op_data->modulus.dataLenInBytes = len; + request->op_data = (void*)op_data; + + status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); + if (CPA_STATUS_SUCCESS == status && NULL != request->op_result.pData) { + request->op_result.dataLenInBytes = len; + } else { + printf( + "CpaFlatBuffer.pData memory allocation failed in " + "bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + + request->op_type = HE_QAT_OP_MODEXP; + request->op_status = status; + request->op_output = (void*)r; + + // Ensure calls are synchronous and blocking + pthread_mutex_init(&request->mutex, NULL); + pthread_cond_init(&request->ready, NULL); + + // Submit request using producer function + // printf("Submit request \n"); + submit_request(&he_qat_buffer, (void*)request); + // printf("Submitted\n"); + + return HE_QAT_STATUS_SUCCESS; +} + From 9d31e18e2cc06883d22b0e86b022dcb1af2a1ec9 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 7 Mar 2022 17:22:54 -0800 Subject: [PATCH 078/364] Add BigNumber conversion unit test. --- CMakeLists.txt | 49 +++++++- test_bnConversion.cpp | 255 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 299 insertions(+), 5 deletions(-) create mode 100644 test_bnConversion.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ebfd96a..c108746 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,7 @@ add_definitions(-DDO_CRYPTO) add_definitions(-DUSER_SPACE) add_compile_options(-fPIC) + # Common utility functions add_subdirectory(common) @@ -47,21 +48,59 @@ target_include_directories(he_qat PUBLIC /opt/openssl/include) target_link_directories(he_qat PUBLIC ${ICP_BUILDOUTPUT_PATH}) target_link_directories(he_qat PUBLIC /opt/openssl/lib) target_link_libraries(he_qat PRIVATE cpa_sample_utils) -target_link_libraries(he_qat PUBLIC z pthread crypto ssl crypto qat_s usdm_drv_s) +target_link_libraries(he_qat PUBLIC qat_s usdm_drv_s) +target_link_libraries(he_qat PUBLIC crypto ssl) +target_link_libraries(he_qat PUBLIC z pthread) #add_definitions(-D_DESTINY_DEBUG_VERBOSE) +if(NOT HE_QAT_DEBUG_VERBOSE) + remove_definitions(-D_DESTINY_DEBUG_VERBOSE) +endif() add_executable(test_context test_context.c) target_link_libraries(test_context PUBLIC he_qat) target_link_libraries(test_context PUBLIC cpa_sample_utils) -target_link_libraries(test_context PUBLIC z pthread crypto ssl crypto qat_s usdm_drv_s) - +target_link_libraries(test_context PUBLIC z pthread ssl crypto qat_s usdm_drv_s) + +set(IPPCP_DIR "/opt/ipp-crypto") +set(IPPCP_CMAKE_PREFIX_DIR "${IPPCP_DIR}/lib/cmake") +list(APPEND CMAKE_PREFIX_PATH "${IPPCP_CMAKE_PREFIX_DIR}") +find_package(ippcp REQUIRED) +#find_package(IPPCrypto REQUIRED MODULE) +#if (NOT IPPCRYPTO_FOUND) +# message(FATAL_ERROR "No Intel IPP Cryptography library found on the system.") +#endif() +#if(NOT TARGET ippcp) +# message(FATAL_ERROR "TARGET IPPCP::ippcp not found") +#else() +# message(STATUS "TARGET IPPCP::ippcp found") +#endif() + +set(HE_QAT_UTILS_INC_DIR "") +add_subdirectory(utils) add_executable(test_bnModExpPerformOp test_bnModExpPerformOp.c) target_link_libraries(test_bnModExpPerformOp PUBLIC he_qat) target_link_libraries(test_bnModExpPerformOp PUBLIC cpa_sample_utils) -target_link_libraries(test_bnModExpPerformOp PUBLIC z pthread crypto ssl crypto qat_s usdm_drv_s) - +target_link_libraries(test_bnModExpPerformOp PUBLIC z pthread ssl crypto qat_s usdm_drv_s) + +add_compile_options(-fpermissive) +add_executable(test_ippModExpPerformOp test_ippModExpPerformOp.cpp) +target_include_directories(test_ippModExpPerformOp PUBLIC ${COMMON_INC_DIR} ${HE_QAT_UTILS_INC_DIR}) +target_link_libraries(test_ippModExpPerformOp PUBLIC he_qat) +target_link_libraries(test_ippModExpPerformOp PUBLIC he_qat_utils) +target_link_libraries(test_ippModExpPerformOp PUBLIC cpa_sample_utils) +target_link_libraries(test_ippModExpPerformOp PUBLIC ippcpmx crypto_mb) +target_link_libraries(test_ippModExpPerformOp PUBLIC z pthread ssl crypto qat_s usdm_drv_s) + +add_compile_options(-fpermissive) +add_executable(test_bnConversion test_bnConversion.cpp) +target_include_directories(test_bnConversion PUBLIC ${COMMON_INC_DIR} ${HE_QAT_UTILS_INC_DIR}) +target_link_libraries(test_bnConversion PUBLIC he_qat) +target_link_libraries(test_bnConversion PUBLIC he_qat_utils) +target_link_libraries(test_bnConversion PUBLIC cpa_sample_utils) +target_link_libraries(test_bnConversion PUBLIC ippcpmx crypto_mb) +target_link_libraries(test_bnConversion PUBLIC z pthread ssl crypto qat_s usdm_drv_s) # Compile test case #add_subdirectory(ln_mod_exp) diff --git a/test_bnConversion.cpp b/test_bnConversion.cpp new file mode 100644 index 0000000..a701094 --- /dev/null +++ b/test_bnConversion.cpp @@ -0,0 +1,255 @@ + +#include "cpa_sample_utils.h" + +#include "he_qat_bn_ops.h" +#include "he_qat_context.h" + +#include +#include +#include +#include +#include + +#include "ippcp.h" +#include "bignum.h" + +#include +#include + +#define LEN_OF_1024_BITS 128 +#define LEN_OF_2048_BITS 256 +#define msb_CAN_BE_ZERO -1 +#define msb_IS_ONE 0 +#define EVEN_RND_NUM 0 +#define ODD_RND_NUM 1 +#define BATCH_SIZE 1 + +using namespace std; + +//int gDebugParam = 1; + +BIGNUM* generateTestBNData(int nbits) { + if (!RAND_status()) return NULL; +#ifdef _DESTINY_DEBUG_VERBOSE + printf("PRNG properly seeded.\n"); +#endif + + BIGNUM* bn = BN_new(); + + if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { + BN_free(bn); + printf("Error while generating BN random number: %lu\n", + ERR_get_error()); + return NULL; + } + + return bn; +} + +unsigned char* paddingZeros(BIGNUM* bn, int nbits) { + if (!bn) return NULL; + + // Returns same address if it fails + int num_bytes = BN_num_bytes(bn); + int bytes_left = nbits / 8 - num_bytes; + if (bytes_left <= 0) return NULL; + + // Returns same address if it fails + unsigned char* bin = NULL; + int len = bytes_left + num_bytes; + if (!(bin = OPENSSL_zalloc(len))) return NULL; + +#ifdef _DESTINY_DEBUG_VERBOSE + printf("Padding bn with %d bytes to total %d bytes\n", bytes_left, len); +#endif + BN_bn2binpad(bn, bin, len); + if (ERR_get_error()) { + OPENSSL_free(bin); + return NULL; + } + + return bin; +} + +void showHexBN(BIGNUM* bn, int nbits) { + int len = nbits / 8; + unsigned char* bin = OPENSSL_zalloc(len); + if (!bin) return; + if (BN_bn2binpad(bn, bin, len)) { + for (size_t i = 0; i < len; i++) printf("%d", bin[i]); + printf("\n"); + } + OPENSSL_free(bin); + return; +} + +void showHexBin(unsigned char* bin, int len) { + if (!bin) return; + for (size_t i = 0; i < len; i++) printf("%d", bin[i]); + printf("\n"); + return; +} + +// data will be changed to little endian format in this function, therefore the abscence of const in front +HE_QAT_STATUS binToBigNumber(BigNumber &bn, unsigned char *data, int nbits) +{ + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; + + BIGNUM *bn_ = BN_new(); + if (ERR_get_error()) return status; + + // Convert raw data to BIGNUM representation to be used as a proxy to convert it to little endian format + int len_ = nbits/8; + BN_bin2bn(data, len_, bn_); + if (ERR_get_error()) { + BN_free(bn_); + return status; + } + + // Convert big number from Big Endian (QAT's format) to Little Endian (BigNumber's format) + BN_bn2lebinpad(bn_, data, len_); + if (ERR_get_error()) { + BN_free(bn_); + return status; + } + + // Uncomment this line if C++ compiler + bn = BigNumber(reinterpret_cast(data), BITSIZE_WORD(nbits)); + // Comment this line if C++ compiler +// bn = BigNumber((Ipp32u *)(data), BITSIZE_WORD(nbits)); + + // Set status of operation + status = HE_QAT_STATUS_SUCCESS; + + // Free up temporary allocated memory space + BN_free(bn_); + + return status; +} + +HE_QAT_STATUS bigNumberToBin(unsigned char *data, int nbits, BigNumber &bn) +{ + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; + + int len_ = nbits/8; + int bit_size_ = 0; // could use that instead of nbits + Ipp32u *ref_bn_ = NULL; + ippsRef_BN(NULL, &bit_size_, &ref_bn_, BN(bn)); + unsigned char *data_ = reinterpret_cast(ref_bn_); +// unsigned char *data = (unsigned char *) ref_bn_; + + BIGNUM *bn_ = BN_new(); + if (ERR_get_error()) return status; + + BN_lebin2bn(data_, len_, bn_); + if (ERR_get_error()) { + BN_free(bn_); + return status; + } + + BN_bn2binpad(bn_, data, len_); + if (ERR_get_error()) { + BN_free(bn_); + return status; + } + + // Set status of operation + status = HE_QAT_STATUS_SUCCESS; + + // Free up temporary allocated memory space + BN_free(bn_); + + return status; +} + +int main(int argc, const char** argv) { + const int bit_length = 1024; + const size_t num_trials = 100; + + double avg_speed_up = 0.0; + double ssl_avg_time = 0.0; + double qat_avg_time = 0.0; + + clock_t start = CLOCKS_PER_SEC; + clock_t ssl_elapsed = CLOCKS_PER_SEC; + clock_t qat_elapsed = CLOCKS_PER_SEC; + + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + // Set up QAT runtime context + acquire_qat_devices(); + + // Set up OpenSSL context (as baseline) + BN_CTX* ctx = BN_CTX_new(); + BN_CTX_start(ctx); + + for (unsigned int mod = 4094; mod < 4096; mod++) { + //BIGNUM* bn_mod = BN_new(); + BIGNUM* bn_mod = generateTestBNData(bit_length); + + if (!bn_mod) continue; + + //BN_set_word(bn_mod, mod); + + char* bn_str = BN_bn2hex(bn_mod); + printf("Generated modulus: %s num_bytes: %d num_bits: %d\n", bn_str, + BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); +// OPENSSL_free(bn_str); + +// +// // Pack BIGNUM (in base 2^8) into BigNumber (in base 2^32) + unsigned char* mpi_base = NULL; + mpi_base = (unsigned char *) calloc(bit_length/8, sizeof(unsigned char)); + if (NULL == mpi_base) { + BN_free(bn_mod); + continue; + } + BN_bn2lebinpad(bn_mod, mpi_base, bit_length/8); +// // revert it +// for (int k = 0; k < bit_length/8; k++) +// be_mpi_base[k] = mpi_base[bit_length/8-k-1]; +// + + printf("Try convert to BigNumber len=%lu\n",bit_length/(8*sizeof(unsigned char))); +// // Convert from base 2^8 to base 2^32 + Ipp32u *ipp_mpi_base = reinterpret_cast(mpi_base);// + (rep_len - bit_length/8)); +// //Ipp32u *ipp_mpi_base = (Ipp32u *) (mpi_base); //(rep_len_2-128); + BigNumber BigNum_base((Ipp32u)0); + BigNum_base = BigNumber((Ipp32u *) ipp_mpi_base, BITSIZE_WORD(bit_length)); + printf("BigNumber has been created.\n"); + // End of packing (this overhead does not exist in practice) + + std::string str; + BigNum_base.num2hex(str); + printf("BigNum_base num2hex output: %s %d\n",str.c_str(),bit_length/8); + +// // Extract raw data from BigNumber 2^32 and convert it to base 2^8 + int bitSize = 0; + Ipp32u *pBigNum_base = NULL; //BN(BigNum_base); + ippsRef_BN(NULL, &bitSize, &pBigNum_base, BN(BigNum_base)); + unsigned char *ippbn = reinterpret_cast(pBigNum_base); +// unsigned char *ippbn = (unsigned char *) pBigNum_base; + BIGNUM *ipp_ref_bn = BN_new(); + BN_lebin2bn(ippbn, bit_length/8, ipp_ref_bn); + char *ipp_ref_bn_str = BN_bn2hex(ipp_ref_bn); + printf(">>>> PRINT IPP ref bn: %s bitSize(%d)\n", ipp_ref_bn_str, BN_num_bits(ipp_ref_bn)); + //BIGNUM *ipp_ref_bn = BN_new(); + //BN_lebin2bn(ippbn, bit_length/8, ipp_ref_bn); + + BN_free(bn_mod); +// BN_free(bn_base); +// BN_free(bn_exponent); + } + + // Tear down OpenSSL context + BN_CTX_end(ctx); + + // Tear down QAT runtime context + release_qat_devices(); + + return (int)status; +} From e1e1acf005c24e336d2e2408bff16aa09b74a798 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Tue, 8 Mar 2022 12:29:27 -0800 Subject: [PATCH 079/364] Main update (#40) * Code clean/refactor/optimize (#16) * Paillier key generation: clean/optimize code - Modify doxygen document - Change getNormalBN & getDJNBN to static - Add N_BIT_SIZE_MAX macro definition * Paillier key operation: clean/optimize code - Modify doxygen document - Rewrite function raw_mul * Paillier public key: clean/optimize code - Modify doxygen document - Rewrite function: randIpp32u, getRandom, apply_obfuscator, ippMultiBuffExp, ippMontExp * Paillier private key: clean/optimize code - Modify doxygen document - Rewrite function: decrpytRAW, decrypt, decryptCRT * Add namespace(ipcl) to Intel Paillier Crypto Lib * Add const keyword (#18) - applied constant protection to all member functions and needed arguments - public key member is const in both paillier_prikey and paillier_ops * Refactoring (#19) * Refactoring - Replaced all pointers and arrays with std::vector - resolves #14 - Changed multi-buffered PaillierEncryptedNumber::raw_mul to return std::vector - resolves #15 - Changed multi-buffered modular exponentation PaillierPublicKey::ippMultiBuffExp to return std::vector - resolves #15 - Applied changes to unit-test and benchmark accordingly - Applied const keywords to test and benchmark functions for keyPair * Bug fix on BM_Mul_CTPT_OMP in benchmark * Updated README - updated unittest_omp per changes to IPCL_ENABLE_OMP flag * Updated README * Removed unused header * Add util function/macro (#24) * Add util function/macro * Minor modifications - Changed PARALLEL_PROCESS_NUM to IPCL_CRYPTO_MB_SIZE - Replaced BigNum macros (BITSIZE_WORD and BITSIZE_DWORD) with functions in BigNum Co-authored-by: Sejun Kim * Updated readme (#25) * Add support for multi cpu architecture (#28) * Add support for multi cpu architecture(i.e. when cpu doesn't support avx512 instructions) * OpenMP enabling cleanup * Skmono/decrypt raw refactoring (#29) * Modified decryptRAW to use m_pubkey->ippMultiBuffExp * Replaced "avx512" with "avx512ifma" - mbx_exp_mb8 works only with ifma instructions * Removed testing code * Renamed OMP compiler flag to IPCL_USE_OMP * Renamed ippMultiBuffExp and ippMontExp - ippMultiBuffExp -> ippMBModExp - ippMontExp -> ippSBModExp - put both multi and single buffered mod exp to private - only expose ippModExp that will take care of any modular exponentiation * bugfix - updated remaining ippMontExp Co-authored-by: Sejun Kim * Updated README on flags (#32) * Updated README (#36) * Fix decryptRAW incorrect result issue (#37) * Added support for Ipp8u vector retrieval of BigNumber for QAT integration (#38) * Move Mod Exp to seperate file (#39) * Move modular exponentation to seperate file * Remove unused function IPP_invert Co-authored-by: Pengfei Zhao --- CMakeLists.txt | 6 +- README.md | 50 +-- benchmark/CMakeLists.txt | 1 - benchmark/bench_cryptography.cpp | 193 ++++------- benchmark/bench_ops.cpp | 438 +++++++++--------------- ipcl/CMakeLists.txt | 10 + ipcl/bignum.cpp | 15 + ipcl/include/ipcl/bignum.h | 11 +- ipcl/include/ipcl/common.hpp | 12 + ipcl/include/ipcl/mod_exp.hpp | 35 ++ ipcl/include/ipcl/paillier_keygen.hpp | 5 + ipcl/include/ipcl/paillier_ops.hpp | 44 ++- ipcl/include/ipcl/paillier_prikey.hpp | 35 +- ipcl/include/ipcl/paillier_pubkey.hpp | 81 +++-- ipcl/include/ipcl/util.hpp | 42 +++ ipcl/mod_exp.cpp | 168 ++++++++++ ipcl/paillier_keygen.cpp | 25 +- ipcl/paillier_ops.cpp | 75 +++-- ipcl/paillier_prikey.cpp | 137 +++----- ipcl/paillier_pubkey.cpp | 235 +++++-------- test/CMakeLists.txt | 1 - test/test_cryptography.cpp | 102 +++--- test/test_ops.cpp | 459 ++++++++++++-------------- 23 files changed, 1069 insertions(+), 1111 deletions(-) create mode 100644 ipcl/include/ipcl/common.hpp create mode 100644 ipcl/include/ipcl/mod_exp.hpp create mode 100644 ipcl/include/ipcl/util.hpp create mode 100644 ipcl/mod_exp.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 80bd6da..7918c0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,10 @@ option(IPCL_ENABLE_OMP "Enable OpenMP testing/benchmarking" ON) option(IPCL_DOCS "Enable document building" OFF) option(IPCL_SHARED "Build shared library" ON) +if(IPCL_ENABLE_OMP) + add_compile_definitions(IPCL_USE_OMP) +endif() + if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(IPCL_DEBUG ON) else() @@ -102,7 +106,7 @@ include(ipcl-util) include(cmake/ippcrypto.cmake) -if(IPCL_TEST OR IPCL_OMP_TEST) +if(IPCL_TEST) include(cmake/gtest.cmake) endif() if(IPCL_BENCHMARK) diff --git a/README.md b/README.md index 5c61789..29dcf69 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,13 @@ Intel Paillier Cryptosystem Library is an open-source library which provides acc - [Intel Paillier Cryptosystem Library](#intel-paillier-cryptosystem-library) - [Contents](#contents) - [Introduction](#introduction) + - [Performance](#performance) - [Building the Library](#building-the-library) - - [Requirements](#requirements) + - [Prerequisites](#prerequisites) - [Dependencies](#dependencies) - [Instructions](#instructions) - [Testing and Benchmarking](#testing-and-benchmarking) +- [Python Extension](#python-extension) - [Standardization](#standardization) - [Contributors](#contributors) @@ -26,16 +28,21 @@ As a public key encryption scheme, Paillier cryptosystem has three stages: For increased security, typically the key length is at least 1024 bits, but recommendation is 2048 bits or larger. To handle such large size integers, conventional implementations of the Paillier cryptosystem utilizes the GNU Multiple Precision Arithmetic Library (GMP). The essential computation of the scheme relies on the modular exponentiation, and our library takes advantage of the multi-buffer modular exponentiation function (```mbx_exp_mb8```) of IPP-Crypto library, which is enabled in AVX512IFMA instruction sets supporting SKUs, such as Intel Icelake Xeon CPUs. +### Performance +To be added after P2CA review ## Building the Library -### Requirements -The hardware requirement to use the library is AVX512IFMA instruction sets enabled CPUs, as listed in Intel codenames: +### Prerequisites +For best performance, especially due to the multi-buffer modular exponentiation function, the library is to be used on AVX512IFMA enabled systems, as listed below in Intel CPU codenames: - Intel Cannon Lake - Intel Ice Lake -Note: We are planning to add support for more SKUs. +The library can be built and used without AVX512IFMA, as if the instruction set is not detected on the system, it will automatically switch to non multi-buffer modular exponentiation. -As for the operating systems, ehe library has been tested and confirmed to work on Ubuntu 18.04, 20.04 and RHEL 8.0. +The following operating systems have been tested and deemed to be fully functional. + - Ubuntu 18.04 and higher + - Red Hat Enterprise Linux 8.1 and higher +We will keep working on adding more supported operating systems. ### Dependencies Must have dependencies include: ``` @@ -45,7 +52,7 @@ pthread g++ >= 7.0 or clang >= 10.0 ``` -The following libraries are also required, +The following libraries and tools are also required, ``` nasm>=2.15 OpenSSL>=1.1.0 @@ -53,12 +60,12 @@ OpenSSL>=1.1.0 For ```nasm```, please refer to the [Netwide Assembler](https://nasm.us/) for installation details. -On Ubuntu, ```OpenSSL``` can be installed by: +On Ubuntu, ```OpenSSL``` can be installed with: ```bash sudo apt update sudo apt install libssl-dev ``` -On RHEL, it needs to be built and installed from source as the static libraries are not installed with package managers. Please refer to [OpenSSL Project](https://github.com/openssl/openssl) for installation details for static libraries. +For RHEL, ```OpenSSL``` needs to be built and installed from source as the static libraries are missing when installed through the package managers. Please refer to [OpenSSL Project](https://github.com/openssl/openssl) for installation details for static libraries. ### Instructions The library can be built using the following commands: @@ -70,13 +77,13 @@ cmake --build build -j It is possible to pass additional options to enable more features. The following table contains the current CMake options, default values are in bold. -| CMake options | Values | Default | Comments | -|-------------------------|-----------|---------|------------------------------| -|`IPCL_TEST` | ON/OFF | ON | unit-test | -|`IPCL_TEST_OMP` | ON/OFF | ON | unit-test w/ OpenMP | -|`IPCL_BENCHMARK` | ON/OFF | ON | benchmark | -|`IPCL_DOCS` | ON/OFF | OFF | build doxygen documentation | -|`IPCL_SHARED` | ON/OFF | ON | build shared library | +| CMake options | Values | Default | Comments | +|-------------------------|-----------|---------|-------------------------------------| +|`IPCL_TEST` | ON/OFF | ON | unit-test | +|`IPCL_BENCHMARK` | ON/OFF | ON | benchmark | +|`IPCL_ENABLE_OMP` | ON/OFF | ON | enables OpenMP functionalities | +|`IPCL_DOCS` | ON/OFF | OFF | build doxygen documentation | +|`IPCL_SHARED` | ON/OFF | ON | build shared library | ## Testing and Benchmarking To run a set of unit tests via [Googletest](https://github.com/google/googletest), configure and build library with `-DIPCL_TEST=ON` (see [Instructions](#instructions)). @@ -84,23 +91,22 @@ Then, run ```bash cmake --build build --target unittest ``` -For OpenMP testing, configure and build with `-DIPCL_TEST_OMP=ON`, and run -```bash -cmake --build build --target unittest_omp -``` For running benchmark via [Google Benchmark](https://github.com/google/benchmark), configure and build library with `-DIPCL_BENCHMARK=ON` (see [Instructions](#instructions)). Then, run ```bash cmake --build build --target benchmark ``` -OpenMP benchmarks will automatically be applied if `-DIPCL_TEST_OMP=ON` is set. +Setting the CMake flag ```-DIPCL_ENABLE_OMP=ON``` during configuration will automatically enable OpenMP unit-tests and benchmarks. + +The executables are located at `${IPCL_DIR}/build/test/unittest_ipcl` and `${IPCL_DIR}/build/benchmark/bench_ipcl`. -The unit-test executable itself is located at `${IPCL_DIR}/build/test/unit-test`, `${IPCL_DIR}/build/test/unit-test_omp` and `${IPCL_DIR}/build/benchmark/bench_ipcl`. +# Python Extension +Alongside the Intel Paillier Cryptosystem Library, we provide a Python extension package utilizing this library as a backend. For installation and usage detail, refer to [Intel Paillier Cryptosystem Library - Python](https://github.com/intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.pailliercryptolib-python). # Standardization This library is in compliance with the homomorphic encryption standards [ISO/IEC 18033-6](https://www.iso.org/standard/67740.html). -The compliance test is included in the [unit-test](test/test_cryptography.cpp#L117-L258). +The compliance test is included in the [unit-test](test/test_cryptography.cpp#L112-L256). # Contributors Main contributors to this project, sorted by alphabetical order of last name are: diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 7fcd633..ae35824 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -18,6 +18,5 @@ target_link_libraries(bench_ipcl PRIVATE # enable OpenMP benchmarks if(IPCL_ENABLE_OMP) find_package(OpenMP REQUIRED) - add_compile_definitions(IPCL_BENCHMARK_OMP) target_link_libraries(bench_ipcl PRIVATE OpenMP::OpenMP_CXX) endif() diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index c59cae4..06f28e2 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -4,72 +4,57 @@ #include #include -#ifdef IPCL_BENCHMARK_OMP +#ifdef IPCL_USE_OMP #include -#endif +#endif // IPCL_USE_OMP #include "ipcl/paillier_keygen.hpp" static void BM_KeyGen(benchmark::State& state) { int64_t n_length = state.range(0); for (auto _ : state) { - keyPair key = generateKeypair(n_length, true); + ipcl::keyPair key = ipcl::generateKeypair(n_length, true); } } BENCHMARK(BM_KeyGen)->Unit(benchmark::kMicrosecond)->Args({1024})->Args({2048}); static void BM_Encrypt(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** pt = new BigNumber*[dsize]; - BigNumber** ct = new BigNumber*[dsize]; + std::vector> pt(dsize, + std::vector(8)); + std::vector> ct(dsize, + std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - pt[i] = new BigNumber[8]; - ct[i] = new BigNumber[8]; - pt[i][0] = BigNumber((unsigned int)i); + pt[i][0] = ipcl::BigNumber((unsigned int)i); } for (auto _ : state) { for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); } - - for (size_t i = 0; i < dsize; ++i) { - delete[] pt[i]; - delete[] ct[i]; - } - - delete[] pt; - delete[] ct; } BENCHMARK(BM_Encrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); static void BM_Encrypt_buff8(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** pt = new BigNumber*[dsize / 8]; - BigNumber** ct = new BigNumber*[dsize / 8]; + std::vector> pt(dsize / 8, + std::vector(8)); + std::vector> ct(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { - pt[i] = new BigNumber[8]; - ct[i] = new BigNumber[8]; for (size_t j = 0; j < 8; ++j) - pt[i][j] = BigNumber((unsigned int)(i * 8 + j)); + pt[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } for (auto _ : state) { for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); } - - for (size_t i = 0; i < dsize / 8; ++i) { - delete[] pt[i]; - delete[] ct[i]; - } - delete[] pt; - delete[] ct; } BENCHMARK(BM_Encrypt_buff8) @@ -79,16 +64,17 @@ BENCHMARK(BM_Encrypt_buff8) static void BM_Decrypt(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); + + std::vector> pt(dsize, + std::vector(8)); + std::vector> ct(dsize, + std::vector(8)); + std::vector> de_ct( + dsize, std::vector(8)); - BigNumber** pt = new BigNumber*[dsize]; - BigNumber** ct = new BigNumber*[dsize]; - BigNumber** de_ct = new BigNumber*[dsize]; for (size_t i = 0; i < dsize; ++i) { - pt[i] = new BigNumber[8]; - ct[i] = new BigNumber[8]; - de_ct[i] = new BigNumber[8]; - pt[i][0] = BigNumber((unsigned int)i); + pt[i][0] = ipcl::BigNumber((unsigned int)i); } for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -98,34 +84,24 @@ static void BM_Decrypt(benchmark::State& state) { key.priv_key->decrypt(de_ct[i], ct[i]); } } - - for (size_t i = 0; i < dsize; ++i) { - delete[] pt[i]; - delete[] ct[i]; - delete[] de_ct[i]; - } - - delete[] pt; - delete[] ct; - delete[] de_ct; } BENCHMARK(BM_Decrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); static void BM_Decrypt_buff8(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** pt = new BigNumber*[dsize / 8]; - BigNumber** ct = new BigNumber*[dsize / 8]; - BigNumber** de_ct = new BigNumber*[dsize / 8]; + std::vector> pt(dsize / 8, + std::vector(8)); + std::vector> ct(dsize / 8, + std::vector(8)); + std::vector> de_ct( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { - pt[i] = new BigNumber[8]; - ct[i] = new BigNumber[8]; - de_ct[i] = new BigNumber[8]; for (size_t j = 0; j < 8; ++j) - pt[i][j] = BigNumber((unsigned int)(i * 8 + j)); + pt[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -134,15 +110,6 @@ static void BM_Decrypt_buff8(benchmark::State& state) { for (size_t i = 0; i < dsize / 8; ++i) key.priv_key->decrypt(de_ct[i], ct[i]); } - - for (size_t i = 0; i < dsize / 8; ++i) { - delete[] pt[i]; - delete[] ct[i]; - delete[] de_ct[i]; - } - delete[] pt; - delete[] ct; - delete[] de_ct; } BENCHMARK(BM_Decrypt_buff8) @@ -150,32 +117,24 @@ BENCHMARK(BM_Decrypt_buff8) ->Args({16}) ->Args({64}); -#ifdef IPCL_BENCHMARK_OMP +#ifdef IPCL_USE_OMP static void BM_Encrypt_OMP(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** pt = new BigNumber*[dsize]; - BigNumber** ct = new BigNumber*[dsize]; + std::vector> pt(dsize, + std::vector(8)); + std::vector> ct(dsize, + std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - pt[i] = new BigNumber[8]; - ct[i] = new BigNumber[8]; - pt[i][0] = BigNumber((unsigned int)i); + pt[i][0] = ipcl::BigNumber((unsigned int)i); } for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); } - - for (size_t i = 0; i < dsize; ++i) { - delete[] pt[i]; - delete[] ct[i]; - } - - delete[] pt; - delete[] ct; } BENCHMARK(BM_Encrypt_OMP) ->Unit(benchmark::kMicrosecond) @@ -184,29 +143,22 @@ BENCHMARK(BM_Encrypt_OMP) static void BM_Encrypt_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** pt = new BigNumber*[dsize / 8]; - BigNumber** ct = new BigNumber*[dsize / 8]; + std::vector> pt(dsize / 8, + std::vector(8)); + std::vector> ct(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { - pt[i] = new BigNumber[8]; - ct[i] = new BigNumber[8]; for (size_t j = 0; j < 8; ++j) - pt[i][j] = BigNumber((unsigned int)(i * 8 + j)); + pt[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); } - - for (size_t i = 0; i < dsize / 8; ++i) { - delete[] pt[i]; - delete[] ct[i]; - } - delete[] pt; - delete[] ct; } BENCHMARK(BM_Encrypt_buff8_OMP) @@ -216,16 +168,16 @@ BENCHMARK(BM_Encrypt_buff8_OMP) static void BM_Decrypt_OMP(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); - - BigNumber** pt = new BigNumber*[dsize]; - BigNumber** ct = new BigNumber*[dsize]; - BigNumber** de_ct = new BigNumber*[dsize]; + ipcl::keyPair key = ipcl::generateKeypair(2048, true); + + std::vector> pt(dsize, + std::vector(8)); + std::vector> ct(dsize, + std::vector(8)); + std::vector> de_ct( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - pt[i] = new BigNumber[8]; - ct[i] = new BigNumber[8]; - de_ct[i] = new BigNumber[8]; - pt[i][0] = BigNumber((unsigned int)i); + pt[i][0] = ipcl::BigNumber((unsigned int)i); } for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -236,16 +188,6 @@ static void BM_Decrypt_OMP(benchmark::State& state) { key.priv_key->decrypt(de_ct[i], ct[i]); } } - - for (size_t i = 0; i < dsize; ++i) { - delete[] pt[i]; - delete[] ct[i]; - delete[] de_ct[i]; - } - - delete[] pt; - delete[] ct; - delete[] de_ct; } BENCHMARK(BM_Decrypt_OMP) @@ -255,18 +197,18 @@ BENCHMARK(BM_Decrypt_OMP) static void BM_Decrypt_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** pt = new BigNumber*[dsize / 8]; - BigNumber** ct = new BigNumber*[dsize / 8]; - BigNumber** de_ct = new BigNumber*[dsize / 8]; + std::vector> pt(dsize / 8, + std::vector(8)); + std::vector> ct(dsize / 8, + std::vector(8)); + std::vector> de_ct( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { - pt[i] = new BigNumber[8]; - ct[i] = new BigNumber[8]; - de_ct[i] = new BigNumber[8]; for (size_t j = 0; j < 8; ++j) - pt[i][j] = BigNumber((unsigned int)(i * 8 + j)); + pt[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -276,19 +218,10 @@ static void BM_Decrypt_buff8_OMP(benchmark::State& state) { for (size_t i = 0; i < dsize / 8; ++i) key.priv_key->decrypt(de_ct[i], ct[i]); } - - for (size_t i = 0; i < dsize / 8; ++i) { - delete[] pt[i]; - delete[] ct[i]; - delete[] de_ct[i]; - } - delete[] pt; - delete[] ct; - delete[] de_ct; } BENCHMARK(BM_Decrypt_buff8_OMP) ->Unit(benchmark::kMicrosecond) ->Args({16}) ->Args({64}); -#endif +#endif // IPCL_USE_OMP diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index 542ed0d..a9a43d2 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -4,9 +4,9 @@ #include #include -#ifdef IPCL_BENCHMARK_OMP +#ifdef IPCL_USE_OMP #include -#endif +#endif // IPCL_USE_OMP #include #include "ipcl/paillier_keygen.hpp" @@ -14,66 +14,53 @@ static void BM_Add_CTCT(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize]; - BigNumber** b = new BigNumber*[dsize]; - BigNumber** ct_a = new BigNumber*[dsize]; - BigNumber** ct_b = new BigNumber*[dsize]; + std::vector> a(dsize, + std::vector(8)); + std::vector> b(dsize, + std::vector(8)); + std::vector> ct_a( + dsize, std::vector(8)); + std::vector> ct_b( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i] = new BigNumber[8]; - a[i][0] = BigNumber((unsigned int)i); - ct_a[i] = new BigNumber[8]; + a[i][0] = ipcl::BigNumber((unsigned int)i); key.pub_key->encrypt(ct_a[i], a[i]); - b[i] = new BigNumber[8]; - b[i][0] = BigNumber((unsigned int)i); - ct_b[i] = new BigNumber[8]; + b[i][0] = ipcl::BigNumber((unsigned int)i); key.pub_key->encrypt(ct_b[i], b[i]); } for (auto _ : state) { for (size_t i = 0; i < dsize; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); - PaillierEncryptedNumber sum = pen_a + pen_b; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); + ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; } } - - for (size_t i = 0; i < dsize; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - delete[] ct_b[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; - delete[] ct_b; } BENCHMARK(BM_Add_CTCT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); static void BM_Add_CTCT_buff8(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize / 8]; - BigNumber** b = new BigNumber*[dsize / 8]; - BigNumber** ct_a = new BigNumber*[dsize / 8]; - BigNumber** ct_b = new BigNumber*[dsize / 8]; + std::vector> a(dsize / 8, + std::vector(8)); + std::vector> b(dsize / 8, + std::vector(8)); + std::vector> ct_a( + dsize / 8, std::vector(8)); + std::vector> ct_b( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { - a[i] = new BigNumber[8]; - ct_a[i] = new BigNumber[8]; - - b[i] = new BigNumber[8]; - ct_b[i] = new BigNumber[8]; for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -82,23 +69,11 @@ static void BM_Add_CTCT_buff8(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize / 8; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); - PaillierEncryptedNumber sum = pen_a + pen_b; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); + ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; } } - - for (size_t i = 0; i < dsize / 8; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - delete[] ct_b[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; - delete[] ct_b; } BENCHMARK(BM_Add_CTCT_buff8) @@ -108,57 +83,46 @@ BENCHMARK(BM_Add_CTCT_buff8) static void BM_Add_CTPT(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize]; - BigNumber** ct_a = new BigNumber*[dsize]; - BigNumber** b = new BigNumber*[dsize]; + std::vector> a(dsize, + std::vector(8)); + std::vector> b(dsize, + std::vector(8)); + std::vector> ct_a( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i] = new BigNumber[8]; - a[i][0] = BigNumber((unsigned int)i); - ct_a[i] = new BigNumber[8]; - b[i] = new BigNumber[8]; - b[i][0] = BigNumber((unsigned int)i); + a[i][0] = ipcl::BigNumber((unsigned int)i); + b[i][0] = ipcl::BigNumber((unsigned int)i); key.pub_key->encrypt(ct_a[i], a[i]); } for (auto _ : state) { for (size_t i = 0; i < dsize; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber sum = pen_a + b[i]; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; } } - - for (size_t i = 0; i < dsize; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; } BENCHMARK(BM_Add_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); static void BM_Add_CTPT_buff8(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize / 8]; - BigNumber** b = new BigNumber*[dsize / 8]; - BigNumber** ct_a = new BigNumber*[dsize / 8]; + std::vector> a(dsize / 8, + std::vector(8)); + std::vector> b(dsize / 8, + std::vector(8)); + std::vector> ct_a( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { - a[i] = new BigNumber[8]; - ct_a[i] = new BigNumber[8]; - - b[i] = new BigNumber[8]; for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -166,20 +130,10 @@ static void BM_Add_CTPT_buff8(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize / 8; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber sum = pen_a + b[i]; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; } } - - for (size_t i = 0; i < dsize / 8; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; } BENCHMARK(BM_Add_CTPT_buff8) @@ -189,58 +143,47 @@ BENCHMARK(BM_Add_CTPT_buff8) static void BM_Mul_CTPT(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize]; - BigNumber** ct_a = new BigNumber*[dsize]; - BigNumber** b = new BigNumber*[dsize]; + std::vector> a(dsize, + std::vector(8)); + std::vector> b(dsize, + std::vector(8)); + std::vector> ct_a( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i] = new BigNumber[8]; - a[i][0] = BigNumber((unsigned int)i); - ct_a[i] = new BigNumber[8]; - b[i] = new BigNumber[8]; - b[i][0] = BigNumber((unsigned int)i); + a[i][0] = ipcl::BigNumber((unsigned int)i); + b[i][0] = ipcl::BigNumber((unsigned int)i); key.pub_key->encrypt(ct_a[i], a[i]); } for (auto _ : state) { for (size_t i = 0; i < dsize; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber pen_b(key.pub_key, b[i]); - PaillierEncryptedNumber sum = pen_a * pen_b; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber pen_b(key.pub_key, b[i]); + ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; } } - - for (size_t i = 0; i < dsize; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; } BENCHMARK(BM_Mul_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); static void BM_Mul_CTPT_buff8(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize / 8]; - BigNumber** b = new BigNumber*[dsize / 8]; - BigNumber** ct_a = new BigNumber*[dsize / 8]; + std::vector> a(dsize / 8, + std::vector(8)); + std::vector> b(dsize / 8, + std::vector(8)); + std::vector> ct_a( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { - a[i] = new BigNumber[8]; - ct_a[i] = new BigNumber[8]; - - b[i] = new BigNumber[8]; for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -248,21 +191,11 @@ static void BM_Mul_CTPT_buff8(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize / 8; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber pen_b(key.pub_key, b[i]); - PaillierEncryptedNumber sum = pen_a * pen_b; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber pen_b(key.pub_key, b[i]); + ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; } } - - for (size_t i = 0; i < dsize / 8; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; } BENCHMARK(BM_Mul_CTPT_buff8) @@ -270,48 +203,36 @@ BENCHMARK(BM_Mul_CTPT_buff8) ->Args({16}) ->Args({64}); -#ifdef IPCL_BENCHMARK_OMP +#ifdef IPCL_USE_OMP static void BM_Add_CTCT_OMP(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize]; - BigNumber** b = new BigNumber*[dsize]; - BigNumber** ct_a = new BigNumber*[dsize]; - BigNumber** ct_b = new BigNumber*[dsize]; + std::vector> a(dsize, + std::vector(8)); + std::vector> b(dsize, + std::vector(8)); + std::vector> ct_a( + dsize, std::vector(8)); + std::vector> ct_b( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i] = new BigNumber[8]; - a[i][0] = BigNumber((unsigned int)i); - ct_a[i] = new BigNumber[8]; + a[i][0] = ipcl::BigNumber((unsigned int)i); key.pub_key->encrypt(ct_a[i], a[i]); - b[i] = new BigNumber[8]; - b[i][0] = BigNumber((unsigned int)i); - ct_b[i] = new BigNumber[8]; + b[i][0] = ipcl::BigNumber((unsigned int)i); key.pub_key->encrypt(ct_b[i], b[i]); } for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); - PaillierEncryptedNumber sum = pen_a + pen_b; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); + ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; } } - - for (size_t i = 0; i < dsize; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - delete[] ct_b[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; - delete[] ct_b; } BENCHMARK(BM_Add_CTCT_OMP) @@ -321,22 +242,21 @@ BENCHMARK(BM_Add_CTCT_OMP) static void BM_Add_CTCT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize / 8]; - BigNumber** b = new BigNumber*[dsize / 8]; - BigNumber** ct_a = new BigNumber*[dsize / 8]; - BigNumber** ct_b = new BigNumber*[dsize / 8]; + std::vector> a(dsize / 8, + std::vector(8)); + std::vector> b(dsize / 8, + std::vector(8)); + std::vector> ct_a( + dsize / 8, std::vector(8)); + std::vector> ct_b( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { - a[i] = new BigNumber[8]; - ct_a[i] = new BigNumber[8]; - - b[i] = new BigNumber[8]; - ct_b[i] = new BigNumber[8]; for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -346,23 +266,11 @@ static void BM_Add_CTCT_buff8_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize / 8; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); - PaillierEncryptedNumber sum = pen_a + pen_b; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); + ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; } } - - for (size_t i = 0; i < dsize / 8; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - delete[] ct_b[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; - delete[] ct_b; } BENCHMARK(BM_Add_CTCT_buff8_OMP) @@ -372,38 +280,28 @@ BENCHMARK(BM_Add_CTCT_buff8_OMP) static void BM_Add_CTPT_OMP(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize]; - BigNumber** ct_a = new BigNumber*[dsize]; - BigNumber** b = new BigNumber*[dsize]; + std::vector> a(dsize, + std::vector(8)); + std::vector> b(dsize, + std::vector(8)); + std::vector> ct_a( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i] = new BigNumber[8]; - a[i][0] = BigNumber((unsigned int)i); - ct_a[i] = new BigNumber[8]; - b[i] = new BigNumber[8]; - b[i][0] = BigNumber((unsigned int)i); + a[i][0] = ipcl::BigNumber((unsigned int)i); + b[i][0] = ipcl::BigNumber((unsigned int)i); key.pub_key->encrypt(ct_a[i], a[i]); } for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber sum = pen_a + b[i]; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; } } - - for (size_t i = 0; i < dsize; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; } BENCHMARK(BM_Add_CTPT_OMP) @@ -413,20 +311,19 @@ BENCHMARK(BM_Add_CTPT_OMP) static void BM_Add_CTPT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize / 8]; - BigNumber** b = new BigNumber*[dsize / 8]; - BigNumber** ct_a = new BigNumber*[dsize / 8]; + std::vector> a(dsize / 8, + std::vector(8)); + std::vector> b(dsize / 8, + std::vector(8)); + std::vector> ct_a( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { - a[i] = new BigNumber[8]; - ct_a[i] = new BigNumber[8]; - - b[i] = new BigNumber[8]; for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -435,20 +332,10 @@ static void BM_Add_CTPT_buff8_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize / 8; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber sum = pen_a + b[i]; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; } } - - for (size_t i = 0; i < dsize / 8; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; } BENCHMARK(BM_Add_CTPT_buff8_OMP) @@ -458,39 +345,29 @@ BENCHMARK(BM_Add_CTPT_buff8_OMP) static void BM_Mul_CTPT_OMP(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize]; - BigNumber** ct_a = new BigNumber*[dsize]; - BigNumber** b = new BigNumber*[dsize]; + std::vector> a(dsize, + std::vector(8)); + std::vector> b(dsize, + std::vector(8)); + std::vector> ct_a( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i] = new BigNumber[8]; - a[i][0] = BigNumber((unsigned int)i); - ct_a[i] = new BigNumber[8]; - b[i] = new BigNumber[8]; - b[i][0] = BigNumber((unsigned int)i); + a[i][0] = ipcl::BigNumber((unsigned int)i); + b[i][0] = ipcl::BigNumber((unsigned int)i); key.pub_key->encrypt(ct_a[i], a[i]); } for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber pen_b(key.pub_key, b[i]); - PaillierEncryptedNumber sum = pen_a * pen_b; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber pen_b(key.pub_key, b[i]); + ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; } } - - for (size_t i = 0; i < dsize; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; } BENCHMARK(BM_Mul_CTPT_OMP) @@ -500,20 +377,19 @@ BENCHMARK(BM_Mul_CTPT_OMP) static void BM_Mul_CTPT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber** a = new BigNumber*[dsize / 8]; - BigNumber** b = new BigNumber*[dsize / 8]; - BigNumber** ct_a = new BigNumber*[dsize / 8]; + std::vector> a(dsize / 8, + std::vector(8)); + std::vector> b(dsize / 8, + std::vector(8)); + std::vector> ct_a( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { - a[i] = new BigNumber[8]; - ct_a[i] = new BigNumber[8]; - - b[i] = new BigNumber[8]; for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -522,25 +398,15 @@ static void BM_Mul_CTPT_buff8_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize / 8; ++i) { - PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - PaillierEncryptedNumber pen_b(key.pub_key, b[i]); - PaillierEncryptedNumber sum = pen_a * pen_b; + ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::PaillierEncryptedNumber pen_b(key.pub_key, b[i]); + ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; } } - - for (size_t i = 0; i < dsize / 8; ++i) { - delete[] a[i]; - delete[] b[i]; - delete[] ct_a[i]; - } - - delete[] a; - delete[] ct_a; - delete[] b; } BENCHMARK(BM_Mul_CTPT_buff8_OMP) ->Unit(benchmark::kMicrosecond) ->Args({16}) ->Args({64}); -#endif +#endif // IPCL_USE_OMP diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 540cde2..4ad679f 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -6,6 +6,7 @@ set(IPCL_SRCS paillier_prikey.cpp paillier_ops.cpp paillier_keygen.cpp bignum.cpp + mod_exp.cpp ) @@ -53,6 +54,15 @@ else() target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) endif() +# check whether cpu support avx512 flag +set(CPU_AVX512_FLAG "avx512ifma") +execute_process(COMMAND lscpu COMMAND grep ${CPU_AVX512_FLAG} OUTPUT_VARIABLE CPU_ENABLE_AVX512) +if("${CPU_ENABLE_AVX512}" STREQUAL "") + message(STATUS "Support AVX512IFMA: False") +else() + message(STATUS "Support AVX512IFMA: True") + add_compile_definitions(IPCL_CRYPTO_MB_MOD_EXP) +endif() set_target_properties(ipcl PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(ipcl PROPERTIES VERSION ${IPCL_VERSION}) diff --git a/ipcl/bignum.cpp b/ipcl/bignum.cpp index 537ca1d..b0b578e 100644 --- a/ipcl/bignum.cpp +++ b/ipcl/bignum.cpp @@ -25,6 +25,8 @@ // ////////////////////////////////////////////////////////////////////// +namespace ipcl { + BigNumber::~BigNumber() { delete[](Ipp8u*) m_pBN; } bool BigNumber::create(const Ipp32u* pData, int length, IppsBigNumSGN sgn) { @@ -498,3 +500,16 @@ std::ostream& operator<<(std::ostream& os, const BigNumber& a) { os << s; return os; } + +void BigNumber::num2char(std::vector& dest) const { + int bnBitLen; + unsigned char* bnData; + ippsRef_BN(nullptr, &bnBitLen, reinterpret_cast(&bnData), *this); + int len = (bnBitLen + 7) >> 3; + dest.assign(bnData, bnData + len); +} + +int BITSIZE_WORD(int n) { return (((n) + 31) >> 5); } +int BITSIZE_DWORD(int n) { return (((n) + 63) >> 6); } + +} // namespace ipcl diff --git a/ipcl/include/ipcl/bignum.h b/ipcl/include/ipcl/bignum.h index 8645bef..c150f5a 100644 --- a/ipcl/include/ipcl/bignum.h +++ b/ipcl/include/ipcl/bignum.h @@ -22,6 +22,8 @@ #include #include +namespace ipcl { + class BigNumber { public: BigNumber(Ipp32u value = 0); @@ -118,6 +120,7 @@ class BigNumber { void num2hex(std::string& s) const; // convert to hex string void num2vec(std::vector& v) const; // convert to 32-bit word vector friend std::ostream& operator<<(std::ostream& os, const BigNumber& a); + void num2char(std::vector& dest) const; protected: bool create(const Ipp32u* pData, int length, @@ -125,10 +128,8 @@ class BigNumber { IppsBigNumState* m_pBN; }; -// convert bit size into 32-bit words -#define BITSIZE_WORD(n) ((((n) + 31) >> 5)) - -// Bin: convert bit size into 64-bit words -#define BITSIZE_DWORD(n) ((((n) + 63) >> 6)) +int BITSIZE_WORD(int n); +int BITSIZE_DWORD(int n); +} // namespace ipcl #endif // _BIGNUM_H_ diff --git a/ipcl/include/ipcl/common.hpp b/ipcl/include/ipcl/common.hpp new file mode 100644 index 0000000..fecc02d --- /dev/null +++ b/ipcl/include/ipcl/common.hpp @@ -0,0 +1,12 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IPCL_INCLUDE_IPCL_COMMON_HPP_ +#define IPCL_INCLUDE_IPCL_COMMON_HPP_ + +namespace ipcl { + +#define IPCL_CRYPTO_MB_SIZE 8 + +} // namespace ipcl +#endif // IPCL_INCLUDE_IPCL_COMMON_HPP_ diff --git a/ipcl/include/ipcl/mod_exp.hpp b/ipcl/include/ipcl/mod_exp.hpp new file mode 100644 index 0000000..e3b3ac4 --- /dev/null +++ b/ipcl/include/ipcl/mod_exp.hpp @@ -0,0 +1,35 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IPCL_INCLUDE_IPCL_MOD_EXP_HPP_ +#define IPCL_INCLUDE_IPCL_MOD_EXP_HPP_ + +#include + +#include "ipcl/bignum.h" +#include "ipcl/util.hpp" + +namespace ipcl { +/** + * Modular exponentiation for multi buffer + * @param[in] base base of the exponentiation + * @param[in] pow pow of the exponentiation + * @param[in] m modular + * @return the modular exponentiation result of type BigNumber + */ +std::vector ippModExp(const std::vector& base, + const std::vector& pow, + const std::vector& m); + +/** + * Modular exponentiation for single buffer + * @param[in] base base of the exponentiation + * @param[in] pow pow of the exponentiation + * @param[in] m modular + * @return the modular exponentiation result of type BigNumber + */ +BigNumber ippModExp(const BigNumber& base, const BigNumber& pow, + const BigNumber& m); + +} // namespace ipcl +#endif // IPCL_INCLUDE_IPCL_MOD_EXP_HPP_ diff --git a/ipcl/include/ipcl/paillier_keygen.hpp b/ipcl/include/ipcl/paillier_keygen.hpp index 8a70c5b..98f154c 100644 --- a/ipcl/include/ipcl/paillier_keygen.hpp +++ b/ipcl/include/ipcl/paillier_keygen.hpp @@ -7,6 +7,8 @@ #include "ipcl/paillier_prikey.hpp" #include "ipcl/paillier_pubkey.hpp" +namespace ipcl { + /** * Paillier key structure contains a public key and private key * pub_key: paillier public key @@ -20,6 +22,7 @@ struct keyPair { /** * Generate prime number * @param[in] maxBitSize Maximum bit length of to be generated prime number + * @return The function return a prime big number */ BigNumber getPrimeBN(int maxBitSize); @@ -27,7 +30,9 @@ BigNumber getPrimeBN(int maxBitSize); * Generate a public/private key pair * @param[in] n_length Bit length of key size * @param[in] enable_DJN Enable DJN (default=true) + * @return The function return the public and private key pair */ keyPair generateKeypair(int64_t n_length, bool enable_DJN = true); +} // namespace ipcl #endif // IPCL_INCLUDE_IPCL_PAILLIER_KEYGEN_HPP_ diff --git a/ipcl/include/ipcl/paillier_ops.hpp b/ipcl/include/ipcl/paillier_ops.hpp index b2971e4..3679b59 100644 --- a/ipcl/include/ipcl/paillier_ops.hpp +++ b/ipcl/include/ipcl/paillier_ops.hpp @@ -4,9 +4,12 @@ #ifndef IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ #define IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ -#include +#include #include "ipcl/paillier_pubkey.hpp" +#include "ipcl/util.hpp" + +namespace ipcl { class PaillierEncryptedNumber { public: @@ -15,24 +18,26 @@ class PaillierEncryptedNumber { * @param[in] pub_key paillier public key * @param[in] bn ciphertext encrypted by paillier public key */ - PaillierEncryptedNumber(PaillierPublicKey* pub_key, const BigNumber& bn); + PaillierEncryptedNumber(const PaillierPublicKey* pub_key, + const BigNumber& bn); /** * PaillierEncryptedNumber constructor * @param[in] pub_key paillier public key * @param[in] bn array of ciphertexts encrypted by paillier public key - * @param[in] length size of array + * @param[in] length size of array(default value is 8) */ - PaillierEncryptedNumber(PaillierPublicKey* pub_key, const BigNumber bn[8], - size_t length = 8); + PaillierEncryptedNumber(const PaillierPublicKey* pub_key, + const std::vector& bn, size_t length = 8); /** * PaillierEncryptedNumber constructor * @param[in] pub_key paillier public key * @param[in] scalar array of integer scalars - * @param[in] length size of array + * @param[in] length size of array(default value is 8) */ - PaillierEncryptedNumber(PaillierPublicKey* pub_key, const uint32_t scalar[8], + PaillierEncryptedNumber(const PaillierPublicKey* pub_key, + const std::vector& scalar, size_t length = 8); /** @@ -51,7 +56,7 @@ class PaillierEncryptedNumber { * Arithmetic addition operator * @param[in] other array of augend */ - PaillierEncryptedNumber operator+(const BigNumber other[8]) const; + PaillierEncryptedNumber operator+(const std::vector& other) const; /** * Arithmetic multiply operator @@ -71,7 +76,7 @@ class PaillierEncryptedNumber { */ void apply_obfuscator() { b_isObfuscator = true; - BigNumber obfuscator[8]; + std::vector obfuscator(8); m_pubkey->apply_obfuscator(obfuscator); BigNumber sq = m_pubkey->getNSQ(); @@ -82,10 +87,11 @@ class PaillierEncryptedNumber { /** * Return ciphertext * @param[in] idx index of ciphertext stored in PaillierEncryptedNumber + * @param[in] idx index of output array(default value is 0) */ BigNumber getBN(size_t idx = 0) const { - if (m_available == 1 && idx > 0) - throw std::out_of_range("PaillierEncryptedNumber only has 1 BigNumber"); + ERROR_CHECK(m_available != 1 || idx <= 0, + "getBN: PaillierEncryptedNumber only has 1 BigNumber"); return m_bn[idx]; } @@ -99,13 +105,13 @@ class PaillierEncryptedNumber { * Rotate PaillierEncryptedNumber * @param[in] shift rotate length */ - PaillierEncryptedNumber rotate(int shift); + PaillierEncryptedNumber rotate(int shift) const; /** * Return entire ciphertext array * @param[out] bn output array */ - void getArrayBN(BigNumber bn[8]) const { std::copy_n(m_bn, 8, bn); } + std::vector getArrayBN() const { return m_bn; } /** * Check if element in PaillierEncryptedNumber is single @@ -122,13 +128,15 @@ class PaillierEncryptedNumber { private: bool b_isObfuscator; int m_available; - PaillierPublicKey* m_pubkey; + const PaillierPublicKey* m_pubkey; size_t m_length; - BigNumber m_bn[8]; + std::vector m_bn; - BigNumber raw_add(const BigNumber& a, const BigNumber& b); - BigNumber raw_mul(const BigNumber& a, const BigNumber& b); - void raw_mul(BigNumber res[8], BigNumber a[8], BigNumber b[8]); + BigNumber raw_add(const BigNumber& a, const BigNumber& b) const; + BigNumber raw_mul(const BigNumber& a, const BigNumber& b) const; + std::vector raw_mul(const std::vector& a, + const std::vector& b) const; }; +} // namespace ipcl #endif // IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ diff --git a/ipcl/include/ipcl/paillier_prikey.hpp b/ipcl/include/ipcl/paillier_prikey.hpp index 44c6021..5ecfc3d 100644 --- a/ipcl/include/ipcl/paillier_prikey.hpp +++ b/ipcl/include/ipcl/paillier_prikey.hpp @@ -4,8 +4,12 @@ #ifndef IPCL_INCLUDE_IPCL_PAILLIER_PRIKEY_HPP_ #define IPCL_INCLUDE_IPCL_PAILLIER_PRIKEY_HPP_ +#include + #include "ipcl/paillier_ops.hpp" +namespace ipcl { + class PaillierPrivateKey { public: /** @@ -14,7 +18,7 @@ class PaillierPrivateKey { * @param[in] p p of private key in paillier scheme * @param[in] q q of private key in paillier scheme */ - PaillierPrivateKey(PaillierPublicKey* public_key, const BigNumber& p, + PaillierPrivateKey(const PaillierPublicKey* public_key, const BigNumber& p, const BigNumber& q); /** @@ -28,15 +32,16 @@ class PaillierPrivateKey { * @param[out] plaintext output of the decryption * @param[in] ciphertext ciphertext to be decrypted */ - void decrypt(BigNumber plaintext[8], const BigNumber ciphertext[8]); + void decrypt(std::vector& plaintext, + const std::vector& ciphertext) const; /** * Decrypt ciphertext * @param[out] plaintext output of the decryption * @param[in] ciphertext PaillierEncryptedNumber to be decrypted */ - void decrypt(BigNumber plaintext[8], - const PaillierEncryptedNumber ciphertext); + void decrypt(std::vector& plaintext, + const PaillierEncryptedNumber ciphertext) const; const void* addr = static_cast(this); @@ -63,17 +68,17 @@ class PaillierPrivateKey { /** * Get public key */ - PaillierPublicKey* getPubKey() const { return m_pubkey; } + const PaillierPublicKey* getPubKey() const { return m_pubkey; } /** * @brief Support function for ISO/IEC 18033-6 compliance check * * @return BigNumber */ - BigNumber getLambda() { return m_lambda; } + BigNumber getLambda() const { return m_lambda; } private: - PaillierPublicKey* m_pubkey; + const PaillierPublicKey* m_pubkey; BigNumber m_n; BigNumber m_nsquare; BigNumber m_g; @@ -96,36 +101,42 @@ class PaillierPrivateKey { * Compute L function in paillier scheme * @param[in] a input a * @param[in] b input b + * @return the L function result of type BigNumber */ - BigNumber computeLfun(const BigNumber& a, const BigNumber& b); + BigNumber computeLfun(const BigNumber& a, const BigNumber& b) const; /** * Compute H function in paillier scheme * @param[in] a input a * @param[in] b input b + * @return the H function result of type BigNumber */ - BigNumber computeHfun(const BigNumber& a, const BigNumber& b); + BigNumber computeHfun(const BigNumber& a, const BigNumber& b) const; /** * Compute CRT function in paillier scheme * @param[in] mp input mp * @param[in] mq input mq + * @return the CRT result of type BigNumber */ - BigNumber computeCRT(const BigNumber& mp, const BigNumber& mq); + BigNumber computeCRT(const BigNumber& mp, const BigNumber& mq) const; /** * Raw decryption function without CRT optimization * @param[out] plaintext output plaintext * @param[in] ciphertext input ciphertext */ - void decryptRAW(BigNumber plaintext[8], const BigNumber ciphertext[8]); + void decryptRAW(std::vector& plaintext, + const std::vector& ciphertext) const; /** * Raw decryption function with CRT optimization * @param[out] plaintext output plaintext * @param[in] ciphertext input ciphertext */ - void decryptCRT(BigNumber plaintext[8], const BigNumber ciphertext[8]); + void decryptCRT(std::vector& plaintext, + const std::vector& ciphertext) const; }; +} // namespace ipcl #endif // IPCL_INCLUDE_IPCL_PAILLIER_PRIKEY_HPP_ diff --git a/ipcl/include/ipcl/paillier_pubkey.hpp b/ipcl/include/ipcl/paillier_pubkey.hpp index f8ca988..ef0301b 100644 --- a/ipcl/include/ipcl/paillier_pubkey.hpp +++ b/ipcl/include/ipcl/paillier_pubkey.hpp @@ -4,15 +4,19 @@ #ifndef IPCL_INCLUDE_IPCL_PAILLIER_PUBKEY_HPP_ #define IPCL_INCLUDE_IPCL_PAILLIER_PUBKEY_HPP_ +#include + #include "ipcl/bignum.h" +namespace ipcl { + class PaillierPublicKey { public: /** * PaillierPublicKey constructor * @param[in] n n of public key in paillier scheme - * @param[in] bits bit length of public key - * @param[in] enableDJN_ enables DJN scheme + * @param[in] bits bit length of public key(default value is 1024) + * @param[in] enableDJN_ enables DJN scheme(default value is false) */ explicit PaillierPublicKey(const BigNumber& n, int bits = 1024, bool enableDJN_ = false); @@ -20,8 +24,8 @@ class PaillierPublicKey { /** * PaillierPublicKey constructor * @param[in] n n of public key in paillier scheme - * @param[in] bits bit length of public key - * @param[in] enableDJN_ enables DJN scheme + * @param[in] bits bit length of public key(default value is 1024) + * @param[in] enableDJN_ enables DJN scheme(default value is false) */ explicit PaillierPublicKey(const Ipp32u n, int bits = 1024, bool enableDJN_ = false) @@ -36,43 +40,29 @@ class PaillierPublicKey { * Encrypt plaintext * @param[out] ciphertext output of the encryption * @param[in] value array of plaintext to be encrypted - * @param[in] make_secure apply obfuscator + * @param[in] make_secure apply obfuscator(default value is true) */ - void encrypt(BigNumber ciphertext[8], const BigNumber value[8], - bool make_secure = true); + void encrypt(std::vector& ciphertext, + const std::vector& value, + bool make_secure = true) const; /** * Encrypt plaintext * @param[out] ciphertext output of the encryption * @param[in] value plaintext to be encrypted */ - void encrypt(BigNumber& ciphertext, const BigNumber& value); + void encrypt(BigNumber& ciphertext, const BigNumber& value) const; /** * Modular exponentiation * @param[in] base base of the exponentiation * @param[in] pow pow of the exponentiation * @param[in] m modular + * @return the modular exponentiation result of type BigNumber */ - BigNumber ippMontExp(const BigNumber& base, const BigNumber& pow, - const BigNumber& m); - - /** - * Multi-buffered modular exponentiation - * @param[out] res array result of the modular exponentiation - * @param[in] base array base of the exponentiation - * @param[in] pow arrya pow of the exponentiation - * @param[in] m arrayodular - */ - void ippMultiBuffExp(BigNumber res[8], BigNumber base[8], - const BigNumber pow[8], BigNumber m[8]); - - /** - * Invert function needed by encoder(float to integer) - * @param[in] a input of a - * @param[in] b input of b - */ - BigNumber IPP_invert(BigNumber a, BigNumber b); + std::vector ippModExp(const std::vector& base, + const std::vector& pow, + const std::vector& m) const; /** * Get N of public key in paillier scheme @@ -103,17 +93,14 @@ class PaillierPublicKey { * Apply obfuscator for ciphertext * @param[out] obfuscator output of obfuscator with random value */ - void apply_obfuscator(BigNumber obfuscator[8]); + void apply_obfuscator(std::vector& obfuscator) const; /** * @brief Set the Random object for ISO/IEC 18033-6 compliance check * * @param r */ - void setRandom(BigNumber r[8]) { - for (int i = 0; i < 8; i++) m_r[i] = r[i]; - m_testv = true; - } + void setRandom(const std::vector& r); const void* addr = static_cast(this); @@ -127,30 +114,42 @@ class PaillierPublicKey { int m_dwords; unsigned int m_init_seed; bool m_enable_DJN; - BigNumber m_r[8]; + std::vector m_r; bool m_testv; /** * Get random value - * @param[in] addr addr of random * @param[in] size size of random + * @return addr of random of type Ipp32u vector */ - Ipp32u* randIpp32u(Ipp32u* addr, int size); + std::vector randIpp32u(int size) const; /** * Raw encrypt function * @param[out] ciphertext array output of the encryption * @param[in] plaintext plaintext array to be encrypted - * @param[in] make_secure apply obfuscator - */ - void raw_encrypt(BigNumber ciphertext[8], const BigNumber plaintext[8], - bool make_secure = true); - + * @param[in] make_secure apply obfuscator(default value is true) + */ + void raw_encrypt(std::vector& ciphertext, + const std::vector& plaintext, + bool make_secure = true) const; + // /** + // * Raw Multi-buffered modular exponentiation + // * @param[in] base array base of the exponentiation + // * @param[in] pow arrya pow of the exponentiation + // * @param[in] m arrayodular + // * @return result of the modular exponentiation of type BigNumber vector + // */ + // std::vector raw_ippMultiBuffExp( + // const std::vector& base, const std::vector& + // pow, const std::vector& m) const; /** * Get random value * @param[in] length bit length + * @return the random value of type BigNumber */ - BigNumber getRandom(int length); + BigNumber getRandom(int length) const; }; +} // namespace ipcl #endif // IPCL_INCLUDE_IPCL_PAILLIER_PUBKEY_HPP_ diff --git a/ipcl/include/ipcl/util.hpp b/ipcl/include/ipcl/util.hpp new file mode 100644 index 0000000..b56cf50 --- /dev/null +++ b/ipcl/include/ipcl/util.hpp @@ -0,0 +1,42 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IPCL_INCLUDE_IPCL_UTIL_HPP_ +#define IPCL_INCLUDE_IPCL_UTIL_HPP_ + +#include +#include +#include + +#include "ipcl/common.hpp" + +namespace ipcl { + +static inline std::string build_log(const char* file, int line, + std::string msg) { + std::string log; + log = "\nFile: " + std::string(file); + log += "\nLine: " + std::to_string(line); + log += "\nError: " + msg; + + return log; +} + +#define ERROR_CHECK(e, ...) \ + do { \ + if (!(e)) \ + throw std::runtime_error(build_log(__FILE__, __LINE__, __VA_ARGS__)); \ + } while (0) + +template +inline void vec_size_check(const std::vector& v, const char* file, + int line) { + if (v.size() != IPCL_CRYPTO_MB_SIZE) + throw std::runtime_error(build_log( + file, line, "Vector size is NOT equal to IPCL_CRYPTO_MB_SIZE")); +} + +#define VEC_SIZE_CHECK(v) vec_size_check(v, __FILE__, __LINE__) + +} // namespace ipcl +#endif // IPCL_INCLUDE_IPCL_UTIL_HPP_ diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp new file mode 100644 index 0000000..6cd11b9 --- /dev/null +++ b/ipcl/mod_exp.cpp @@ -0,0 +1,168 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/mod_exp.hpp" + +#include + +#include + +namespace ipcl { + +static std::vector ippMBModExp(const std::vector& base, + const std::vector& pow, + const std::vector& m) { + VEC_SIZE_CHECK(base); + VEC_SIZE_CHECK(pow); + VEC_SIZE_CHECK(m); + + mbx_status st = MBX_STATUS_OK; + + int bits = m[0].BitSize(); + int dwords = BITSIZE_DWORD(bits); + int bufferLen = mbx_exp_BufferSize(bits); + auto pBuffer = std::vector(bufferLen); + + std::vector out_x(8), b_array(8), p_array(8); + int length = dwords * sizeof(int64u); + + for (int i = 0; i < 8; i++) { + out_x[i] = reinterpret_cast(alloca(length)); + b_array[i] = reinterpret_cast(alloca(length)); + p_array[i] = reinterpret_cast(alloca(length)); + + ERROR_CHECK( + out_x[i] != nullptr && b_array[i] != nullptr && p_array[i] != nullptr, + "ippMultiBuffExp: alloc memory for error"); + + memset(out_x[i], 0, length); + memset(b_array[i], 0, length); + memset(p_array[i], 0, length); + } + + /* + * These two intermediate variables pow_b & pow_p are necessary + * because if they are not used, the length returned from ippsRef_BN + * will be inconsistent with the length allocated by b_array/p_array, + * resulting in data errors. + */ + std::vector pow_b(8), pow_p(8), pow_nsquare(8); + int bBitLen, pBitLen, nsqBitLen; + int expBitLen = 0; + + for (int i = 0; i < 8; i++) { + ippsRef_BN(nullptr, &bBitLen, reinterpret_cast(&pow_b[i]), + base[i]); + ippsRef_BN(nullptr, &pBitLen, reinterpret_cast(&pow_p[i]), + pow[i]); + ippsRef_BN(nullptr, &nsqBitLen, &pow_nsquare[i], m[i]); + + memcpy(b_array[i], pow_b[i], BITSIZE_WORD(bBitLen) * 4); + memcpy(p_array[i], pow_p[i], BITSIZE_WORD(pBitLen) * 4); + + if (expBitLen < pBitLen) expBitLen = pBitLen; + } + + /* + *Note: If actual sizes of exp are different, set the exp_bits parameter equal + *to maximum size of the actual module in bit size and extend all the modules + *with zero bits + */ + st = mbx_exp_mb8(out_x.data(), b_array.data(), p_array.data(), expBitLen, + reinterpret_cast(pow_nsquare.data()), nsqBitLen, + reinterpret_cast(pBuffer.data()), bufferLen); + + for (int i = 0; i < 8; i++) { + ERROR_CHECK(MBX_STATUS_OK == MBX_GET_STS(st, i), + std::string("ippMultiBuffExp: error multi buffered exp " + "modules, error code = ") + + std::to_string(MBX_GET_STS(st, i))); + } + + // It is important to hold a copy of nsquare for thread-safe purpose + BigNumber bn_c(m[0]); + + std::vector res(8, 0); + for (int i = 0; i < 8; i++) { + bn_c.Set(reinterpret_cast(out_x[i]), BITSIZE_WORD(nsqBitLen), + IppsBigNumPOS); + res[i] = bn_c; + } + return res; +} + +static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, + const BigNumber& m) { + IppStatus stat = ippStsNoErr; + // It is important to declear res * bform bit length refer to ipp-crypto spec: + // R should not be less than the data length of the modulus m + BigNumber res(m); + + int bnBitLen; + Ipp32u* pow_m; + ippsRef_BN(nullptr, &bnBitLen, &pow_m, BN(m)); + int nlen = BITSIZE_WORD(bnBitLen); + + int size; + // define and initialize Montgomery Engine over Modulus N + stat = ippsMontGetSize(IppsBinaryMethod, nlen, &size); + ERROR_CHECK(stat == ippStsNoErr, + "ippMontExp: get the size of IppsMontState context error."); + + auto pMont = std::vector(size); + + stat = ippsMontInit(IppsBinaryMethod, nlen, + reinterpret_cast(pMont.data())); + ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: init Mont context error."); + + stat = + ippsMontSet(pow_m, nlen, reinterpret_cast(pMont.data())); + ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: set Mont input error."); + + // encode base into Montfomery form + BigNumber bform(m); + stat = ippsMontForm(BN(base), reinterpret_cast(pMont.data()), + BN(bform)); + ERROR_CHECK(stat == ippStsNoErr, + "ippMontExp: convert big number into Mont form error."); + + // compute R = base^pow mod N + stat = ippsMontExp(BN(bform), BN(pow), + reinterpret_cast(pMont.data()), BN(res)); + ERROR_CHECK(stat == ippStsNoErr, + std::string("ippsMontExp: error code = ") + std::to_string(stat)); + + BigNumber one(1); + // R = MontMul(R,1) + stat = ippsMontMul(BN(res), BN(one), + reinterpret_cast(pMont.data()), BN(res)); + + ERROR_CHECK(stat == ippStsNoErr, + std::string("ippsMontMul: error code = ") + std::to_string(stat)); + + return res; +} + +std::vector ippModExp(const std::vector& base, + const std::vector& pow, + const std::vector& m) { +#ifdef IPCL_CRYPTO_MB_MOD_EXP + return ippMBModExp(base, pow, m); +#else + std::vector res(8); +#ifdef IPCL_USE_OMP +#pragma omp parallel for +#endif + for (int i = 0; i < 8; i++) { + res[i] = ippSBModExp(base[i], pow[i], m[i]); + } + return res; +#endif +} + +BigNumber ippModExp(const BigNumber& base, const BigNumber& pow, + const BigNumber& m) { + return ippSBModExp(base, pow, m); +} + +} // namespace ipcl diff --git a/ipcl/paillier_keygen.cpp b/ipcl/paillier_keygen.cpp index 3acddbf..22f0ce9 100644 --- a/ipcl/paillier_keygen.cpp +++ b/ipcl/paillier_keygen.cpp @@ -7,6 +7,12 @@ #include #include +#include "ipcl/util.hpp" + +namespace ipcl { + +#define N_BIT_SIZE_MAX 2048 + static inline void rand32u(std::vector& addr) { std::random_device dev; std::mt19937 rng(dev()); @@ -46,8 +52,8 @@ BigNumber getPrimeBN(int maxBitSize) { return pBN; } -inline void getNormalBN(int64_t n_length, BigNumber& p, BigNumber& q, - BigNumber& n) { +static inline void getNormalBN(int64_t n_length, BigNumber& p, BigNumber& q, + BigNumber& n) { for (int64_t len = 0; len != n_length; len = n.BitSize()) { p = getPrimeBN(n_length / 2); q = p; @@ -58,8 +64,8 @@ inline void getNormalBN(int64_t n_length, BigNumber& p, BigNumber& q, } } -inline void getDJNBN(int64_t n_length, BigNumber& p, BigNumber& q, - BigNumber& n) { +static inline void getDJNBN(int64_t n_length, BigNumber& p, BigNumber& q, + BigNumber& n) { BigNumber gcd; do { do { @@ -83,11 +89,10 @@ keyPair generateKeypair(int64_t n_length, bool enable_DJN) { https://www.intel.com/content/www/us/en/develop/documentation/ipp-crypto-reference/top/multi-buffer-cryptography-functions/modular-exponentiation/mbx-exp-1024-2048-3072-4096-mb8.html modulus size = n * n (keySize * keySize ) */ - if (n_length > 2048) { - throw std::runtime_error( - "modulus size in bits should belong to either 1Kb, 2Kb, " - "3Kb or 4Kb range only, key size exceed the range!!!"); - } + ERROR_CHECK( + n_length <= N_BIT_SIZE_MAX, + "generateKeyPair: modulus size in bits should belong to either 1Kb, 2Kb, " + "3Kb or 4Kb range only, key size exceed the range!!!"); BigNumber p, q, n; @@ -102,3 +107,5 @@ keyPair generateKeypair(int64_t n_length, bool enable_DJN) { return keyPair{public_key, private_key}; } + +} // namespace ipcl diff --git a/ipcl/paillier_ops.cpp b/ipcl/paillier_ops.cpp index 600a0b2..e61f2b7 100644 --- a/ipcl/paillier_ops.cpp +++ b/ipcl/paillier_ops.cpp @@ -5,29 +5,32 @@ #include +#include "ipcl/mod_exp.hpp" +#include "ipcl/util.hpp" + +namespace ipcl { // constructors // -PaillierEncryptedNumber::PaillierEncryptedNumber(PaillierPublicKey* pub_key, - const BigNumber& bn) +PaillierEncryptedNumber::PaillierEncryptedNumber( + const PaillierPublicKey* pub_key, const BigNumber& bn) : b_isObfuscator(false), m_available(1), m_pubkey(pub_key), m_length(1), - m_bn{bn} // m_bn[0] -{} + m_bn{bn} {} -PaillierEncryptedNumber::PaillierEncryptedNumber(PaillierPublicKey* pub_key, - const BigNumber bn[8], - size_t length) +PaillierEncryptedNumber::PaillierEncryptedNumber( + const PaillierPublicKey* pub_key, const std::vector& bn, + size_t length) : b_isObfuscator(false), m_pubkey(pub_key), m_available(8), m_length(length), m_bn{bn[0], bn[1], bn[2], bn[3], bn[4], bn[5], bn[6], bn[7]} {} -PaillierEncryptedNumber::PaillierEncryptedNumber(PaillierPublicKey* pub_key, - const uint32_t scalar[8], - size_t length) +PaillierEncryptedNumber::PaillierEncryptedNumber( + const PaillierPublicKey* pub_key, const std::vector& scalar, + size_t length) : b_isObfuscator(false), m_pubkey(pub_key), m_available(8), @@ -38,9 +41,8 @@ PaillierEncryptedNumber::PaillierEncryptedNumber(PaillierPublicKey* pub_key, // CT+CT PaillierEncryptedNumber PaillierEncryptedNumber::operator+( const PaillierEncryptedNumber& other) const { - if (m_pubkey->getN() != other.m_pubkey->getN()) { - throw std::runtime_error("two different public keys detected!!"); - } + ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), + "operator+: two different public keys detected!!"); PaillierEncryptedNumber a = *this; PaillierEncryptedNumber b = other; @@ -49,7 +51,7 @@ PaillierEncryptedNumber PaillierEncryptedNumber::operator+( BigNumber sum = a.raw_add(a.m_bn[0], b.m_bn[0]); return PaillierEncryptedNumber(m_pubkey, sum); } else { - BigNumber sum[8]; + std::vector sum(8); for (int i = 0; i < m_available; i++) sum[i] = a.raw_add(a.m_bn[i], b.m_bn[i]); return PaillierEncryptedNumber(m_pubkey, sum); @@ -69,10 +71,13 @@ PaillierEncryptedNumber PaillierEncryptedNumber::operator+( // multi encrypted CT+PT PaillierEncryptedNumber PaillierEncryptedNumber::operator+( - const BigNumber other[8]) const { + const std::vector& other) const { + VEC_SIZE_CHECK(other); + PaillierEncryptedNumber a = *this; - BigNumber b[8], sum[8]; + std::vector b(8); + std::vector sum(8); a.m_pubkey->encrypt(b, other, false); for (int i = 0; i < 8; i++) sum[i] = a.raw_add(a.m_bn[i], b[i]); return PaillierEncryptedNumber(m_pubkey, sum); @@ -82,9 +87,8 @@ PaillierEncryptedNumber PaillierEncryptedNumber::operator+( // integer PaillierEncryptedNumber PaillierEncryptedNumber::operator*( const PaillierEncryptedNumber& other) const { - if (m_pubkey->getN() != other.m_pubkey->getN()) { - throw std::runtime_error("two different public keys detected!!"); - } + ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), + "operator*: two different public keys detected!!"); PaillierEncryptedNumber a = *this; PaillierEncryptedNumber b = other; @@ -93,8 +97,7 @@ PaillierEncryptedNumber PaillierEncryptedNumber::operator*( BigNumber product = a.raw_mul(a.m_bn[0], b.m_bn[0]); return PaillierEncryptedNumber(m_pubkey, product); } else { - BigNumber product[8]; - a.raw_mul(product, a.m_bn, b.m_bn); + std::vector product = a.raw_mul(a.m_bn, b.m_bn); return PaillierEncryptedNumber(m_pubkey, product); } } @@ -110,30 +113,29 @@ PaillierEncryptedNumber PaillierEncryptedNumber::operator*( } BigNumber PaillierEncryptedNumber::raw_add(const BigNumber& a, - const BigNumber& b) { + const BigNumber& b) const { // Hold a copy of nsquare for multi-threaded BigNumber sq = m_pubkey->getNSQ(); return a * b % sq; } -void PaillierEncryptedNumber::raw_mul(BigNumber res[8], BigNumber a[8], - BigNumber b[8]) { - BigNumber sq[8]; - for (int i = 0; i < 8; i++) sq[i] = m_pubkey->getNSQ(); - m_pubkey->ippMultiBuffExp(res, a, b, sq); +std::vector PaillierEncryptedNumber::raw_mul( + const std::vector& a, const std::vector& b) const { + std::vector sq(8, m_pubkey->getNSQ()); + return ipcl::ippModExp(a, b, sq); } BigNumber PaillierEncryptedNumber::raw_mul(const BigNumber& a, - const BigNumber& b) { + const BigNumber& b) const { BigNumber sq = m_pubkey->getNSQ(); - return m_pubkey->ippMontExp(a, b, sq); + return ipcl::ippModExp(a, b, sq); } -PaillierEncryptedNumber PaillierEncryptedNumber::rotate(int shift) { - if (m_available == 1) - throw std::invalid_argument("Cannot rotate single PaillierEncryptedNumber"); - if (shift > 8 || shift < -8) - throw std::invalid_argument("Cannot shift more than 8 or -8"); +PaillierEncryptedNumber PaillierEncryptedNumber::rotate(int shift) const { + ERROR_CHECK(m_available != 1, + "rotate: Cannot rotate single PaillierEncryptedNumber"); + ERROR_CHECK(shift >= -8 && shift <= 8, + "rotate: Cannot shift more than 8 or -8"); if (shift == 0 || shift == 8 || shift == -8) return PaillierEncryptedNumber(m_pubkey, m_bn); @@ -143,9 +145,10 @@ PaillierEncryptedNumber PaillierEncryptedNumber::rotate(int shift) { else shift = -shift; - BigNumber new_bn[8]; - getArrayBN(new_bn); + std::vector new_bn = getArrayBN(); std::rotate(std::begin(new_bn), std::begin(new_bn) + shift, std::end(new_bn)); return PaillierEncryptedNumber(m_pubkey, new_bn); } + +} // namespace ipcl diff --git a/ipcl/paillier_prikey.cpp b/ipcl/paillier_prikey.cpp index bcce535..645cc90 100644 --- a/ipcl/paillier_prikey.cpp +++ b/ipcl/paillier_prikey.cpp @@ -7,10 +7,15 @@ #include +#include "ipcl/mod_exp.hpp" +#include "ipcl/util.hpp" + +namespace ipcl { /** * Compute lcm for p and q * @param[in] p p - 1 of private key * @param[in] q q - 1 of private key + * @return the lcm result of type BigNumber */ static inline BigNumber lcm(const BigNumber& p, const BigNumber& q) { BigNumber gcd(p); @@ -18,7 +23,7 @@ static inline BigNumber lcm(const BigNumber& p, const BigNumber& q) { return p * q / gcd; } -PaillierPrivateKey::PaillierPrivateKey(PaillierPublicKey* public_key, +PaillierPrivateKey::PaillierPrivateKey(const PaillierPublicKey* public_key, const BigNumber& p, const BigNumber& q) : m_pubkey(public_key), m_n(m_pubkey->getN()), @@ -38,97 +43,54 @@ PaillierPrivateKey::PaillierPrivateKey(PaillierPublicKey* public_key, m_lambda(lcm(m_pminusone, m_qminusone)), // TODO(bwang30): check if ippsModInv_BN does the same thing with // mpz_invert - m_x(m_n.InverseMul(m_pubkey->ippMontExp(m_g, m_lambda, m_nsquare) - 1) / - m_n), + m_x(m_n.InverseMul((ipcl::ippModExp(m_g, m_lambda, m_nsquare) - 1) / + m_n)), m_bits(m_pubkey->getBits()), m_dwords(m_pubkey->getDwords()), m_enable_crt(true) { - if (p * q != m_n) { - throw std::runtime_error("Public key does not match p * q."); - } - - if (p == q) { - throw std::runtime_error("p and q error."); - } + ERROR_CHECK(p * q == m_n, + "PaillierPrivateKey ctor: Public key does not match p * q."); + ERROR_CHECK(p != q, "PaillierPrivateKey ctor: p and q are same"); } -void PaillierPrivateKey::decryptRAW(BigNumber plaintext[8], - const BigNumber ciphertext[8]) { - mbx_status st = MBX_STATUS_OK; - - Ipp64u* out_m[8]; - int64u* cip_array[8]; - - int bufferLen; - Ipp8u* pBuffer; - - // setup buffer for mbx_exp - bufferLen = mbx_exp_BufferSize(m_bits * 2); - pBuffer = reinterpret_cast(alloca(bufferLen)); - if (nullptr == pBuffer) throw std::runtime_error("error alloc memory"); - - int length = m_dwords * sizeof(int64u); - for (int i = 0; i < 8; i++) { - out_m[i] = reinterpret_cast(alloca(length)); - cip_array[i] = reinterpret_cast(alloca(length)); - - if (nullptr == out_m[i] || nullptr == cip_array[i]) - throw std::runtime_error("error alloc memory"); - } - - for (int i = 0; i < 8; i++) memset(cip_array[i], 0, m_dwords * 8); - - // TODO(bwang30): add multi-buffered modular exponentiation - Ipp32u *pow_c[8], *pow_lambda[8], *pow_nsquare[8], *pow_qsquare[8]; - int cBitLen, lBitLen, nsqBitLen; - BigNumber lambda = m_lambda; - for (int i = 0; i < 8; i++) { - ippsRef_BN(nullptr, &cBitLen, &pow_c[i], ciphertext[i]); - ippsRef_BN(nullptr, &lBitLen, &pow_lambda[i], lambda); - ippsRef_BN(nullptr, &nsqBitLen, &pow_nsquare[i], m_nsquare); - - memcpy(cip_array[i], pow_c[i], BITSIZE_WORD(cBitLen) * 4); - } - - st = mbx_exp_mb8(out_m, cip_array, reinterpret_cast(pow_lambda), - lBitLen, reinterpret_cast(pow_nsquare), nsqBitLen, - pBuffer, bufferLen); - - for (int i = 0; i < 8; i++) { - if (MBX_STATUS_OK != MBX_GET_STS(st, i)) - throw std::runtime_error( - std::string("error multi buffered exp modules, error code = ") + - std::to_string(MBX_GET_STS(st, i))); - } +void PaillierPrivateKey::decryptRAW( + std::vector& plaintext, + const std::vector& ciphertext) const { + std::vector pow_lambda(IPCL_CRYPTO_MB_SIZE, m_lambda); + std::vector modulo(IPCL_CRYPTO_MB_SIZE, m_nsquare); + std::vector res = ipcl::ippModExp(ciphertext, pow_lambda, modulo); - BigNumber ipp_res(m_nsquare); BigNumber nn = m_n; BigNumber xx = m_x; + for (int i = 0; i < 8; i++) { - ipp_res.Set(reinterpret_cast(out_m[i]), BITSIZE_WORD(nsqBitLen), - IppsBigNumPOS); - BigNumber m = (ipp_res - 1) / nn; + BigNumber m = (res[i] - 1) / nn; m = m * xx; plaintext[i] = m % nn; } } -void PaillierPrivateKey::decrypt(BigNumber plaintext[8], - const BigNumber ciphertext[8]) { +void PaillierPrivateKey::decrypt( + std::vector& plaintext, + const std::vector& ciphertext) const { + VEC_SIZE_CHECK(plaintext); + VEC_SIZE_CHECK(ciphertext); + if (m_enable_crt) decryptCRT(plaintext, ciphertext); else decryptRAW(plaintext, ciphertext); } -void PaillierPrivateKey::decrypt(BigNumber plaintext[8], - const PaillierEncryptedNumber ciphertext) { +void PaillierPrivateKey::decrypt( + std::vector& plaintext, + const PaillierEncryptedNumber ciphertext) const { + VEC_SIZE_CHECK(plaintext); // check key match - if (ciphertext.getPK().getN() != m_pubkey->getN()) - throw std::runtime_error("public key mismatch error."); + ERROR_CHECK(ciphertext.getPK().getN() == m_pubkey->getN(), + "decrypt: public key mismatch error."); - BigNumber res[8]; - ciphertext.getArrayBN(res); + std::vector res = ciphertext.getArrayBN(); if (m_enable_crt) decryptCRT(plaintext, res); else @@ -136,30 +98,21 @@ void PaillierPrivateKey::decrypt(BigNumber plaintext[8], } // CRT to calculate base^exp mod n^2 -void PaillierPrivateKey::decryptCRT(BigNumber plaintext[8], - const BigNumber ciphertext[8]) { - BigNumber resp[8]; - BigNumber resq[8]; - - BigNumber pm1[8]; - BigNumber qm1[8]; - - BigNumber psq[8], qsq[8]; - BigNumber basep[8], baseq[8]; +void PaillierPrivateKey::decryptCRT( + std::vector& plaintext, + const std::vector& ciphertext) const { + std::vector basep(8), baseq(8); + std::vector pm1(8, m_pminusone), qm1(8, m_qminusone); + std::vector psq(8, m_psquare), qsq(8, m_qsquare); for (int i = 0; i < 8; i++) { - psq[i] = m_psquare; - qsq[i] = m_qsquare; - pm1[i] = m_pminusone; - qm1[i] = m_qminusone; - basep[i] = ciphertext[i] % psq[i]; baseq[i] = ciphertext[i] % qsq[i]; } // Based on the fact a^b mod n = (a mod n)^b mod n - m_pubkey->ippMultiBuffExp(resp, basep, pm1, psq); - m_pubkey->ippMultiBuffExp(resq, baseq, qm1, qsq); + std::vector resp = ipcl::ippModExp(basep, pm1, psq); + std::vector resq = ipcl::ippModExp(baseq, qm1, qsq); for (int i = 0; i < 8; i++) { BigNumber dp = computeLfun(resp[i], m_p) * m_hp % m_p; @@ -169,22 +122,24 @@ void PaillierPrivateKey::decryptCRT(BigNumber plaintext[8], } BigNumber PaillierPrivateKey::computeCRT(const BigNumber& mp, - const BigNumber& mq) { + const BigNumber& mq) const { BigNumber u = (mq - mp) * m_pinverse % m_q; return mp + (u * m_p); } BigNumber PaillierPrivateKey::computeLfun(const BigNumber& a, - const BigNumber& b) { + const BigNumber& b) const { return (a - 1) / b; } BigNumber PaillierPrivateKey::computeHfun(const BigNumber& a, - const BigNumber& b) { + const BigNumber& b) const { // Based on the fact a^b mod n = (a mod n)^b mod n BigNumber xm = a - 1; BigNumber base = m_g % b; - BigNumber pm = m_pubkey->ippMontExp(base, xm, b); + BigNumber pm = ipcl::ippModExp(base, xm, b); BigNumber lcrt = computeLfun(pm, a); return a.InverseMul(lcrt); } + +} // namespace ipcl diff --git a/ipcl/paillier_pubkey.cpp b/ipcl/paillier_pubkey.cpp index f0c3a3f..250b820 100644 --- a/ipcl/paillier_pubkey.cpp +++ b/ipcl/paillier_pubkey.cpp @@ -5,10 +5,20 @@ #include +#include #include #include #include +#ifdef IPCL_CRYPTO_OMP +#include +#endif + +#include "ipcl/mod_exp.hpp" +#include "ipcl/util.hpp" + +namespace ipcl { + static inline auto randomUniformUnsignedInt() { std::random_device dev; std::mt19937 rng(dev()); @@ -26,43 +36,59 @@ PaillierPublicKey::PaillierPublicKey(const BigNumber& n, int bits, m_init_seed(randomUniformUnsignedInt()), m_enable_DJN(false), m_testv(false) { - if (enableDJN_) this->enableDJN(); // this sets m_enable_DJN + if (enableDJN_) this->enableDJN(); // sets m_enable_DJN } // array of 32-bit random, using rand() from stdlib -Ipp32u* PaillierPublicKey::randIpp32u(Ipp32u* addr, int size) { - for (int i = 0; i < size; i++) - addr[i] = (rand_r(&m_init_seed) << 16) + rand_r(&m_init_seed); +std::vector PaillierPublicKey::randIpp32u(int size) const { + std::vector addr(size); + // TODO(skmono): check if copy of m_init_seed is needed for const + unsigned int init_seed = m_init_seed; + for (auto& a : addr) a = (rand_r(&init_seed) << 16) + rand_r(&init_seed); return addr; } // length is Arbitery -BigNumber PaillierPublicKey::getRandom(int length) { +BigNumber PaillierPublicKey::getRandom(int length) const { + IppStatus stat; int size; int seedBitSize = 160; int seedSize = BITSIZE_WORD(seedBitSize); - Ipp32u* seed = reinterpret_cast(alloca(seedSize * sizeof(Ipp32u))); - if (nullptr == seed) throw std::runtime_error("error alloc memory"); - ippsPRNGGetSize(&size); - IppsPRNGState* pRand = reinterpret_cast(alloca(size)); - if (nullptr == pRand) throw std::runtime_error("error alloc memory"); - ippsPRNGInit(seedBitSize, pRand); - Ipp32u* addr = randIpp32u(seed, seedSize); - BigNumber bseed(addr, seedSize, IppsBigNumPOS); + stat = ippsPRNGGetSize(&size); + ERROR_CHECK(stat == ippStsNoErr, + "getRandom: get IppsPRNGState context error."); + + auto pRand = std::vector(size); - ippsPRNGSetSeed(BN(bseed), pRand); + stat = + ippsPRNGInit(seedBitSize, reinterpret_cast(pRand.data())); + ERROR_CHECK(stat == ippStsNoErr, "getRandom: init rand context error."); + + auto seed = randIpp32u(seedSize); + BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); + + stat = ippsPRNGSetSeed(BN(bseed), + reinterpret_cast(pRand.data())); + ERROR_CHECK(stat == ippStsNoErr, "getRandom: set up seed value error."); // define length Big Numbers int bn_size = BITSIZE_WORD(length); - ippsBigNumGetSize(bn_size, &size); + stat = ippsBigNumGetSize(bn_size, &size); + ERROR_CHECK(stat == ippStsNoErr, + "getRandom: get IppsBigNumState context error."); + IppsBigNumState* pBN = reinterpret_cast(alloca(size)); - if (nullptr == pBN) throw std::runtime_error("error alloc memory"); - ippsBigNumInit(bn_size, pBN); + ERROR_CHECK(pBN != nullptr, "getRandom: big number alloca error"); + + stat = ippsBigNumInit(bn_size, pBN); + ERROR_CHECK(stat == ippStsNoErr, "getRandom: init big number context error."); int bnBitSize = length; - ippsPRNGenRDRAND_BN(pBN, bnBitSize, pRand); + ippsPRNGenRDRAND_BN(pBN, bnBitSize, + reinterpret_cast(pRand.data())); BigNumber rand(pBN); + return rand; } @@ -79,26 +105,26 @@ void PaillierPublicKey::enableDJN() { BigNumber rmod_sq = rmod * rmod; BigNumber rmod_neg = rmod_sq * -1; BigNumber h = rmod_neg % m_n; - m_hs = ippMontExp(h, m_n, m_nsquare); + m_hs = ipcl::ippModExp(h, m_n, m_nsquare); m_randbits = m_bits >> 1; // bits/2 m_enable_DJN = true; } -void PaillierPublicKey::apply_obfuscator(BigNumber obfuscator[8]) { - BigNumber r[8]; - BigNumber pown[8]; - BigNumber base[8]; - BigNumber sq[8]; +void PaillierPublicKey::apply_obfuscator( + std::vector& obfuscator) const { + std::vector r(8); + std::vector pown(8, m_n); + std::vector base(8, m_hs); + std::vector sq(8, m_nsquare); + + VEC_SIZE_CHECK(obfuscator); if (m_enable_DJN) { - for (int i = 0; i < 8; i++) { - r[i] = getRandom(m_randbits); - base[i] = m_hs; - sq[i] = m_nsquare; + for (auto& r_ : r) { + r_ = getRandom(m_randbits); } - - ippMultiBuffExp(obfuscator, base, r, sq); + obfuscator = ipcl::ippModExp(base, r, sq); } else { for (int i = 0; i < 8; i++) { if (m_testv) { @@ -110,13 +136,20 @@ void PaillierPublicKey::apply_obfuscator(BigNumber obfuscator[8]) { pown[i] = m_n; sq[i] = m_nsquare; } - ippMultiBuffExp(obfuscator, r, pown, sq); + obfuscator = ipcl::ippModExp(r, pown, sq); } } -void PaillierPublicKey::raw_encrypt(BigNumber ciphertext[8], - const BigNumber plaintext[8], - bool make_secure) { +void PaillierPublicKey::setRandom(const std::vector& r) { + VEC_SIZE_CHECK(r); + + std::copy(r.begin(), r.end(), std::back_inserter(m_r)); + m_testv = true; +} + +void PaillierPublicKey::raw_encrypt(std::vector& ciphertext, + const std::vector& plaintext, + bool make_secure) const { // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 BigNumber sq = m_nsquare; for (int i = 0; i < 8; i++) { @@ -125,7 +158,7 @@ void PaillierPublicKey::raw_encrypt(BigNumber ciphertext[8], } if (make_secure) { - BigNumber obfuscator[8]; + std::vector obfuscator(8); apply_obfuscator(obfuscator); for (int i = 0; i < 8; i++) @@ -133,13 +166,18 @@ void PaillierPublicKey::raw_encrypt(BigNumber ciphertext[8], } } -void PaillierPublicKey::encrypt(BigNumber ciphertext[8], - const BigNumber value[8], bool make_secure) { +void PaillierPublicKey::encrypt(std::vector& ciphertext, + const std::vector& value, + bool make_secure) const { + VEC_SIZE_CHECK(ciphertext); + VEC_SIZE_CHECK(value); + raw_encrypt(ciphertext, value, make_secure); } // Used for CT+PT, where PT do not need to add obfuscator -void PaillierPublicKey::encrypt(BigNumber& ciphertext, const BigNumber& value) { +void PaillierPublicKey::encrypt(BigNumber& ciphertext, + const BigNumber& value) const { // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 BigNumber bn = value; BigNumber sq = m_nsquare; @@ -151,123 +189,4 @@ void PaillierPublicKey::encrypt(BigNumber& ciphertext, const BigNumber& value) { ---------------------------------------------------------- */ } -void PaillierPublicKey::ippMultiBuffExp(BigNumber res[8], BigNumber base[8], - const BigNumber pow[8], - BigNumber m[8]) { - mbx_status st = MBX_STATUS_OK; - - // Memory used for multi-buffered modular exponentiation - Ipp64u* out_x[8]; - - int64u* b_array[8]; - int64u* p_array[8]; - - int bufferLen; - Ipp8u* pBuffer; - - // setup buffer for mbx_exp - int bits = m[0].BitSize(); - int dwords = BITSIZE_DWORD(bits); - bufferLen = mbx_exp_BufferSize(bits); - pBuffer = reinterpret_cast(alloca(bufferLen)); - if (nullptr == pBuffer) throw std::runtime_error("error alloc memory"); - - int length = dwords * sizeof(int64u); - for (int i = 0; i < 8; i++) { - out_x[i] = reinterpret_cast(alloca(length)); - - b_array[i] = reinterpret_cast(alloca(length)); - p_array[i] = reinterpret_cast(alloca(length)); - - if (nullptr == out_x[i] || nullptr == b_array[i] || nullptr == p_array[i]) - throw std::runtime_error("error alloc memory"); - } - - for (int i = 0; i < 8; i++) { - memset(b_array[i], 0, dwords * 8); - memset(p_array[i], 0, dwords * 8); - } - - Ipp32u *pow_b[8], *pow_p[8], *pow_nsquare[8]; - int bBitLen, pBitLen, nsqBitLen; - int expBitLen = 0; - for (int i = 0; i < 8; i++) { - ippsRef_BN(nullptr, &bBitLen, &pow_b[i], base[i]); - ippsRef_BN(nullptr, &pBitLen, &pow_p[i], pow[i]); - ippsRef_BN(nullptr, &nsqBitLen, &pow_nsquare[i], m[i]); - - memcpy(b_array[i], pow_b[i], BITSIZE_WORD(bBitLen) * 4); - memcpy(p_array[i], pow_p[i], BITSIZE_WORD(pBitLen) * 4); - if (expBitLen < pBitLen) expBitLen = pBitLen; - } - - /* - *Note: If actual sizes of exp are different, set the exp_bits parameter equal - *to maximum size of the actual module in bit size and extend all the modules - *with zero bits - */ - st = mbx_exp_mb8(out_x, b_array, p_array, expBitLen, - reinterpret_cast(pow_nsquare), nsqBitLen, pBuffer, - bufferLen); - - for (int i = 0; i < 8; i++) { - if (MBX_STATUS_OK != MBX_GET_STS(st, i)) - throw std::runtime_error( - std::string("error multi buffered exp modules, error code = ") + - std::to_string(MBX_GET_STS(st, i))); - } - - // It is important to hold a copy of nsquare for thread-safe purpose - BigNumber bn_c(m[0]); - for (int i = 0; i < 8; i++) { - bn_c.Set(reinterpret_cast(out_x[i]), BITSIZE_WORD(nsqBitLen), - IppsBigNumPOS); - - res[i] = bn_c; - } -} - -BigNumber PaillierPublicKey::ippMontExp(const BigNumber& base, - const BigNumber& pow, - const BigNumber& m) { - IppStatus st = ippStsNoErr; - // It is important to declear res * bform bit length refer to ipp-crypto spec: - // R should not be less than the data length of the modulus m - BigNumber res(m); - - int bnBitLen; - Ipp32u* pow_m; - ippsRef_BN(nullptr, &bnBitLen, &pow_m, BN(m)); - int nlen = BITSIZE_WORD(bnBitLen); - - int size; - // define and initialize Montgomery Engine over Modulus N - ippsMontGetSize(IppsBinaryMethod, nlen, &size); - IppsMontState* pMont = reinterpret_cast(new Ipp8u[size]); - if (nullptr == pMont) throw std::runtime_error("error alloc memory"); - ippsMontInit(IppsBinaryMethod, nlen, pMont); - ippsMontSet(pow_m, nlen, pMont); - - // encode base into Montfomery form - BigNumber bform(m); - ippsMontForm(BN(base), pMont, BN(bform)); - - // compute R = base^pow mod N - st = ippsMontExp(BN(bform), BN(pow), pMont, BN(res)); - if (ippStsNoErr != st) - throw std::runtime_error(std::string("ippsMontExp error code = ") + - std::to_string(st)); - - BigNumber one(1); - st = ippsMontMul(BN(res), BN(one), pMont, BN(res)); // R = MontMul(R,1) - if (ippStsNoErr != st) - throw std::runtime_error(std::string("ippsMontMul error code = ") + - std::to_string(st)); - - delete[] reinterpret_cast(pMont); - return res; -} - -BigNumber PaillierPublicKey::IPP_invert(BigNumber a, BigNumber b) { - return b.InverseMul(a); -} +} // namespace ipcl diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 759ad04..bb24a5f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -18,6 +18,5 @@ target_link_libraries(unittest_ipcl PRIVATE # enable OpenMP unittests if(IPCL_ENABLE_OMP) find_package(OpenMP REQUIRED) - add_compile_definitions(IPCL_UNITTEST_OMP) target_link_libraries(unittest_ipcl PRIVATE OpenMP::OpenMP_CXX) endif() diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index e6631a1..c0cfe75 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -6,22 +6,22 @@ #include #include -#ifdef IPCL_UNITTEST_OMP +#ifdef IPCL_USE_OMP #include -#endif +#endif // IPCL_USE_OMP #include "gtest/gtest.h" #include "ipcl/paillier_keygen.hpp" #include "ipcl/paillier_ops.hpp" TEST(CryptoTest, CryptoTest) { - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - BigNumber ct[8]; - BigNumber dt[8]; + std::vector ct(8); + std::vector dt(8); - uint32_t pt[8]; - BigNumber ptbn[8]; + std::vector pt(8); + std::vector ptbn(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -44,17 +44,21 @@ TEST(CryptoTest, CryptoTest) { delete key.priv_key; } -#ifdef IPCL_UNITTEST_OMP -void Encryption(int num_threads, std::vector v_ct, - std::vector v_ptbn, keyPair key) { +#ifdef IPCL_USE_OMP +void Encryption(int num_threads, + std::vector>& v_ct, + const std::vector>& v_ptbn, + const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { key.pub_key->encrypt(v_ct[i], v_ptbn[i]); } } -void Decryption(int num_threads, std::vector v_dt, - std::vector v_ct, keyPair key) { +void Decryption(int num_threads, + std::vector>& v_dt, + const std::vector>& v_ct, + const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { key.priv_key->decrypt(v_dt[i], v_ct[i]); @@ -63,26 +67,24 @@ void Decryption(int num_threads, std::vector v_dt, TEST(CryptoTest, CryptoTest_OMP) { // use one keypair to do several encryption/decryption - keyPair key = generateKeypair(2048, true); + ipcl::keyPair key = ipcl::generateKeypair(2048, true); size_t num_threads = omp_get_max_threads(); - // std::cout << "available threads: " << num_threads << std::endl; - std::vector v_ct(num_threads); - std::vector v_dt(num_threads); - std::vector v_pt(num_threads); - std::vector v_ptbn(num_threads); + std::vector> v_ct( + num_threads, std::vector(8)); + std::vector> v_dt( + num_threads, std::vector(8)); + std::vector> v_pt(num_threads, + std::vector(8)); + std::vector> v_ptbn( + num_threads, std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { - v_ct[i] = new BigNumber[8]; - v_dt[i] = new BigNumber[8]; - v_pt[i] = new uint32_t[8]; - v_ptbn[i] = new BigNumber[8]; - // for each threads, generated different rand testing value for (int j = 0; j < 8; j++) { v_pt[i][j] = dist(rng); @@ -102,44 +104,39 @@ TEST(CryptoTest, CryptoTest_OMP) { } } - for (int i = 0; i < num_threads; i++) { - delete[] v_ct[i]; - delete[] v_dt[i]; - delete[] v_pt[i]; - delete[] v_ptbn[i]; - } - delete key.pub_key; delete key.priv_key; } -#endif +#endif // IPCL_USE_OMP TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { - BigNumber p = + ipcl::BigNumber p = "0xff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c" "8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b4" "0a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff76" "4dd8b091f11a0943a2dd2b983b0df02f4c4d00b413"; - BigNumber q = + ipcl::BigNumber q = "0xdacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d" "9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de70" "72a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49b" "aa0f610bad100cdf47cc86e5034e2a0b2179e04ec7"; - BigNumber n = p * q; + ipcl::BigNumber n = p * q; int n_length = n.BitSize(); - PaillierPublicKey* public_key = new PaillierPublicKey(n, n_length); - PaillierPrivateKey* private_key = new PaillierPrivateKey(public_key, p, q); + ipcl::PaillierPublicKey* public_key = + new ipcl::PaillierPublicKey(n, n_length); + ipcl::PaillierPrivateKey* private_key = + new ipcl::PaillierPrivateKey(public_key, p, q); - keyPair key = {public_key, private_key}; + ipcl::keyPair key = {public_key, private_key}; - BigNumber ptbn[8]; - BigNumber ct[8]; - BigNumber dt[8]; - BigNumber ir[8]; + std::vector ptbn(8); + std::vector ct(8); + std::vector dt(8); + std::vector ir(8); - BigNumber c1 = + ipcl::BigNumber c1 = "0x1fb7f08a42deb47876e4cbdc3f0b172c033563a696ad7a7c76fa5971b793fa488dcdd6" "bd65c7c5440d67d847cb89ccca468b2c96763fff5a5ece8330251112d65e59b7da94cfe9" "309f441ccc8f59c67dec75113d37b1ee929c8d4ce6b5e561a30a91104b0526de892e4eff" @@ -156,7 +153,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "b98ccb676367b7b3b269c670cd0210edf70ad9cb337f766af75fe06d18b3f7f7c2eae656" "5ff2815c2c09b1a1f5"; - BigNumber c2 = + ipcl::BigNumber c2 = "0x61803645f2798c06f2c08fc254eee612c55542051c8777d6ce69ede9c84a179afb2081" "167494dee727488ae5e9b56d98f4fcf132514616859fc854fbd3acf6aecd97324ac3f2af" "fa9f44864a9afc505754aa3b564b4617e887d6aa1f88095bccf6b47f458566f9d85e80fc" @@ -173,7 +170,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "d6f1d6864f1fd3e2e3937e00d391ad330b443aec85528571740ed5538188c32caab27c7b" "f437df2bb97cb90e02"; - BigNumber c1c2 = + ipcl::BigNumber c1c2 = "0x309f6e614d875e3bb0a77eedeb8895e7c6f297f161f576aef4f8b72bb5b81ef78b831a" "af134b09fe8697159cfd678c49920cb790e36580c5201a96848d7242fceb025808dd26b5" "0ff573ffca3f65e51b3b9fe85c7e44f5c8df0a9e524f64a5acc5c62cba7475978eb55e08" @@ -190,9 +187,9 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "a6d47f9af6e68e18960fa5916cc48994334354d6303312b8e96602766bec337a8a92c596" "b21b6038828a6c9744"; - BigNumber m1m2 = "0x616263646566676869606a6b6c6d6e6f"; + ipcl::BigNumber m1m2 = "0x616263646566676869606a6b6c6d6e6f"; - BigNumber r0 = + ipcl::BigNumber r0 = "0x57fb19590c31dc7c034b2a889cf4037ce3db799909c1eb0adb6199d8e96791daca9018" "891f34309daff32dced4af7d793d16734d055e28023acab7295956bfbfdf62bf0ccb2ed3" "1d5d176ca8b404e93007565fb6b72c33a512b4dc4f719231d62e27e34c3733929af32247" @@ -201,7 +198,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "27991c44a43750c24ed0825718ad14cfb9c6b40b78ff3d25f71741f2def1c9d420d4b0fa" "1e0a02e7851b5ec6a81133a368b80d1500b0f28fc653d2e6ff4366236dbf80ae3b4beae3" "5e04579f2c"; - BigNumber r1 = + ipcl::BigNumber r1 = "0x6ee8ed76227672a7bcaa1e7f152c2ea39f2fa225f0713f58210c59b2270b110e38b650" "69aaedbeffc713c021336cc12f65227cc0357ca531c07c706e7224c2c11c3145bc0a05b1" "64f426ec03350820f9f416377e8720ddb577843cae929178bfe5772e2cc1e9b94e8fce81" @@ -222,12 +219,13 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { key.pub_key->encrypt(ct, ptbn); - PaillierEncryptedNumber a(key.pub_key, ct[0]); - PaillierEncryptedNumber b(key.pub_key, ct[1]); - PaillierEncryptedNumber sum = a + b; - BigNumber res = sum.getBN(); + ipcl::PaillierEncryptedNumber a(key.pub_key, ct[0]); + ipcl::PaillierEncryptedNumber b(key.pub_key, ct[1]); + ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::BigNumber res = sum.getBN(); - BigNumber ct12[8], dt12[8]; + std::vector ct12(8); + std::vector dt12(8); for (int i = 0; i < 8; i++) { ct12[i] = res; } diff --git a/test/test_ops.cpp b/test/test_ops.cpp index b9b9dcf..c2ab740 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -6,87 +6,98 @@ #include #include -#ifdef IPCL_UNITTEST_OMP +#ifdef IPCL_USE_OMP #include -#endif +#endif // IPCL_USE_OMP #include "gtest/gtest.h" #include "ipcl/paillier_keygen.hpp" #include "ipcl/paillier_ops.hpp" -void CtPlusCt(BigNumber res[8], BigNumber ct1[8], BigNumber ct2[8], - keyPair key) { +void CtPlusCt(std::vector& res, + const std::vector& ct1, + const std::vector& ct2, + const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { - PaillierEncryptedNumber a(key.pub_key, ct1[i]); - PaillierEncryptedNumber b(key.pub_key, ct2[i]); - PaillierEncryptedNumber sum = a + b; + ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); + ipcl::PaillierEncryptedNumber b(key.pub_key, ct2[i]); + ipcl::PaillierEncryptedNumber sum = a + b; res[i] = sum.getBN(); } } -void CtPlusCtArray(BigNumber res[8], BigNumber ct1[8], BigNumber ct2[8], - keyPair key) { - PaillierEncryptedNumber a(key.pub_key, ct1); - PaillierEncryptedNumber b(key.pub_key, ct2); - PaillierEncryptedNumber sum = a + b; - sum.getArrayBN(res); +void CtPlusCtArray(std::vector& res, + const std::vector& ct1, + const std::vector& ct2, + const ipcl::keyPair key) { + ipcl::PaillierEncryptedNumber a(key.pub_key, ct1); + ipcl::PaillierEncryptedNumber b(key.pub_key, ct2); + ipcl::PaillierEncryptedNumber sum = a + b; + res = sum.getArrayBN(); } -void CtPlusPt(BigNumber res[8], BigNumber ct1[8], uint32_t pt2[8], - keyPair key) { +void CtPlusPt(std::vector& res, + const std::vector& ct1, + const std::vector& pt2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { - PaillierEncryptedNumber a(key.pub_key, ct1[i]); - BigNumber b = pt2[i]; - PaillierEncryptedNumber sum = a + b; + ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); + ipcl::BigNumber b = pt2[i]; + ipcl::PaillierEncryptedNumber sum = a + b; res[i] = sum.getBN(); } } -void CtPlusPtArray(BigNumber res[8], BigNumber ct1[8], BigNumber ptbn2[8], - keyPair key) { - BigNumber stmp[8]; - PaillierEncryptedNumber a(key.pub_key, ct1); - PaillierEncryptedNumber sum = a + ptbn2; - sum.getArrayBN(res); +void CtPlusPtArray(std::vector& res, + const std::vector& ct1, + const std::vector& ptbn2, + const ipcl::keyPair key) { + ipcl::PaillierEncryptedNumber a(key.pub_key, ct1); + ipcl::PaillierEncryptedNumber sum = a + ptbn2; + res = sum.getArrayBN(); } -void CtMultiplyPt(BigNumber res[8], BigNumber ct1[8], uint32_t pt2[8], - keyPair key) { +void CtMultiplyPt(std::vector& res, + const std::vector& ct1, + const std::vector& pt2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { - PaillierEncryptedNumber a(key.pub_key, ct1[i]); - PaillierEncryptedNumber b(key.pub_key, pt2[i]); - PaillierEncryptedNumber sum = a * b; + ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); + ipcl::PaillierEncryptedNumber b(key.pub_key, pt2[i]); + ipcl::PaillierEncryptedNumber sum = a * b; res[i] = sum.getBN(); } } -void CtMultiplyPtArray(BigNumber res[8], BigNumber ct1[8], uint32_t pt2[8], - keyPair key) { - PaillierEncryptedNumber a(key.pub_key, ct1); - PaillierEncryptedNumber b(key.pub_key, pt2); - PaillierEncryptedNumber sum = a * b; - sum.getArrayBN(res); +void CtMultiplyPtArray(std::vector& res, + const std::vector& ct1, + const std::vector& pt2, + const ipcl::keyPair key) { + ipcl::PaillierEncryptedNumber a(key.pub_key, ct1); + ipcl::PaillierEncryptedNumber b(key.pub_key, pt2); + ipcl::PaillierEncryptedNumber sum = a * b; + res = sum.getArrayBN(); } -void AddSub(BigNumber res[8], BigNumber ct1[8], BigNumber ct2[8], keyPair key) { +void AddSub(std::vector& res, + const std::vector& ct1, + const std::vector& ct2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { - PaillierEncryptedNumber a(key.pub_key, ct1[i]); - PaillierEncryptedNumber b(key.pub_key, ct2[i]); - BigNumber m1(2); + ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); + ipcl::PaillierEncryptedNumber b(key.pub_key, ct2[i]); + ipcl::BigNumber m1(2); a = a + b * m1; - PaillierEncryptedNumber sum = a + b; + ipcl::PaillierEncryptedNumber sum = a + b; res[i] = sum.getBN(); } } TEST(OperationTest, CtPlusCtTest) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); - BigNumber ct1[8], ct2[8]; - BigNumber dt[8], res[8]; + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); - uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8], ptbn2[8]; + std::vector pt1(8), pt2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -121,13 +132,13 @@ TEST(OperationTest, CtPlusCtTest) { } TEST(OperationTest, CtPlusCtArrayTest) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); - BigNumber ct1[8], ct2[8]; - BigNumber dt[8], res[8]; + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); - uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8], ptbn2[8]; + std::vector pt1(8), pt2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -162,13 +173,13 @@ TEST(OperationTest, CtPlusCtArrayTest) { } TEST(OperationTest, CtPlusPtTest) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); - BigNumber ct1[8], ct2[8]; - BigNumber dt[8], res[8]; + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); - uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8]; + std::vector pt1(8), pt2(8); + std::vector ptbn1(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -201,13 +212,13 @@ TEST(OperationTest, CtPlusPtTest) { } TEST(OperationTest, CtPlusPtArrayTest) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); - BigNumber ct1[8], ct2[8]; - BigNumber dt[8], res[8]; + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); - uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8], ptbn2[8]; + std::vector pt1(8), pt2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -241,13 +252,13 @@ TEST(OperationTest, CtPlusPtArrayTest) { } TEST(OperationTest, CtMultiplyPtTest) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); - BigNumber ct1[8], ct2[8]; - BigNumber dt[8], res[8]; + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); - uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8]; + std::vector pt1(8), pt2(8); + std::vector ptbn1(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -280,13 +291,13 @@ TEST(OperationTest, CtMultiplyPtTest) { } TEST(OperationTest, CtMultiplyZeroPtTest) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); - BigNumber ct1[8], ct2[8]; - BigNumber dt[8], res[8]; + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); - uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8]; + std::vector pt1(8), pt2(8); + std::vector ptbn1(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -319,13 +330,13 @@ TEST(OperationTest, CtMultiplyZeroPtTest) { } TEST(OperationTest, CtMultiplyPtArrayTest) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); - BigNumber ct1[8]; - BigNumber dt[8], res[8]; + std::vector ct1(8); + std::vector dt(8), res(8); - uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8], ptbn2[8]; + std::vector pt1(8), pt2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -359,13 +370,13 @@ TEST(OperationTest, CtMultiplyPtArrayTest) { } TEST(OperationTest, AddSubTest) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); - BigNumber ct1[8], ct2[8]; - BigNumber dt[8], res[8]; + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); - uint32_t pt1[8], pt2[8]; - BigNumber ptbn1[8], ptbn2[8]; + std::vector pt1(8), pt2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -398,103 +409,111 @@ TEST(OperationTest, AddSubTest) { delete key.priv_key; } -#ifdef IPCL_UNITTEST_OMP -void CtPlusCt_OMP(int num_threads, std::vector v_sum, - std::vector v_ct1, std::vector v_ct2, - keyPair key) { +#ifdef IPCL_USE_OMP +void CtPlusCt_OMP(int num_threads, + std::vector>& v_sum, + const std::vector>& v_ct1, + const std::vector>& v_ct2, + const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { - PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); - PaillierEncryptedNumber b(key.pub_key, v_ct2[i][j]); - PaillierEncryptedNumber sum = a + b; + ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); + ipcl::PaillierEncryptedNumber b(key.pub_key, v_ct2[i][j]); + ipcl::PaillierEncryptedNumber sum = a + b; v_sum[i][j] = sum.getBN(); } } } -void CtPlusPt_OMP(int num_threads, std::vector v_sum, - std::vector v_ct1, std::vector v_pt2, - keyPair key) { +void CtPlusPt_OMP(int num_threads, + std::vector>& v_sum, + const std::vector>& v_ct1, + const std::vector>& v_pt2, + const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { - BigNumber b = v_pt2[i][j]; - PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); - PaillierEncryptedNumber sum = a + b; + ipcl::BigNumber b = v_pt2[i][j]; + ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); + ipcl::PaillierEncryptedNumber sum = a + b; v_sum[i][j] = sum.getBN(); } } } -void CtPlusPtArray_OMP(int num_threads, std::vector v_sum, - std::vector v_ct1, - std::vector v_pt2, keyPair key) { +void CtPlusPtArray_OMP(int num_threads, + std::vector>& v_sum, + const std::vector>& v_ct1, + const std::vector>& v_pt2, + const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); - BigNumber b[8]; + ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); + std::vector b(8); for (int j = 0; j < 8; j++) { b[j] = v_pt2[i][j]; } - PaillierEncryptedNumber sum = a + b; - sum.getArrayBN(v_sum[i]); + ipcl::PaillierEncryptedNumber sum = a + b; + v_sum[i] = sum.getArrayBN(); } } -void CtMultiplyPt_OMP(int num_threads, std::vector v_product, - std::vector v_ct1, - std::vector v_pt2, keyPair key) { +void CtMultiplyPt_OMP(int num_threads, + std::vector>& v_product, + const std::vector>& v_ct1, + const std::vector>& v_pt2, + const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { - PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); - BigNumber b = v_pt2[i][j]; - PaillierEncryptedNumber product = a * b; + ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); + ipcl::BigNumber b = v_pt2[i][j]; + ipcl::PaillierEncryptedNumber product = a * b; v_product[i][j] = product.getBN(); } } } -void CtMultiplyPtArray_OMP(int num_threads, std::vector v_product, - std::vector v_ct1, - std::vector v_pt2, keyPair key) { +void CtMultiplyPtArray_OMP( + int num_threads, std::vector>& v_product, + const std::vector>& v_ct1, + const std::vector>& v_pt2, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); - PaillierEncryptedNumber b(key.pub_key, v_pt2[i]); - PaillierEncryptedNumber product = a * b; - product.getArrayBN(v_product[i]); + ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); + ipcl::PaillierEncryptedNumber b(key.pub_key, v_pt2[i]); + ipcl::PaillierEncryptedNumber product = a * b; + v_product[i] = product.getArrayBN(); } } TEST(OperationTest, CtPlusCtTest_OMP) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); size_t num_threads = omp_get_max_threads(); - std::vector v_ct1(num_threads); - std::vector v_ct2(num_threads); - std::vector v_dt(num_threads); - std::vector v_sum(num_threads); - std::vector v_pt1(num_threads); - std::vector v_pt2(num_threads); - std::vector v_ptbn1(num_threads); - std::vector v_ptbn2(num_threads); + std::vector> v_ct1( + num_threads, std::vector(8)); + std::vector> v_ct2( + num_threads, std::vector(8)); + std::vector> v_dt( + num_threads, std::vector(8)); + std::vector> v_sum( + num_threads, std::vector(8)); + std::vector> v_pt1(num_threads, + std::vector(8)); + std::vector> v_pt2(num_threads, + std::vector(8)); + std::vector> v_ptbn1( + num_threads, std::vector(8)); + std::vector> v_ptbn2( + num_threads, std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { - v_ct1[i] = new BigNumber[8]; - v_ct2[i] = new BigNumber[8]; - v_dt[i] = new BigNumber[8]; - v_sum[i] = new BigNumber[8]; - v_pt1[i] = new uint32_t[8]; - v_pt2[i] = new uint32_t[8]; - v_ptbn1[i] = new BigNumber[8]; - v_ptbn2[i] = new BigNumber[8]; - // for each threads, generated different rand testing value for (int j = 0; j < 8; j++) { v_pt1[i][j] = dist(rng); @@ -531,46 +550,34 @@ TEST(OperationTest, CtPlusCtTest_OMP) { } } - for (int i = 0; i < num_threads; i++) { - delete[] v_ct1[i]; - delete[] v_ct2[i]; - delete[] v_dt[i]; - delete[] v_pt1[i]; - delete[] v_pt2[i]; - delete[] v_ptbn1[i]; - delete[] v_ptbn2[i]; - delete[] v_sum[i]; - } - delete key.pub_key; delete key.priv_key; } TEST(OperationTest, CtPlusPtTest_OMP) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); size_t num_threads = omp_get_max_threads(); - std::vector v_ct1(num_threads); - std::vector v_dt(num_threads); - std::vector v_sum(num_threads); - std::vector v_pt1(num_threads); - std::vector v_pt2(num_threads); - std::vector v_ptbn1(num_threads); - std::vector v_ptbn2(num_threads); + std::vector> v_ct1( + num_threads, std::vector(8)); + std::vector> v_dt( + num_threads, std::vector(8)); + std::vector> v_sum( + num_threads, std::vector(8)); + std::vector> v_pt1(num_threads, + std::vector(8)); + std::vector> v_pt2(num_threads, + std::vector(8)); + std::vector> v_ptbn1( + num_threads, std::vector(8)); + std::vector> v_ptbn2( + num_threads, std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { - v_ct1[i] = new BigNumber[8]; - v_dt[i] = new BigNumber[8]; - v_sum[i] = new BigNumber[8]; - v_pt1[i] = new uint32_t[8]; - v_pt2[i] = new uint32_t[8]; - v_ptbn1[i] = new BigNumber[8]; - v_ptbn2[i] = new BigNumber[8]; - // for each threads, generated different rand testing value for (int j = 0; j < 8; j++) { v_pt1[i][j] = dist(rng); @@ -606,45 +613,34 @@ TEST(OperationTest, CtPlusPtTest_OMP) { } } - for (int i = 0; i < num_threads; i++) { - delete[] v_ct1[i]; - delete[] v_dt[i]; - delete[] v_pt1[i]; - delete[] v_pt2[i]; - delete[] v_ptbn1[i]; - delete[] v_ptbn2[i]; - delete[] v_sum[i]; - } - delete key.pub_key; delete key.priv_key; } TEST(OperationTest, CtPlusPtArrayTest_OMP) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); size_t num_threads = omp_get_max_threads(); - std::vector v_ct1(num_threads); - std::vector v_dt(num_threads); - std::vector v_sum(num_threads); - std::vector v_pt1(num_threads); - std::vector v_pt2(num_threads); - std::vector v_ptbn1(num_threads); - std::vector v_ptbn2(num_threads); + std::vector> v_ct1( + num_threads, std::vector(8)); + std::vector> v_dt( + num_threads, std::vector(8)); + std::vector> v_sum( + num_threads, std::vector(8)); + std::vector> v_pt1(num_threads, + std::vector(8)); + std::vector> v_pt2(num_threads, + std::vector(8)); + std::vector> v_ptbn1( + num_threads, std::vector(8)); + std::vector> v_ptbn2( + num_threads, std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { - v_ct1[i] = new BigNumber[8]; - v_dt[i] = new BigNumber[8]; - v_sum[i] = new BigNumber[8]; - v_pt1[i] = new uint32_t[8]; - v_pt2[i] = new uint32_t[8]; - v_ptbn1[i] = new BigNumber[8]; - v_ptbn2[i] = new BigNumber[8]; - // for each threads, generated different rand testing value for (int j = 0; j < 8; j++) { v_pt1[i][j] = dist(rng); @@ -680,46 +676,35 @@ TEST(OperationTest, CtPlusPtArrayTest_OMP) { } } - for (int i = 0; i < num_threads; i++) { - delete[] v_ct1[i]; - delete[] v_dt[i]; - delete[] v_pt1[i]; - delete[] v_pt2[i]; - delete[] v_ptbn1[i]; - delete[] v_ptbn2[i]; - delete[] v_sum[i]; - } - delete key.pub_key; delete key.priv_key; } TEST(OperationTest, CtMultiplyPtTest_OMP) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); size_t num_threads = omp_get_max_threads(); - std::vector v_ct1(num_threads); - std::vector v_dt(num_threads); - std::vector v_product(num_threads); - std::vector v_pt1(num_threads); - std::vector v_pt2(num_threads); - std::vector v_ptbn1(num_threads); - std::vector v_ptbn2(num_threads); + std::vector> v_ct1( + num_threads, std::vector(8)); + std::vector> v_dt( + num_threads, std::vector(8)); + std::vector> v_product( + num_threads, std::vector(8)); + std::vector> v_pt1(num_threads, + std::vector(8)); + std::vector> v_pt2(num_threads, + std::vector(8)); + std::vector> v_ptbn1( + num_threads, std::vector(8)); + std::vector> v_ptbn2( + num_threads, std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { - v_ct1[i] = new BigNumber[8]; - v_dt[i] = new BigNumber[8]; - v_product[i] = new BigNumber[8]; - v_pt1[i] = new uint32_t[8]; - v_pt2[i] = new uint32_t[8]; - v_ptbn1[i] = new BigNumber[8]; - v_ptbn2[i] = new BigNumber[8]; - // for each threads, generated different rand testing value for (int j = 0; j < 8; j++) { v_pt1[i][j] = dist(rng); @@ -754,48 +739,36 @@ TEST(OperationTest, CtMultiplyPtTest_OMP) { } } - for (int i = 0; i < num_threads; i++) { - delete[] v_ct1[i]; - delete[] v_dt[i]; - delete[] v_pt1[i]; - delete[] v_pt2[i]; - delete[] v_ptbn1[i]; - delete[] v_ptbn2[i]; - delete[] v_product[i]; - } - delete key.pub_key; delete key.priv_key; } TEST(OperationTest, CtMultiplyPtArrayTest_OMP) { - keyPair key = generateKeypair(2048); + ipcl::keyPair key = ipcl::generateKeypair(2048); size_t num_threads = omp_get_max_threads(); - std::vector v_ct1(num_threads); - std::vector v_dt(num_threads); - std::vector v_product(num_threads); - std::vector v_pt1(num_threads); - std::vector v_pt2(num_threads); - std::vector v_ptbn1(num_threads); - std::vector v_ptbn2(num_threads); + std::vector> v_ct1( + num_threads, std::vector(8)); + std::vector> v_dt( + num_threads, std::vector(8)); + std::vector> v_product( + num_threads, std::vector(8)); + std::vector> v_pt1(num_threads, + std::vector(8)); + std::vector> v_pt2(num_threads, + std::vector(8)); + std::vector> v_ptbn1( + num_threads, std::vector(8)); + std::vector> v_ptbn2( + num_threads, std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { - v_ct1[i] = new BigNumber[8]; - v_dt[i] = new BigNumber[8]; - v_product[i] = new BigNumber[8]; - v_pt1[i] = new uint32_t[8]; - v_pt2[i] = new uint32_t[8]; - v_ptbn1[i] = new BigNumber[8]; - v_ptbn2[i] = new BigNumber[8]; - // for each threads, generated different rand testing value - for (int j = 0; j < 8; j++) { v_pt1[i][j] = dist(rng); v_pt2[i][j] = dist(rng); @@ -828,17 +801,7 @@ TEST(OperationTest, CtMultiplyPtArrayTest_OMP) { } } - for (int i = 0; i < num_threads; i++) { - delete[] v_ct1[i]; - delete[] v_dt[i]; - delete[] v_pt1[i]; - delete[] v_pt2[i]; - delete[] v_ptbn1[i]; - delete[] v_ptbn2[i]; - delete[] v_product[i]; - } - delete key.pub_key; delete key.priv_key; } -#endif +#endif // IPCL_USE_OMP From 5ff47e7e3602b23a54bdae74f55be06c10e18cb3 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Tue, 8 Mar 2022 13:11:03 -0800 Subject: [PATCH 080/364] Fixed docstring typo in getBN - multiple description (#41) --- ipcl/include/ipcl/paillier_ops.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipcl/include/ipcl/paillier_ops.hpp b/ipcl/include/ipcl/paillier_ops.hpp index 3679b59..454408a 100644 --- a/ipcl/include/ipcl/paillier_ops.hpp +++ b/ipcl/include/ipcl/paillier_ops.hpp @@ -87,7 +87,7 @@ class PaillierEncryptedNumber { /** * Return ciphertext * @param[in] idx index of ciphertext stored in PaillierEncryptedNumber - * @param[in] idx index of output array(default value is 0) + * (default = 0) */ BigNumber getBN(size_t idx = 0) const { ERROR_CHECK(m_available != 1 || idx <= 0, From cce3df63aad3a6aaf39e6bff8521b4c57129837e Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Tue, 8 Mar 2022 14:14:08 -0800 Subject: [PATCH 081/364] Skmono/header dependency fix (#43) * Removed paillier_pubkey header include from paillier_keygen * Fixed unit-test url in README --- README.md | 2 +- ipcl/include/ipcl/paillier_keygen.hpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 29dcf69..c05a834 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ Alongside the Intel Paillier Cryptosystem Library, we provide a Python extension # Standardization This library is in compliance with the homomorphic encryption standards [ISO/IEC 18033-6](https://www.iso.org/standard/67740.html). -The compliance test is included in the [unit-test](test/test_cryptography.cpp#L112-L256). +The compliance test is included in the [unit-test](https://github.com/intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.pailliercryptolib/blob/main/test/test_cryptography.cpp#L112-L256). # Contributors Main contributors to this project, sorted by alphabetical order of last name are: diff --git a/ipcl/include/ipcl/paillier_keygen.hpp b/ipcl/include/ipcl/paillier_keygen.hpp index 98f154c..e3dd6b3 100644 --- a/ipcl/include/ipcl/paillier_keygen.hpp +++ b/ipcl/include/ipcl/paillier_keygen.hpp @@ -5,7 +5,6 @@ #define IPCL_INCLUDE_IPCL_PAILLIER_KEYGEN_HPP_ #include "ipcl/paillier_prikey.hpp" -#include "ipcl/paillier_pubkey.hpp" namespace ipcl { From 02736bc61995f205d45a6c276249a4ec3d0bcdad Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 8 Mar 2022 22:13:10 -0800 Subject: [PATCH 082/364] Update conversion functions and test case. --- test_bnConversion.cpp | 203 +++++++++++++++++++++++++----------------- 1 file changed, 122 insertions(+), 81 deletions(-) diff --git a/test_bnConversion.cpp b/test_bnConversion.cpp index a701094..6bda36b 100644 --- a/test_bnConversion.cpp +++ b/test_bnConversion.cpp @@ -26,7 +26,7 @@ using namespace std; -//int gDebugParam = 1; +// int gDebugParam = 1; BIGNUM* generateTestBNData(int nbits) { if (!RAND_status()) return NULL; @@ -90,74 +90,108 @@ void showHexBin(unsigned char* bin, int len) { return; } -// data will be changed to little endian format in this function, therefore the abscence of const in front -HE_QAT_STATUS binToBigNumber(BigNumber &bn, unsigned char *data, int nbits) -{ +/// @brief +/// @function binToBigNumber +// +/// data will be changed to little endian format in this function, therefore the +/// abscence of const in front +HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, + int nbits) { HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; - BIGNUM *bn_ = BN_new(); + BIGNUM* bn_ = BN_new(); if (ERR_get_error()) return status; - - // Convert raw data to BIGNUM representation to be used as a proxy to convert it to little endian format - int len_ = nbits/8; + + // Convert raw data to BIGNUM representation to be used as a proxy to + // convert it to little endian format + int len_ = (nbits + 7) >> 3; // nbits/8; BN_bin2bn(data, len_, bn_); if (ERR_get_error()) { BN_free(bn_); - return status; + return status; } - - // Convert big number from Big Endian (QAT's format) to Little Endian (BigNumber's format) - BN_bn2lebinpad(bn_, data, len_); + + //Ipp8u* data_ = new Ipp8u[len_]; + unsigned char *data_ = (unsigned char *) calloc(len_, sizeof(unsigned char)); + if (NULL == data_) return HE_QAT_STATUS_FAIL; + + // Convert big number from Big Endian (QAT's format) to Little Endian + // (BigNumber's format) + BN_bn2lebinpad(bn_, data_, len_); if (ERR_get_error()) { BN_free(bn_); - return status; + return status; } +// char* bn_str = BN_bn2hex(bn_); +// printf("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, +// BN_num_bytes(bn_), BN_num_bits(bn_)); // Uncomment this line if C++ compiler - bn = BigNumber(reinterpret_cast(data), BITSIZE_WORD(nbits)); - // Comment this line if C++ compiler -// bn = BigNumber((Ipp32u *)(data), BITSIZE_WORD(nbits)); - - // Set status of operation + bn = BigNumber(reinterpret_cast(data_), BITSIZE_WORD(nbits)); + // Comment this line for C-style casting with C compiler other than C++ + // compiler + // bn = BigNumber((Ipp32u *)(data), BITSIZE_WORD(nbits)); +// std::string str; +// bn.num2hex(str); +// printf("--- BigNumber: %s\n",str.c_str()); + + // Set status of operation status = HE_QAT_STATUS_SUCCESS; // Free up temporary allocated memory space BN_free(bn_); + // Do we have to deallocate data_ or is it being reused in BigNumber? Need + // to check. + return status; } -HE_QAT_STATUS bigNumberToBin(unsigned char *data, int nbits, BigNumber &bn) -{ +/// @brief +/// @function bigNumberToBin +/// Converts/encapsulates big number data to/into an object of BigNumber's +/// type/class. +/// @param[out] data BigNumber object's raw data in big endian format. +/// @param[in] nbits Number of bits. Has to be power of 2, e.g. 1024, 2048, +/// 4096, etc. +/// @param[in] bn BigNumber object holding a multi-precision that can be +/// represented in nbits. +HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, + const BigNumber& bn) { HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; - + if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; - - int len_ = nbits/8; - int bit_size_ = 0; // could use that instead of nbits - Ipp32u *ref_bn_ = NULL; + if (nbits % 2) return HE_QAT_STATUS_INVALID_PARAM; + + int len_ = (nbits + 7) >> 3; // nbits/8; + int bit_size_ = 0; // could use that instead of nbits + Ipp32u* ref_bn_ = NULL; ippsRef_BN(NULL, &bit_size_, &ref_bn_, BN(bn)); - unsigned char *data_ = reinterpret_cast(ref_bn_); -// unsigned char *data = (unsigned char *) ref_bn_; - - BIGNUM *bn_ = BN_new(); + + // Can be optimized to a + // unsigned char *data_ = (unsigned char *) calloc(len_, sizeof(unsigned + // char)); if (NULL == data_) return HE_QAT_STATUS_FAIL; + + // memcpy(data_, reinterpret_cast(ref_bn_), len_); + + BIGNUM* bn_ = BN_new(); if (ERR_get_error()) return status; - - BN_lebin2bn(data_, len_, bn_); + + BN_lebin2bn(reinterpret_cast(ref_bn_), len_, bn_); if (ERR_get_error()) { BN_free(bn_); - return status; + return status; } BN_bn2binpad(bn_, data, len_); if (ERR_get_error()) { BN_free(bn_); - return status; + return status; } - // Set status of operation + // Set status of operation status = HE_QAT_STATUS_SUCCESS; // Free up temporary allocated memory space @@ -187,62 +221,69 @@ int main(int argc, const char** argv) { BN_CTX* ctx = BN_CTX_new(); BN_CTX_start(ctx); - for (unsigned int mod = 4094; mod < 4096; mod++) { - //BIGNUM* bn_mod = BN_new(); - BIGNUM* bn_mod = generateTestBNData(bit_length); + for (unsigned int mod = 0; mod < num_trials; mod++) { + // BIGNUM* bn_mod = BN_new(); + BIGNUM* bn_mod = generateTestBNData(bit_length); if (!bn_mod) continue; - //BN_set_word(bn_mod, mod); + // BN_set_word(bn_mod, mod); char* bn_str = BN_bn2hex(bn_mod); - printf("Generated modulus: %s num_bytes: %d num_bits: %d\n", bn_str, + printf("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); -// OPENSSL_free(bn_str); - -// -// // Pack BIGNUM (in base 2^8) into BigNumber (in base 2^32) - unsigned char* mpi_base = NULL; - mpi_base = (unsigned char *) calloc(bit_length/8, sizeof(unsigned char)); - if (NULL == mpi_base) { - BN_free(bn_mod); - continue; - } - BN_bn2lebinpad(bn_mod, mpi_base, bit_length/8); -// // revert it -// for (int k = 0; k < bit_length/8; k++) -// be_mpi_base[k] = mpi_base[bit_length/8-k-1]; -// + OPENSSL_free(bn_str); + + int len_ = (bit_length + 7) >> 3; - printf("Try convert to BigNumber len=%lu\n",bit_length/(8*sizeof(unsigned char))); -// // Convert from base 2^8 to base 2^32 - Ipp32u *ipp_mpi_base = reinterpret_cast(mpi_base);// + (rep_len - bit_length/8)); -// //Ipp32u *ipp_mpi_base = (Ipp32u *) (mpi_base); //(rep_len_2-128); - BigNumber BigNum_base((Ipp32u)0); - BigNum_base = BigNumber((Ipp32u *) ipp_mpi_base, BITSIZE_WORD(bit_length)); - printf("BigNumber has been created.\n"); - // End of packing (this overhead does not exist in practice) - - std::string str; - BigNum_base.num2hex(str); - printf("BigNum_base num2hex output: %s %d\n",str.c_str(),bit_length/8); - -// // Extract raw data from BigNumber 2^32 and convert it to base 2^8 - int bitSize = 0; - Ipp32u *pBigNum_base = NULL; //BN(BigNum_base); - ippsRef_BN(NULL, &bitSize, &pBigNum_base, BN(BigNum_base)); - unsigned char *ippbn = reinterpret_cast(pBigNum_base); -// unsigned char *ippbn = (unsigned char *) pBigNum_base; - BIGNUM *ipp_ref_bn = BN_new(); - BN_lebin2bn(ippbn, bit_length/8, ipp_ref_bn); - char *ipp_ref_bn_str = BN_bn2hex(ipp_ref_bn); - printf(">>>> PRINT IPP ref bn: %s bitSize(%d)\n", ipp_ref_bn_str, BN_num_bits(ipp_ref_bn)); - //BIGNUM *ipp_ref_bn = BN_new(); - //BN_lebin2bn(ippbn, bit_length/8, ipp_ref_bn); + unsigned char* bn_mod_data_ = + (unsigned char*)calloc(len_, sizeof(unsigned char)); + if (NULL == bn_mod_data_) exit(1); + BN_bn2binpad(bn_mod, bn_mod_data_, len_); BN_free(bn_mod); -// BN_free(bn_base); -// BN_free(bn_exponent); + + BigNumber big_num((Ipp32u)0); + + start = clock(); + status = binToBigNumber(big_num, bn_mod_data_, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("Failed at binToBigNumber()\n"); + exit(1); + } + ssl_elapsed = clock() - start; + printf("Conversion to BigNumber has completed in %.1lfus.\n",(ssl_elapsed / (CLOCKS_PER_SEC / 1000000.0))); + + int bit_len = 0; + ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); + std::string str; + big_num.num2hex(str); + printf("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, + bit_len); + + start = clock(); + unsigned char* ref_bn_data_ = + (unsigned char*)calloc(len_, sizeof(unsigned char)); + if (NULL == ref_bn_data_) exit(1); + status = bigNumberToBin(ref_bn_data_, bit_length, big_num); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("Failed at bigNumberToBin()\n"); + exit(1); + } + qat_elapsed = clock() - start; + printf("Conversion from BigNumber has completed %.1lfus.\n",(qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); + + BIGNUM* ref_bin_ = BN_new(); + BN_bin2bn(ref_bn_data_, len_, ref_bin_); + bn_str = BN_bn2hex(ref_bin_); + printf("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, + BN_num_bytes(ref_bin_), BN_num_bits(ref_bin_)); + printf("-----------------------\n"); + + OPENSSL_free(bn_str); + free(bn_mod_data_); + free(ref_bn_data_); + BN_free(ref_bin_); } // Tear down OpenSSL context From 70d65079dddb9dd9a6265cf9406593e6644bc8b6 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 8 Mar 2022 22:51:15 -0800 Subject: [PATCH 083/364] Simplify conversion functions. --- test_bnConversion.cpp | 111 ++++++++++-------------------------------- 1 file changed, 25 insertions(+), 86 deletions(-) diff --git a/test_bnConversion.cpp b/test_bnConversion.cpp index 6bda36b..7bceb90 100644 --- a/test_bnConversion.cpp +++ b/test_bnConversion.cpp @@ -97,56 +97,19 @@ void showHexBin(unsigned char* bin, int len) { /// abscence of const in front HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, int nbits) { - HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; - if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; - - BIGNUM* bn_ = BN_new(); - if (ERR_get_error()) return status; - - // Convert raw data to BIGNUM representation to be used as a proxy to - // convert it to little endian format int len_ = (nbits + 7) >> 3; // nbits/8; - BN_bin2bn(data, len_, bn_); - if (ERR_get_error()) { - BN_free(bn_); - return status; - } - //Ipp8u* data_ = new Ipp8u[len_]; - unsigned char *data_ = (unsigned char *) calloc(len_, sizeof(unsigned char)); - if (NULL == data_) return HE_QAT_STATUS_FAIL; + // Create BigNumber containg input data passed as argument + bn = BigNumber(reinterpret_cast(data), BITSIZE_WORD(nbits)); + Ipp32u* ref_bn_data_ = NULL; + ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); - // Convert big number from Big Endian (QAT's format) to Little Endian - // (BigNumber's format) - BN_bn2lebinpad(bn_, data_, len_); - if (ERR_get_error()) { - BN_free(bn_); - return status; - } -// char* bn_str = BN_bn2hex(bn_); -// printf("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, -// BN_num_bytes(bn_), BN_num_bits(bn_)); - - // Uncomment this line if C++ compiler - bn = BigNumber(reinterpret_cast(data_), BITSIZE_WORD(nbits)); - // Comment this line for C-style casting with C compiler other than C++ - // compiler - // bn = BigNumber((Ipp32u *)(data), BITSIZE_WORD(nbits)); -// std::string str; -// bn.num2hex(str); -// printf("--- BigNumber: %s\n",str.c_str()); - - // Set status of operation - status = HE_QAT_STATUS_SUCCESS; + // Convert it to little endian format + unsigned char* data_ = reinterpret_cast(ref_bn_data_); + for (int i = 0; i < len_; i++) data_[i] = data[len_ - 1 - i]; - // Free up temporary allocated memory space - BN_free(bn_); - - // Do we have to deallocate data_ or is it being reused in BigNumber? Need - // to check. - - return status; + return HE_QAT_STATUS_SUCCESS; } /// @brief @@ -160,49 +123,23 @@ HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, /// represented in nbits. HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, const BigNumber& bn) { - HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; - if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; - if (nbits % 2) return HE_QAT_STATUS_INVALID_PARAM; - int len_ = (nbits + 7) >> 3; // nbits/8; - int bit_size_ = 0; // could use that instead of nbits - Ipp32u* ref_bn_ = NULL; - ippsRef_BN(NULL, &bit_size_, &ref_bn_, BN(bn)); - - // Can be optimized to a - // unsigned char *data_ = (unsigned char *) calloc(len_, sizeof(unsigned - // char)); if (NULL == data_) return HE_QAT_STATUS_FAIL; - - // memcpy(data_, reinterpret_cast(ref_bn_), len_); - - BIGNUM* bn_ = BN_new(); - if (ERR_get_error()) return status; - - BN_lebin2bn(reinterpret_cast(ref_bn_), len_, bn_); - if (ERR_get_error()) { - BN_free(bn_); - return status; - } - - BN_bn2binpad(bn_, data, len_); - if (ERR_get_error()) { - BN_free(bn_); - return status; - } - // Set status of operation - status = HE_QAT_STATUS_SUCCESS; + // Extract raw vector of data in little endian format + Ipp32u* ref_bn_data_ = NULL; + ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); - // Free up temporary allocated memory space - BN_free(bn_); + // Revert it to big endian format + unsigned char* data_ = reinterpret_cast(ref_bn_data_); + for (int i = 0; i < len_; i++) data[i] = data_[len_ - 1 - i]; - return status; + return HE_QAT_STATUS_SUCCESS; } int main(int argc, const char** argv) { const int bit_length = 1024; - const size_t num_trials = 100; + const size_t num_trials = 4; double avg_speed_up = 0.0; double ssl_avg_time = 0.0; @@ -244,15 +181,16 @@ int main(int argc, const char** argv) { BN_free(bn_mod); BigNumber big_num((Ipp32u)0); - - start = clock(); + + start = clock(); status = binToBigNumber(big_num, bn_mod_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { printf("Failed at binToBigNumber()\n"); exit(1); } - ssl_elapsed = clock() - start; - printf("Conversion to BigNumber has completed in %.1lfus.\n",(ssl_elapsed / (CLOCKS_PER_SEC / 1000000.0))); + ssl_elapsed = clock() - start; + printf("Conversion to BigNumber has completed in %.1lfus.\n", + (ssl_elapsed / (CLOCKS_PER_SEC / 1000000.0))); int bit_len = 0; ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); @@ -261,7 +199,7 @@ int main(int argc, const char** argv) { printf("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, bit_len); - start = clock(); + start = clock(); unsigned char* ref_bn_data_ = (unsigned char*)calloc(len_, sizeof(unsigned char)); if (NULL == ref_bn_data_) exit(1); @@ -270,8 +208,9 @@ int main(int argc, const char** argv) { printf("Failed at bigNumberToBin()\n"); exit(1); } - qat_elapsed = clock() - start; - printf("Conversion from BigNumber has completed %.1lfus.\n",(qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); + qat_elapsed = clock() - start; + printf("Conversion from BigNumber has completed %.1lfus.\n", + (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); BIGNUM* ref_bin_ = BN_new(); BN_bin2bn(ref_bn_data_, len_, ref_bin_); From 936c3c2d64eb82b841887877b89cacfb236c4874 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 8 Mar 2022 23:33:10 -0800 Subject: [PATCH 084/364] Add BigNumber conversion functions to he_qat_utils.*. --- he_qat_utils.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++ he_qat_utils.h | 44 ++++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 he_qat_utils.c create mode 100644 he_qat_utils.h diff --git a/he_qat_utils.c b/he_qat_utils.c new file mode 100644 index 0000000..9a55b08 --- /dev/null +++ b/he_qat_utils.c @@ -0,0 +1,109 @@ +#include "he_qat_utils.h" + +#ifdef __cplusplus +#include "utils/bignum.h" +#endif + +#include +#include + +BIGNUM* generateTestBNData(int nbits) { + if (!RAND_status()) return NULL; +#ifdef _DESTINY_DEBUG_VERBOSE + printf("PRNG properly seeded.\n"); +#endif + + BIGNUM* bn = BN_new(); + + if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { + BN_free(bn); + printf("Error while generating BN random number: %lu\n", + ERR_get_error()); + return NULL; + } + + return bn; +} + +unsigned char* paddingZeros(BIGNUM* bn, int nbits) { + if (!bn) return NULL; + + // Returns same address if it fails + int num_bytes = BN_num_bytes(bn); + int bytes_left = nbits / 8 - num_bytes; + if (bytes_left <= 0) return NULL; + + // Returns same address if it fails + unsigned char* bin = NULL; + int len = bytes_left + num_bytes; + if (!(bin = OPENSSL_zalloc(len))) return NULL; + +#ifdef _DESTINY_DEBUG_VERBOSE + printf("Padding bn with %d bytes to total %d bytes\n", bytes_left, len); +#endif + BN_bn2binpad(bn, bin, len); + if (ERR_get_error()) { + OPENSSL_free(bin); + return NULL; + } + + return bin; +} + +void showHexBN(BIGNUM* bn, int nbits) { + int len = nbits / 8; + unsigned char* bin = OPENSSL_zalloc(len); + if (!bin) return; + if (BN_bn2binpad(bn, bin, len)) { + for (size_t i = 0; i < len; i++) printf("%d", bin[i]); + printf("\n"); + } + OPENSSL_free(bin); + return; +} + +void showHexBin(unsigned char* bin, int len) { + if (!bin) return; + for (size_t i = 0; i < len; i++) printf("%d", bin[i]); + printf("\n"); + return; +} + +#ifdef __cplusplus +HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, + int nbits) { + if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; + int len_ = (nbits + 7) >> 3; // nbits/8; + + // Create BigNumber containg input data passed as argument + bn = BigNumber(reinterpret_cast(data), BITSIZE_WORD(nbits)); + Ipp32u* ref_bn_data_ = NULL; + ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); + + // Convert it to little endian format + unsigned char* data_ = reinterpret_cast(ref_bn_data_); + for (int i = 0; i < len_; i++) data_[i] = data[len_ - 1 - i]; + + return HE_QAT_STATUS_SUCCESS; +} + +HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, + const BigNumber& bn) { + if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; + int len_ = (nbits + 7) >> 3; // nbits/8; + + // Extract raw vector of data in little endian format + Ipp32u* ref_bn_data_ = NULL; + ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); + + // Revert it to big endian format + unsigned char* data_ = reinterpret_cast(ref_bn_data_); + for (int i = 0; i < len_; i++) data[i] = data_[len_ - 1 - i]; + + return HE_QAT_STATUS_SUCCESS; +} + +} // extern "C" { +#endif + +#endif // HE_QAT_UTILS_H_ diff --git a/he_qat_utils.h b/he_qat_utils.h new file mode 100644 index 0000000..67a456a --- /dev/null +++ b/he_qat_utils.h @@ -0,0 +1,44 @@ + +#ifndef HE_QAT_UTILS_H_ +#define HE_QAT_UTILS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define LEN_OF_1024_BITS 128 +#define LEN_OF_2048_BITS 256 +#define msb_CAN_BE_ZERO -1 +#define msb_IS_ONE 0 +#define EVEN_RND_NUM 0 +#define ODD_RND_NUM 1 +#define BATCH_SIZE 1 + +BIGNUM* generateTestBNData(int nbits); +unsigned char* paddingZeros(BIGNUM* bn, int nbits); +void showHexBN(BIGNUM* bn, int nbits); +void showHexBin(unsigned char* bin, int len); + +#ifdef __cplusplus +/// @brief +/// @function binToBigNumber +/// Converts/encapsulates QAT's raw large number data to/into a BigNumber object. +/// data will be changed to little endian format in this function, therefore the +HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, + int nbits); +/// @brief +/// @function bigNumberToBin +/// Convert BigNumber object into raw data compatible with QAT. +/// @param[out] data BigNumber object's raw data in big endian format. +/// @param[in] nbits Number of bits. Has to be power of 2, e.g. 1024, 2048, +/// 4096, etc. +/// @param[in] bn BigNumber object holding a multi-precision that can be +/// represented in nbits. +HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, + const BigNumber& bn); +} // extern "C" { +#endif + +#endif // HE_QAT_UTILS_H_ From 22e4f7c56700998f7d5c816ec527962830612351 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 8 Mar 2022 23:36:28 -0800 Subject: [PATCH 085/364] Format: clang-format source code. --- he_qat_bn_ops.c | 23 ++++++++++++----------- he_qat_bn_ops.h | 8 +++++--- he_qat_context.h | 2 +- he_qat_types.h | 4 ++-- he_qat_utils.c | 4 ++-- he_qat_utils.h | 11 ++++++----- 6 files changed, 28 insertions(+), 24 deletions(-) diff --git a/he_qat_bn_ops.c b/he_qat_bn_ops.c index 0af59b2..5535c32 100644 --- a/he_qat_bn_ops.c +++ b/he_qat_bn_ops.c @@ -514,10 +514,11 @@ task->op_data; if (op_data) { PHYS_CONTIG_FREE(op_data->base.pData); /// @function /// Callback function for lnIppModExpPerformOp. It performs any data processing /// required after the modular exponentiation. -static void HE_QAT_bnModExpCallback(void* pCallbackTag, // This type can be variable - CpaStatus status, - void* pOpData, // This is fixed -- please swap it - CpaFlatBuffer* pOut) { +static void HE_QAT_bnModExpCallback( + void* pCallbackTag, // This type can be variable + CpaStatus status, + void* pOpData, // This is fixed -- please swap it + CpaFlatBuffer* pOut) { HE_QAT_TaskRequest* request = NULL; // Check if input data for the op is available and do something @@ -532,8 +533,9 @@ static void HE_QAT_bnModExpCallback(void* pCallbackTag, // This type can be var // printf("pOpData is same as input\n"); // Mark request as complete or ready to be used request->request_status = HE_QAT_STATUS_READY; - // Copy compute results to output destination - memcpy(request->op_output, request->op_result.pData, request->op_result.dataLenInBytes); + // Copy compute results to output destination + memcpy(request->op_output, request->op_result.pData, + request->op_result.dataLenInBytes); } else { // printf("pOpData is NOT same as input\n"); request->request_status = HE_QAT_STATUS_FAIL; @@ -547,7 +549,8 @@ static void HE_QAT_bnModExpCallback(void* pCallbackTag, // This type can be var return; } -HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, unsigned char* e, unsigned char* m, int nbits) { +HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, + unsigned char* e, unsigned char* m, int nbits) { // Unpack data and copy to QAT friendly memory space int len = nbits / 8; @@ -560,7 +563,6 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, unsigned char* Cpa8U* pModulus = NULL; Cpa8U* pExponent = NULL; - // TODO(fdiasmor): Try it with 8-byte alignment. CpaStatus status = CPA_STATUS_FAIL; status = PHYS_CONTIG_ALLOC(&pBase, len); @@ -587,7 +589,7 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, unsigned char* return HE_QAT_STATUS_FAIL; } - // HE_QAT_TaskRequest request = + // HE_QAT_TaskRequest request = // HE_QAT_PACK_MODEXP_REQUEST(pBase, pExponent, pModulus, r) // Pack it as a QAT Task Request HE_QAT_TaskRequest* request = @@ -598,7 +600,7 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, unsigned char* "bnModExpPerformOp.\n"); return HE_QAT_STATUS_FAIL; } - + CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)calloc(1, sizeof(CpaCyLnModExpOpData)); if (NULL == op_data) { @@ -638,4 +640,3 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, unsigned char* return HE_QAT_STATUS_SUCCESS; } - diff --git a/he_qat_bn_ops.h b/he_qat_bn_ops.h index ebdb061..47afe7d 100644 --- a/he_qat_bn_ops.h +++ b/he_qat_bn_ops.h @@ -81,7 +81,8 @@ void getBnModExpRequest(unsigned int num_requests); /// @brief /// @function -/// Generic big number modular exponentiation for input data in primitive type format (unsigned char *). +/// Generic big number modular exponentiation for input data in primitive type +/// format (unsigned char *). /// @details /// Create private buffer for code section. Create QAT contiguous memory space. /// Copy data and package into a request and call producer function to submit @@ -91,10 +92,11 @@ void getBnModExpRequest(unsigned int num_requests); /// @param[in] e Exponent number of the modular exponentiation operation. /// @param[in] m Modulus number of the modular exponentiation operation. /// @param[in] nbits Number of bits (bit precision) of input/output big numbers. -HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, unsigned char* e, unsigned char* m, int nbits); +HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, + unsigned char* e, unsigned char* m, int nbits); #ifdef __cplusplus -} //extern "C" { +} // extern "C" { #endif #endif diff --git a/he_qat_context.h b/he_qat_context.h index 3330403..3c56c62 100644 --- a/he_qat_context.h +++ b/he_qat_context.h @@ -25,7 +25,7 @@ HE_QAT_STATUS acquire_qat_devices(); HE_QAT_STATUS release_qat_devices(); #ifdef __cplusplus -} //extern "C" { +} // extern "C" { #endif #endif diff --git a/he_qat_types.h b/he_qat_types.h index fcc1da6..743d9f7 100644 --- a/he_qat_types.h +++ b/he_qat_types.h @@ -53,7 +53,7 @@ typedef struct { } HE_QAT_InstConfig; #ifdef __cplusplus -} // close the extern "C" { +} // close the extern "C" { #endif -#endif // _HE_QAT_TYPES_H_ +#endif // _HE_QAT_TYPES_H_ diff --git a/he_qat_utils.c b/he_qat_utils.c index 9a55b08..2fcf3c5 100644 --- a/he_qat_utils.c +++ b/he_qat_utils.c @@ -103,7 +103,7 @@ HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, return HE_QAT_STATUS_SUCCESS; } -} // extern "C" { +} // extern "C" { #endif -#endif // HE_QAT_UTILS_H_ +#endif // HE_QAT_UTILS_H_ diff --git a/he_qat_utils.h b/he_qat_utils.h index 67a456a..e63afce 100644 --- a/he_qat_utils.h +++ b/he_qat_utils.h @@ -18,14 +18,15 @@ extern "C" { BIGNUM* generateTestBNData(int nbits); unsigned char* paddingZeros(BIGNUM* bn, int nbits); -void showHexBN(BIGNUM* bn, int nbits); +void showHexBN(BIGNUM* bn, int nbits); void showHexBin(unsigned char* bin, int len); #ifdef __cplusplus /// @brief /// @function binToBigNumber -/// Converts/encapsulates QAT's raw large number data to/into a BigNumber object. -/// data will be changed to little endian format in this function, therefore the +/// Converts/encapsulates QAT's raw large number data to/into a BigNumber +/// object. data will be changed to little endian format in this function, +/// therefore the HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, int nbits); /// @brief @@ -38,7 +39,7 @@ HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, /// represented in nbits. HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, const BigNumber& bn); -} // extern "C" { +} // extern "C" { #endif -#endif // HE_QAT_UTILS_H_ +#endif // HE_QAT_UTILS_H_ From 520a683998b84520ee14fcfd912ecdf2ab96dbbf Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Thu, 10 Mar 2022 01:36:44 +0800 Subject: [PATCH 086/364] Replace vector fixed size 8 with IPCL_CRYPTO_MB_SIZE (#45) * Replace vector fixed size 8 with IPCL_CRYPTO_MB_SIZE * Remove useless ippModExp definition --- ipcl/include/ipcl/paillier_ops.hpp | 11 ++++++----- ipcl/include/ipcl/paillier_pubkey.hpp | 11 ----------- ipcl/mod_exp.cpp | 20 +++++++++++--------- ipcl/paillier_ops.cpp | 16 ++++++++-------- ipcl/paillier_prikey.cpp | 14 ++++++++------ ipcl/paillier_pubkey.cpp | 16 ++++++++-------- 6 files changed, 41 insertions(+), 47 deletions(-) diff --git a/ipcl/include/ipcl/paillier_ops.hpp b/ipcl/include/ipcl/paillier_ops.hpp index 454408a..f7d0d72 100644 --- a/ipcl/include/ipcl/paillier_ops.hpp +++ b/ipcl/include/ipcl/paillier_ops.hpp @@ -25,20 +25,21 @@ class PaillierEncryptedNumber { * PaillierEncryptedNumber constructor * @param[in] pub_key paillier public key * @param[in] bn array of ciphertexts encrypted by paillier public key - * @param[in] length size of array(default value is 8) + * @param[in] length size of array(default value is IPCL_CRYPTO_MB_SIZE) */ PaillierEncryptedNumber(const PaillierPublicKey* pub_key, - const std::vector& bn, size_t length = 8); + const std::vector& bn, + size_t length = IPCL_CRYPTO_MB_SIZE); /** * PaillierEncryptedNumber constructor * @param[in] pub_key paillier public key * @param[in] scalar array of integer scalars - * @param[in] length size of array(default value is 8) + * @param[in] length size of array(default value is IPCL_CRYPTO_MB_SIZE) */ PaillierEncryptedNumber(const PaillierPublicKey* pub_key, const std::vector& scalar, - size_t length = 8); + size_t length = IPCL_CRYPTO_MB_SIZE); /** * Arithmetic addition operator @@ -76,7 +77,7 @@ class PaillierEncryptedNumber { */ void apply_obfuscator() { b_isObfuscator = true; - std::vector obfuscator(8); + std::vector obfuscator(IPCL_CRYPTO_MB_SIZE); m_pubkey->apply_obfuscator(obfuscator); BigNumber sq = m_pubkey->getNSQ(); diff --git a/ipcl/include/ipcl/paillier_pubkey.hpp b/ipcl/include/ipcl/paillier_pubkey.hpp index ef0301b..9b51247 100644 --- a/ipcl/include/ipcl/paillier_pubkey.hpp +++ b/ipcl/include/ipcl/paillier_pubkey.hpp @@ -53,17 +53,6 @@ class PaillierPublicKey { */ void encrypt(BigNumber& ciphertext, const BigNumber& value) const; - /** - * Modular exponentiation - * @param[in] base base of the exponentiation - * @param[in] pow pow of the exponentiation - * @param[in] m modular - * @return the modular exponentiation result of type BigNumber - */ - std::vector ippModExp(const std::vector& base, - const std::vector& pow, - const std::vector& m) const; - /** * Get N of public key in paillier scheme */ diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index 6cd11b9..e38bda3 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -23,10 +23,11 @@ static std::vector ippMBModExp(const std::vector& base, int bufferLen = mbx_exp_BufferSize(bits); auto pBuffer = std::vector(bufferLen); - std::vector out_x(8), b_array(8), p_array(8); + std::vector out_x(IPCL_CRYPTO_MB_SIZE), b_array(IPCL_CRYPTO_MB_SIZE), + p_array(IPCL_CRYPTO_MB_SIZE); int length = dwords * sizeof(int64u); - for (int i = 0; i < 8; i++) { + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { out_x[i] = reinterpret_cast(alloca(length)); b_array[i] = reinterpret_cast(alloca(length)); p_array[i] = reinterpret_cast(alloca(length)); @@ -46,11 +47,12 @@ static std::vector ippMBModExp(const std::vector& base, * will be inconsistent with the length allocated by b_array/p_array, * resulting in data errors. */ - std::vector pow_b(8), pow_p(8), pow_nsquare(8); + std::vector pow_b(IPCL_CRYPTO_MB_SIZE), pow_p(IPCL_CRYPTO_MB_SIZE), + pow_nsquare(IPCL_CRYPTO_MB_SIZE); int bBitLen, pBitLen, nsqBitLen; int expBitLen = 0; - for (int i = 0; i < 8; i++) { + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { ippsRef_BN(nullptr, &bBitLen, reinterpret_cast(&pow_b[i]), base[i]); ippsRef_BN(nullptr, &pBitLen, reinterpret_cast(&pow_p[i]), @@ -72,7 +74,7 @@ static std::vector ippMBModExp(const std::vector& base, reinterpret_cast(pow_nsquare.data()), nsqBitLen, reinterpret_cast(pBuffer.data()), bufferLen); - for (int i = 0; i < 8; i++) { + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { ERROR_CHECK(MBX_STATUS_OK == MBX_GET_STS(st, i), std::string("ippMultiBuffExp: error multi buffered exp " "modules, error code = ") + @@ -82,8 +84,8 @@ static std::vector ippMBModExp(const std::vector& base, // It is important to hold a copy of nsquare for thread-safe purpose BigNumber bn_c(m[0]); - std::vector res(8, 0); - for (int i = 0; i < 8; i++) { + std::vector res(IPCL_CRYPTO_MB_SIZE, 0); + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { bn_c.Set(reinterpret_cast(out_x[i]), BITSIZE_WORD(nsqBitLen), IppsBigNumPOS); res[i] = bn_c; @@ -149,11 +151,11 @@ std::vector ippModExp(const std::vector& base, #ifdef IPCL_CRYPTO_MB_MOD_EXP return ippMBModExp(base, pow, m); #else - std::vector res(8); + std::vector res(IPCL_CRYPTO_MB_SIZE); #ifdef IPCL_USE_OMP #pragma omp parallel for #endif - for (int i = 0; i < 8; i++) { + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { res[i] = ippSBModExp(base[i], pow[i], m[i]); } return res; diff --git a/ipcl/paillier_ops.cpp b/ipcl/paillier_ops.cpp index e61f2b7..363a028 100644 --- a/ipcl/paillier_ops.cpp +++ b/ipcl/paillier_ops.cpp @@ -6,7 +6,6 @@ #include #include "ipcl/mod_exp.hpp" -#include "ipcl/util.hpp" namespace ipcl { // constructors @@ -24,7 +23,7 @@ PaillierEncryptedNumber::PaillierEncryptedNumber( size_t length) : b_isObfuscator(false), m_pubkey(pub_key), - m_available(8), + m_available(IPCL_CRYPTO_MB_SIZE), m_length(length), m_bn{bn[0], bn[1], bn[2], bn[3], bn[4], bn[5], bn[6], bn[7]} {} @@ -33,7 +32,7 @@ PaillierEncryptedNumber::PaillierEncryptedNumber( size_t length) : b_isObfuscator(false), m_pubkey(pub_key), - m_available(8), + m_available(IPCL_CRYPTO_MB_SIZE), m_length(length), m_bn{scalar[0], scalar[1], scalar[2], scalar[3], scalar[4], scalar[5], scalar[6], scalar[7]} {} @@ -51,7 +50,7 @@ PaillierEncryptedNumber PaillierEncryptedNumber::operator+( BigNumber sum = a.raw_add(a.m_bn[0], b.m_bn[0]); return PaillierEncryptedNumber(m_pubkey, sum); } else { - std::vector sum(8); + std::vector sum(IPCL_CRYPTO_MB_SIZE); for (int i = 0; i < m_available; i++) sum[i] = a.raw_add(a.m_bn[i], b.m_bn[i]); return PaillierEncryptedNumber(m_pubkey, sum); @@ -76,10 +75,11 @@ PaillierEncryptedNumber PaillierEncryptedNumber::operator+( PaillierEncryptedNumber a = *this; - std::vector b(8); - std::vector sum(8); + std::vector b(IPCL_CRYPTO_MB_SIZE); + std::vector sum(IPCL_CRYPTO_MB_SIZE); a.m_pubkey->encrypt(b, other, false); - for (int i = 0; i < 8; i++) sum[i] = a.raw_add(a.m_bn[i], b[i]); + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) + sum[i] = a.raw_add(a.m_bn[i], b[i]); return PaillierEncryptedNumber(m_pubkey, sum); } @@ -121,7 +121,7 @@ BigNumber PaillierEncryptedNumber::raw_add(const BigNumber& a, std::vector PaillierEncryptedNumber::raw_mul( const std::vector& a, const std::vector& b) const { - std::vector sq(8, m_pubkey->getNSQ()); + std::vector sq(IPCL_CRYPTO_MB_SIZE, m_pubkey->getNSQ()); return ipcl::ippModExp(a, b, sq); } diff --git a/ipcl/paillier_prikey.cpp b/ipcl/paillier_prikey.cpp index 645cc90..b005388 100644 --- a/ipcl/paillier_prikey.cpp +++ b/ipcl/paillier_prikey.cpp @@ -63,7 +63,7 @@ void PaillierPrivateKey::decryptRAW( BigNumber nn = m_n; BigNumber xx = m_x; - for (int i = 0; i < 8; i++) { + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { BigNumber m = (res[i] - 1) / nn; m = m * xx; plaintext[i] = m % nn; @@ -101,11 +101,13 @@ void PaillierPrivateKey::decrypt( void PaillierPrivateKey::decryptCRT( std::vector& plaintext, const std::vector& ciphertext) const { - std::vector basep(8), baseq(8); - std::vector pm1(8, m_pminusone), qm1(8, m_qminusone); - std::vector psq(8, m_psquare), qsq(8, m_qsquare); + std::vector basep(IPCL_CRYPTO_MB_SIZE), baseq(IPCL_CRYPTO_MB_SIZE); + std::vector pm1(IPCL_CRYPTO_MB_SIZE, m_pminusone), + qm1(IPCL_CRYPTO_MB_SIZE, m_qminusone); + std::vector psq(IPCL_CRYPTO_MB_SIZE, m_psquare), + qsq(IPCL_CRYPTO_MB_SIZE, m_qsquare); - for (int i = 0; i < 8; i++) { + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { basep[i] = ciphertext[i] % psq[i]; baseq[i] = ciphertext[i] % qsq[i]; } @@ -114,7 +116,7 @@ void PaillierPrivateKey::decryptCRT( std::vector resp = ipcl::ippModExp(basep, pm1, psq); std::vector resq = ipcl::ippModExp(baseq, qm1, qsq); - for (int i = 0; i < 8; i++) { + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { BigNumber dp = computeLfun(resp[i], m_p) * m_hp % m_p; BigNumber dq = computeLfun(resq[i], m_q) * m_hq % m_q; plaintext[i] = computeCRT(dp, dq); diff --git a/ipcl/paillier_pubkey.cpp b/ipcl/paillier_pubkey.cpp index 250b820..fd624dd 100644 --- a/ipcl/paillier_pubkey.cpp +++ b/ipcl/paillier_pubkey.cpp @@ -113,10 +113,10 @@ void PaillierPublicKey::enableDJN() { void PaillierPublicKey::apply_obfuscator( std::vector& obfuscator) const { - std::vector r(8); - std::vector pown(8, m_n); - std::vector base(8, m_hs); - std::vector sq(8, m_nsquare); + std::vector r(IPCL_CRYPTO_MB_SIZE); + std::vector pown(IPCL_CRYPTO_MB_SIZE, m_n); + std::vector base(IPCL_CRYPTO_MB_SIZE, m_hs); + std::vector sq(IPCL_CRYPTO_MB_SIZE, m_nsquare); VEC_SIZE_CHECK(obfuscator); @@ -126,7 +126,7 @@ void PaillierPublicKey::apply_obfuscator( } obfuscator = ipcl::ippModExp(base, r, sq); } else { - for (int i = 0; i < 8; i++) { + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { if (m_testv) { r[i] = m_r[i]; } else { @@ -152,16 +152,16 @@ void PaillierPublicKey::raw_encrypt(std::vector& ciphertext, bool make_secure) const { // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 BigNumber sq = m_nsquare; - for (int i = 0; i < 8; i++) { + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { BigNumber bn(plaintext[i]); ciphertext[i] = (m_n * bn + 1) % sq; } if (make_secure) { - std::vector obfuscator(8); + std::vector obfuscator(IPCL_CRYPTO_MB_SIZE); apply_obfuscator(obfuscator); - for (int i = 0; i < 8; i++) + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) ciphertext[i] = sq.ModMul(ciphertext[i], obfuscator[i]); } } From 61c2964563b32fc327c82c0a514cfed4beab2c7c Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Thu, 10 Mar 2022 02:46:28 +0800 Subject: [PATCH 087/364] change lvalue to rvalue (#46) * Replace vector fixed size 8 with IPCL_CRYPTO_MB_SIZE * Remove useless ippModExp definition * Change some lvalue to rvalue in order to reduce copy operations Co-authored-by: Sejun Kim --- ipcl/mod_exp.cpp | 14 +++++++------- ipcl/paillier_keygen.cpp | 24 ++++++++++++------------ ipcl/paillier_ops.cpp | 16 ++++++++-------- ipcl/paillier_prikey.cpp | 20 ++++++++++---------- ipcl/paillier_pubkey.cpp | 10 +++++----- 5 files changed, 42 insertions(+), 42 deletions(-) diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index e38bda3..f6cb1de 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -18,14 +18,14 @@ static std::vector ippMBModExp(const std::vector& base, mbx_status st = MBX_STATUS_OK; - int bits = m[0].BitSize(); - int dwords = BITSIZE_DWORD(bits); - int bufferLen = mbx_exp_BufferSize(bits); - auto pBuffer = std::vector(bufferLen); + int&& bits = m[0].BitSize(); + int&& dwords = BITSIZE_DWORD(bits); + int&& bufferLen = mbx_exp_BufferSize(bits); + auto&& pBuffer = std::vector(bufferLen); std::vector out_x(IPCL_CRYPTO_MB_SIZE), b_array(IPCL_CRYPTO_MB_SIZE), p_array(IPCL_CRYPTO_MB_SIZE); - int length = dwords * sizeof(int64u); + int&& length = dwords * sizeof(int64u); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { out_x[i] = reinterpret_cast(alloca(length)); @@ -103,7 +103,7 @@ static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, int bnBitLen; Ipp32u* pow_m; ippsRef_BN(nullptr, &bnBitLen, &pow_m, BN(m)); - int nlen = BITSIZE_WORD(bnBitLen); + int&& nlen = BITSIZE_WORD(bnBitLen); int size; // define and initialize Montgomery Engine over Modulus N @@ -111,7 +111,7 @@ static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: get the size of IppsMontState context error."); - auto pMont = std::vector(size); + auto&& pMont = std::vector(size); stat = ippsMontInit(IppsBinaryMethod, nlen, reinterpret_cast(pMont.data())); diff --git a/ipcl/paillier_keygen.cpp b/ipcl/paillier_keygen.cpp index 22f0ce9..59ef948 100644 --- a/ipcl/paillier_keygen.cpp +++ b/ipcl/paillier_keygen.cpp @@ -13,7 +13,7 @@ namespace ipcl { #define N_BIT_SIZE_MAX 2048 -static inline void rand32u(std::vector& addr) { +static void rand32u(std::vector& addr) { std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -23,18 +23,18 @@ static inline void rand32u(std::vector& addr) { BigNumber getPrimeBN(int maxBitSize) { int PrimeSize; ippsPrimeGetSize(maxBitSize, &PrimeSize); - auto primeGen = std::vector(PrimeSize); + auto&& primeGen = std::vector(PrimeSize); ippsPrimeInit(maxBitSize, reinterpret_cast(primeGen.data())); // define Pseudo Random Generator (default settings) - int seedBitSize = 160; - int seedSize = BITSIZE_WORD(seedBitSize); + int&& seedBitSize = 160; + int&& seedSize = BITSIZE_WORD(seedBitSize); ippsPRNGGetSize(&PrimeSize); - auto rand = std::vector(PrimeSize); + auto&& rand = std::vector(PrimeSize); ippsPRNGInit(seedBitSize, reinterpret_cast(rand.data())); - auto seed = std::vector(seedSize); + auto&& seed = std::vector(seedSize); rand32u(seed); BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); @@ -52,8 +52,8 @@ BigNumber getPrimeBN(int maxBitSize) { return pBN; } -static inline void getNormalBN(int64_t n_length, BigNumber& p, BigNumber& q, - BigNumber& n) { +static void getNormalBN(int64_t n_length, BigNumber& p, BigNumber& q, + BigNumber& n) { for (int64_t len = 0; len != n_length; len = n.BitSize()) { p = getPrimeBN(n_length / 2); q = p; @@ -64,8 +64,8 @@ static inline void getNormalBN(int64_t n_length, BigNumber& p, BigNumber& q, } } -static inline void getDJNBN(int64_t n_length, BigNumber& p, BigNumber& q, - BigNumber& n) { +static void getDJNBN(int64_t n_length, BigNumber& p, BigNumber& q, + BigNumber& n) { BigNumber gcd; do { do { @@ -76,8 +76,8 @@ static inline void getDJNBN(int64_t n_length, BigNumber& p, BigNumber& q, q = getPrimeBN(n_length / 2); } while (q == p || !p.TestBit(1)); // get q: q!=p and q mod 4 = 3 - BigNumber pminusone = p - 1; - BigNumber qminusone = q - 1; + BigNumber&& pminusone = p - 1; + BigNumber&& qminusone = q - 1; gcd = pminusone.gcd(qminusone); } while (gcd.compare(2)); // gcd(p-1,q-1)=2 diff --git a/ipcl/paillier_ops.cpp b/ipcl/paillier_ops.cpp index 363a028..0ca209b 100644 --- a/ipcl/paillier_ops.cpp +++ b/ipcl/paillier_ops.cpp @@ -47,7 +47,7 @@ PaillierEncryptedNumber PaillierEncryptedNumber::operator+( PaillierEncryptedNumber b = other; if (m_available == 1) { - BigNumber sum = a.raw_add(a.m_bn[0], b.m_bn[0]); + BigNumber&& sum = a.raw_add(a.m_bn[0], b.m_bn[0]); return PaillierEncryptedNumber(m_pubkey, sum); } else { std::vector sum(IPCL_CRYPTO_MB_SIZE); @@ -64,7 +64,7 @@ PaillierEncryptedNumber PaillierEncryptedNumber::operator+( BigNumber b; a.m_pubkey->encrypt(b, other); - BigNumber sum = a.raw_add(a.m_bn[0], b); + BigNumber&& sum = a.raw_add(a.m_bn[0], b); return PaillierEncryptedNumber(m_pubkey, sum); } @@ -94,10 +94,10 @@ PaillierEncryptedNumber PaillierEncryptedNumber::operator*( PaillierEncryptedNumber b = other; if (m_available == 1) { - BigNumber product = a.raw_mul(a.m_bn[0], b.m_bn[0]); + BigNumber&& product = a.raw_mul(a.m_bn[0], b.m_bn[0]); return PaillierEncryptedNumber(m_pubkey, product); } else { - std::vector product = a.raw_mul(a.m_bn, b.m_bn); + std::vector&& product = a.raw_mul(a.m_bn, b.m_bn); return PaillierEncryptedNumber(m_pubkey, product); } } @@ -108,14 +108,14 @@ PaillierEncryptedNumber PaillierEncryptedNumber::operator*( PaillierEncryptedNumber a = *this; BigNumber b = other; - BigNumber product = a.raw_mul(a.m_bn[0], b); + BigNumber&& product = a.raw_mul(a.m_bn[0], b); return PaillierEncryptedNumber(m_pubkey, product); } BigNumber PaillierEncryptedNumber::raw_add(const BigNumber& a, const BigNumber& b) const { // Hold a copy of nsquare for multi-threaded - BigNumber sq = m_pubkey->getNSQ(); + BigNumber&& sq = m_pubkey->getNSQ(); return a * b % sq; } @@ -127,7 +127,7 @@ std::vector PaillierEncryptedNumber::raw_mul( BigNumber PaillierEncryptedNumber::raw_mul(const BigNumber& a, const BigNumber& b) const { - BigNumber sq = m_pubkey->getNSQ(); + BigNumber&& sq = m_pubkey->getNSQ(); return ipcl::ippModExp(a, b, sq); } @@ -145,7 +145,7 @@ PaillierEncryptedNumber PaillierEncryptedNumber::rotate(int shift) const { else shift = -shift; - std::vector new_bn = getArrayBN(); + std::vector&& new_bn = getArrayBN(); std::rotate(std::begin(new_bn), std::begin(new_bn) + shift, std::end(new_bn)); return PaillierEncryptedNumber(m_pubkey, new_bn); diff --git a/ipcl/paillier_prikey.cpp b/ipcl/paillier_prikey.cpp index b005388..5897e98 100644 --- a/ipcl/paillier_prikey.cpp +++ b/ipcl/paillier_prikey.cpp @@ -90,7 +90,7 @@ void PaillierPrivateKey::decrypt( ERROR_CHECK(ciphertext.getPK().getN() == m_pubkey->getN(), "decrypt: public key mismatch error."); - std::vector res = ciphertext.getArrayBN(); + std::vector&& res = ciphertext.getArrayBN(); if (m_enable_crt) decryptCRT(plaintext, res); else @@ -113,19 +113,19 @@ void PaillierPrivateKey::decryptCRT( } // Based on the fact a^b mod n = (a mod n)^b mod n - std::vector resp = ipcl::ippModExp(basep, pm1, psq); - std::vector resq = ipcl::ippModExp(baseq, qm1, qsq); + std::vector&& resp = ipcl::ippModExp(basep, pm1, psq); + std::vector&& resq = ipcl::ippModExp(baseq, qm1, qsq); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - BigNumber dp = computeLfun(resp[i], m_p) * m_hp % m_p; - BigNumber dq = computeLfun(resq[i], m_q) * m_hq % m_q; + BigNumber&& dp = computeLfun(resp[i], m_p) * m_hp % m_p; + BigNumber&& dq = computeLfun(resq[i], m_q) * m_hq % m_q; plaintext[i] = computeCRT(dp, dq); } } BigNumber PaillierPrivateKey::computeCRT(const BigNumber& mp, const BigNumber& mq) const { - BigNumber u = (mq - mp) * m_pinverse % m_q; + BigNumber&& u = (mq - mp) * m_pinverse % m_q; return mp + (u * m_p); } @@ -137,10 +137,10 @@ BigNumber PaillierPrivateKey::computeLfun(const BigNumber& a, BigNumber PaillierPrivateKey::computeHfun(const BigNumber& a, const BigNumber& b) const { // Based on the fact a^b mod n = (a mod n)^b mod n - BigNumber xm = a - 1; - BigNumber base = m_g % b; - BigNumber pm = ipcl::ippModExp(base, xm, b); - BigNumber lcrt = computeLfun(pm, a); + BigNumber&& xm = a - 1; + BigNumber&& base = m_g % b; + BigNumber&& pm = ipcl::ippModExp(base, xm, b); + BigNumber&& lcrt = computeLfun(pm, a); return a.InverseMul(lcrt); } diff --git a/ipcl/paillier_pubkey.cpp b/ipcl/paillier_pubkey.cpp index fd624dd..e3e80f1 100644 --- a/ipcl/paillier_pubkey.cpp +++ b/ipcl/paillier_pubkey.cpp @@ -65,7 +65,7 @@ BigNumber PaillierPublicKey::getRandom(int length) const { ippsPRNGInit(seedBitSize, reinterpret_cast(pRand.data())); ERROR_CHECK(stat == ippStsNoErr, "getRandom: init rand context error."); - auto seed = randIpp32u(seedSize); + auto&& seed = randIpp32u(seedSize); BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); stat = ippsPRNGSetSeed(BN(bseed), @@ -97,14 +97,14 @@ void PaillierPublicKey::enableDJN() { BigNumber rmod; do { int rand_bit = m_n.BitSize(); - BigNumber rand = getRandom(rand_bit + 128); + BigNumber&& rand = getRandom(rand_bit + 128); rmod = rand % m_n; gcd = rand.gcd(m_n); } while (gcd.compare(1)); - BigNumber rmod_sq = rmod * rmod; - BigNumber rmod_neg = rmod_sq * -1; - BigNumber h = rmod_neg % m_n; + BigNumber&& rmod_sq = rmod * rmod; + BigNumber&& rmod_neg = rmod_sq * -1; + BigNumber&& h = rmod_neg % m_n; m_hs = ipcl::ippModExp(h, m_n, m_nsquare); m_randbits = m_bits >> 1; // bits/2 From 727a3508847eb47e8a8fd8217906522c10c3f5a0 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 9 Mar 2022 15:39:58 -0800 Subject: [PATCH 088/364] Remove test case. --- CMakeLists.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c108746..70143dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,14 +84,14 @@ target_link_libraries(test_bnModExpPerformOp PUBLIC he_qat) target_link_libraries(test_bnModExpPerformOp PUBLIC cpa_sample_utils) target_link_libraries(test_bnModExpPerformOp PUBLIC z pthread ssl crypto qat_s usdm_drv_s) -add_compile_options(-fpermissive) -add_executable(test_ippModExpPerformOp test_ippModExpPerformOp.cpp) -target_include_directories(test_ippModExpPerformOp PUBLIC ${COMMON_INC_DIR} ${HE_QAT_UTILS_INC_DIR}) -target_link_libraries(test_ippModExpPerformOp PUBLIC he_qat) -target_link_libraries(test_ippModExpPerformOp PUBLIC he_qat_utils) -target_link_libraries(test_ippModExpPerformOp PUBLIC cpa_sample_utils) -target_link_libraries(test_ippModExpPerformOp PUBLIC ippcpmx crypto_mb) -target_link_libraries(test_ippModExpPerformOp PUBLIC z pthread ssl crypto qat_s usdm_drv_s) +#add_compile_options(-fpermissive) +#add_executable(test_ippModExpPerformOp test_ippModExpPerformOp.cpp) +#target_include_directories(test_ippModExpPerformOp PUBLIC ${COMMON_INC_DIR} ${HE_QAT_UTILS_INC_DIR}) +#target_link_libraries(test_ippModExpPerformOp PUBLIC he_qat) +#target_link_libraries(test_ippModExpPerformOp PUBLIC he_qat_utils) +#target_link_libraries(test_ippModExpPerformOp PUBLIC cpa_sample_utils) +#target_link_libraries(test_ippModExpPerformOp PUBLIC ippcpmx crypto_mb) +#target_link_libraries(test_ippModExpPerformOp PUBLIC z pthread ssl crypto qat_s usdm_drv_s) add_compile_options(-fpermissive) add_executable(test_bnConversion test_bnConversion.cpp) From fe116e27bf4aa78f3fd5017400a6611d375ad845 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 9 Mar 2022 15:50:03 -0800 Subject: [PATCH 089/364] Remove compilation warnings for C++ compiler. --- include/cpa_sample_cnv_utils.h | 6 ++++++ include/cpa_sample_utils.h | 4 ++++ test_bnConversion.cpp | 13 +++++++++++-- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/include/cpa_sample_cnv_utils.h b/include/cpa_sample_cnv_utils.h index dd3730e..5670737 100644 --- a/include/cpa_sample_cnv_utils.h +++ b/include/cpa_sample_cnv_utils.h @@ -80,6 +80,7 @@ #ifdef __cplusplus extern "C" { +#include #endif /* Common macro definitions */ @@ -171,7 +172,12 @@ static const char *getSampleCnVModeStr(void) static void getCnvFlagInternal(CpaBoolean *cnv, CpaBoolean *cnvnr) { +#ifdef __cplusplus + CpaDcInstanceCapabilities cap; + memset(&cap, 0, sizeof(CpaDcInstanceCapabilities)); +#else CpaDcInstanceCapabilities cap = {0}; +#endif if (getSampleDcCapabilities(&cap) != CPA_STATUS_SUCCESS) { return EvaluateSampleCnVFlag(NULL, cnv, cnvnr); diff --git a/include/cpa_sample_utils.h b/include/cpa_sample_utils.h index 72dbcce..5c28ae6 100644 --- a/include/cpa_sample_utils.h +++ b/include/cpa_sample_utils.h @@ -583,7 +583,11 @@ static __inline CpaStatus sampleThreadCreate(sampleThread *thread, void *args) { #ifdef USER_SPACE +#ifdef __cplusplus + if (pthread_create(thread, NULL, (void* (*)(void*)) funct, args) != 0) +#else if (pthread_create(thread, NULL, funct, args) != 0) +#endif { PRINT_ERR("Failed create thread\n"); return CPA_STATUS_FAIL; diff --git a/test_bnConversion.cpp b/test_bnConversion.cpp index 7bceb90..581c93c 100644 --- a/test_bnConversion.cpp +++ b/test_bnConversion.cpp @@ -4,10 +4,19 @@ #include "he_qat_bn_ops.h" #include "he_qat_context.h" +#ifdef __cplusplus +extern "C" { +#endif + #include #include #include #include + +#ifdef __cplusplus +} +#endif + #include #include "ippcp.h" @@ -57,7 +66,7 @@ unsigned char* paddingZeros(BIGNUM* bn, int nbits) { // Returns same address if it fails unsigned char* bin = NULL; int len = bytes_left + num_bytes; - if (!(bin = OPENSSL_zalloc(len))) return NULL; + if (!(bin = (unsigned char *) OPENSSL_zalloc(len))) return NULL; #ifdef _DESTINY_DEBUG_VERBOSE printf("Padding bn with %d bytes to total %d bytes\n", bytes_left, len); @@ -73,7 +82,7 @@ unsigned char* paddingZeros(BIGNUM* bn, int nbits) { void showHexBN(BIGNUM* bn, int nbits) { int len = nbits / 8; - unsigned char* bin = OPENSSL_zalloc(len); + unsigned char* bin = (unsigned char *) OPENSSL_zalloc(len); if (!bin) return; if (BN_bn2binpad(bn, bin, len)) { for (size_t i = 0; i < len; i++) printf("%d", bin[i]); From 2b181ae1699233a06a93f86a8efc1db10faef2dd Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 9 Mar 2022 16:09:56 -0800 Subject: [PATCH 090/364] Clang-format source code. --- test_bnConversion.cpp | 4 ++-- test_bnModExpPerformOp.c | 17 +++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/test_bnConversion.cpp b/test_bnConversion.cpp index 581c93c..b827912 100644 --- a/test_bnConversion.cpp +++ b/test_bnConversion.cpp @@ -66,7 +66,7 @@ unsigned char* paddingZeros(BIGNUM* bn, int nbits) { // Returns same address if it fails unsigned char* bin = NULL; int len = bytes_left + num_bytes; - if (!(bin = (unsigned char *) OPENSSL_zalloc(len))) return NULL; + if (!(bin = (unsigned char*)OPENSSL_zalloc(len))) return NULL; #ifdef _DESTINY_DEBUG_VERBOSE printf("Padding bn with %d bytes to total %d bytes\n", bytes_left, len); @@ -82,7 +82,7 @@ unsigned char* paddingZeros(BIGNUM* bn, int nbits) { void showHexBN(BIGNUM* bn, int nbits) { int len = nbits / 8; - unsigned char* bin = (unsigned char *) OPENSSL_zalloc(len); + unsigned char* bin = (unsigned char*)OPENSSL_zalloc(len); if (!bin) return; if (BN_bn2binpad(bn, bin, len)) { for (size_t i = 0; i < len; i++) printf("%d", bin[i]); diff --git a/test_bnModExpPerformOp.c b/test_bnModExpPerformOp.c index a139a5a..3561f53 100644 --- a/test_bnModExpPerformOp.c +++ b/test_bnModExpPerformOp.c @@ -17,7 +17,7 @@ #define ODD_RND_NUM 1 #define BATCH_SIZE 1 -//int gDebugParam = 1; +// int gDebugParam = 1; BIGNUM* generateTestBNData(int nbits) { if (!RAND_status()) return NULL; @@ -82,7 +82,7 @@ void showHexBin(unsigned char* bin, int len) { } int main(int argc, const char** argv) { - const int bit_length = 4096; //1024; + const int bit_length = 4096; // 1024; const size_t num_trials = 100; double avg_speed_up = 0.0; @@ -122,7 +122,7 @@ int main(int argc, const char** argv) { BIGNUM* bn_base = generateTestBNData(bit_length); - // Perform OpenSSL ModExp Op + // Perform OpenSSL ModExp Op BIGNUM* ssl_res = BN_new(); start = clock(); BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); @@ -147,12 +147,12 @@ int main(int argc, const char** argv) { // printf("OpenSSL: %.1lfus\t", ssl_elapsed / (CLOCKS_PER_SEC / // 1000000.0)); - // Perform QAT ModExp Op + // Perform QAT ModExp Op BIGNUM* qat_res = BN_new(); start = clock(); for (unsigned int j = 0; j < BATCH_SIZE; j++) - status = bnModExpPerformOp(qat_res, bn_base, bn_exponent, - bn_mod, bit_length); + status = bnModExpPerformOp(qat_res, bn_base, bn_exponent, bn_mod, + bit_length); getBnModExpRequest(BATCH_SIZE); qat_elapsed = clock() - start; @@ -169,8 +169,9 @@ int main(int argc, const char** argv) { ((qat_elapsed / (CLOCKS_PER_SEC / 1000000.0)) / BATCH_SIZE)) / (mod + 1); - printf("Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", - (mod+1), ssl_avg_time, qat_avg_time, avg_speed_up); + printf( + "Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", + (mod + 1), ssl_avg_time, qat_avg_time, avg_speed_up); // printf("QAT: %.1lfus\t", qat_elapsed / (CLOCKS_PER_SEC / // 1000000.0)); printf("Speed Up: %.1lfx\t", (ssl_elapsed / From af699f0cfb130c81c9fa66cef4850a5f9f01bc4d Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 9 Mar 2022 18:04:30 -0800 Subject: [PATCH 091/364] Remove utils. --- utils/CMakeLists.txt | 23 --- utils/bignum.cpp | 437 ------------------------------------------- utils/bignum.h | 106 ----------- utils/utils.cpp | 46 ----- utils/utils.h | 34 ---- 5 files changed, 646 deletions(-) delete mode 100644 utils/CMakeLists.txt delete mode 100644 utils/bignum.cpp delete mode 100644 utils/bignum.h delete mode 100644 utils/utils.cpp delete mode 100644 utils/utils.h diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt deleted file mode 100644 index c4ebb74..0000000 --- a/utils/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ - -# Include directories -list(APPEND HE_QAT_UTILS_INC_DIR - ${CMAKE_CURRENT_LIST_DIR} - ${IPPCP_DIR}/include -) -message(STATUS "HE_QAT_UTILS_INC_DIR: ${HE_QAT_UTILS_INC_DIR}") - -# Source files -set(HE_QAT_UTILS_SRC ${CMAKE_CURRENT_LIST_DIR}/utils.cpp - ${CMAKE_CURRENT_LIST_DIR}/bignum.cpp -) - -add_library(he_qat_utils ${HE_QAT_UTILS_SRC}) -target_include_directories(he_qat_utils - PUBLIC $ # Public headers - PUBLIC $ # Public headers -) -target_link_directories(he_qat_utils PUBLIC ${IPPCP_DIR}/lib/intel64) -target_link_libraries(he_qat_utils PUBLIC ippcpmx crypto_mb) - -set(HE_QAT_UTILS_INC_DIR ${HE_QAT_UTILS_INC_DIR} PARENT_SCOPE) - diff --git a/utils/bignum.cpp b/utils/bignum.cpp deleted file mode 100644 index 57a372c..0000000 --- a/utils/bignum.cpp +++ /dev/null @@ -1,437 +0,0 @@ -/******************************************************************************* -* Copyright 2019-2021 Intel Corporation -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*******************************************************************************/ - -#include "bignum.h" -#include -#include -#include "utils.h" - -////////////////////////////////////////////////////////////////////// -// -// BigNumber -// -////////////////////////////////////////////////////////////////////// -BigNumber::~BigNumber() -{ - delete [] (Ipp8u*)m_pBN; -} - -bool BigNumber::create(const Ipp32u* pData, int length, IppsBigNumSGN sgn) -{ - int size; - ippsBigNumGetSize(length, &size); - m_pBN = (IppsBigNumState*)( new Ipp8u[size] ); - if(!m_pBN) - return false; - ippsBigNumInit(length, m_pBN); - if (pData) - ippsSet_BN(sgn, length, pData, m_pBN); - return true; -} - -// -// constructors -// -BigNumber::BigNumber(Ipp32u value) -{ - create(&value, 1, IppsBigNumPOS); -} - -BigNumber::BigNumber(Ipp32s value) -{ - Ipp32s avalue = abs(value); - create((Ipp32u*)&avalue, 1, (value<0)? IppsBigNumNEG : IppsBigNumPOS); -} - -BigNumber::BigNumber(const IppsBigNumState* pBN) -{ - IppsBigNumSGN bnSgn; - int bnBitLen; - Ipp32u* bnData; - ippsRef_BN(&bnSgn, &bnBitLen, &bnData, pBN); - - create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); -} - -BigNumber::BigNumber(const Ipp32u* pData, int length, IppsBigNumSGN sgn) -{ - create(pData, length, sgn); -} - -static char HexDigitList[] = "0123456789ABCDEF"; - -BigNumber::BigNumber(const char* s) -{ - bool neg = '-' == s[0]; - if(neg) s++; - bool hex = ('0'==s[0]) && (('x'==s[1]) || ('X'==s[1])); - - int dataLen; - Ipp32u base; - if(hex) { - s += 2; - base = 0x10; - dataLen = (int)(strlen_safe(s) + 7)/8; - } - else { - base = 10; - dataLen = (int)(strlen_safe(s) + 9)/10; - } - - create(0, dataLen); - *(this) = Zero(); - while(*s) { - char tmp[2] = {s[0],0}; - Ipp32u digit = (Ipp32u)strcspn(HexDigitList, tmp); - *this = (*this) * base + BigNumber( digit ); - s++; - } - - if(neg) - (*this) = Zero()- (*this); -} - -BigNumber::BigNumber(const BigNumber& bn) -{ - IppsBigNumSGN bnSgn; - int bnBitLen; - Ipp32u* bnData; - ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); - - create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); -} - -// -// set value -// -void BigNumber::Set(const Ipp32u* pData, int length, IppsBigNumSGN sgn) -{ - ippsSet_BN(sgn, length, pData, BN(*this)); -} - -// -// constants -// -const BigNumber& BigNumber::Zero() -{ - static const BigNumber zero(0); - return zero; -} - -const BigNumber& BigNumber::One() -{ - static const BigNumber one(1); - return one; -} - -const BigNumber& BigNumber::Two() -{ - static const BigNumber two(2); - return two; -} - -// -// arithmetic operators -// -BigNumber& BigNumber::operator =(const BigNumber& bn) -{ - if(this != &bn) { // prevent self copy - IppsBigNumSGN bnSgn; - int bnBitLen; - Ipp32u* bnData; - ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); - - delete [] (Ipp8u*)m_pBN; - create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); - } - return *this; -} - -BigNumber& BigNumber::operator += (const BigNumber& bn) -{ - int aBitLen; - ippsRef_BN(NULL, &aBitLen, NULL, *this); - int bBitLen; - ippsRef_BN(NULL, &bBitLen, NULL, bn); - int rBitLen = IPP_MAX(aBitLen, bBitLen) + 1; - - BigNumber result(0, BITSIZE_WORD(rBitLen)); - ippsAdd_BN(*this, bn, result); - *this = result; - return *this; -} - -BigNumber& BigNumber::operator -= (const BigNumber& bn) -{ - int aBitLen; - ippsRef_BN(NULL, &aBitLen, NULL, *this); - int bBitLen; - ippsRef_BN(NULL, &bBitLen, NULL, bn); - int rBitLen = IPP_MAX(aBitLen, bBitLen); - - BigNumber result(0, BITSIZE_WORD(rBitLen)); - ippsSub_BN(*this, bn, result); - *this = result; - return *this; -} - -BigNumber& BigNumber::operator *= (const BigNumber& bn) -{ - int aBitLen; - ippsRef_BN(NULL, &aBitLen, NULL, *this); - int bBitLen; - ippsRef_BN(NULL, &bBitLen, NULL, bn); - int rBitLen = aBitLen + bBitLen; - - BigNumber result(0, BITSIZE_WORD(rBitLen)); - ippsMul_BN(*this, bn, result); - *this = result; - return *this; -} - -BigNumber& BigNumber::operator *= (Ipp32u n) -{ - int aBitLen; - ippsRef_BN(NULL, &aBitLen, NULL, *this); - - BigNumber result(0, BITSIZE_WORD(aBitLen+32)); - BigNumber bn(n); - ippsMul_BN(*this, bn, result); - *this = result; - return *this; -} - -BigNumber& BigNumber::operator %= (const BigNumber& bn) -{ - BigNumber remainder(bn); - ippsMod_BN(BN(*this), BN(bn), BN(remainder)); - *this = remainder; - return *this; -} - -BigNumber& BigNumber::operator /= (const BigNumber& bn) -{ - BigNumber quotient(*this); - BigNumber remainder(bn); - ippsDiv_BN(BN(*this), BN(bn), BN(quotient), BN(remainder)); - *this = quotient; - return *this; -} - -BigNumber operator + (const BigNumber& a, const BigNumber& b ) -{ - BigNumber r(a); - return r += b; -} - -BigNumber operator - (const BigNumber& a, const BigNumber& b ) -{ - BigNumber r(a); - return r -= b; -} - -BigNumber operator * (const BigNumber& a, const BigNumber& b ) -{ - BigNumber r(a); - return r *= b; -} - -BigNumber operator * (const BigNumber& a, Ipp32u n) -{ - BigNumber r(a); - return r *= n; -} - -BigNumber operator / (const BigNumber& a, const BigNumber& b ) -{ - BigNumber q(a); - return q /= b; -} - -BigNumber operator % (const BigNumber& a, const BigNumber& b ) -{ - BigNumber r(b); - ippsMod_BN(BN(a), BN(b), BN(r)); - return r; -} - -// -// modulo arithmetic -// -BigNumber BigNumber::Modulo(const BigNumber& a) const -{ - return a % *this; -} - -BigNumber BigNumber::InverseAdd(const BigNumber& a) const -{ - BigNumber t = Modulo(a); - if(t==BigNumber::Zero()) - return t; - else - return *this - t; -} - -BigNumber BigNumber::InverseMul(const BigNumber& a) const -{ - BigNumber r(*this); - ippsModInv_BN(BN(a), BN(*this), BN(r)); - return r; -} - -BigNumber BigNumber::ModAdd(const BigNumber& a, const BigNumber& b) const -{ - BigNumber r = this->Modulo(a+b); - return r; -} - -BigNumber BigNumber::ModSub(const BigNumber& a, const BigNumber& b) const -{ - BigNumber r = this->Modulo(a + this->InverseAdd(b)); - return r; -} - -BigNumber BigNumber::ModMul(const BigNumber& a, const BigNumber& b) const -{ - BigNumber r = this->Modulo(a*b); - return r; -} - -// -// comparison -// -int BigNumber::compare(const BigNumber &bn) const -{ - Ipp32u result; - BigNumber tmp = *this - bn; - ippsCmpZero_BN(BN(tmp), &result); - return (result==IS_ZERO)? 0 : (result==GREATER_THAN_ZERO)? 1 : -1; -} - -bool operator < (const BigNumber &a, const BigNumber &b) { return a.compare(b) < 0; } -bool operator > (const BigNumber &a, const BigNumber &b) { return a.compare(b) > 0; } -bool operator == (const BigNumber &a, const BigNumber &b) { return 0 == a.compare(b);} -bool operator != (const BigNumber &a, const BigNumber &b) { return 0 != a.compare(b);} - -// easy tests -// -bool BigNumber::IsOdd() const -{ - Ipp32u* bnData; - ippsRef_BN(NULL, NULL, &bnData, *this); - return bnData[0]&1; -} - -// -// size of BigNumber -// -int BigNumber::LSB() const -{ - if( *this == BigNumber::Zero() ) - return 0; - - vector v; - num2vec(v); - - int lsb = 0; - vector::iterator i; - for(i=v.begin(); i!=v.end(); i++) { - Ipp32u x = *i; - if(0==x) - lsb += 32; - else { - while(0==(x&1)) { - lsb++; - x >>= 1; - } - break; - } - } - return lsb; -} - -int BigNumber::MSB() const -{ - if( *this == BigNumber::Zero() ) - return 0; - - vector v; - num2vec(v); - - int msb = (int)v.size()*32 -1; - vector::reverse_iterator i; - for(i=v.rbegin(); i!=v.rend(); i++) { - Ipp32u x = *i; - if(0==x) - msb -=32; - else { - while(!(x&0x80000000)) { - msb--; - x <<= 1; - } - break; - } - } - return msb; -} - -int Bit(const vector& v, int n) -{ - return 0 != ( v[n>>5] & (1<<(n&0x1F)) ); -} - -// -// conversions and output -// -void BigNumber::num2vec( vector& v ) const -{ - int bnBitLen; - Ipp32u* bnData; - ippsRef_BN(NULL, &bnBitLen, &bnData, *this); - - int len = BITSIZE_WORD(bnBitLen);; - for(int n=0; n0; n--) { - Ipp32u x = bnData[n-1]; - for(int nd=8; nd>0; nd--) { - char c = HexDigitList[(x>>(nd-1)*4)&0xF]; - s.append(1, c); - } - } -} - -ostream& operator << ( ostream &os, const BigNumber& a) -{ - string s; - a.num2hex(s); - os << s.c_str(); - return os; -} diff --git a/utils/bignum.h b/utils/bignum.h deleted file mode 100644 index 51696d1..0000000 --- a/utils/bignum.h +++ /dev/null @@ -1,106 +0,0 @@ -/******************************************************************************* -* Copyright 2019-2021 Intel Corporation -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*******************************************************************************/ - -#if !defined _BIGNUMBER_H_ -#define _BIGNUMBER_H_ - -#include "ippcp.h" - -#include -#include -#include - -using namespace std; - -class BigNumber -{ -public: - BigNumber(Ipp32u value=0); - BigNumber(Ipp32s value); - BigNumber(const IppsBigNumState* pBN); - BigNumber(const Ipp32u* pData, int length=1, IppsBigNumSGN sgn=IppsBigNumPOS); - BigNumber(const BigNumber& bn); - BigNumber(const char *s); - virtual ~BigNumber(); - - // set value - void Set(const Ipp32u* pData, int length=1, IppsBigNumSGN sgn=IppsBigNumPOS); - // conversion to IppsBigNumState - friend IppsBigNumState* BN(const BigNumber& bn) {return bn.m_pBN;} - operator IppsBigNumState* () const { return m_pBN; } - - // some useful constatns - static const BigNumber& Zero(); - static const BigNumber& One(); - static const BigNumber& Two(); - - // arithmetic operators probably need - BigNumber& operator = (const BigNumber& bn); - BigNumber& operator += (const BigNumber& bn); - BigNumber& operator -= (const BigNumber& bn); - BigNumber& operator *= (Ipp32u n); - BigNumber& operator *= (const BigNumber& bn); - BigNumber& operator /= (const BigNumber& bn); - BigNumber& operator %= (const BigNumber& bn); - friend BigNumber operator + (const BigNumber& a, const BigNumber& b); - friend BigNumber operator - (const BigNumber& a, const BigNumber& b); - friend BigNumber operator * (const BigNumber& a, const BigNumber& b); - friend BigNumber operator * (const BigNumber& a, Ipp32u); - friend BigNumber operator % (const BigNumber& a, const BigNumber& b); - friend BigNumber operator / (const BigNumber& a, const BigNumber& b); - - // modulo arithmetic - BigNumber Modulo(const BigNumber& a) const; - BigNumber ModAdd(const BigNumber& a, const BigNumber& b) const; - BigNumber ModSub(const BigNumber& a, const BigNumber& b) const; - BigNumber ModMul(const BigNumber& a, const BigNumber& b) const; - BigNumber InverseAdd(const BigNumber& a) const; - BigNumber InverseMul(const BigNumber& a) const; - - // comparisons - friend bool operator < (const BigNumber& a, const BigNumber& b); - friend bool operator > (const BigNumber& a, const BigNumber& b); - friend bool operator == (const BigNumber& a, const BigNumber& b); - friend bool operator != (const BigNumber& a, const BigNumber& b); - friend bool operator <= (const BigNumber& a, const BigNumber& b) {return !(a>b);} - friend bool operator >= (const BigNumber& a, const BigNumber& b) {return !(a>5;} - friend int Bit(const vector& v, int n); - - // conversion and output - void num2hex( string& s ) const; // convert to hex string - void num2vec( vector& v ) const; // convert to 32-bit word vector - friend ostream& operator << (ostream& os, const BigNumber& a); - -protected: - bool create(const Ipp32u* pData, int length, IppsBigNumSGN sgn=IppsBigNumPOS); - int compare(const BigNumber& ) const; - IppsBigNumState* m_pBN; -}; - -// convert bit size into 32-bit words -#define BITSIZE_WORD(n) ((((n)+31)>>5)) - -#endif // _BIGNUMBER_H_ diff --git a/utils/utils.cpp b/utils/utils.cpp deleted file mode 100644 index a89e150..0000000 --- a/utils/utils.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* -* Copyright 2021 Intel Corporation -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*******************************************************************************/ - - -#include "utils.h" - -size_t strlen_safe(const char* dest, size_t dmax) { - size_t count; - - /* check null pointer */ - if (NULL == dest) { - return 0UL; - } - - /* check max equal zero */ - if (0UL == dmax) { - return 0UL; - } - - /* check dmax > 4Kb */ - if (dmax > RSIZE_MAX_STR) { - return 0UL; - } - - count = 0UL; - while (*dest && dmax) { - ++count; - --dmax; - ++dest; - } - - return count; -} diff --git a/utils/utils.h b/utils/utils.h deleted file mode 100644 index 6b1f079..0000000 --- a/utils/utils.h +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* -* Copyright 2021 Intel Corporation -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*******************************************************************************/ -#ifndef _UTILS_H_ -#define _UTILS_H_ - -#include - -#define RSIZE_MAX_STR (4UL << 10) /* 4Kb */ - -/** - * \brief - * The strnlen_s function computes the length of the string pointed to by dest. - * \param[in] dest pointer to string - * \param[in] dmax restricted maximum length. (default 4Kb) - * \return size_t - * The function returns the string length, excluding the terminating - * null character. If dest is NULL, then strnlen_s returns 0. - */ -size_t strlen_safe(const char* dest, size_t dmax = RSIZE_MAX_STR); - -#endif // _UTILS_H_ From 3a5d9d9410e4956de54541fa9eab58405c65b431 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 9 Mar 2022 18:05:28 -0800 Subject: [PATCH 092/364] Add misc to replace utils. --- he_qat_misc.cpp | 107 +++++++++++ he_qat_misc.h | 47 +++++ misc/CMakeLists.txt | 23 +++ misc/bignum.cpp | 437 ++++++++++++++++++++++++++++++++++++++++++++ misc/bignum.h | 106 +++++++++++ misc/utils.cpp | 46 +++++ misc/utils.h | 34 ++++ 7 files changed, 800 insertions(+) create mode 100644 he_qat_misc.cpp create mode 100644 he_qat_misc.h create mode 100644 misc/CMakeLists.txt create mode 100644 misc/bignum.cpp create mode 100644 misc/bignum.h create mode 100644 misc/utils.cpp create mode 100644 misc/utils.h diff --git a/he_qat_misc.cpp b/he_qat_misc.cpp new file mode 100644 index 0000000..b975e4b --- /dev/null +++ b/he_qat_misc.cpp @@ -0,0 +1,107 @@ +#include "he_qat_misc.h" + +//#ifdef __cplusplus +//#include "bignum.h" +//#endif + +#include +#include + +BIGNUM* generateTestBNData(int nbits) { + if (!RAND_status()) return NULL; +#ifdef _DESTINY_DEBUG_VERBOSE + printf("PRNG properly seeded.\n"); +#endif + + BIGNUM* bn = BN_new(); + + if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { + BN_free(bn); + printf("Error while generating BN random number: %lu\n", + ERR_get_error()); + return NULL; + } + + return bn; +} + +unsigned char* paddingZeros(BIGNUM* bn, int nbits) { + if (!bn) return NULL; + + // Returns same address if it fails + int num_bytes = BN_num_bytes(bn); + int bytes_left = nbits / 8 - num_bytes; + if (bytes_left <= 0) return NULL; + + // Returns same address if it fails + unsigned char* bin = NULL; + int len = bytes_left + num_bytes; + if (!(bin = reinterpret_cast(OPENSSL_zalloc(len)))) return NULL; + +#ifdef _DESTINY_DEBUG_VERBOSE + printf("Padding bn with %d bytes to total %d bytes\n", bytes_left, len); +#endif + BN_bn2binpad(bn, bin, len); + if (ERR_get_error()) { + OPENSSL_free(bin); + return NULL; + } + + return bin; +} + +void showHexBN(BIGNUM* bn, int nbits) { + int len = nbits / 8; + unsigned char* bin = reinterpret_cast(OPENSSL_zalloc(len)); + if (!bin) return; + if (BN_bn2binpad(bn, bin, len)) { + for (size_t i = 0; i < len; i++) printf("%d", bin[i]); + printf("\n"); + } + OPENSSL_free(bin); + return; +} + +void showHexBin(unsigned char* bin, int len) { + if (!bin) return; + for (size_t i = 0; i < len; i++) printf("%d", bin[i]); + printf("\n"); + return; +} + +//#ifdef __cplusplus +HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, + int nbits) { + if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; + int len_ = (nbits + 7) >> 3; // nbits/8; + + // Create BigNumber containg input data passed as argument + bn = BigNumber(reinterpret_cast(data), BITSIZE_WORD(nbits)); + Ipp32u* ref_bn_data_ = NULL; + ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); + + // Convert it to little endian format + unsigned char* data_ = reinterpret_cast(ref_bn_data_); + for (int i = 0; i < len_; i++) data_[i] = data[len_ - 1 - i]; + + return HE_QAT_STATUS_SUCCESS; +} + +HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, + const BigNumber& bn) { + if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; + int len_ = (nbits + 7) >> 3; // nbits/8; + + // Extract raw vector of data in little endian format + Ipp32u* ref_bn_data_ = NULL; + ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); + + // Revert it to big endian format + unsigned char* data_ = reinterpret_cast(ref_bn_data_); + for (int i = 0; i < len_; i++) data[i] = data_[len_ - 1 - i]; + + return HE_QAT_STATUS_SUCCESS; +} + +//} // extern "C" { +//#endif diff --git a/he_qat_misc.h b/he_qat_misc.h new file mode 100644 index 0000000..4c29bee --- /dev/null +++ b/he_qat_misc.h @@ -0,0 +1,47 @@ + +#ifndef HE_QAT_MISC_H_ +#define HE_QAT_MISC_H_ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +#include "he_qat_types.h" +#include "bignum.h" +#include + +//#define LEN_OF_1024_BITS 128 +//#define LEN_OF_2048_BITS 256 +//#define msb_CAN_BE_ZERO -1 +//#define msb_IS_ONE 0 +//#define EVEN_RND_NUM 0 +//#define ODD_RND_NUM 1 +//#define BATCH_SIZE 1 + +BIGNUM* generateTestBNData(int nbits); +unsigned char* paddingZeros(BIGNUM* bn, int nbits); +void showHexBN(BIGNUM* bn, int nbits); +void showHexBin(unsigned char* bin, int len); + +//#ifdef __cplusplus +/// @brief +/// @function binToBigNumber +/// Converts/encapsulates QAT's raw large number data to/into a BigNumber +/// object. data will be changed to little endian format in this function, +/// therefore the +HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, + int nbits); +/// @brief +/// @function bigNumberToBin +/// Convert BigNumber object into raw data compatible with QAT. +/// @param[out] data BigNumber object's raw data in big endian format. +/// @param[in] nbits Number of bits. Has to be power of 2, e.g. 1024, 2048, +/// 4096, etc. +/// @param[in] bn BigNumber object holding a multi-precision that can be +/// represented in nbits. +HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, + const BigNumber& bn); +//} // extern "C" { +//#endif + +#endif // HE_QAT_MISC_H_ diff --git a/misc/CMakeLists.txt b/misc/CMakeLists.txt new file mode 100644 index 0000000..a1e5ca0 --- /dev/null +++ b/misc/CMakeLists.txt @@ -0,0 +1,23 @@ + +# Include directories +list(APPEND HE_QAT_MISC_INC_DIR + ${CMAKE_CURRENT_LIST_DIR} + ${IPPCP_DIR}/include +) +message(STATUS "HE_QAT_MISC_INC_DIR: ${HE_QAT_MISC_INC_DIR}") + +# Source files +list(APPEND HE_QAT_MISC_SRC ${CMAKE_CURRENT_LIST_DIR}/utils.cpp + ${CMAKE_CURRENT_LIST_DIR}/bignum.cpp +) + +add_library(he_qat_misc ${HE_QAT_MISC_SRC}) +target_include_directories(he_qat_misc + PUBLIC $ # Public headers + PUBLIC $ # Public headers +) +target_link_directories(he_qat_misc PUBLIC ${IPPCP_DIR}/lib/intel64) +target_link_libraries(he_qat_misc PUBLIC ippcpmx crypto_mb) + +set(HE_QAT_MISC_INC_DIR ${HE_QAT_MISC_INC_DIR} PARENT_SCOPE) + diff --git a/misc/bignum.cpp b/misc/bignum.cpp new file mode 100644 index 0000000..57a372c --- /dev/null +++ b/misc/bignum.cpp @@ -0,0 +1,437 @@ +/******************************************************************************* +* Copyright 2019-2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#include "bignum.h" +#include +#include +#include "utils.h" + +////////////////////////////////////////////////////////////////////// +// +// BigNumber +// +////////////////////////////////////////////////////////////////////// +BigNumber::~BigNumber() +{ + delete [] (Ipp8u*)m_pBN; +} + +bool BigNumber::create(const Ipp32u* pData, int length, IppsBigNumSGN sgn) +{ + int size; + ippsBigNumGetSize(length, &size); + m_pBN = (IppsBigNumState*)( new Ipp8u[size] ); + if(!m_pBN) + return false; + ippsBigNumInit(length, m_pBN); + if (pData) + ippsSet_BN(sgn, length, pData, m_pBN); + return true; +} + +// +// constructors +// +BigNumber::BigNumber(Ipp32u value) +{ + create(&value, 1, IppsBigNumPOS); +} + +BigNumber::BigNumber(Ipp32s value) +{ + Ipp32s avalue = abs(value); + create((Ipp32u*)&avalue, 1, (value<0)? IppsBigNumNEG : IppsBigNumPOS); +} + +BigNumber::BigNumber(const IppsBigNumState* pBN) +{ + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, pBN); + + create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); +} + +BigNumber::BigNumber(const Ipp32u* pData, int length, IppsBigNumSGN sgn) +{ + create(pData, length, sgn); +} + +static char HexDigitList[] = "0123456789ABCDEF"; + +BigNumber::BigNumber(const char* s) +{ + bool neg = '-' == s[0]; + if(neg) s++; + bool hex = ('0'==s[0]) && (('x'==s[1]) || ('X'==s[1])); + + int dataLen; + Ipp32u base; + if(hex) { + s += 2; + base = 0x10; + dataLen = (int)(strlen_safe(s) + 7)/8; + } + else { + base = 10; + dataLen = (int)(strlen_safe(s) + 9)/10; + } + + create(0, dataLen); + *(this) = Zero(); + while(*s) { + char tmp[2] = {s[0],0}; + Ipp32u digit = (Ipp32u)strcspn(HexDigitList, tmp); + *this = (*this) * base + BigNumber( digit ); + s++; + } + + if(neg) + (*this) = Zero()- (*this); +} + +BigNumber::BigNumber(const BigNumber& bn) +{ + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); + + create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); +} + +// +// set value +// +void BigNumber::Set(const Ipp32u* pData, int length, IppsBigNumSGN sgn) +{ + ippsSet_BN(sgn, length, pData, BN(*this)); +} + +// +// constants +// +const BigNumber& BigNumber::Zero() +{ + static const BigNumber zero(0); + return zero; +} + +const BigNumber& BigNumber::One() +{ + static const BigNumber one(1); + return one; +} + +const BigNumber& BigNumber::Two() +{ + static const BigNumber two(2); + return two; +} + +// +// arithmetic operators +// +BigNumber& BigNumber::operator =(const BigNumber& bn) +{ + if(this != &bn) { // prevent self copy + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); + + delete [] (Ipp8u*)m_pBN; + create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); + } + return *this; +} + +BigNumber& BigNumber::operator += (const BigNumber& bn) +{ + int aBitLen; + ippsRef_BN(NULL, &aBitLen, NULL, *this); + int bBitLen; + ippsRef_BN(NULL, &bBitLen, NULL, bn); + int rBitLen = IPP_MAX(aBitLen, bBitLen) + 1; + + BigNumber result(0, BITSIZE_WORD(rBitLen)); + ippsAdd_BN(*this, bn, result); + *this = result; + return *this; +} + +BigNumber& BigNumber::operator -= (const BigNumber& bn) +{ + int aBitLen; + ippsRef_BN(NULL, &aBitLen, NULL, *this); + int bBitLen; + ippsRef_BN(NULL, &bBitLen, NULL, bn); + int rBitLen = IPP_MAX(aBitLen, bBitLen); + + BigNumber result(0, BITSIZE_WORD(rBitLen)); + ippsSub_BN(*this, bn, result); + *this = result; + return *this; +} + +BigNumber& BigNumber::operator *= (const BigNumber& bn) +{ + int aBitLen; + ippsRef_BN(NULL, &aBitLen, NULL, *this); + int bBitLen; + ippsRef_BN(NULL, &bBitLen, NULL, bn); + int rBitLen = aBitLen + bBitLen; + + BigNumber result(0, BITSIZE_WORD(rBitLen)); + ippsMul_BN(*this, bn, result); + *this = result; + return *this; +} + +BigNumber& BigNumber::operator *= (Ipp32u n) +{ + int aBitLen; + ippsRef_BN(NULL, &aBitLen, NULL, *this); + + BigNumber result(0, BITSIZE_WORD(aBitLen+32)); + BigNumber bn(n); + ippsMul_BN(*this, bn, result); + *this = result; + return *this; +} + +BigNumber& BigNumber::operator %= (const BigNumber& bn) +{ + BigNumber remainder(bn); + ippsMod_BN(BN(*this), BN(bn), BN(remainder)); + *this = remainder; + return *this; +} + +BigNumber& BigNumber::operator /= (const BigNumber& bn) +{ + BigNumber quotient(*this); + BigNumber remainder(bn); + ippsDiv_BN(BN(*this), BN(bn), BN(quotient), BN(remainder)); + *this = quotient; + return *this; +} + +BigNumber operator + (const BigNumber& a, const BigNumber& b ) +{ + BigNumber r(a); + return r += b; +} + +BigNumber operator - (const BigNumber& a, const BigNumber& b ) +{ + BigNumber r(a); + return r -= b; +} + +BigNumber operator * (const BigNumber& a, const BigNumber& b ) +{ + BigNumber r(a); + return r *= b; +} + +BigNumber operator * (const BigNumber& a, Ipp32u n) +{ + BigNumber r(a); + return r *= n; +} + +BigNumber operator / (const BigNumber& a, const BigNumber& b ) +{ + BigNumber q(a); + return q /= b; +} + +BigNumber operator % (const BigNumber& a, const BigNumber& b ) +{ + BigNumber r(b); + ippsMod_BN(BN(a), BN(b), BN(r)); + return r; +} + +// +// modulo arithmetic +// +BigNumber BigNumber::Modulo(const BigNumber& a) const +{ + return a % *this; +} + +BigNumber BigNumber::InverseAdd(const BigNumber& a) const +{ + BigNumber t = Modulo(a); + if(t==BigNumber::Zero()) + return t; + else + return *this - t; +} + +BigNumber BigNumber::InverseMul(const BigNumber& a) const +{ + BigNumber r(*this); + ippsModInv_BN(BN(a), BN(*this), BN(r)); + return r; +} + +BigNumber BigNumber::ModAdd(const BigNumber& a, const BigNumber& b) const +{ + BigNumber r = this->Modulo(a+b); + return r; +} + +BigNumber BigNumber::ModSub(const BigNumber& a, const BigNumber& b) const +{ + BigNumber r = this->Modulo(a + this->InverseAdd(b)); + return r; +} + +BigNumber BigNumber::ModMul(const BigNumber& a, const BigNumber& b) const +{ + BigNumber r = this->Modulo(a*b); + return r; +} + +// +// comparison +// +int BigNumber::compare(const BigNumber &bn) const +{ + Ipp32u result; + BigNumber tmp = *this - bn; + ippsCmpZero_BN(BN(tmp), &result); + return (result==IS_ZERO)? 0 : (result==GREATER_THAN_ZERO)? 1 : -1; +} + +bool operator < (const BigNumber &a, const BigNumber &b) { return a.compare(b) < 0; } +bool operator > (const BigNumber &a, const BigNumber &b) { return a.compare(b) > 0; } +bool operator == (const BigNumber &a, const BigNumber &b) { return 0 == a.compare(b);} +bool operator != (const BigNumber &a, const BigNumber &b) { return 0 != a.compare(b);} + +// easy tests +// +bool BigNumber::IsOdd() const +{ + Ipp32u* bnData; + ippsRef_BN(NULL, NULL, &bnData, *this); + return bnData[0]&1; +} + +// +// size of BigNumber +// +int BigNumber::LSB() const +{ + if( *this == BigNumber::Zero() ) + return 0; + + vector v; + num2vec(v); + + int lsb = 0; + vector::iterator i; + for(i=v.begin(); i!=v.end(); i++) { + Ipp32u x = *i; + if(0==x) + lsb += 32; + else { + while(0==(x&1)) { + lsb++; + x >>= 1; + } + break; + } + } + return lsb; +} + +int BigNumber::MSB() const +{ + if( *this == BigNumber::Zero() ) + return 0; + + vector v; + num2vec(v); + + int msb = (int)v.size()*32 -1; + vector::reverse_iterator i; + for(i=v.rbegin(); i!=v.rend(); i++) { + Ipp32u x = *i; + if(0==x) + msb -=32; + else { + while(!(x&0x80000000)) { + msb--; + x <<= 1; + } + break; + } + } + return msb; +} + +int Bit(const vector& v, int n) +{ + return 0 != ( v[n>>5] & (1<<(n&0x1F)) ); +} + +// +// conversions and output +// +void BigNumber::num2vec( vector& v ) const +{ + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(NULL, &bnBitLen, &bnData, *this); + + int len = BITSIZE_WORD(bnBitLen);; + for(int n=0; n0; n--) { + Ipp32u x = bnData[n-1]; + for(int nd=8; nd>0; nd--) { + char c = HexDigitList[(x>>(nd-1)*4)&0xF]; + s.append(1, c); + } + } +} + +ostream& operator << ( ostream &os, const BigNumber& a) +{ + string s; + a.num2hex(s); + os << s.c_str(); + return os; +} diff --git a/misc/bignum.h b/misc/bignum.h new file mode 100644 index 0000000..51696d1 --- /dev/null +++ b/misc/bignum.h @@ -0,0 +1,106 @@ +/******************************************************************************* +* Copyright 2019-2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#if !defined _BIGNUMBER_H_ +#define _BIGNUMBER_H_ + +#include "ippcp.h" + +#include +#include +#include + +using namespace std; + +class BigNumber +{ +public: + BigNumber(Ipp32u value=0); + BigNumber(Ipp32s value); + BigNumber(const IppsBigNumState* pBN); + BigNumber(const Ipp32u* pData, int length=1, IppsBigNumSGN sgn=IppsBigNumPOS); + BigNumber(const BigNumber& bn); + BigNumber(const char *s); + virtual ~BigNumber(); + + // set value + void Set(const Ipp32u* pData, int length=1, IppsBigNumSGN sgn=IppsBigNumPOS); + // conversion to IppsBigNumState + friend IppsBigNumState* BN(const BigNumber& bn) {return bn.m_pBN;} + operator IppsBigNumState* () const { return m_pBN; } + + // some useful constatns + static const BigNumber& Zero(); + static const BigNumber& One(); + static const BigNumber& Two(); + + // arithmetic operators probably need + BigNumber& operator = (const BigNumber& bn); + BigNumber& operator += (const BigNumber& bn); + BigNumber& operator -= (const BigNumber& bn); + BigNumber& operator *= (Ipp32u n); + BigNumber& operator *= (const BigNumber& bn); + BigNumber& operator /= (const BigNumber& bn); + BigNumber& operator %= (const BigNumber& bn); + friend BigNumber operator + (const BigNumber& a, const BigNumber& b); + friend BigNumber operator - (const BigNumber& a, const BigNumber& b); + friend BigNumber operator * (const BigNumber& a, const BigNumber& b); + friend BigNumber operator * (const BigNumber& a, Ipp32u); + friend BigNumber operator % (const BigNumber& a, const BigNumber& b); + friend BigNumber operator / (const BigNumber& a, const BigNumber& b); + + // modulo arithmetic + BigNumber Modulo(const BigNumber& a) const; + BigNumber ModAdd(const BigNumber& a, const BigNumber& b) const; + BigNumber ModSub(const BigNumber& a, const BigNumber& b) const; + BigNumber ModMul(const BigNumber& a, const BigNumber& b) const; + BigNumber InverseAdd(const BigNumber& a) const; + BigNumber InverseMul(const BigNumber& a) const; + + // comparisons + friend bool operator < (const BigNumber& a, const BigNumber& b); + friend bool operator > (const BigNumber& a, const BigNumber& b); + friend bool operator == (const BigNumber& a, const BigNumber& b); + friend bool operator != (const BigNumber& a, const BigNumber& b); + friend bool operator <= (const BigNumber& a, const BigNumber& b) {return !(a>b);} + friend bool operator >= (const BigNumber& a, const BigNumber& b) {return !(a>5;} + friend int Bit(const vector& v, int n); + + // conversion and output + void num2hex( string& s ) const; // convert to hex string + void num2vec( vector& v ) const; // convert to 32-bit word vector + friend ostream& operator << (ostream& os, const BigNumber& a); + +protected: + bool create(const Ipp32u* pData, int length, IppsBigNumSGN sgn=IppsBigNumPOS); + int compare(const BigNumber& ) const; + IppsBigNumState* m_pBN; +}; + +// convert bit size into 32-bit words +#define BITSIZE_WORD(n) ((((n)+31)>>5)) + +#endif // _BIGNUMBER_H_ diff --git a/misc/utils.cpp b/misc/utils.cpp new file mode 100644 index 0000000..a89e150 --- /dev/null +++ b/misc/utils.cpp @@ -0,0 +1,46 @@ +/******************************************************************************* +* Copyright 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + + +#include "utils.h" + +size_t strlen_safe(const char* dest, size_t dmax) { + size_t count; + + /* check null pointer */ + if (NULL == dest) { + return 0UL; + } + + /* check max equal zero */ + if (0UL == dmax) { + return 0UL; + } + + /* check dmax > 4Kb */ + if (dmax > RSIZE_MAX_STR) { + return 0UL; + } + + count = 0UL; + while (*dest && dmax) { + ++count; + --dmax; + ++dest; + } + + return count; +} diff --git a/misc/utils.h b/misc/utils.h new file mode 100644 index 0000000..6b1f079 --- /dev/null +++ b/misc/utils.h @@ -0,0 +1,34 @@ +/******************************************************************************* +* Copyright 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ +#ifndef _UTILS_H_ +#define _UTILS_H_ + +#include + +#define RSIZE_MAX_STR (4UL << 10) /* 4Kb */ + +/** + * \brief + * The strnlen_s function computes the length of the string pointed to by dest. + * \param[in] dest pointer to string + * \param[in] dmax restricted maximum length. (default 4Kb) + * \return size_t + * The function returns the string length, excluding the terminating + * null character. If dest is NULL, then strnlen_s returns 0. + */ +size_t strlen_safe(const char* dest, size_t dmax = RSIZE_MAX_STR); + +#endif // _UTILS_H_ From 4ba5624c826a792cd4cfac3a9927a67b812de30b Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 9 Mar 2022 18:06:37 -0800 Subject: [PATCH 093/364] Update test case to reflect new changes with misc. --- test_bnConversion.cpp | 235 +++++++++++++++++++++--------------------- 1 file changed, 118 insertions(+), 117 deletions(-) diff --git a/test_bnConversion.cpp b/test_bnConversion.cpp index b827912..f0c9633 100644 --- a/test_bnConversion.cpp +++ b/test_bnConversion.cpp @@ -1,6 +1,7 @@ #include "cpa_sample_utils.h" +#include "he_qat_misc.h" #include "he_qat_bn_ops.h" #include "he_qat_context.h" @@ -20,131 +21,131 @@ extern "C" { #include #include "ippcp.h" -#include "bignum.h" +//#include "bignum.h" -#include +//#include #include -#define LEN_OF_1024_BITS 128 -#define LEN_OF_2048_BITS 256 -#define msb_CAN_BE_ZERO -1 -#define msb_IS_ONE 0 -#define EVEN_RND_NUM 0 -#define ODD_RND_NUM 1 -#define BATCH_SIZE 1 +//#define LEN_OF_1024_BITS 128 +//#define LEN_OF_2048_BITS 256 +//#define msb_CAN_BE_ZERO -1 +//#define msb_IS_ONE 0 +//#define EVEN_RND_NUM 0 +//#define ODD_RND_NUM 1 +//#define BATCH_SIZE 1 -using namespace std; +//using namespace std; // int gDebugParam = 1; -BIGNUM* generateTestBNData(int nbits) { - if (!RAND_status()) return NULL; -#ifdef _DESTINY_DEBUG_VERBOSE - printf("PRNG properly seeded.\n"); -#endif - - BIGNUM* bn = BN_new(); - - if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { - BN_free(bn); - printf("Error while generating BN random number: %lu\n", - ERR_get_error()); - return NULL; - } - - return bn; -} - -unsigned char* paddingZeros(BIGNUM* bn, int nbits) { - if (!bn) return NULL; - - // Returns same address if it fails - int num_bytes = BN_num_bytes(bn); - int bytes_left = nbits / 8 - num_bytes; - if (bytes_left <= 0) return NULL; - - // Returns same address if it fails - unsigned char* bin = NULL; - int len = bytes_left + num_bytes; - if (!(bin = (unsigned char*)OPENSSL_zalloc(len))) return NULL; - -#ifdef _DESTINY_DEBUG_VERBOSE - printf("Padding bn with %d bytes to total %d bytes\n", bytes_left, len); -#endif - BN_bn2binpad(bn, bin, len); - if (ERR_get_error()) { - OPENSSL_free(bin); - return NULL; - } - - return bin; -} - -void showHexBN(BIGNUM* bn, int nbits) { - int len = nbits / 8; - unsigned char* bin = (unsigned char*)OPENSSL_zalloc(len); - if (!bin) return; - if (BN_bn2binpad(bn, bin, len)) { - for (size_t i = 0; i < len; i++) printf("%d", bin[i]); - printf("\n"); - } - OPENSSL_free(bin); - return; -} - -void showHexBin(unsigned char* bin, int len) { - if (!bin) return; - for (size_t i = 0; i < len; i++) printf("%d", bin[i]); - printf("\n"); - return; -} - -/// @brief -/// @function binToBigNumber +//BIGNUM* generateTestBNData(int nbits) { +// if (!RAND_status()) return NULL; +//#ifdef _DESTINY_DEBUG_VERBOSE +// printf("PRNG properly seeded.\n"); +//#endif // -/// data will be changed to little endian format in this function, therefore the -/// abscence of const in front -HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, - int nbits) { - if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; - int len_ = (nbits + 7) >> 3; // nbits/8; - - // Create BigNumber containg input data passed as argument - bn = BigNumber(reinterpret_cast(data), BITSIZE_WORD(nbits)); - Ipp32u* ref_bn_data_ = NULL; - ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); - - // Convert it to little endian format - unsigned char* data_ = reinterpret_cast(ref_bn_data_); - for (int i = 0; i < len_; i++) data_[i] = data[len_ - 1 - i]; - - return HE_QAT_STATUS_SUCCESS; -} - -/// @brief -/// @function bigNumberToBin -/// Converts/encapsulates big number data to/into an object of BigNumber's -/// type/class. -/// @param[out] data BigNumber object's raw data in big endian format. -/// @param[in] nbits Number of bits. Has to be power of 2, e.g. 1024, 2048, -/// 4096, etc. -/// @param[in] bn BigNumber object holding a multi-precision that can be -/// represented in nbits. -HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, - const BigNumber& bn) { - if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; - int len_ = (nbits + 7) >> 3; // nbits/8; - - // Extract raw vector of data in little endian format - Ipp32u* ref_bn_data_ = NULL; - ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); - - // Revert it to big endian format - unsigned char* data_ = reinterpret_cast(ref_bn_data_); - for (int i = 0; i < len_; i++) data[i] = data_[len_ - 1 - i]; - - return HE_QAT_STATUS_SUCCESS; -} +// BIGNUM* bn = BN_new(); +// +// if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { +// BN_free(bn); +// printf("Error while generating BN random number: %lu\n", +// ERR_get_error()); +// return NULL; +// } +// +// return bn; +//} +// +//unsigned char* paddingZeros(BIGNUM* bn, int nbits) { +// if (!bn) return NULL; +// +// // Returns same address if it fails +// int num_bytes = BN_num_bytes(bn); +// int bytes_left = nbits / 8 - num_bytes; +// if (bytes_left <= 0) return NULL; +// +// // Returns same address if it fails +// unsigned char* bin = NULL; +// int len = bytes_left + num_bytes; +// if (!(bin = (unsigned char*)OPENSSL_zalloc(len))) return NULL; +// +//#ifdef _DESTINY_DEBUG_VERBOSE +// printf("Padding bn with %d bytes to total %d bytes\n", bytes_left, len); +//#endif +// BN_bn2binpad(bn, bin, len); +// if (ERR_get_error()) { +// OPENSSL_free(bin); +// return NULL; +// } +// +// return bin; +//} +// +//void showHexBN(BIGNUM* bn, int nbits) { +// int len = nbits / 8; +// unsigned char* bin = (unsigned char*)OPENSSL_zalloc(len); +// if (!bin) return; +// if (BN_bn2binpad(bn, bin, len)) { +// for (size_t i = 0; i < len; i++) printf("%d", bin[i]); +// printf("\n"); +// } +// OPENSSL_free(bin); +// return; +//} +// +//void showHexBin(unsigned char* bin, int len) { +// if (!bin) return; +// for (size_t i = 0; i < len; i++) printf("%d", bin[i]); +// printf("\n"); +// return; +//} +// +///// @brief +///// @function binToBigNumber +//// +///// data will be changed to little endian format in this function, therefore the +///// abscence of const in front +//HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, +// int nbits) { +// if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; +// int len_ = (nbits + 7) >> 3; // nbits/8; +// +// // Create BigNumber containg input data passed as argument +// bn = BigNumber(reinterpret_cast(data), BITSIZE_WORD(nbits)); +// Ipp32u* ref_bn_data_ = NULL; +// ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); +// +// // Convert it to little endian format +// unsigned char* data_ = reinterpret_cast(ref_bn_data_); +// for (int i = 0; i < len_; i++) data_[i] = data[len_ - 1 - i]; +// +// return HE_QAT_STATUS_SUCCESS; +//} +// +///// @brief +///// @function bigNumberToBin +///// Converts/encapsulates big number data to/into an object of BigNumber's +///// type/class. +///// @param[out] data BigNumber object's raw data in big endian format. +///// @param[in] nbits Number of bits. Has to be power of 2, e.g. 1024, 2048, +///// 4096, etc. +///// @param[in] bn BigNumber object holding a multi-precision that can be +///// represented in nbits. +//HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, +// const BigNumber& bn) { +// if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; +// int len_ = (nbits + 7) >> 3; // nbits/8; +// +// // Extract raw vector of data in little endian format +// Ipp32u* ref_bn_data_ = NULL; +// ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); +// +// // Revert it to big endian format +// unsigned char* data_ = reinterpret_cast(ref_bn_data_); +// for (int i = 0; i < len_; i++) data[i] = data_[len_ - 1 - i]; +// +// return HE_QAT_STATUS_SUCCESS; +//} int main(int argc, const char** argv) { const int bit_length = 1024; From ce0f12b5063d474e0ac8e90512209ce288980cce Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 9 Mar 2022 18:07:46 -0800 Subject: [PATCH 094/364] Update the cmake build system to include misc. --- CMakeLists.txt | 49 ++++++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 70143dd..c13cb41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,18 +36,29 @@ add_definitions(-DDO_CRYPTO) add_definitions(-DUSER_SPACE) add_compile_options(-fPIC) - # Common utility functions add_subdirectory(common) +set(IPPCP_DIR "/opt/ipp-crypto") +set(IPPCP_CMAKE_PREFIX_DIR "${IPPCP_DIR}/lib/cmake") +list(APPEND CMAKE_PREFIX_PATH "${IPPCP_CMAKE_PREFIX_DIR}") +find_package(ippcp REQUIRED) + +set(HE_QAT_MISC_INC_DIR ${COMMON_INC_DIR} ${CMAKE_CURRENT_LIST_DIR}) +set(HE_QAT_MISC_SRC ${CMAKE_CURRENT_LIST_DIR}/he_qat_misc.cpp) +add_subdirectory(misc) + set(HE_QAT_SRC ${CMAKE_CURRENT_LIST_DIR}/he_qat_bn_ops.c ${CMAKE_CURRENT_LIST_DIR}/he_qat_context.c) -add_library(he_qat SHARED ${HE_QAT_SRC}) + +add_library(he_qat SHARED ${HE_QAT_SRC}) # Let BUILD_SHARED_LIBS do the job by removing the qualifier SHARED target_include_directories(he_qat PUBLIC ${COMMON_INC_DIR}) +#target_include_directories(he_qat PUBLIC ${HE_QAT_MISC_INC_DIR}) target_include_directories(he_qat PUBLIC /opt/openssl/include) target_link_directories(he_qat PUBLIC ${ICP_BUILDOUTPUT_PATH}) target_link_directories(he_qat PUBLIC /opt/openssl/lib) target_link_libraries(he_qat PRIVATE cpa_sample_utils) +#target_link_libraries(he_qat PRIVATE he_qat_utils) target_link_libraries(he_qat PUBLIC qat_s usdm_drv_s) target_link_libraries(he_qat PUBLIC crypto ssl) target_link_libraries(he_qat PUBLIC z pthread) @@ -58,14 +69,12 @@ if(NOT HE_QAT_DEBUG_VERBOSE) endif() add_executable(test_context test_context.c) +target_include_directories(test_context PUBLIC ${HE_QAT_MISC_INC_DIR}) target_link_libraries(test_context PUBLIC he_qat) -target_link_libraries(test_context PUBLIC cpa_sample_utils) +#target_link_libraries(test_context PUBLIC cpa_sample_utils) target_link_libraries(test_context PUBLIC z pthread ssl crypto qat_s usdm_drv_s) -set(IPPCP_DIR "/opt/ipp-crypto") -set(IPPCP_CMAKE_PREFIX_DIR "${IPPCP_DIR}/lib/cmake") -list(APPEND CMAKE_PREFIX_PATH "${IPPCP_CMAKE_PREFIX_DIR}") -find_package(ippcp REQUIRED) + #find_package(IPPCrypto REQUIRED MODULE) #if (NOT IPPCRYPTO_FOUND) # message(FATAL_ERROR "No Intel IPP Cryptography library found on the system.") @@ -76,31 +85,21 @@ find_package(ippcp REQUIRED) # message(STATUS "TARGET IPPCP::ippcp found") #endif() -set(HE_QAT_UTILS_INC_DIR "") -add_subdirectory(utils) + add_executable(test_bnModExpPerformOp test_bnModExpPerformOp.c) +#target_include_directories(test_bnModExpPerformOp PUBLIC ${HE_QAT_UTILS_INC_DIR}) target_link_libraries(test_bnModExpPerformOp PUBLIC he_qat) -target_link_libraries(test_bnModExpPerformOp PUBLIC cpa_sample_utils) +#target_link_libraries(test_bnModExpPerformOp PUBLIC cpa_sample_utils) target_link_libraries(test_bnModExpPerformOp PUBLIC z pthread ssl crypto qat_s usdm_drv_s) -#add_compile_options(-fpermissive) -#add_executable(test_ippModExpPerformOp test_ippModExpPerformOp.cpp) -#target_include_directories(test_ippModExpPerformOp PUBLIC ${COMMON_INC_DIR} ${HE_QAT_UTILS_INC_DIR}) -#target_link_libraries(test_ippModExpPerformOp PUBLIC he_qat) -#target_link_libraries(test_ippModExpPerformOp PUBLIC he_qat_utils) -#target_link_libraries(test_ippModExpPerformOp PUBLIC cpa_sample_utils) -#target_link_libraries(test_ippModExpPerformOp PUBLIC ippcpmx crypto_mb) -#target_link_libraries(test_ippModExpPerformOp PUBLIC z pthread ssl crypto qat_s usdm_drv_s) - add_compile_options(-fpermissive) add_executable(test_bnConversion test_bnConversion.cpp) -target_include_directories(test_bnConversion PUBLIC ${COMMON_INC_DIR} ${HE_QAT_UTILS_INC_DIR}) +target_include_directories(test_bnConversion PUBLIC ${HE_QAT_MISC_INC_DIR}) target_link_libraries(test_bnConversion PUBLIC he_qat) -target_link_libraries(test_bnConversion PUBLIC he_qat_utils) -target_link_libraries(test_bnConversion PUBLIC cpa_sample_utils) -target_link_libraries(test_bnConversion PUBLIC ippcpmx crypto_mb) +target_link_libraries(test_bnConversion PUBLIC he_qat_misc) +#target_link_libraries(test_bnConversion PUBLIC he_qat_utils) +#target_link_libraries(test_bnConversion PUBLIC cpa_sample_utils) +#target_link_libraries(test_bnConversion PUBLIC ippcpmx crypto_mb) target_link_libraries(test_bnConversion PUBLIC z pthread ssl crypto qat_s usdm_drv_s) -# Compile test case -#add_subdirectory(ln_mod_exp) From 90ac815b49abee54b01f38058fcddc68586e1b71 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 9 Mar 2022 18:08:54 -0800 Subject: [PATCH 095/364] Remove utils source code. --- he_qat_utils.c | 109 ------------------------------------------------- he_qat_utils.h | 45 -------------------- 2 files changed, 154 deletions(-) delete mode 100644 he_qat_utils.c delete mode 100644 he_qat_utils.h diff --git a/he_qat_utils.c b/he_qat_utils.c deleted file mode 100644 index 2fcf3c5..0000000 --- a/he_qat_utils.c +++ /dev/null @@ -1,109 +0,0 @@ -#include "he_qat_utils.h" - -#ifdef __cplusplus -#include "utils/bignum.h" -#endif - -#include -#include - -BIGNUM* generateTestBNData(int nbits) { - if (!RAND_status()) return NULL; -#ifdef _DESTINY_DEBUG_VERBOSE - printf("PRNG properly seeded.\n"); -#endif - - BIGNUM* bn = BN_new(); - - if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { - BN_free(bn); - printf("Error while generating BN random number: %lu\n", - ERR_get_error()); - return NULL; - } - - return bn; -} - -unsigned char* paddingZeros(BIGNUM* bn, int nbits) { - if (!bn) return NULL; - - // Returns same address if it fails - int num_bytes = BN_num_bytes(bn); - int bytes_left = nbits / 8 - num_bytes; - if (bytes_left <= 0) return NULL; - - // Returns same address if it fails - unsigned char* bin = NULL; - int len = bytes_left + num_bytes; - if (!(bin = OPENSSL_zalloc(len))) return NULL; - -#ifdef _DESTINY_DEBUG_VERBOSE - printf("Padding bn with %d bytes to total %d bytes\n", bytes_left, len); -#endif - BN_bn2binpad(bn, bin, len); - if (ERR_get_error()) { - OPENSSL_free(bin); - return NULL; - } - - return bin; -} - -void showHexBN(BIGNUM* bn, int nbits) { - int len = nbits / 8; - unsigned char* bin = OPENSSL_zalloc(len); - if (!bin) return; - if (BN_bn2binpad(bn, bin, len)) { - for (size_t i = 0; i < len; i++) printf("%d", bin[i]); - printf("\n"); - } - OPENSSL_free(bin); - return; -} - -void showHexBin(unsigned char* bin, int len) { - if (!bin) return; - for (size_t i = 0; i < len; i++) printf("%d", bin[i]); - printf("\n"); - return; -} - -#ifdef __cplusplus -HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, - int nbits) { - if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; - int len_ = (nbits + 7) >> 3; // nbits/8; - - // Create BigNumber containg input data passed as argument - bn = BigNumber(reinterpret_cast(data), BITSIZE_WORD(nbits)); - Ipp32u* ref_bn_data_ = NULL; - ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); - - // Convert it to little endian format - unsigned char* data_ = reinterpret_cast(ref_bn_data_); - for (int i = 0; i < len_; i++) data_[i] = data[len_ - 1 - i]; - - return HE_QAT_STATUS_SUCCESS; -} - -HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, - const BigNumber& bn) { - if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; - int len_ = (nbits + 7) >> 3; // nbits/8; - - // Extract raw vector of data in little endian format - Ipp32u* ref_bn_data_ = NULL; - ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); - - // Revert it to big endian format - unsigned char* data_ = reinterpret_cast(ref_bn_data_); - for (int i = 0; i < len_; i++) data[i] = data_[len_ - 1 - i]; - - return HE_QAT_STATUS_SUCCESS; -} - -} // extern "C" { -#endif - -#endif // HE_QAT_UTILS_H_ diff --git a/he_qat_utils.h b/he_qat_utils.h deleted file mode 100644 index e63afce..0000000 --- a/he_qat_utils.h +++ /dev/null @@ -1,45 +0,0 @@ - -#ifndef HE_QAT_UTILS_H_ -#define HE_QAT_UTILS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#define LEN_OF_1024_BITS 128 -#define LEN_OF_2048_BITS 256 -#define msb_CAN_BE_ZERO -1 -#define msb_IS_ONE 0 -#define EVEN_RND_NUM 0 -#define ODD_RND_NUM 1 -#define BATCH_SIZE 1 - -BIGNUM* generateTestBNData(int nbits); -unsigned char* paddingZeros(BIGNUM* bn, int nbits); -void showHexBN(BIGNUM* bn, int nbits); -void showHexBin(unsigned char* bin, int len); - -#ifdef __cplusplus -/// @brief -/// @function binToBigNumber -/// Converts/encapsulates QAT's raw large number data to/into a BigNumber -/// object. data will be changed to little endian format in this function, -/// therefore the -HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, - int nbits); -/// @brief -/// @function bigNumberToBin -/// Convert BigNumber object into raw data compatible with QAT. -/// @param[out] data BigNumber object's raw data in big endian format. -/// @param[in] nbits Number of bits. Has to be power of 2, e.g. 1024, 2048, -/// 4096, etc. -/// @param[in] bn BigNumber object holding a multi-precision that can be -/// represented in nbits. -HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, - const BigNumber& bn); -} // extern "C" { -#endif - -#endif // HE_QAT_UTILS_H_ From f8195e41172834a0b8377017cc2fb62253ec6f22 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 9 Mar 2022 18:09:51 -0800 Subject: [PATCH 096/364] Format source code with clang-format. --- he_qat_misc.cpp | 5 +++-- he_qat_misc.h | 2 +- test_bnConversion.cpp | 23 ++++++++++++----------- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/he_qat_misc.cpp b/he_qat_misc.cpp index b975e4b..79fc256 100644 --- a/he_qat_misc.cpp +++ b/he_qat_misc.cpp @@ -36,7 +36,8 @@ unsigned char* paddingZeros(BIGNUM* bn, int nbits) { // Returns same address if it fails unsigned char* bin = NULL; int len = bytes_left + num_bytes; - if (!(bin = reinterpret_cast(OPENSSL_zalloc(len)))) return NULL; + if (!(bin = reinterpret_cast(OPENSSL_zalloc(len)))) + return NULL; #ifdef _DESTINY_DEBUG_VERBOSE printf("Padding bn with %d bytes to total %d bytes\n", bytes_left, len); @@ -52,7 +53,7 @@ unsigned char* paddingZeros(BIGNUM* bn, int nbits) { void showHexBN(BIGNUM* bn, int nbits) { int len = nbits / 8; - unsigned char* bin = reinterpret_cast(OPENSSL_zalloc(len)); + unsigned char* bin = reinterpret_cast(OPENSSL_zalloc(len)); if (!bin) return; if (BN_bn2binpad(bn, bin, len)) { for (size_t i = 0; i < len; i++) printf("%d", bin[i]); diff --git a/he_qat_misc.h b/he_qat_misc.h index 4c29bee..01b5755 100644 --- a/he_qat_misc.h +++ b/he_qat_misc.h @@ -3,7 +3,7 @@ #define HE_QAT_MISC_H_ //#ifdef __cplusplus -//extern "C" { +// extern "C" { //#endif #include "he_qat_types.h" diff --git a/test_bnConversion.cpp b/test_bnConversion.cpp index f0c9633..4654f80 100644 --- a/test_bnConversion.cpp +++ b/test_bnConversion.cpp @@ -34,11 +34,11 @@ extern "C" { //#define ODD_RND_NUM 1 //#define BATCH_SIZE 1 -//using namespace std; +// using namespace std; // int gDebugParam = 1; -//BIGNUM* generateTestBNData(int nbits) { +// BIGNUM* generateTestBNData(int nbits) { // if (!RAND_status()) return NULL; //#ifdef _DESTINY_DEBUG_VERBOSE // printf("PRNG properly seeded.\n"); @@ -56,7 +56,7 @@ extern "C" { // return bn; //} // -//unsigned char* paddingZeros(BIGNUM* bn, int nbits) { +// unsigned char* paddingZeros(BIGNUM* bn, int nbits) { // if (!bn) return NULL; // // // Returns same address if it fails @@ -81,7 +81,7 @@ extern "C" { // return bin; //} // -//void showHexBN(BIGNUM* bn, int nbits) { +// void showHexBN(BIGNUM* bn, int nbits) { // int len = nbits / 8; // unsigned char* bin = (unsigned char*)OPENSSL_zalloc(len); // if (!bin) return; @@ -93,7 +93,7 @@ extern "C" { // return; //} // -//void showHexBin(unsigned char* bin, int len) { +// void showHexBin(unsigned char* bin, int len) { // if (!bin) return; // for (size_t i = 0; i < len; i++) printf("%d", bin[i]); // printf("\n"); @@ -103,17 +103,18 @@ extern "C" { ///// @brief ///// @function binToBigNumber //// -///// data will be changed to little endian format in this function, therefore the +///// data will be changed to little endian format in this function, therefore +///the ///// abscence of const in front -//HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, +// HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, // int nbits) { // if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; // int len_ = (nbits + 7) >> 3; // nbits/8; // // // Create BigNumber containg input data passed as argument -// bn = BigNumber(reinterpret_cast(data), BITSIZE_WORD(nbits)); -// Ipp32u* ref_bn_data_ = NULL; -// ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); +// bn = BigNumber(reinterpret_cast(data), +// BITSIZE_WORD(nbits)); Ipp32u* ref_bn_data_ = NULL; ippsRef_BN(NULL, NULL, +// &ref_bn_data_, BN(bn)); // // // Convert it to little endian format // unsigned char* data_ = reinterpret_cast(ref_bn_data_); @@ -131,7 +132,7 @@ extern "C" { ///// 4096, etc. ///// @param[in] bn BigNumber object holding a multi-precision that can be ///// represented in nbits. -//HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, +// HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, // const BigNumber& bn) { // if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; // int len_ = (nbits + 7) >> 3; // nbits/8; From e9deef7cf09ea337ba50a2ba29234f955e57040d Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 9 Mar 2022 18:20:22 -0800 Subject: [PATCH 097/364] Remove legacy code. --- ln_mod_exp/CMakeLists.txt | 33 -- ln_mod_exp/cpa_mod_exp_sample.c | 601 --------------------------- ln_mod_exp/cpa_mod_exp_sample_user.c | 265 ------------ ln_mod_exp/qat_modexp_validation.c | 235 ----------- 4 files changed, 1134 deletions(-) delete mode 100644 ln_mod_exp/CMakeLists.txt delete mode 100644 ln_mod_exp/cpa_mod_exp_sample.c delete mode 100644 ln_mod_exp/cpa_mod_exp_sample_user.c delete mode 100644 ln_mod_exp/qat_modexp_validation.c diff --git a/ln_mod_exp/CMakeLists.txt b/ln_mod_exp/CMakeLists.txt deleted file mode 100644 index d62066f..0000000 --- a/ln_mod_exp/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ - -set(LNMODEXP_SRC cpa_mod_exp_sample.c) - -list(APPEND COMMON_INC_DIR ${CMAKE_CURRENT_LIST_DIR}) - -add_library(ln_mod_exp SHARED ${LNMODEXP_SRC}) -target_include_directories(ln_mod_exp PUBLIC ${COMMON_INC_DIR}) -target_link_directories(ln_mod_exp PUBLIC ${ICP_BUILDOUTPUT_PATH}) -target_link_libraries(ln_mod_exp PRIVATE cpa_sample_utils) -target_link_libraries(ln_mod_exp PUBLIC z pthread crypto qat_s usdm_drv_s) - -add_executable(test_ln_mod_exp cpa_mod_exp_sample_user.c) -target_include_directories(test_ln_mod_exp PUBLIC ${COMMON_INC_DIR}) -target_link_directories(test_ln_mod_exp PUBLIC ${ICP_BUILDOUTPUT_PATH}) -target_include_directories(test_ln_mod_exp PUBLIC /opt/openssl/include) -target_link_directories(test_ln_mod_exp PUBLIC /opt/openssl/lib) -target_link_libraries(test_ln_mod_exp PRIVATE cpa_sample_utils) -target_link_libraries(test_ln_mod_exp PRIVATE ln_mod_exp) -target_link_libraries(test_ln_mod_exp PUBLIC z pthread crypto ssl crypto qat_s usdm_drv_s) - -add_executable(qat_modexp_validation qat_modexp_validation.c) -target_include_directories(qat_modexp_validation PUBLIC ${COMMON_INC_DIR}) -target_link_directories(qat_modexp_validation PUBLIC ${ICP_BUILDOUTPUT_PATH}) -target_include_directories(qat_modexp_validation PUBLIC /opt/openssl/include) -target_link_directories(qat_modexp_validation PUBLIC /opt/openssl/lib) -target_link_libraries(qat_modexp_validation PRIVATE cpa_sample_utils) -target_link_libraries(qat_modexp_validation PRIVATE ln_mod_exp) -target_link_libraries(qat_modexp_validation PUBLIC z pthread crypto ssl crypto qat_s usdm_drv_s) - -install(TARGETS ln_mod_exp DESTINATION "lib") -install(TARGETS test_ln_mod_exp DESTINATION "bin") -install(TARGETS qat_modexp_validation DESTINATION "bin") - diff --git a/ln_mod_exp/cpa_mod_exp_sample.c b/ln_mod_exp/cpa_mod_exp_sample.c deleted file mode 100644 index 0d5647b..0000000 --- a/ln_mod_exp/cpa_mod_exp_sample.c +++ /dev/null @@ -1,601 +0,0 @@ -/*************************************************************************** - * - * BSD LICENSE - * - * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * version: QAT.L.4.15.0-00011 - * - ***************************************************************************/ - -/* - * This is sample code that uses the primality testing APIs. A hard-coded - * prime number is tested with four different algorithms: - * - * - GCD primality test - * - Fermat primality test - * - Miller-Rabin primality test. This test requires random numbers that are - * also hardcoded here (see unsigned char MR[]) - * - Lucas primality test - */ - -#include "cpa.h" -#include "cpa_cy_im.h" -//#include "cpa_cy_prime.h" -#include "cpa_cy_ln.h" - -#include -#include - -#include "cpa_sample_utils.h" - -#define NB_MR_ROUNDS 2 -#define TIMEOUT_MS 5000 /* 5 seconds*/ - -extern int gDebugParam; - -/* Sample prime number: we want to test the primality of this number */ -//static Cpa8U sampleBase_1024[] = { -// 0x07, 0x3A, 0xD3, 0x1F, 0x2B, 0x41, 0xAD, 0x36, -// 0x23, 0xDD, 0xD0, 0x47, 0x8A, 0xB5, 0xC9, 0xD6, -// 0xC4, 0x5B, 0x43, 0x4C, 0xE7, 0x74, 0x9A, 0xA1, -// 0x3D, 0x38, 0xAD, 0xC1, 0x7E, 0x7A, 0xD2, 0xF2, -// 0xD4, 0x6C, 0x6D, 0x87, 0x32, 0x52, 0x1D, 0xDA, -// 0x16, 0x1C, 0xCB, 0x2B, 0x2C, 0x1D, 0x8E, 0x29, -// 0xA6, 0x3F, 0xD9, 0x0C, 0xD4, 0xCE, 0x2C, 0x9C, -// 0x0F, 0xBE, 0x5D, 0x6E, 0x68, 0x5A, 0xBF, 0x7D, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x36, 0x61, 0xAD, 0x36, 0x36, 0x61, 0xAD, 0x36, -// 0x96, 0x43, 0xC9, 0xD6, 0x96, 0x43, 0xC9, 0xD6, -// 0x5A, 0xA9, 0x9A, 0xA1, 0x5A, 0xA9, 0x9A, 0xA1, -// 0x95, 0xB4, 0xD2, 0xF2, 0x95, 0xB4, 0xD2, 0xF2, -// 0xC8, 0xDF, 0x1D, 0xDA, 0xC8, 0xDF, 0x1D, 0xDA, -// 0x7C, 0x82, 0x8E, 0x29, 0x7C, 0x82, 0x8E, 0x29, -// 0x40, 0xC9, 0x2C, 0x9C, 0x40, 0xC9, 0x2C, 0x9C}; - -// 216 (in big endian format) -static Cpa8U sampleBase_1024[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8}; - -// 7 (in big endian format) -static Cpa8U sampleModulus_1024[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07}; - -// 3 (in big endian format) -static Cpa8U sampleExponent_1024[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}; - - -/* Forward declaration */ -CpaStatus lnModExpSample(void); -CpaStatus bnModExpSample(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits); - -static clock_t qat_start; -static clock_t qat_elapsed; - -/* - * Callback function - * - * This function is "called back" (invoked by the implementation of - * the API) when the asynchronous operation has completed. The - * context in which it is invoked depends on the implementation, but - * as described in the API it should not sleep (since it may be called - * in a context which does not permit sleeping, e.g. a Linux bottom - * half). - * - * This function can perform whatever processing is appropriate to the - * application. For example, it may free memory, continue processing, - * etc. In this example, the function prints out the status of the - * primality test, and sets the complete variable to indicate it has - * been called. - */ -static void lnModExpCallback(void *pCallbackTag, - CpaStatus status, - void *pOpData, - CpaFlatBuffer *pOut) -{ - qat_elapsed = clock() - qat_start; - -#ifdef _DESTINY_DEBUG_VERBOSE - PRINT_DBG("lnModExpCallback, status = %d.\n", status); - if (NULL == pOpData) { - PRINT_ERR("pOpData is null, status = %d\n", status); - return; - } else { - CpaCyLnModExpOpData *opData = (CpaCyLnModExpOpData *) pOpData; - displayHexArray("\tbase: ",opData->base.pData, - opData->base.dataLenInBytes); - displayHexArray("\texponent: ",opData->exponent.pData, - opData->exponent.dataLenInBytes); - displayHexArray("\tmodulus: ",opData->modulus.pData, - opData->modulus.dataLenInBytes); - } -#endif - - if (CPA_STATUS_SUCCESS != status) { - PRINT_ERR("callback failed, status = %d\n", status); - } else { -#ifdef _DESTINY_DEBUG_VERBOSE - // 216^3 mod 7 = 6 - displayHexArray("\tb^e mod m: ", pOut->pData, pOut->dataLenInBytes); -#endif - printf("QAT: %.1lfus\t", qat_elapsed / (CLOCKS_PER_SEC / 1000000.0)); - - // The callback tag in this happens to be a synchronization object - if (NULL != pCallbackTag) { -#ifdef _DESTINY_DEBUG_VERBOSE - PRINT_DBG("Modular exponentiation completed.\n"); - PRINT_DBG("Wake up waiting thread from callback function.\n"); -#endif - COMPLETE((struct COMPLETION_STRUCT *)pCallbackTag); - } - } - - return ; -} - - -static CpaStatus bnModExpPerformOp(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits, CpaInstanceHandle cyInstHandle) -{ - // nbits is the number of security bits - int len = nbits / 8; // length in bytes - - CpaStatus status = CPA_STATUS_SUCCESS; - - //CpaBoolean testPassed = CPA_FALSE; - - // Mod Exp buffers - Cpa8U *pBase = NULL; - Cpa8U *pModulus = NULL; - Cpa8U *pExponent = NULL; - CpaFlatBuffer modExpRes = {.pData = NULL, .dataLenInBytes = 0}; - - struct COMPLETION_STRUCT complete; - -#ifdef _DESTINY_DEBUG_VERBOSE - PRINT_DBG("modExpPerformOp\n"); -#endif - - COMPLETION_INIT(&complete); - - // Allocate device memory and copy data from host - status = PHYS_CONTIG_ALLOC(&pBase, len); - if (NULL != pBase) { - unsigned char *bin = (unsigned char *) calloc(len, sizeof(unsigned char)); - if (BN_bn2binpad(b,bin,len)) { - memcpy(pBase,bin,len); - } else { - PHYS_CONTIG_FREE(pBase); - } - } - if (CPA_STATUS_SUCCESS == status) { - status = PHYS_CONTIG_ALLOC(&pModulus, len); - if (NULL != pModulus) { - unsigned char *bin = (unsigned char *) calloc(len, sizeof(unsigned char)); - if (BN_bn2binpad(m,bin,len)) { - memcpy(pModulus,bin,len); - } else { - PHYS_CONTIG_FREE(pModulus); - } - } - } - if (CPA_STATUS_SUCCESS == status) { - status = PHYS_CONTIG_ALLOC(&pExponent, len); - if (NULL != pExponent) { - unsigned char *bin = (unsigned char *) calloc(len, sizeof(unsigned char)); - if (BN_bn2binpad(e,bin,len)) { - memcpy(pExponent,bin,len); - } else { - PHYS_CONTIG_FREE(pExponent); - } - } - } - - // Create test op data for the modular exponentiation - CpaCyLnModExpOpData modExpOpData = { - .modulus = {.dataLenInBytes = 0, .pData = NULL}, - .base = {.dataLenInBytes = 0, .pData = NULL}, - .exponent = {.dataLenInBytes = 0, .pData = NULL}}; - - // Allocate memory to store modular exponentiation results - if (CPA_STATUS_SUCCESS == status) { - status = PHYS_CONTIG_ALLOC(&modExpRes.pData, len); - if (NULL != modExpRes.pData) { - modExpRes.dataLenInBytes = len; - } - } - -#ifdef _DESTINY_DEBUG_VERBOSE - printf("\tPerform %dth large number modular exponentiation.\n",i); -#endif - - if (CPA_STATUS_SUCCESS == status) { - modExpOpData.base.dataLenInBytes = len; - modExpOpData.base.pData = pBase; - modExpOpData.exponent.dataLenInBytes = len; - modExpOpData.exponent.pData = pExponent; - modExpOpData.modulus.dataLenInBytes = len; - modExpOpData.modulus.pData = pModulus; - - qat_start = clock(); - status = cpaCyLnModExp(cyInstHandle, - lnModExpCallback, //NULL, /*callback function*/ - (void *)&complete, //NULL, /*callback tag*/ - &modExpOpData, - &modExpRes); - - if ((CPA_STATUS_RETRY != status) && (CPA_STATUS_SUCCESS != status)) { - //if (CPA_STATUS_SUCCESS != - // cpaCyGetStatusText(cyInstHandle, status, statusErrorString)) { - // PRINT_ERR("Error retrieving status string.\n"); - //} -#ifdef _DESTINY_DEBUG_VERBOSE - PRINT_ERR("doModExp Fail -- "); //%s\n", statusErrorString); -#endif - status = CPA_STATUS_FAIL; - //goto finish; - } - } - - if (CPA_STATUS_SUCCESS == status) - { - /** Wait until the callback function has been called*/ - if (!COMPLETION_WAIT(&complete, TIMEOUT_MS)) - { -#ifdef _DESTINY_DEBUG_VERBOSE - PRINT_ERR("timeout or interruption in cpaCySymPerformOp\n"); -#endif - status = CPA_STATUS_FAIL; - } - } - - r = BN_bin2bn(modExpRes.pData, modExpRes.dataLenInBytes, r); - - /** Free all allocated structures before exit*/ - PHYS_CONTIG_FREE(pBase); - PHYS_CONTIG_FREE(pModulus); - PHYS_CONTIG_FREE(pExponent); - PHYS_CONTIG_FREE(modExpRes.pData); - - COMPLETION_DESTROY(&complete); - - return status; -} - - -/* - * Perform a primality test operation on an hardcoded prime number - */ -static CpaStatus lnModExpPerformOp(CpaInstanceHandle cyInstHandle) -{ - CpaStatus status = CPA_STATUS_SUCCESS; - - //CpaBoolean testPassed = CPA_FALSE; - - // Mod Exp buffers - Cpa8U *pBase = NULL; - Cpa8U *pModulus = NULL; - Cpa8U *pExponent = NULL; - CpaFlatBuffer modExpRes = {.pData = NULL, .dataLenInBytes = 0}; - - struct COMPLETION_STRUCT complete; - - PRINT_DBG("modExpPerformOp\n"); - - COMPLETION_INIT(&complete); - - // Allocate device memory and copy data from host - status = PHYS_CONTIG_ALLOC(&pBase, sizeof(sampleBase_1024)); - if (NULL != pBase) { - memcpy(pBase, sampleBase_1024, sizeof(sampleBase_1024)); - } - if (CPA_STATUS_SUCCESS == status) { - status = PHYS_CONTIG_ALLOC(&pModulus, sizeof(sampleModulus_1024)); - if (NULL != pModulus) { - memcpy(pModulus, sampleModulus_1024, sizeof(sampleModulus_1024)); - } - } - if (CPA_STATUS_SUCCESS == status) { - status = PHYS_CONTIG_ALLOC(&pExponent, sizeof(sampleExponent_1024)); - if (NULL != pExponent) { - memcpy(pExponent, sampleExponent_1024, sizeof(sampleExponent_1024)); - } - } - - // Create test op data for the modular exponentiation - //if (CPA_STATUS_SUCCESS == status) { - // status = OS_MALLOC(&pModExpTestOpData, sizeof(CpaCyPrimeTestOpData)); - //} - CpaCyLnModExpOpData modExpOpData = { - .modulus = {.dataLenInBytes = 0, .pData = NULL}, - .base = {.dataLenInBytes = 0, .pData = NULL}, - .exponent = {.dataLenInBytes = 0, .pData = NULL}}; - - // Allocate memory to store modular exponentiation results - if (CPA_STATUS_SUCCESS == status) { - status = PHYS_CONTIG_ALLOC(&modExpRes.pData, sizeof(sampleModulus_1024)); - if (NULL != modExpRes.pData) { - modExpRes.dataLenInBytes = sizeof(sampleModulus_1024); - } - } - - int i = 0; - //for (i = 0; i < 10; i++) { - printf("\tPerform %dth large number modular exponentiation.\n",i); - if (CPA_STATUS_SUCCESS == status) { - modExpOpData.base.dataLenInBytes = sizeof(sampleBase_1024); - modExpOpData.base.pData = pBase; - modExpOpData.exponent.dataLenInBytes = sizeof(sampleExponent_1024); - modExpOpData.exponent.pData = pExponent; - modExpOpData.modulus.dataLenInBytes = sizeof(sampleModulus_1024); - modExpOpData.modulus.pData = pModulus; - - displayHexArray("--base: ",pBase,//modExpOpData.base.pData, - modExpOpData.base.dataLenInBytes); - displayHexArray("--exponent: ",pExponent,//modExpOpData.exponent.pData, - modExpOpData.exponent.dataLenInBytes); - displayHexArray("--modulus: ",pModulus,//modExpOpData.modulus.pData, - modExpOpData.modulus.dataLenInBytes); - - - status = cpaCyLnModExp(cyInstHandle, - lnModExpCallback, //NULL, /*callback function*/ - (void *)&complete, //NULL, /*callback tag*/ - &modExpOpData, - &modExpRes); - - if ((CPA_STATUS_RETRY != status) && (CPA_STATUS_SUCCESS != status)) { - //if (CPA_STATUS_SUCCESS != - // cpaCyGetStatusText(cyInstHandle, status, statusErrorString)) { - // PRINT_ERR("Error retrieving status string.\n"); - //} - PRINT_ERR("doModExp Fail -- "); //%s\n", statusErrorString); - status = CPA_STATUS_FAIL; - //goto finish; - } - } - - if (CPA_STATUS_SUCCESS == status) - { - /** Wait until the callback function has been called*/ - if (!COMPLETION_WAIT(&complete, TIMEOUT_MS)) - { - PRINT_ERR("timeout or interruption in cpaCySymPerformOp\n"); - status = CPA_STATUS_FAIL; - } else { - - displayHexArray("--modExpRes: ",modExpRes.pData,modExpRes.dataLenInBytes); - } - } - //} - - displayHexArray("++modExpRes: ",modExpRes.pData,modExpRes.dataLenInBytes); - - /** Free all allocated structures before exit*/ - PHYS_CONTIG_FREE(pBase); - PHYS_CONTIG_FREE(pModulus); - PHYS_CONTIG_FREE(pExponent); - - COMPLETION_DESTROY(&complete); - - return status; -} - - -CpaStatus lnModExpSample(void) -{ - CpaStatus status = CPA_STATUS_SUCCESS; - CpaInstanceHandle cyInstHandle = NULL; - //CpaCyPrimeStats64 primeStats = {0}; - CpaCyLnStats64 lnStats = {0}; - - PRINT_DBG("start of modExp sample code\n"); - - /* - * In this simplified version of instance discovery, we discover - * exactly one instance of a crypto service. - */ - sampleCyGetInstance(&cyInstHandle); - if (cyInstHandle == NULL) { - return CPA_STATUS_FAIL; - } - - /* Start Cryptographic component */ - PRINT_DBG("cpaCyStartInstance\n"); - status = cpaCyStartInstance(cyInstHandle); - - if (CPA_STATUS_SUCCESS == status) { - // Set the address translation function for the instance - status = cpaCySetAddressTranslation(cyInstHandle, sampleVirtToPhys); - } - - if (CPA_STATUS_SUCCESS == status) { - /* - * If the instance is polled start the polling thread. Note that - * how the polling is done is implementation-dependent. - */ - sampleCyStartPolling(cyInstHandle); - - /** Perform large number modular exponentiation test operations */ - status = lnModExpPerformOp(cyInstHandle); - } - - if (CPA_STATUS_SUCCESS == status) { - PRINT_DBG("cpaCyLnStatsQuery\n"); - //status = cpaCyPrimeQueryStats64(cyInstHandle, &primeStats); - status = cpaCyLnStatsQuery64(cyInstHandle, &lnStats); - if (status != CPA_STATUS_SUCCESS) { - PRINT_ERR("cpaCyLnStatsQuery() failed. (status = %d)\n", status); - } - PRINT_DBG("Number of lnModExp requests: %llu\n", - (unsigned long long)lnStats.numLnModExpRequests); - } - - /* Stop the polling thread */ - sampleCyStopPolling(); - - /** Stop Cryptographic component */ - PRINT_DBG("cpaCyStopInstance\n"); - status = cpaCyStopInstance(cyInstHandle); - - if (CPA_STATUS_SUCCESS == status) - { - PRINT_DBG("Sample code ran successfully\n"); - } - else - { - PRINT_DBG("Sample code failed with status of %d\n", status); - } - - return status; -} - - -CpaStatus bnModExpSample(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits) -{ - CpaStatus status = CPA_STATUS_SUCCESS; - CpaInstanceHandle cyInstHandle = NULL; - //CpaCyPrimeStats64 primeStats = {0}; - CpaCyLnStats64 lnStats = {0}; - -#ifdef _DESTINY_DEBUG_VERBOSE - PRINT_DBG("start of bnModExp sample code\n"); -#endif - - /* - * In this simplified version of instance discovery, we discover - * exactly one instance of a crypto service. - */ - sampleCyGetInstance(&cyInstHandle); - if (cyInstHandle == NULL) { - return CPA_STATUS_FAIL; - } - -#ifdef _DESTINY_DEBUG_VERBOSE - /* Start Cryptographic component */ - PRINT_DBG("cpaCyStartInstance\n"); -#endif - status = cpaCyStartInstance(cyInstHandle); - - if (CPA_STATUS_SUCCESS == status) { - // Set the address translation function for the instance - status = cpaCySetAddressTranslation(cyInstHandle, sampleVirtToPhys); - } - - if (CPA_STATUS_SUCCESS == status) { - /* - * If the instance is polled start the polling thread. Note that - * how the polling is done is implementation-dependent. - */ - sampleCyStartPolling(cyInstHandle); - - /** Perform big number modular exponentiation test operation */ - status = bnModExpPerformOp(r, b, e, m, nbits, cyInstHandle); - } - - if (CPA_STATUS_SUCCESS == status) { -#ifdef _DESTINY_DEBUG_VERBOSE - PRINT_DBG("cpaCyLnStatsQuery\n"); -#endif - //status = cpaCyPrimeQueryStats64(cyInstHandle, &primeStats); - status = cpaCyLnStatsQuery64(cyInstHandle, &lnStats); - if (status != CPA_STATUS_SUCCESS) { - PRINT_ERR("cpaCyLnStatsQuery() failed. (status = %d)\n", status); - } -#ifdef _DESTINY_DEBUG_VERBOSE - PRINT_DBG("Number of bnModExp requests: %llu\n", - (unsigned long long)lnStats.numLnModExpRequests); -#endif - } - - /* Stop the polling thread */ - sampleCyStopPolling(); - -#ifdef _DESTINY_DEBUG_VERBOSE - /** Stop Cryptographic component */ - PRINT_DBG("cpaCyStopInstance\n"); -#endif - status = cpaCyStopInstance(cyInstHandle); - -#ifdef _DESTINY_DEBUG_VERBOSE - if (CPA_STATUS_SUCCESS == status) { - PRINT_DBG("Sample code ran successfully\n"); - } else { - PRINT_DBG("Sample code failed with status of %d\n", status); - } -#endif - return status; -} - diff --git a/ln_mod_exp/cpa_mod_exp_sample_user.c b/ln_mod_exp/cpa_mod_exp_sample_user.c deleted file mode 100644 index dc60ee0..0000000 --- a/ln_mod_exp/cpa_mod_exp_sample_user.c +++ /dev/null @@ -1,265 +0,0 @@ -/****************************************************************************** - * - * BSD LICENSE - * - * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * version: QAT.L.4.15.0-00011 - * - *****************************************************************************/ - -/** - ****************************************************************************** - * @file cpa_mod_exp_sample_user.c - * - *****************************************************************************/ - -#include "cpa_sample_utils.h" -#include "icp_sal_user.h" - -#include -#include -#include - -#define LEN_OF_1024_BITS 128 -#define LEN_OF_2048_BITS 256 -#define msb_CAN_BE_ZERO -1 -#define msb_IS_ONE 0 -#define EVEN_RND_NUM 0 -#define ODD_RND_NUM 1 - -/* - * BN_rand() generates a cryptographically strong pseudo-random number of bits bits in length and stores it in rnd. If top is -1, the most significant bit of the random number can be zero. If top is 0, it is set to 1, and if top is 1, the two most significant bits of the number will be set to 1, so that the product of two such random numbers will always have 2*bits length. If bottom is true, the number will be odd. - */ - - -extern CpaStatus lnModExpSample(void); -extern CpaStatus bnModExpSample(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits); - -int gDebugParam = 1; - - -BIGNUM *generateTestBNData(int nbits) -{ - if (!RAND_status()) - return NULL; - printf("PRNG properly seeded.\n"); - - BIGNUM *bn = BN_new(); - - if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { - BN_free(bn); - printf("Error while generating BN random number: %lu\n",ERR_get_error()); - return NULL; - } - - return bn; -} - -unsigned char *paddingZeros(BIGNUM *bn, int nbits) -{ - if (!bn) return NULL; - - // Returns same address if it fails - int num_bytes = BN_num_bytes(bn); - int bytes_left = nbits/8 - num_bytes; - if (bytes_left <= 0) return NULL; - - // Returns same address if it fails - unsigned char *bin = NULL; - int len = bytes_left + num_bytes; - if (!(bin = OPENSSL_zalloc(len))) return NULL; - - printf("Padding bn with %d bytes to total %d bytes\n",bytes_left,len); - BN_bn2binpad(bn,bin,len); - if (ERR_get_error()) { - OPENSSL_free(bin); - return NULL; - } - - return bin; -} - -void showHexBN(BIGNUM *bn, int nbits) -{ - int len = nbits / 8; - unsigned char *bin = OPENSSL_zalloc(len); - if (!bin) return ; - if (BN_bn2binpad(bn,bin,len)) { - for (size_t i = 0; i < len; i++) - printf("%d",bin[i]); - printf("\n"); - } - OPENSSL_free(bin); - return ; -} - -void showHexBin(unsigned char *bin, int len) -{ - if (!bin) return ; - for (size_t i = 0; i < len; i++) - printf("%d",bin[i]); - printf("\n"); - return ; -} - -int main(int argc, const char **argv) -{ - //BIGNUM *base = NULL; - - // OpenSSL as baseline - - BN_CTX *ctx = BN_CTX_new(); - BN_CTX_start(ctx); - - BIGNUM *bn = generateTestBNData(1024); - - if (bn) { - char *bn_str = BN_bn2hex(bn); - printf("Generated BN: %s num_bytes: %d num_bits: %d\n",bn_str,BN_num_bytes(bn),BN_num_bits(bn)); - - BN_ULONG c0 = 7, c1 = 3, c2 = 216; - - printf("BN_ULONG size in bytes: %lu\n", sizeof(BN_ULONG)); - - BIGNUM *bn_c0, *bn_c1, *bn_c2, *res; - - res = BN_new(); - bn_c0 = BN_new(); - bn_c1 = BN_new(); - bn_c2 = BN_new(); - - BN_set_word(bn_c0,c0); - BN_set_word(bn_c1,c1); - BN_set_word(bn_c2,c2); - - bn_str = BN_bn2hex(bn_c0); - printf("BN c0: %s num_bytes: %d num_bits: %d\n",bn_str,BN_num_bytes(bn_c0),BN_num_bits(bn_c0)); - bn_str = BN_bn2hex(bn_c1); - printf("BN c1: %s num_bytes: %d num_bits: %d\n",bn_str,BN_num_bytes(bn_c1),BN_num_bits(bn_c1)); - bn_str = BN_bn2hex(bn_c2); - printf("BN c2: %s num_bytes: %d num_bits: %d\n",bn_str,BN_num_bytes(bn_c2),BN_num_bits(bn_c2)); - - if (BN_mod_exp(res, bn_c2, bn_c1, bn_c0, ctx)) { - bn_str = BN_bn2hex(res); - printf("BN mod exp res: %s num_bytes: %d num_bits: %d\n",bn_str,BN_num_bytes(res),BN_num_bits(res)); - showHexBN(res,1024); - } else { - printf("Modular exponentiation failed.\n"); - } - - // - CpaStatus status = CPA_STATUS_SUCCESS; - - PRINT_DBG("Starting bnModExp Sample Code App ...\n"); - - status = qaeMemInit(); - if (CPA_STATUS_SUCCESS != status) - { - PRINT_ERR("Failed to initialize memory driver\n"); - return (int)status; - } - - status = icp_sal_userStartMultiProcess("SSL", CPA_FALSE); - if (CPA_STATUS_SUCCESS != status) - { - PRINT_ERR("Failed to start user process SSL\n"); - qaeMemDestroy(); - return (int)status; - } - - //status = lnModExpSample(); - BIGNUM *r = BN_new(); - status = bnModExpSample(r, bn_c2, bn_c1, bn_c0, 1024); - if (CPA_STATUS_SUCCESS != status) - { - PRINT_ERR("\nbnModExp Sample Code App failed\n"); - } - else - { - PRINT_DBG("\nbnModExp Sample Code App finished\n"); - } - - icp_sal_userStop(); - qaeMemDestroy(); - - OPENSSL_free(bn_str); - //BN_free(res); - BN_free(bn_c0); - BN_free(bn_c1); - BN_free(bn_c2); - BN_free(bn); - } - - BN_CTX_end(ctx); - - return 0; - - // QAT - - CpaStatus stat = CPA_STATUS_SUCCESS; - - if (argc > 1) - { - gDebugParam = atoi(argv[1]); - } - - PRINT_DBG("Starting LnModExp Sample Code App ...\n"); - - stat = qaeMemInit(); - if (CPA_STATUS_SUCCESS != stat) - { - PRINT_ERR("Failed to initialize memory driver\n"); - return (int)stat; - } - - stat = icp_sal_userStartMultiProcess("SSL", CPA_FALSE); - if (CPA_STATUS_SUCCESS != stat) - { - PRINT_ERR("Failed to start user process SSL\n"); - qaeMemDestroy(); - return (int)stat; - } - - stat = lnModExpSample(); - if (CPA_STATUS_SUCCESS != stat) - { - PRINT_ERR("\nLnModExp Sample Code App failed\n"); - } - else - { - PRINT_DBG("\nLnModExp Sample Code App finished\n"); - } - - icp_sal_userStop(); - qaeMemDestroy(); - - return (int)stat; -} diff --git a/ln_mod_exp/qat_modexp_validation.c b/ln_mod_exp/qat_modexp_validation.c deleted file mode 100644 index be59896..0000000 --- a/ln_mod_exp/qat_modexp_validation.c +++ /dev/null @@ -1,235 +0,0 @@ -/****************************************************************************** - * - * BSD LICENSE - * - * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * version: QAT.L.4.15.0-00011 - * - *****************************************************************************/ - -/** - ****************************************************************************** - * @file cpa_mod_exp_sample_user.c - * - *****************************************************************************/ - -#include "cpa_sample_utils.h" -#include "icp_sal_user.h" - -#include -#include -#include -#include - -#define LEN_OF_1024_BITS 128 -#define LEN_OF_2048_BITS 256 -#define msb_CAN_BE_ZERO -1 -#define msb_IS_ONE 0 -#define EVEN_RND_NUM 0 -#define ODD_RND_NUM 1 - -/* - * BN_rand() generates a cryptographically strong pseudo-random number of bits bits in length and stores it in rnd. If top is -1, the most significant bit of the random number can be zero. If top is 0, it is set to 1, and if top is 1, the two most significant bits of the number will be set to 1, so that the product of two such random numbers will always have 2*bits length. If bottom is true, the number will be odd. - */ - -extern CpaStatus lnModExpSample(void); -extern CpaStatus bnModExpSample(BIGNUM *r, BIGNUM *b, BIGNUM *e, BIGNUM *m, int nbits); - -int gDebugParam = 1; - - -BIGNUM *generateTestBNData(int nbits) -{ - if (!RAND_status()) - return NULL; -#ifdef _DESTINY_DEBUG_VERBOSE - printf("PRNG properly seeded.\n"); -#endif - - BIGNUM *bn = BN_new(); - - if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { - BN_free(bn); - printf("Error while generating BN random number: %lu\n",ERR_get_error()); - return NULL; - } - - return bn; -} - -unsigned char *paddingZeros(BIGNUM *bn, int nbits) -{ - if (!bn) return NULL; - - // Returns same address if it fails - int num_bytes = BN_num_bytes(bn); - int bytes_left = nbits/8 - num_bytes; - if (bytes_left <= 0) return NULL; - - // Returns same address if it fails - unsigned char *bin = NULL; - int len = bytes_left + num_bytes; - if (!(bin = OPENSSL_zalloc(len))) return NULL; - -#ifdef _DESTINY_DEBUG_VERBOSE - printf("Padding bn with %d bytes to total %d bytes\n",bytes_left,len); -#endif - BN_bn2binpad(bn,bin,len); - if (ERR_get_error()) { - OPENSSL_free(bin); - return NULL; - } - - return bin; -} - -void showHexBN(BIGNUM *bn, int nbits) -{ - int len = nbits / 8; - unsigned char *bin = OPENSSL_zalloc(len); - if (!bin) return ; - if (BN_bn2binpad(bn,bin,len)) { - for (size_t i = 0; i < len; i++) - printf("%d",bin[i]); - printf("\n"); - } - OPENSSL_free(bin); - return ; -} - -void showHexBin(unsigned char *bin, int len) -{ - if (!bin) return ; - for (size_t i = 0; i < len; i++) - printf("%d",bin[i]); - printf("\n"); - return ; -} - -int main(int argc, const char **argv) -{ - const size_t num_trials = 100; - const int bit_length = 1024; - - // OpenSSL as baseline - BN_CTX *ctx = BN_CTX_new(); - BN_CTX_start(ctx); - - CpaStatus status = CPA_STATUS_SUCCESS; - - for (size_t mod = 0; mod < num_trials; mod++) { - printf("Trial #%0.3lu\t",mod+1); - - BIGNUM *bn_mod = generateTestBNData(bit_length); - - if (!bn_mod) continue; - - char *bn_str = BN_bn2hex(bn_mod); -#ifdef _DESTINY_DEBUG_VERBOSE - printf("Generated modulus: %s num_bytes: %d num_bits: %d\n", - bn_str,BN_num_bytes(bn_mod),BN_num_bits(bn_mod)); -#endif - // bn_exponent in [0..bn_mod] - BIGNUM *bn_exponent = BN_new(); - if (!BN_rand_range(bn_exponent, bn_mod)) { - BN_free(bn_mod); - continue; - } - - BIGNUM *bn_base = generateTestBNData(bit_length); - - BIGNUM *ssl_res = BN_new(); - clock_t start = clock(); - BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); - clock_t elapsed = clock() - start; - printf("OpenSSL: %.1lfus\t", elapsed / (CLOCKS_PER_SEC / 1000000.0)); - - //if (BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx)) { - if (!ERR_get_error()) { - bn_str = BN_bn2hex(ssl_res); -#ifdef _DESTINY_DEBUG_VERBOSE - printf("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", - bn_str, BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); - showHexBN(ssl_res, bit_length); -#endif - } else { - printf("Modular exponentiation failed.\n"); - } - -#ifdef _DESTINY_DEBUG_VERBOSE - PRINT_DBG("Starting QAT bnModExp Sample Code App ...\n"); -#endif - status = qaeMemInit(); - if (CPA_STATUS_SUCCESS != status) { - PRINT_ERR("Failed to initialize memory driver\n"); - return (int)status; - } - - status = icp_sal_userStartMultiProcess("SSL", CPA_FALSE); - if (CPA_STATUS_SUCCESS != status) { - PRINT_ERR("Failed to start user process SSL\n"); - qaeMemDestroy(); - return (int)status; - } - - BIGNUM *qat_res = BN_new(); - status = bnModExpSample(qat_res, bn_base, bn_exponent, bn_mod, bit_length); - if (CPA_STATUS_SUCCESS != status) { - PRINT_ERR("\nQAT bnModExp Sample Code App failed\n"); - } -#ifdef _DESTINY_DEBUG_VERBOSE - else { - PRINT_DBG("\nQAT bnModExp Sample Code App finished\n"); - } -#endif - - icp_sal_userStop(); - qaeMemDestroy(); - - if (BN_cmp(qat_res, ssl_res) != 0) - printf("\t** FAIL **\n"); - else - printf("\t** PASS **\n"); - - OPENSSL_free(bn_str); - - BN_free(ssl_res); - BN_free(qat_res); - - BN_free(bn_mod); - BN_free(bn_base); - BN_free(bn_exponent); - } - - BN_CTX_end(ctx); - - return (int)status; -} From e5670c1946c83ff4d34d84d4d0e73a7c3cb1ea19 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 10 Mar 2022 00:41:37 -0800 Subject: [PATCH 098/364] Reorganize source code directory structure. --- .../test_bnConversion.cpp | 2 +- .../test_bnModExpPerformOp.c | 0 test_context.c => examples/test_context.c | 0 he_qat_bn_ops.c => he_qat/he_qat_bn_ops.c | 0 he_qat_context.c => he_qat/he_qat_context.c | 0 .../include/he_qat_bn_ops.h | 0 .../include/he_qat_context.h | 0 .../include/he_qat_types.h | 0 misc/bignum.cpp | 613 ++++++++---------- misc/bignum.h | 178 ++--- he_qat_misc.cpp => misc/he_qat_misc.cpp | 0 he_qat_misc.h => misc/he_qat_misc.h | 0 misc/utils.cpp | 29 +- misc/utils.h | 34 +- 14 files changed, 409 insertions(+), 447 deletions(-) rename test_bnConversion.cpp => examples/test_bnConversion.cpp (99%) rename test_bnModExpPerformOp.c => examples/test_bnModExpPerformOp.c (100%) rename test_context.c => examples/test_context.c (100%) rename he_qat_bn_ops.c => he_qat/he_qat_bn_ops.c (100%) rename he_qat_context.c => he_qat/he_qat_context.c (100%) rename he_qat_bn_ops.h => he_qat/include/he_qat_bn_ops.h (100%) rename he_qat_context.h => he_qat/include/he_qat_context.h (100%) rename he_qat_types.h => he_qat/include/he_qat_types.h (100%) rename he_qat_misc.cpp => misc/he_qat_misc.cpp (100%) rename he_qat_misc.h => misc/he_qat_misc.h (100%) diff --git a/test_bnConversion.cpp b/examples/test_bnConversion.cpp similarity index 99% rename from test_bnConversion.cpp rename to examples/test_bnConversion.cpp index 4654f80..9a38c0d 100644 --- a/test_bnConversion.cpp +++ b/examples/test_bnConversion.cpp @@ -104,7 +104,7 @@ extern "C" { ///// @function binToBigNumber //// ///// data will be changed to little endian format in this function, therefore -///the +/// the ///// abscence of const in front // HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, // int nbits) { diff --git a/test_bnModExpPerformOp.c b/examples/test_bnModExpPerformOp.c similarity index 100% rename from test_bnModExpPerformOp.c rename to examples/test_bnModExpPerformOp.c diff --git a/test_context.c b/examples/test_context.c similarity index 100% rename from test_context.c rename to examples/test_context.c diff --git a/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c similarity index 100% rename from he_qat_bn_ops.c rename to he_qat/he_qat_bn_ops.c diff --git a/he_qat_context.c b/he_qat/he_qat_context.c similarity index 100% rename from he_qat_context.c rename to he_qat/he_qat_context.c diff --git a/he_qat_bn_ops.h b/he_qat/include/he_qat_bn_ops.h similarity index 100% rename from he_qat_bn_ops.h rename to he_qat/include/he_qat_bn_ops.h diff --git a/he_qat_context.h b/he_qat/include/he_qat_context.h similarity index 100% rename from he_qat_context.h rename to he_qat/include/he_qat_context.h diff --git a/he_qat_types.h b/he_qat/include/he_qat_types.h similarity index 100% rename from he_qat_types.h rename to he_qat/include/he_qat_types.h diff --git a/misc/bignum.cpp b/misc/bignum.cpp index 57a372c..1e88859 100644 --- a/misc/bignum.cpp +++ b/misc/bignum.cpp @@ -1,18 +1,18 @@ /******************************************************************************* -* Copyright 2019-2021 Intel Corporation -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*******************************************************************************/ + * Copyright 2019-2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ #include "bignum.h" #include @@ -24,414 +24,371 @@ // BigNumber // ////////////////////////////////////////////////////////////////////// -BigNumber::~BigNumber() -{ - delete [] (Ipp8u*)m_pBN; -} +BigNumber::~BigNumber() { delete[](Ipp8u*) m_pBN; } -bool BigNumber::create(const Ipp32u* pData, int length, IppsBigNumSGN sgn) -{ - int size; - ippsBigNumGetSize(length, &size); - m_pBN = (IppsBigNumState*)( new Ipp8u[size] ); - if(!m_pBN) - return false; - ippsBigNumInit(length, m_pBN); - if (pData) - ippsSet_BN(sgn, length, pData, m_pBN); - return true; +bool BigNumber::create(const Ipp32u* pData, int length, IppsBigNumSGN sgn) { + int size; + ippsBigNumGetSize(length, &size); + m_pBN = (IppsBigNumState*)(new Ipp8u[size]); + if (!m_pBN) return false; + ippsBigNumInit(length, m_pBN); + if (pData) ippsSet_BN(sgn, length, pData, m_pBN); + return true; } // // constructors // -BigNumber::BigNumber(Ipp32u value) -{ - create(&value, 1, IppsBigNumPOS); -} +BigNumber::BigNumber(Ipp32u value) { create(&value, 1, IppsBigNumPOS); } -BigNumber::BigNumber(Ipp32s value) -{ - Ipp32s avalue = abs(value); - create((Ipp32u*)&avalue, 1, (value<0)? IppsBigNumNEG : IppsBigNumPOS); +BigNumber::BigNumber(Ipp32s value) { + Ipp32s avalue = abs(value); + create((Ipp32u*)&avalue, 1, (value < 0) ? IppsBigNumNEG : IppsBigNumPOS); } -BigNumber::BigNumber(const IppsBigNumState* pBN) -{ - IppsBigNumSGN bnSgn; - int bnBitLen; - Ipp32u* bnData; - ippsRef_BN(&bnSgn, &bnBitLen, &bnData, pBN); +BigNumber::BigNumber(const IppsBigNumState* pBN) { + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, pBN); - create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); + create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); } -BigNumber::BigNumber(const Ipp32u* pData, int length, IppsBigNumSGN sgn) -{ - create(pData, length, sgn); +BigNumber::BigNumber(const Ipp32u* pData, int length, IppsBigNumSGN sgn) { + create(pData, length, sgn); } static char HexDigitList[] = "0123456789ABCDEF"; -BigNumber::BigNumber(const char* s) -{ - bool neg = '-' == s[0]; - if(neg) s++; - bool hex = ('0'==s[0]) && (('x'==s[1]) || ('X'==s[1])); - - int dataLen; - Ipp32u base; - if(hex) { - s += 2; - base = 0x10; - dataLen = (int)(strlen_safe(s) + 7)/8; - } - else { - base = 10; - dataLen = (int)(strlen_safe(s) + 9)/10; - } - - create(0, dataLen); - *(this) = Zero(); - while(*s) { - char tmp[2] = {s[0],0}; - Ipp32u digit = (Ipp32u)strcspn(HexDigitList, tmp); - *this = (*this) * base + BigNumber( digit ); - s++; - } - - if(neg) - (*this) = Zero()- (*this); -} - -BigNumber::BigNumber(const BigNumber& bn) -{ - IppsBigNumSGN bnSgn; - int bnBitLen; - Ipp32u* bnData; - ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); - - create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); +BigNumber::BigNumber(const char* s) { + bool neg = '-' == s[0]; + if (neg) s++; + bool hex = ('0' == s[0]) && (('x' == s[1]) || ('X' == s[1])); + + int dataLen; + Ipp32u base; + if (hex) { + s += 2; + base = 0x10; + dataLen = (int)(strlen_safe(s) + 7) / 8; + } else { + base = 10; + dataLen = (int)(strlen_safe(s) + 9) / 10; + } + + create(0, dataLen); + *(this) = Zero(); + while (*s) { + char tmp[2] = {s[0], 0}; + Ipp32u digit = (Ipp32u)strcspn(HexDigitList, tmp); + *this = (*this) * base + BigNumber(digit); + s++; + } + + if (neg) (*this) = Zero() - (*this); +} + +BigNumber::BigNumber(const BigNumber& bn) { + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); + + create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); } // // set value // -void BigNumber::Set(const Ipp32u* pData, int length, IppsBigNumSGN sgn) -{ - ippsSet_BN(sgn, length, pData, BN(*this)); +void BigNumber::Set(const Ipp32u* pData, int length, IppsBigNumSGN sgn) { + ippsSet_BN(sgn, length, pData, BN(*this)); } // // constants // -const BigNumber& BigNumber::Zero() -{ - static const BigNumber zero(0); - return zero; +const BigNumber& BigNumber::Zero() { + static const BigNumber zero(0); + return zero; } -const BigNumber& BigNumber::One() -{ - static const BigNumber one(1); - return one; +const BigNumber& BigNumber::One() { + static const BigNumber one(1); + return one; } -const BigNumber& BigNumber::Two() -{ - static const BigNumber two(2); - return two; +const BigNumber& BigNumber::Two() { + static const BigNumber two(2); + return two; } // // arithmetic operators // -BigNumber& BigNumber::operator =(const BigNumber& bn) -{ - if(this != &bn) { // prevent self copy - IppsBigNumSGN bnSgn; - int bnBitLen; - Ipp32u* bnData; - ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); - - delete [] (Ipp8u*)m_pBN; - create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); - } - return *this; -} +BigNumber& BigNumber::operator=(const BigNumber& bn) { + if (this != &bn) { // prevent self copy + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); -BigNumber& BigNumber::operator += (const BigNumber& bn) -{ - int aBitLen; - ippsRef_BN(NULL, &aBitLen, NULL, *this); - int bBitLen; - ippsRef_BN(NULL, &bBitLen, NULL, bn); - int rBitLen = IPP_MAX(aBitLen, bBitLen) + 1; + delete[](Ipp8u*) m_pBN; + create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); + } + return *this; +} + +BigNumber& BigNumber::operator+=(const BigNumber& bn) { + int aBitLen; + ippsRef_BN(NULL, &aBitLen, NULL, *this); + int bBitLen; + ippsRef_BN(NULL, &bBitLen, NULL, bn); + int rBitLen = IPP_MAX(aBitLen, bBitLen) + 1; - BigNumber result(0, BITSIZE_WORD(rBitLen)); - ippsAdd_BN(*this, bn, result); - *this = result; - return *this; + BigNumber result(0, BITSIZE_WORD(rBitLen)); + ippsAdd_BN(*this, bn, result); + *this = result; + return *this; } -BigNumber& BigNumber::operator -= (const BigNumber& bn) -{ - int aBitLen; - ippsRef_BN(NULL, &aBitLen, NULL, *this); - int bBitLen; - ippsRef_BN(NULL, &bBitLen, NULL, bn); - int rBitLen = IPP_MAX(aBitLen, bBitLen); +BigNumber& BigNumber::operator-=(const BigNumber& bn) { + int aBitLen; + ippsRef_BN(NULL, &aBitLen, NULL, *this); + int bBitLen; + ippsRef_BN(NULL, &bBitLen, NULL, bn); + int rBitLen = IPP_MAX(aBitLen, bBitLen); - BigNumber result(0, BITSIZE_WORD(rBitLen)); - ippsSub_BN(*this, bn, result); - *this = result; - return *this; + BigNumber result(0, BITSIZE_WORD(rBitLen)); + ippsSub_BN(*this, bn, result); + *this = result; + return *this; } -BigNumber& BigNumber::operator *= (const BigNumber& bn) -{ - int aBitLen; - ippsRef_BN(NULL, &aBitLen, NULL, *this); - int bBitLen; - ippsRef_BN(NULL, &bBitLen, NULL, bn); - int rBitLen = aBitLen + bBitLen; +BigNumber& BigNumber::operator*=(const BigNumber& bn) { + int aBitLen; + ippsRef_BN(NULL, &aBitLen, NULL, *this); + int bBitLen; + ippsRef_BN(NULL, &bBitLen, NULL, bn); + int rBitLen = aBitLen + bBitLen; - BigNumber result(0, BITSIZE_WORD(rBitLen)); - ippsMul_BN(*this, bn, result); - *this = result; - return *this; + BigNumber result(0, BITSIZE_WORD(rBitLen)); + ippsMul_BN(*this, bn, result); + *this = result; + return *this; } -BigNumber& BigNumber::operator *= (Ipp32u n) -{ - int aBitLen; - ippsRef_BN(NULL, &aBitLen, NULL, *this); +BigNumber& BigNumber::operator*=(Ipp32u n) { + int aBitLen; + ippsRef_BN(NULL, &aBitLen, NULL, *this); - BigNumber result(0, BITSIZE_WORD(aBitLen+32)); - BigNumber bn(n); - ippsMul_BN(*this, bn, result); - *this = result; - return *this; + BigNumber result(0, BITSIZE_WORD(aBitLen + 32)); + BigNumber bn(n); + ippsMul_BN(*this, bn, result); + *this = result; + return *this; } -BigNumber& BigNumber::operator %= (const BigNumber& bn) -{ - BigNumber remainder(bn); - ippsMod_BN(BN(*this), BN(bn), BN(remainder)); - *this = remainder; - return *this; +BigNumber& BigNumber::operator%=(const BigNumber& bn) { + BigNumber remainder(bn); + ippsMod_BN(BN(*this), BN(bn), BN(remainder)); + *this = remainder; + return *this; } -BigNumber& BigNumber::operator /= (const BigNumber& bn) -{ - BigNumber quotient(*this); - BigNumber remainder(bn); - ippsDiv_BN(BN(*this), BN(bn), BN(quotient), BN(remainder)); - *this = quotient; - return *this; +BigNumber& BigNumber::operator/=(const BigNumber& bn) { + BigNumber quotient(*this); + BigNumber remainder(bn); + ippsDiv_BN(BN(*this), BN(bn), BN(quotient), BN(remainder)); + *this = quotient; + return *this; } -BigNumber operator + (const BigNumber& a, const BigNumber& b ) -{ - BigNumber r(a); - return r += b; +BigNumber operator+(const BigNumber& a, const BigNumber& b) { + BigNumber r(a); + return r += b; } -BigNumber operator - (const BigNumber& a, const BigNumber& b ) -{ - BigNumber r(a); - return r -= b; +BigNumber operator-(const BigNumber& a, const BigNumber& b) { + BigNumber r(a); + return r -= b; } -BigNumber operator * (const BigNumber& a, const BigNumber& b ) -{ - BigNumber r(a); - return r *= b; +BigNumber operator*(const BigNumber& a, const BigNumber& b) { + BigNumber r(a); + return r *= b; } -BigNumber operator * (const BigNumber& a, Ipp32u n) -{ - BigNumber r(a); - return r *= n; +BigNumber operator*(const BigNumber& a, Ipp32u n) { + BigNumber r(a); + return r *= n; } -BigNumber operator / (const BigNumber& a, const BigNumber& b ) -{ - BigNumber q(a); - return q /= b; +BigNumber operator/(const BigNumber& a, const BigNumber& b) { + BigNumber q(a); + return q /= b; } -BigNumber operator % (const BigNumber& a, const BigNumber& b ) -{ - BigNumber r(b); - ippsMod_BN(BN(a), BN(b), BN(r)); - return r; +BigNumber operator%(const BigNumber& a, const BigNumber& b) { + BigNumber r(b); + ippsMod_BN(BN(a), BN(b), BN(r)); + return r; } // // modulo arithmetic // -BigNumber BigNumber::Modulo(const BigNumber& a) const -{ - return a % *this; -} +BigNumber BigNumber::Modulo(const BigNumber& a) const { return a % *this; } -BigNumber BigNumber::InverseAdd(const BigNumber& a) const -{ - BigNumber t = Modulo(a); - if(t==BigNumber::Zero()) - return t; - else - return *this - t; +BigNumber BigNumber::InverseAdd(const BigNumber& a) const { + BigNumber t = Modulo(a); + if (t == BigNumber::Zero()) + return t; + else + return *this - t; } -BigNumber BigNumber::InverseMul(const BigNumber& a) const -{ - BigNumber r(*this); - ippsModInv_BN(BN(a), BN(*this), BN(r)); - return r; +BigNumber BigNumber::InverseMul(const BigNumber& a) const { + BigNumber r(*this); + ippsModInv_BN(BN(a), BN(*this), BN(r)); + return r; } -BigNumber BigNumber::ModAdd(const BigNumber& a, const BigNumber& b) const -{ - BigNumber r = this->Modulo(a+b); - return r; +BigNumber BigNumber::ModAdd(const BigNumber& a, const BigNumber& b) const { + BigNumber r = this->Modulo(a + b); + return r; } -BigNumber BigNumber::ModSub(const BigNumber& a, const BigNumber& b) const -{ - BigNumber r = this->Modulo(a + this->InverseAdd(b)); - return r; +BigNumber BigNumber::ModSub(const BigNumber& a, const BigNumber& b) const { + BigNumber r = this->Modulo(a + this->InverseAdd(b)); + return r; } -BigNumber BigNumber::ModMul(const BigNumber& a, const BigNumber& b) const -{ - BigNumber r = this->Modulo(a*b); - return r; +BigNumber BigNumber::ModMul(const BigNumber& a, const BigNumber& b) const { + BigNumber r = this->Modulo(a * b); + return r; } // // comparison // -int BigNumber::compare(const BigNumber &bn) const -{ - Ipp32u result; - BigNumber tmp = *this - bn; - ippsCmpZero_BN(BN(tmp), &result); - return (result==IS_ZERO)? 0 : (result==GREATER_THAN_ZERO)? 1 : -1; +int BigNumber::compare(const BigNumber& bn) const { + Ipp32u result; + BigNumber tmp = *this - bn; + ippsCmpZero_BN(BN(tmp), &result); + return (result == IS_ZERO) ? 0 : (result == GREATER_THAN_ZERO) ? 1 : -1; } -bool operator < (const BigNumber &a, const BigNumber &b) { return a.compare(b) < 0; } -bool operator > (const BigNumber &a, const BigNumber &b) { return a.compare(b) > 0; } -bool operator == (const BigNumber &a, const BigNumber &b) { return 0 == a.compare(b);} -bool operator != (const BigNumber &a, const BigNumber &b) { return 0 != a.compare(b);} +bool operator<(const BigNumber& a, const BigNumber& b) { + return a.compare(b) < 0; +} +bool operator>(const BigNumber& a, const BigNumber& b) { + return a.compare(b) > 0; +} +bool operator==(const BigNumber& a, const BigNumber& b) { + return 0 == a.compare(b); +} +bool operator!=(const BigNumber& a, const BigNumber& b) { + return 0 != a.compare(b); +} // easy tests // -bool BigNumber::IsOdd() const -{ - Ipp32u* bnData; - ippsRef_BN(NULL, NULL, &bnData, *this); - return bnData[0]&1; +bool BigNumber::IsOdd() const { + Ipp32u* bnData; + ippsRef_BN(NULL, NULL, &bnData, *this); + return bnData[0] & 1; } // // size of BigNumber // -int BigNumber::LSB() const -{ - if( *this == BigNumber::Zero() ) - return 0; - - vector v; - num2vec(v); - - int lsb = 0; - vector::iterator i; - for(i=v.begin(); i!=v.end(); i++) { - Ipp32u x = *i; - if(0==x) - lsb += 32; - else { - while(0==(x&1)) { - lsb++; - x >>= 1; - } - break; - } - } - return lsb; -} - -int BigNumber::MSB() const -{ - if( *this == BigNumber::Zero() ) - return 0; - - vector v; - num2vec(v); - - int msb = (int)v.size()*32 -1; - vector::reverse_iterator i; - for(i=v.rbegin(); i!=v.rend(); i++) { - Ipp32u x = *i; - if(0==x) - msb -=32; - else { - while(!(x&0x80000000)) { - msb--; - x <<= 1; - } - break; - } - } - return msb; -} - -int Bit(const vector& v, int n) -{ - return 0 != ( v[n>>5] & (1<<(n&0x1F)) ); +int BigNumber::LSB() const { + if (*this == BigNumber::Zero()) return 0; + + vector v; + num2vec(v); + + int lsb = 0; + vector::iterator i; + for (i = v.begin(); i != v.end(); i++) { + Ipp32u x = *i; + if (0 == x) + lsb += 32; + else { + while (0 == (x & 1)) { + lsb++; + x >>= 1; + } + break; + } + } + return lsb; +} + +int BigNumber::MSB() const { + if (*this == BigNumber::Zero()) return 0; + + vector v; + num2vec(v); + + int msb = (int)v.size() * 32 - 1; + vector::reverse_iterator i; + for (i = v.rbegin(); i != v.rend(); i++) { + Ipp32u x = *i; + if (0 == x) + msb -= 32; + else { + while (!(x & 0x80000000)) { + msb--; + x <<= 1; + } + break; + } + } + return msb; +} + +int Bit(const vector& v, int n) { + return 0 != (v[n >> 5] & (1 << (n & 0x1F))); } // // conversions and output // -void BigNumber::num2vec( vector& v ) const -{ - int bnBitLen; - Ipp32u* bnData; - ippsRef_BN(NULL, &bnBitLen, &bnData, *this); - - int len = BITSIZE_WORD(bnBitLen);; - for(int n=0; n0; n--) { - Ipp32u x = bnData[n-1]; - for(int nd=8; nd>0; nd--) { - char c = HexDigitList[(x>>(nd-1)*4)&0xF]; - s.append(1, c); - } - } -} - -ostream& operator << ( ostream &os, const BigNumber& a) -{ - string s; - a.num2hex(s); - os << s.c_str(); - return os; +void BigNumber::num2vec(vector& v) const { + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(NULL, &bnBitLen, &bnData, *this); + + int len = BITSIZE_WORD(bnBitLen); + ; + for (int n = 0; n < len; n++) v.push_back(bnData[n]); +} + +void BigNumber::num2hex(string& s) const { + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, *this); + + int len = BITSIZE_WORD(bnBitLen); + + s.append(1, (bnSgn == ippBigNumNEG) ? '-' : ' '); + s.append(1, '0'); + s.append(1, 'x'); + for (int n = len; n > 0; n--) { + Ipp32u x = bnData[n - 1]; + for (int nd = 8; nd > 0; nd--) { + char c = HexDigitList[(x >> (nd - 1) * 4) & 0xF]; + s.append(1, c); + } + } +} + +ostream& operator<<(ostream& os, const BigNumber& a) { + string s; + a.num2hex(s); + os << s.c_str(); + return os; } diff --git a/misc/bignum.h b/misc/bignum.h index 51696d1..68c3e4d 100644 --- a/misc/bignum.h +++ b/misc/bignum.h @@ -1,18 +1,18 @@ /******************************************************************************* -* Copyright 2019-2021 Intel Corporation -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*******************************************************************************/ + * Copyright 2019-2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ #if !defined _BIGNUMBER_H_ #define _BIGNUMBER_H_ @@ -25,82 +25,88 @@ using namespace std; -class BigNumber -{ +class BigNumber { public: - BigNumber(Ipp32u value=0); - BigNumber(Ipp32s value); - BigNumber(const IppsBigNumState* pBN); - BigNumber(const Ipp32u* pData, int length=1, IppsBigNumSGN sgn=IppsBigNumPOS); - BigNumber(const BigNumber& bn); - BigNumber(const char *s); - virtual ~BigNumber(); - - // set value - void Set(const Ipp32u* pData, int length=1, IppsBigNumSGN sgn=IppsBigNumPOS); - // conversion to IppsBigNumState - friend IppsBigNumState* BN(const BigNumber& bn) {return bn.m_pBN;} - operator IppsBigNumState* () const { return m_pBN; } - - // some useful constatns - static const BigNumber& Zero(); - static const BigNumber& One(); - static const BigNumber& Two(); - - // arithmetic operators probably need - BigNumber& operator = (const BigNumber& bn); - BigNumber& operator += (const BigNumber& bn); - BigNumber& operator -= (const BigNumber& bn); - BigNumber& operator *= (Ipp32u n); - BigNumber& operator *= (const BigNumber& bn); - BigNumber& operator /= (const BigNumber& bn); - BigNumber& operator %= (const BigNumber& bn); - friend BigNumber operator + (const BigNumber& a, const BigNumber& b); - friend BigNumber operator - (const BigNumber& a, const BigNumber& b); - friend BigNumber operator * (const BigNumber& a, const BigNumber& b); - friend BigNumber operator * (const BigNumber& a, Ipp32u); - friend BigNumber operator % (const BigNumber& a, const BigNumber& b); - friend BigNumber operator / (const BigNumber& a, const BigNumber& b); - - // modulo arithmetic - BigNumber Modulo(const BigNumber& a) const; - BigNumber ModAdd(const BigNumber& a, const BigNumber& b) const; - BigNumber ModSub(const BigNumber& a, const BigNumber& b) const; - BigNumber ModMul(const BigNumber& a, const BigNumber& b) const; - BigNumber InverseAdd(const BigNumber& a) const; - BigNumber InverseMul(const BigNumber& a) const; - - // comparisons - friend bool operator < (const BigNumber& a, const BigNumber& b); - friend bool operator > (const BigNumber& a, const BigNumber& b); - friend bool operator == (const BigNumber& a, const BigNumber& b); - friend bool operator != (const BigNumber& a, const BigNumber& b); - friend bool operator <= (const BigNumber& a, const BigNumber& b) {return !(a>b);} - friend bool operator >= (const BigNumber& a, const BigNumber& b) {return !(a>5;} - friend int Bit(const vector& v, int n); - - // conversion and output - void num2hex( string& s ) const; // convert to hex string - void num2vec( vector& v ) const; // convert to 32-bit word vector - friend ostream& operator << (ostream& os, const BigNumber& a); + BigNumber(Ipp32u value = 0); + BigNumber(Ipp32s value); + BigNumber(const IppsBigNumState* pBN); + BigNumber(const Ipp32u* pData, int length = 1, + IppsBigNumSGN sgn = IppsBigNumPOS); + BigNumber(const BigNumber& bn); + BigNumber(const char* s); + virtual ~BigNumber(); + + // set value + void Set(const Ipp32u* pData, int length = 1, + IppsBigNumSGN sgn = IppsBigNumPOS); + // conversion to IppsBigNumState + friend IppsBigNumState* BN(const BigNumber& bn) { return bn.m_pBN; } + operator IppsBigNumState*() const { return m_pBN; } + + // some useful constatns + static const BigNumber& Zero(); + static const BigNumber& One(); + static const BigNumber& Two(); + + // arithmetic operators probably need + BigNumber& operator=(const BigNumber& bn); + BigNumber& operator+=(const BigNumber& bn); + BigNumber& operator-=(const BigNumber& bn); + BigNumber& operator*=(Ipp32u n); + BigNumber& operator*=(const BigNumber& bn); + BigNumber& operator/=(const BigNumber& bn); + BigNumber& operator%=(const BigNumber& bn); + friend BigNumber operator+(const BigNumber& a, const BigNumber& b); + friend BigNumber operator-(const BigNumber& a, const BigNumber& b); + friend BigNumber operator*(const BigNumber& a, const BigNumber& b); + friend BigNumber operator*(const BigNumber& a, Ipp32u); + friend BigNumber operator%(const BigNumber& a, const BigNumber& b); + friend BigNumber operator/(const BigNumber& a, const BigNumber& b); + + // modulo arithmetic + BigNumber Modulo(const BigNumber& a) const; + BigNumber ModAdd(const BigNumber& a, const BigNumber& b) const; + BigNumber ModSub(const BigNumber& a, const BigNumber& b) const; + BigNumber ModMul(const BigNumber& a, const BigNumber& b) const; + BigNumber InverseAdd(const BigNumber& a) const; + BigNumber InverseMul(const BigNumber& a) const; + + // comparisons + friend bool operator<(const BigNumber& a, const BigNumber& b); + friend bool operator>(const BigNumber& a, const BigNumber& b); + friend bool operator==(const BigNumber& a, const BigNumber& b); + friend bool operator!=(const BigNumber& a, const BigNumber& b); + friend bool operator<=(const BigNumber& a, const BigNumber& b) { + return !(a > b); + } + friend bool operator>=(const BigNumber& a, const BigNumber& b) { + return !(a < b); + } + + // easy tests + bool IsOdd() const; + bool IsEven() const { return !IsOdd(); } + + // size of BigNumber + int MSB() const; + int LSB() const; + int BitSize() const { return MSB() + 1; } + int DwordSize() const { return (BitSize() + 31) >> 5; } + friend int Bit(const vector& v, int n); + + // conversion and output + void num2hex(string& s) const; // convert to hex string + void num2vec(vector& v) const; // convert to 32-bit word vector + friend ostream& operator<<(ostream& os, const BigNumber& a); protected: - bool create(const Ipp32u* pData, int length, IppsBigNumSGN sgn=IppsBigNumPOS); - int compare(const BigNumber& ) const; - IppsBigNumState* m_pBN; + bool create(const Ipp32u* pData, int length, + IppsBigNumSGN sgn = IppsBigNumPOS); + int compare(const BigNumber&) const; + IppsBigNumState* m_pBN; }; // convert bit size into 32-bit words -#define BITSIZE_WORD(n) ((((n)+31)>>5)) +#define BITSIZE_WORD(n) ((((n) + 31) >> 5)) -#endif // _BIGNUMBER_H_ +#endif // _BIGNUMBER_H_ diff --git a/he_qat_misc.cpp b/misc/he_qat_misc.cpp similarity index 100% rename from he_qat_misc.cpp rename to misc/he_qat_misc.cpp diff --git a/he_qat_misc.h b/misc/he_qat_misc.h similarity index 100% rename from he_qat_misc.h rename to misc/he_qat_misc.h diff --git a/misc/utils.cpp b/misc/utils.cpp index a89e150..1bf189b 100644 --- a/misc/utils.cpp +++ b/misc/utils.cpp @@ -1,19 +1,18 @@ /******************************************************************************* -* Copyright 2021 Intel Corporation -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*******************************************************************************/ - + * Copyright 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ #include "utils.h" diff --git a/misc/utils.h b/misc/utils.h index 6b1f079..bc06bff 100644 --- a/misc/utils.h +++ b/misc/utils.h @@ -1,18 +1,18 @@ /******************************************************************************* -* Copyright 2021 Intel Corporation -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*******************************************************************************/ + * Copyright 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ #ifndef _UTILS_H_ #define _UTILS_H_ @@ -21,14 +21,14 @@ #define RSIZE_MAX_STR (4UL << 10) /* 4Kb */ /** - * \brief + * \brief * The strnlen_s function computes the length of the string pointed to by dest. * \param[in] dest pointer to string * \param[in] dmax restricted maximum length. (default 4Kb) - * \return size_t + * \return size_t * The function returns the string length, excluding the terminating * null character. If dest is NULL, then strnlen_s returns 0. */ size_t strlen_safe(const char* dest, size_t dmax = RSIZE_MAX_STR); -#endif // _UTILS_H_ +#endif // _UTILS_H_ From 9c3c0cfb0e6bc363baea8da0b77670fcef3aee21 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 10 Mar 2022 00:43:38 -0800 Subject: [PATCH 099/364] Refactor CMake build system. --- CMakeLists.txt | 192 +++++++++++++++++++--------------------- examples/CMakeLists.txt | 24 +++++ he_qat/CMakeLists.txt | 23 +++++ misc/CMakeLists.txt | 37 ++++---- 4 files changed, 154 insertions(+), 122 deletions(-) create mode 100644 examples/CMakeLists.txt create mode 100644 he_qat/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index c13cb41..fec91b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,105 +1,91 @@ cmake_minimum_required(VERSION 3.13) -project(QATModExp LANGUAGES C CXX) - -set(CMAKE_C_STANDARD 99) -set(CMAKE_C_STANDARD_REQUIRED ON) -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -include(CheckCCompilerFlag) -include(CheckCXXCompilerFlag) -include(CMakePackageConfigHelpers) - -set(COMMON_INC_DIR ${CMAKE_CURRENT_LIST_DIR}/include) - -set(CMAKE_INSTALL_PREFIX "install") - -set(ICP_ROOT $ENV{ICP_ROOT}) -set(ICP_BUILDOUTPUT_PATH ${ICP_ROOT}/build) -set(ICP_BUILDSYSTEM_PATH ${ICP_ROOT}/quickassist/build_system) -set(ICP_API_DIR ${ICP_ROOT}/quickassist) -set(ICP_LAC_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer) -set(ICP_OSAL_DIR ${ICP_ROOT}/quickassist/utilities/oasl) -set(ICP_ADF_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/qat_direct) -set(CMN_ROOT ${ICP_ROOT}/quickassist/utilities/libusdm_drv) - -list(APPEND COMMON_INC_DIR - ${ICP_API_DIR}/include - ${ICP_LAC_DIR}/include - ${ICP_ADF_DIR}/include - ${CMN_ROOT} -) - -# Macros for the test case -add_definitions(-DDO_CRYPTO) -add_definitions(-DUSER_SPACE) -add_compile_options(-fPIC) - -# Common utility functions -add_subdirectory(common) - -set(IPPCP_DIR "/opt/ipp-crypto") -set(IPPCP_CMAKE_PREFIX_DIR "${IPPCP_DIR}/lib/cmake") -list(APPEND CMAKE_PREFIX_PATH "${IPPCP_CMAKE_PREFIX_DIR}") -find_package(ippcp REQUIRED) - -set(HE_QAT_MISC_INC_DIR ${COMMON_INC_DIR} ${CMAKE_CURRENT_LIST_DIR}) -set(HE_QAT_MISC_SRC ${CMAKE_CURRENT_LIST_DIR}/he_qat_misc.cpp) -add_subdirectory(misc) - -set(HE_QAT_SRC ${CMAKE_CURRENT_LIST_DIR}/he_qat_bn_ops.c - ${CMAKE_CURRENT_LIST_DIR}/he_qat_context.c) - -add_library(he_qat SHARED ${HE_QAT_SRC}) # Let BUILD_SHARED_LIBS do the job by removing the qualifier SHARED -target_include_directories(he_qat PUBLIC ${COMMON_INC_DIR}) -#target_include_directories(he_qat PUBLIC ${HE_QAT_MISC_INC_DIR}) -target_include_directories(he_qat PUBLIC /opt/openssl/include) -target_link_directories(he_qat PUBLIC ${ICP_BUILDOUTPUT_PATH}) -target_link_directories(he_qat PUBLIC /opt/openssl/lib) -target_link_libraries(he_qat PRIVATE cpa_sample_utils) -#target_link_libraries(he_qat PRIVATE he_qat_utils) -target_link_libraries(he_qat PUBLIC qat_s usdm_drv_s) -target_link_libraries(he_qat PUBLIC crypto ssl) -target_link_libraries(he_qat PUBLIC z pthread) - -#add_definitions(-D_DESTINY_DEBUG_VERBOSE) -if(NOT HE_QAT_DEBUG_VERBOSE) - remove_definitions(-D_DESTINY_DEBUG_VERBOSE) -endif() - -add_executable(test_context test_context.c) -target_include_directories(test_context PUBLIC ${HE_QAT_MISC_INC_DIR}) -target_link_libraries(test_context PUBLIC he_qat) -#target_link_libraries(test_context PUBLIC cpa_sample_utils) -target_link_libraries(test_context PUBLIC z pthread ssl crypto qat_s usdm_drv_s) - - -#find_package(IPPCrypto REQUIRED MODULE) -#if (NOT IPPCRYPTO_FOUND) -# message(FATAL_ERROR "No Intel IPP Cryptography library found on the system.") -#endif() -#if(NOT TARGET ippcp) -# message(FATAL_ERROR "TARGET IPPCP::ippcp not found") -#else() -# message(STATUS "TARGET IPPCP::ippcp found") -#endif() - - - -add_executable(test_bnModExpPerformOp test_bnModExpPerformOp.c) -#target_include_directories(test_bnModExpPerformOp PUBLIC ${HE_QAT_UTILS_INC_DIR}) -target_link_libraries(test_bnModExpPerformOp PUBLIC he_qat) -#target_link_libraries(test_bnModExpPerformOp PUBLIC cpa_sample_utils) -target_link_libraries(test_bnModExpPerformOp PUBLIC z pthread ssl crypto qat_s usdm_drv_s) - -add_compile_options(-fpermissive) -add_executable(test_bnConversion test_bnConversion.cpp) -target_include_directories(test_bnConversion PUBLIC ${HE_QAT_MISC_INC_DIR}) -target_link_libraries(test_bnConversion PUBLIC he_qat) -target_link_libraries(test_bnConversion PUBLIC he_qat_misc) -#target_link_libraries(test_bnConversion PUBLIC he_qat_utils) -#target_link_libraries(test_bnConversion PUBLIC cpa_sample_utils) -#target_link_libraries(test_bnConversion PUBLIC ippcpmx crypto_mb) -target_link_libraries(test_bnConversion PUBLIC z pthread ssl crypto qat_s usdm_drv_s) - + project(QATModExp LANGUAGES C CXX) + + set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED ON) set( + CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) + + include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) include( + CMakePackageConfigHelpers) + + set(HE_QAT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) set( + HE_QAT_SRC_DIR ${HE_QAT_ROOT_DIR} / + he_qat) set(HE_QAT_INC_DIR ${HE_QAT_ROOT_DIR} / he_qat / + include) + +#OpenSSL installation + set(OPENSSL_INC_DIR / opt / openssl / + include) set(OPENSSL_LIB_DIR / opt / openssl / lib) + + set(COMMON_INC_DIR ${CMAKE_CURRENT_LIST_DIR} / include) + + set(CMAKE_INSTALL_PREFIX "install") + +#QAT lib installation + set(ICP_ROOT $ENV{ICP_ROOT}) set( + ICP_BUILDOUTPUT_PATH ${ICP_ROOT} / + build) set(ICP_BUILDSYSTEM_PATH ${ + ICP_ROOT} / + quickassist / + build_system) set(ICP_API_DIR ${ + ICP_ROOT} / + quickassist) + set(ICP_LAC_DIR ${ICP_ROOT} / quickassist / + lookaside / + access_layer) set(ICP_OSAL_DIR ${ + ICP_ROOT} / + quickassist / + utilities / oasl) + set(ICP_ADF_DIR ${ICP_ROOT} / + quickassist / lookaside / + access_layer / src / + qat_direct) set(CMN_ROOT ${ + ICP_ROOT} / + quickassist / + utilities / + libusdm_drv) + + list(APPEND COMMON_INC_DIR ${ + ICP_API_DIR} / + include ${ICP_LAC_DIR} / + include ${ICP_ADF_DIR} / + include ${CMN_ROOT}) + +#Macros for the test case + add_definitions(-DDO_CRYPTO) add_definitions( + -DUSER_SPACE) add_compile_options(-fPIC) + +#Common utility functions + add_subdirectory(common) + +#IPP Crypto installation + set(IPPCP_DIR + "/opt/ipp-crypto") + set(IPPCP_CMAKE_PREFIX_DIR + "${IPPCP_DIR}/" + "lib/cmake") + list( + APPEND + CMAKE_PREFIX_PATH + "${IPPCP_" + "CMAKE_" + "PREFIX_" + "DIR}") + find_package( + ippcp + REQUIRED) + +#Helper functions +#set(HE_QAT_MISC_INC_DIR ${COMMON_INC_DIR} ${CMAKE_CURRENT_LIST_DIR}) +#set(HE_QAT_MISC_INC_DIR ${COMMON_INC_DIR}) +#set(HE_QAT_MISC_SRC ${HE_QAT_SRC_DIR} / he_qat_misc.cpp) + add_subdirectory( + misc) + +#Library + add_subdirectory( + he_qat) + +#Validation test examples + add_subdirectory( + examples) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 0000000..0564fe7 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,24 @@ + +#add_definitions(-D_DESTINY_DEBUG_VERBOSE) +if (NOT HE_QAT_DEBUG_VERBOSE) + remove_definitions(-D_DESTINY_DEBUG_VERBOSE) +endif() + +add_executable(test_context test_context.c) +target_include_directories(test_context PUBLIC ${COMMON_INC_DIR} ${HE_QAT_MISC_INC_DIR}) +target_link_libraries(test_context PUBLIC he_qat) +#target_link_libraries(test_context PUBLIC cpa_sample_utils) +target_link_libraries(test_context PUBLIC z pthread ssl crypto qat_s usdm_drv_s) + +add_executable(test_bnModExpPerformOp test_bnModExpPerformOp.c) +target_include_directories(test_bnModExpPerformOp PUBLIC ${COMMON_INC_DIR}) # ${HE_QAT_UTILS_INC_DIR}) +target_link_libraries(test_bnModExpPerformOp PUBLIC he_qat) +#target_link_libraries(test_bnModExpPerformOp PUBLIC cpa_sample_utils) +target_link_libraries(test_bnModExpPerformOp PUBLIC z pthread ssl crypto qat_s usdm_drv_s) + +add_compile_options(-fpermissive) +add_executable(test_bnConversion test_bnConversion.cpp) +target_include_directories(test_bnConversion PUBLIC ${COMMON_INC_DIR} ${HE_QAT_MISC_INC_DIR}) +target_link_libraries(test_bnConversion PUBLIC he_qat) +target_link_libraries(test_bnConversion PUBLIC he_qat_misc) +target_link_libraries(test_bnConversion PUBLIC z pthread ssl crypto qat_s usdm_drv_s) diff --git a/he_qat/CMakeLists.txt b/he_qat/CMakeLists.txt new file mode 100644 index 0000000..f4c4e04 --- /dev/null +++ b/he_qat/CMakeLists.txt @@ -0,0 +1,23 @@ + +set(HE_QAT_SRC ${HE_QAT_SRC_DIR} / he_qat_bn_ops.c ${HE_QAT_SRC_DIR} / + he_qat_context.c) + + add_library(he_qat SHARED ${HE_QAT_SRC}) + + target_include_directories( + he_qat PUBLIC $< + BUILD_INTERFACE : ${COMMON_INC_DIR}> #Public headers PUBLIC + $ #Public headers PUBLIC $< + BUILD_INTERFACE : ${OPENSSL_INC_DIR}> #Public headers PUBLIC + $ #Public headers + PRIVATE $ { COMMON_INC_DIR } #Private headers PRIVATE + $ { OPENSSL_INC_DIR } #Private headers) +#target_include_directories(he_qat PUBLIC ${HE_QAT_UTILS_INC_DIR}) + + target_link_directories(he_qat PUBLIC ${ICP_BUILDOUTPUT_PATH}) + target_link_directories(he_qat PUBLIC ${OPENSSL_LIB_DIR}) + target_link_libraries(he_qat PRIVATE cpa_sample_utils) +#target_link_libraries(he_qat PRIVATE he_qat_utils) + target_link_libraries(he_qat PUBLIC qat_s usdm_drv_s) + target_link_libraries(he_qat PUBLIC crypto ssl) + target_link_libraries(he_qat PUBLIC z pthread) diff --git a/misc/CMakeLists.txt b/misc/CMakeLists.txt index a1e5ca0..fe218a4 100644 --- a/misc/CMakeLists.txt +++ b/misc/CMakeLists.txt @@ -1,23 +1,22 @@ -# Include directories -list(APPEND HE_QAT_MISC_INC_DIR - ${CMAKE_CURRENT_LIST_DIR} - ${IPPCP_DIR}/include -) -message(STATUS "HE_QAT_MISC_INC_DIR: ${HE_QAT_MISC_INC_DIR}") +#Include directories +#list(APPEND HE_QAT_MISC_INC_DIR +set(HE_QAT_MISC_INC_DIR ${COMMON_INC_DIR} ${HE_QAT_INC_DIR} ${ + CMAKE_CURRENT_LIST_DIR} ${IPPCP_DIR} / + include) message(STATUS "HE_QAT_MISC_INC_DIR: ${HE_QAT_MISC_INC_DIR}") -# Source files -list(APPEND HE_QAT_MISC_SRC ${CMAKE_CURRENT_LIST_DIR}/utils.cpp - ${CMAKE_CURRENT_LIST_DIR}/bignum.cpp -) +#Source files +#list(APPEND HE_QAT_MISC_SRC ${CMAKE_CURRENT_LIST_DIR} / utils.cpp + set(HE_QAT_MISC_SRC ${CMAKE_CURRENT_LIST_DIR} / + he_qat_misc.cpp ${CMAKE_CURRENT_LIST_DIR} / + utils.cpp ${CMAKE_CURRENT_LIST_DIR} / bignum.cpp) -add_library(he_qat_misc ${HE_QAT_MISC_SRC}) -target_include_directories(he_qat_misc - PUBLIC $ # Public headers - PUBLIC $ # Public headers -) -target_link_directories(he_qat_misc PUBLIC ${IPPCP_DIR}/lib/intel64) -target_link_libraries(he_qat_misc PUBLIC ippcpmx crypto_mb) - -set(HE_QAT_MISC_INC_DIR ${HE_QAT_MISC_INC_DIR} PARENT_SCOPE) + add_library(he_qat_misc ${HE_QAT_MISC_SRC}) target_include_directories( + he_qat_misc PUBLIC $< + BUILD_INTERFACE : ${HE_QAT_MISC_INC_DIR}> #Public headers PUBLIC + $ #Public headers) + target_link_directories(he_qat_misc PUBLIC ${IPPCP_DIR} / lib / + intel64) + target_link_libraries(he_qat_misc PUBLIC ippcpmx crypto_mb) +#set(HE_QAT_MISC_INC_DIR ${HE_QAT_MISC_INC_DIR} PARENT_SCOPE) From d9311b670d1ce313b7ca513b2a8f701bffeee88f Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 10 Mar 2022 00:59:37 -0800 Subject: [PATCH 100/364] Update README.md. --- README.md | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0289325..808c353 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Intel Homomorphic Encryption Acceleration Library for QAT (HEQAT Lib) is an open-source library which provides accelerated performance for homomorphic encryption (HE) math functions involving multi-precision numbers and modular arithmetic. This library is written in C99. ## Contents -- [Intel Paillier Cryptosystem Library](#intel-paillier-cryptosystem-library) +- [Intel Homomorphic Encryption Acceleration Library for QAT](#intel-homomorphic-encryption-library-for-qat) - [Contents](#contents) - [Introduction](#introduction) - [Building the Library](#building-the-library) @@ -15,14 +15,40 @@ Intel Homomorphic Encryption Acceleration Library for QAT (HEQAT Lib) is an open ## Introduction -This library is underconstruction and currently only offers acceleration of modular exponentiation of multi-precision numbers, ranging from 1024 to 8192-bit numbers. Current stage of implementation provides the big number modular exponentiation featuring OpenSSL BIGNUM data type and has the following characteristics: - - Synchronous: It means that calls will place a work request to be offloaded to the accelerator and processed in the order they are issued. - - Blocking: It means that the next buffered work request waits for completion of processing of the most recently request offloaded to the accelerator, when processing must be currently in progress. - - Batch Support: The internal buffer is set accommodate 16 request at once so that the maximum batch size is 16. Therefore, only up to 16 requests can exercised asynchronously from the application for any single `for loop` or code block along with a call to the `get` function that waits for completion of the requests. +This library is underconstruction and currently only offers acceleration of modular exponentiation of multi-precision numbers, i.e. large numbers whose precision range from 1024 to 8192 bits. Current stage of implementation supports modular exponentiation of big numbers encoded with OpenSSL's BIGNUM data type and IPP Crypto's BigNumber class. More details about the modes of operation and characteristics of the execution flow are described below: + + - Synchronous: It means that calls will be made to send modular exponentiation work requests to be offloaded to the accelerator and processed in the order they are issued. + + - Blocking: It means that the next buffered work request waits for completion of the processing of the most recent request offloaded to the accelerator, when processing must be currently in progress. + + - Batch Support: The internal buffer is set accommodate 16 request at a time so that the maximum batch size is 16. Therefore, only up to 16 requests can be exercised asynchronously from the application side, be it from a single `for loop` or static code block. Finally, in order to collect the requests, a call to the `get` function that waits for completion of the requests must be done. + - Single-Threaded: It is currently safer to use single-threaded, although multiple threading is partially supported (try it at your own risk). Multi-threading can only be supported so long as the internal buffer can fill all the requests submitted by multiple threads, otherwise it will hang (this feature will become reliable in later versions). + - Single instance: The library is configure to use only 1 single QAT endpoint at any time at the creation of the QAT runtime context. ## Building the Library + +``` +export ICP_ROOT=$HOME/QAT +cmake -S . -B build +cmake --build build +``` + +### Running Examples + +``` +./build/examples/test_context +``` + +``` +./build/examples/test_bnModExpPerformOp +``` + +``` +./build/examples/test_bnConversion +``` + ### Requirements The hardware requirement to use the library is the following: - Intel Sapphire Rapids @@ -31,6 +57,7 @@ The hardware requirement to use the library is the following: As for the operating systems, the library has been tested and confirmed to work on Ubuntu 20.04. ### Dependencies + Required dependencies include: ``` cmake >=3.15.1 From 34058e30399c8f97b059728d338bf724c43bae6f Mon Sep 17 00:00:00 2001 From: Hamish Hunt Date: Thu, 10 Mar 2022 23:17:21 +0000 Subject: [PATCH 101/364] Refactor review (#52) * tidy refactor * removed unnecessary tmps * move method to cpp * aliases with const refs * typo and scope vars * consistency camel case convention --- README.md | 6 +-- ipcl/bignum.cpp | 3 -- ipcl/include/ipcl/bignum.h | 4 +- ipcl/include/ipcl/common.hpp | 2 +- ipcl/include/ipcl/mod_exp.hpp | 1 - ipcl/include/ipcl/paillier_ops.hpp | 10 +---- ipcl/include/ipcl/paillier_pubkey.hpp | 2 +- ipcl/include/ipcl/util.hpp | 16 ++++---- ipcl/mod_exp.cpp | 35 ++++++++-------- ipcl/paillier_keygen.cpp | 16 ++++---- ipcl/paillier_ops.cpp | 58 +++++++++++++++------------ ipcl/paillier_prikey.cpp | 29 ++++++-------- ipcl/paillier_pubkey.cpp | 36 ++++++++--------- 13 files changed, 105 insertions(+), 113 deletions(-) diff --git a/README.md b/README.md index c05a834..ca17e85 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ We will keep working on adding more supported operating systems. ### Dependencies Must have dependencies include: ``` -cmake >=3.15.1 +cmake >= 3.15.1 git pthread g++ >= 7.0 or clang >= 10.0 @@ -54,8 +54,8 @@ g++ >= 7.0 or clang >= 10.0 The following libraries and tools are also required, ``` -nasm>=2.15 -OpenSSL>=1.1.0 +nasm >= 2.15 +OpenSSL >= 1.1.0 ``` For ```nasm```, please refer to the [Netwide Assembler](https://nasm.us/) for installation details. diff --git a/ipcl/bignum.cpp b/ipcl/bignum.cpp index b0b578e..b5adab3 100644 --- a/ipcl/bignum.cpp +++ b/ipcl/bignum.cpp @@ -509,7 +509,4 @@ void BigNumber::num2char(std::vector& dest) const { dest.assign(bnData, bnData + len); } -int BITSIZE_WORD(int n) { return (((n) + 31) >> 5); } -int BITSIZE_DWORD(int n) { return (((n) + 63) >> 6); } - } // namespace ipcl diff --git a/ipcl/include/ipcl/bignum.h b/ipcl/include/ipcl/bignum.h index c150f5a..fe62dc1 100644 --- a/ipcl/include/ipcl/bignum.h +++ b/ipcl/include/ipcl/bignum.h @@ -128,8 +128,8 @@ class BigNumber { IppsBigNumState* m_pBN; }; -int BITSIZE_WORD(int n); -int BITSIZE_DWORD(int n); +constexpr int BITSIZE_WORD(int n) { return (((n) + 31) >> 5); } +constexpr int BITSIZE_DWORD(int n) { return (((n) + 63) >> 6); } } // namespace ipcl #endif // _BIGNUM_H_ diff --git a/ipcl/include/ipcl/common.hpp b/ipcl/include/ipcl/common.hpp index fecc02d..f954026 100644 --- a/ipcl/include/ipcl/common.hpp +++ b/ipcl/include/ipcl/common.hpp @@ -6,7 +6,7 @@ namespace ipcl { -#define IPCL_CRYPTO_MB_SIZE 8 +constexpr int IPCL_CRYPTO_MB_SIZE = 8; } // namespace ipcl #endif // IPCL_INCLUDE_IPCL_COMMON_HPP_ diff --git a/ipcl/include/ipcl/mod_exp.hpp b/ipcl/include/ipcl/mod_exp.hpp index e3b3ac4..810ff27 100644 --- a/ipcl/include/ipcl/mod_exp.hpp +++ b/ipcl/include/ipcl/mod_exp.hpp @@ -7,7 +7,6 @@ #include #include "ipcl/bignum.h" -#include "ipcl/util.hpp" namespace ipcl { /** diff --git a/ipcl/include/ipcl/paillier_ops.hpp b/ipcl/include/ipcl/paillier_ops.hpp index f7d0d72..4fbb84b 100644 --- a/ipcl/include/ipcl/paillier_ops.hpp +++ b/ipcl/include/ipcl/paillier_ops.hpp @@ -75,15 +75,7 @@ class PaillierEncryptedNumber { * Apply obfuscator for ciphertext, obfuscated needed only when the ciphertext * is exposed */ - void apply_obfuscator() { - b_isObfuscator = true; - std::vector obfuscator(IPCL_CRYPTO_MB_SIZE); - m_pubkey->apply_obfuscator(obfuscator); - - BigNumber sq = m_pubkey->getNSQ(); - for (int i = 0; i < m_available; i++) - m_bn[i] = sq.ModMul(m_bn[i], obfuscator[i]); - } + void applyObfuscator(); /** * Return ciphertext diff --git a/ipcl/include/ipcl/paillier_pubkey.hpp b/ipcl/include/ipcl/paillier_pubkey.hpp index 9b51247..228e107 100644 --- a/ipcl/include/ipcl/paillier_pubkey.hpp +++ b/ipcl/include/ipcl/paillier_pubkey.hpp @@ -82,7 +82,7 @@ class PaillierPublicKey { * Apply obfuscator for ciphertext * @param[out] obfuscator output of obfuscator with random value */ - void apply_obfuscator(std::vector& obfuscator) const; + void applyObfuscator(std::vector& obfuscator) const; /** * @brief Set the Random object for ISO/IEC 18033-6 compliance check diff --git a/ipcl/include/ipcl/util.hpp b/ipcl/include/ipcl/util.hpp index b56cf50..488e2e1 100644 --- a/ipcl/include/ipcl/util.hpp +++ b/ipcl/include/ipcl/util.hpp @@ -6,20 +6,20 @@ #include #include +#include #include #include "ipcl/common.hpp" namespace ipcl { -static inline std::string build_log(const char* file, int line, - std::string msg) { - std::string log; - log = "\nFile: " + std::string(file); - log += "\nLine: " + std::to_string(line); - log += "\nError: " + msg; - - return log; +inline std::string build_log(const char* file, int line, + const std::string& msg) { + std::ostringstream log; + log << "\nFile: " << file + << "\nLine: " << line + << "\nError: " << msg; + return log.str(); } #define ERROR_CHECK(e, ...) \ diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index f6cb1de..5bb680c 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "ipcl/mod_exp.hpp" +#include "ipcl/util.hpp" #include @@ -18,14 +19,15 @@ static std::vector ippMBModExp(const std::vector& base, mbx_status st = MBX_STATUS_OK; - int&& bits = m[0].BitSize(); - int&& dwords = BITSIZE_DWORD(bits); - int&& bufferLen = mbx_exp_BufferSize(bits); - auto&& pBuffer = std::vector(bufferLen); + int bits = m.front().BitSize(); + int dwords = BITSIZE_DWORD(bits); + int bufferLen = mbx_exp_BufferSize(bits); + auto buffer = std::vector(bufferLen); - std::vector out_x(IPCL_CRYPTO_MB_SIZE), b_array(IPCL_CRYPTO_MB_SIZE), - p_array(IPCL_CRYPTO_MB_SIZE); - int&& length = dwords * sizeof(int64u); + std::vector out_x(IPCL_CRYPTO_MB_SIZE); + std::vector b_array(IPCL_CRYPTO_MB_SIZE); + std::vector p_array(IPCL_CRYPTO_MB_SIZE); + int length = dwords * sizeof(int64u); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { out_x[i] = reinterpret_cast(alloca(length)); @@ -47,12 +49,13 @@ static std::vector ippMBModExp(const std::vector& base, * will be inconsistent with the length allocated by b_array/p_array, * resulting in data errors. */ - std::vector pow_b(IPCL_CRYPTO_MB_SIZE), pow_p(IPCL_CRYPTO_MB_SIZE), - pow_nsquare(IPCL_CRYPTO_MB_SIZE); - int bBitLen, pBitLen, nsqBitLen; + std::vector pow_b(IPCL_CRYPTO_MB_SIZE); + std::vector pow_p(IPCL_CRYPTO_MB_SIZE); + std::vector pow_nsquare(IPCL_CRYPTO_MB_SIZE); + int nsqBitLen; int expBitLen = 0; - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + for (int i = 0, bBitLen, pBitLen; i < IPCL_CRYPTO_MB_SIZE; i++) { ippsRef_BN(nullptr, &bBitLen, reinterpret_cast(&pow_b[i]), base[i]); ippsRef_BN(nullptr, &pBitLen, reinterpret_cast(&pow_p[i]), @@ -72,7 +75,7 @@ static std::vector ippMBModExp(const std::vector& base, */ st = mbx_exp_mb8(out_x.data(), b_array.data(), p_array.data(), expBitLen, reinterpret_cast(pow_nsquare.data()), nsqBitLen, - reinterpret_cast(pBuffer.data()), bufferLen); + reinterpret_cast(buffer.data()), bufferLen); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { ERROR_CHECK(MBX_STATUS_OK == MBX_GET_STS(st, i), @@ -82,7 +85,7 @@ static std::vector ippMBModExp(const std::vector& base, } // It is important to hold a copy of nsquare for thread-safe purpose - BigNumber bn_c(m[0]); + BigNumber bn_c(m.front()); std::vector res(IPCL_CRYPTO_MB_SIZE, 0); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { @@ -96,14 +99,14 @@ static std::vector ippMBModExp(const std::vector& base, static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, const BigNumber& m) { IppStatus stat = ippStsNoErr; - // It is important to declear res * bform bit length refer to ipp-crypto spec: + // It is important to declare res * bform bit length refer to ipp-crypto spec: // R should not be less than the data length of the modulus m BigNumber res(m); int bnBitLen; Ipp32u* pow_m; ippsRef_BN(nullptr, &bnBitLen, &pow_m, BN(m)); - int&& nlen = BITSIZE_WORD(bnBitLen); + int nlen = BITSIZE_WORD(bnBitLen); int size; // define and initialize Montgomery Engine over Modulus N @@ -111,7 +114,7 @@ static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: get the size of IppsMontState context error."); - auto&& pMont = std::vector(size); + auto pMont = std::vector(size); stat = ippsMontInit(IppsBinaryMethod, nlen, reinterpret_cast(pMont.data())); diff --git a/ipcl/paillier_keygen.cpp b/ipcl/paillier_keygen.cpp index 59ef948..22d95b0 100644 --- a/ipcl/paillier_keygen.cpp +++ b/ipcl/paillier_keygen.cpp @@ -11,7 +11,7 @@ namespace ipcl { -#define N_BIT_SIZE_MAX 2048 +constexpr int N_BIT_SIZE_MAX = 2048; static void rand32u(std::vector& addr) { std::random_device dev; @@ -23,18 +23,18 @@ static void rand32u(std::vector& addr) { BigNumber getPrimeBN(int maxBitSize) { int PrimeSize; ippsPrimeGetSize(maxBitSize, &PrimeSize); - auto&& primeGen = std::vector(PrimeSize); + auto primeGen = std::vector(PrimeSize); ippsPrimeInit(maxBitSize, reinterpret_cast(primeGen.data())); // define Pseudo Random Generator (default settings) - int&& seedBitSize = 160; - int&& seedSize = BITSIZE_WORD(seedBitSize); + constexpr int seedBitSize = 160; + constexpr int seedSize = BITSIZE_WORD(seedBitSize); ippsPRNGGetSize(&PrimeSize); - auto&& rand = std::vector(PrimeSize); + auto rand = std::vector(PrimeSize); ippsPRNGInit(seedBitSize, reinterpret_cast(rand.data())); - auto&& seed = std::vector(seedSize); + auto seed = std::vector(seedSize); rand32u(seed); BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); @@ -76,9 +76,7 @@ static void getDJNBN(int64_t n_length, BigNumber& p, BigNumber& q, q = getPrimeBN(n_length / 2); } while (q == p || !p.TestBit(1)); // get q: q!=p and q mod 4 = 3 - BigNumber&& pminusone = p - 1; - BigNumber&& qminusone = q - 1; - gcd = pminusone.gcd(qminusone); + gcd = (p - 1).gcd(q -1); // (p - 1) is a BigNumer } while (gcd.compare(2)); // gcd(p-1,q-1)=2 n = p * q; diff --git a/ipcl/paillier_ops.cpp b/ipcl/paillier_ops.cpp index 0ca209b..fd28835 100644 --- a/ipcl/paillier_ops.cpp +++ b/ipcl/paillier_ops.cpp @@ -2,11 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 #include "ipcl/paillier_ops.hpp" +#include "ipcl/mod_exp.hpp" #include -#include "ipcl/mod_exp.hpp" - namespace ipcl { // constructors // @@ -43,28 +42,28 @@ PaillierEncryptedNumber PaillierEncryptedNumber::operator+( ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), "operator+: two different public keys detected!!"); - PaillierEncryptedNumber a = *this; - PaillierEncryptedNumber b = other; + const auto& a = *this; + const auto& b = other; if (m_available == 1) { - BigNumber&& sum = a.raw_add(a.m_bn[0], b.m_bn[0]); - return PaillierEncryptedNumber(m_pubkey, sum); - } else { - std::vector sum(IPCL_CRYPTO_MB_SIZE); - for (int i = 0; i < m_available; i++) - sum[i] = a.raw_add(a.m_bn[i], b.m_bn[i]); + BigNumber sum = a.raw_add(a.m_bn.front(), b.m_bn.front()); return PaillierEncryptedNumber(m_pubkey, sum); } + + std::vector sum(IPCL_CRYPTO_MB_SIZE); + for (int i = 0; i < m_available; i++) + sum[i] = a.raw_add(a.m_bn[i], b.m_bn[i]); + return PaillierEncryptedNumber(m_pubkey, sum); } // CT+PT PaillierEncryptedNumber PaillierEncryptedNumber::operator+( const BigNumber& other) const { - PaillierEncryptedNumber a = *this; + const auto& a = *this; BigNumber b; a.m_pubkey->encrypt(b, other); - BigNumber&& sum = a.raw_add(a.m_bn[0], b); + BigNumber sum = a.raw_add(a.m_bn.front(), b); return PaillierEncryptedNumber(m_pubkey, sum); } @@ -73,7 +72,7 @@ PaillierEncryptedNumber PaillierEncryptedNumber::operator+( const std::vector& other) const { VEC_SIZE_CHECK(other); - PaillierEncryptedNumber a = *this; + const auto& a = *this; std::vector b(IPCL_CRYPTO_MB_SIZE); std::vector sum(IPCL_CRYPTO_MB_SIZE); @@ -90,32 +89,31 @@ PaillierEncryptedNumber PaillierEncryptedNumber::operator*( ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), "operator*: two different public keys detected!!"); - PaillierEncryptedNumber a = *this; - PaillierEncryptedNumber b = other; + const auto& a = *this; + const auto& b = other; if (m_available == 1) { - BigNumber&& product = a.raw_mul(a.m_bn[0], b.m_bn[0]); - return PaillierEncryptedNumber(m_pubkey, product); - } else { - std::vector&& product = a.raw_mul(a.m_bn, b.m_bn); + BigNumber product = a.raw_mul(a.m_bn.front(), b.m_bn.front()); return PaillierEncryptedNumber(m_pubkey, product); } + + std::vector product = a.raw_mul(a.m_bn, b.m_bn); + return PaillierEncryptedNumber(m_pubkey, product); } // CT*PT PaillierEncryptedNumber PaillierEncryptedNumber::operator*( const BigNumber& other) const { - PaillierEncryptedNumber a = *this; + const auto& a = *this; - BigNumber b = other; - BigNumber&& product = a.raw_mul(a.m_bn[0], b); + BigNumber product = a.raw_mul(a.m_bn.front(), other); return PaillierEncryptedNumber(m_pubkey, product); } BigNumber PaillierEncryptedNumber::raw_add(const BigNumber& a, const BigNumber& b) const { // Hold a copy of nsquare for multi-threaded - BigNumber&& sq = m_pubkey->getNSQ(); + const BigNumber& sq = m_pubkey->getNSQ(); return a * b % sq; } @@ -127,7 +125,7 @@ std::vector PaillierEncryptedNumber::raw_mul( BigNumber PaillierEncryptedNumber::raw_mul(const BigNumber& a, const BigNumber& b) const { - BigNumber&& sq = m_pubkey->getNSQ(); + const BigNumber& sq = m_pubkey->getNSQ(); return ipcl::ippModExp(a, b, sq); } @@ -145,10 +143,20 @@ PaillierEncryptedNumber PaillierEncryptedNumber::rotate(int shift) const { else shift = -shift; - std::vector&& new_bn = getArrayBN(); + std::vector new_bn = getArrayBN(); std::rotate(std::begin(new_bn), std::begin(new_bn) + shift, std::end(new_bn)); return PaillierEncryptedNumber(m_pubkey, new_bn); } +void PaillierEncryptedNumber::applyObfuscator() { + b_isObfuscator = true; + std::vector obfuscator(IPCL_CRYPTO_MB_SIZE); + m_pubkey->applyObfuscator(obfuscator); + + const BigNumber& sq = m_pubkey->getNSQ(); + for (int i = 0; i < m_available; i++) + m_bn[i] = sq.ModMul(m_bn[i], obfuscator[i]); +} + } // namespace ipcl diff --git a/ipcl/paillier_prikey.cpp b/ipcl/paillier_prikey.cpp index 5897e98..0763726 100644 --- a/ipcl/paillier_prikey.cpp +++ b/ipcl/paillier_prikey.cpp @@ -60,13 +60,10 @@ void PaillierPrivateKey::decryptRAW( std::vector modulo(IPCL_CRYPTO_MB_SIZE, m_nsquare); std::vector res = ipcl::ippModExp(ciphertext, pow_lambda, modulo); - BigNumber nn = m_n; - BigNumber xx = m_x; - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - BigNumber m = (res[i] - 1) / nn; - m = m * xx; - plaintext[i] = m % nn; + BigNumber m = (res[i] - 1) / m_n; + m *= m_x; + plaintext[i] = m % m_n; } } @@ -90,7 +87,7 @@ void PaillierPrivateKey::decrypt( ERROR_CHECK(ciphertext.getPK().getN() == m_pubkey->getN(), "decrypt: public key mismatch error."); - std::vector&& res = ciphertext.getArrayBN(); + const std::vector& res = ciphertext.getArrayBN(); if (m_enable_crt) decryptCRT(plaintext, res); else @@ -113,19 +110,19 @@ void PaillierPrivateKey::decryptCRT( } // Based on the fact a^b mod n = (a mod n)^b mod n - std::vector&& resp = ipcl::ippModExp(basep, pm1, psq); - std::vector&& resq = ipcl::ippModExp(baseq, qm1, qsq); + std::vector resp = ipcl::ippModExp(basep, pm1, psq); + std::vector resq = ipcl::ippModExp(baseq, qm1, qsq); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - BigNumber&& dp = computeLfun(resp[i], m_p) * m_hp % m_p; - BigNumber&& dq = computeLfun(resq[i], m_q) * m_hq % m_q; + BigNumber dp = computeLfun(resp[i], m_p) * m_hp % m_p; + BigNumber dq = computeLfun(resq[i], m_q) * m_hq % m_q; plaintext[i] = computeCRT(dp, dq); } } BigNumber PaillierPrivateKey::computeCRT(const BigNumber& mp, const BigNumber& mq) const { - BigNumber&& u = (mq - mp) * m_pinverse % m_q; + BigNumber u = (mq - mp) * m_pinverse % m_q; return mp + (u * m_p); } @@ -137,10 +134,10 @@ BigNumber PaillierPrivateKey::computeLfun(const BigNumber& a, BigNumber PaillierPrivateKey::computeHfun(const BigNumber& a, const BigNumber& b) const { // Based on the fact a^b mod n = (a mod n)^b mod n - BigNumber&& xm = a - 1; - BigNumber&& base = m_g % b; - BigNumber&& pm = ipcl::ippModExp(base, xm, b); - BigNumber&& lcrt = computeLfun(pm, a); + BigNumber xm = a - 1; + BigNumber base = m_g % b; + BigNumber pm = ipcl::ippModExp(base, xm, b); + BigNumber lcrt = computeLfun(pm, a); return a.InverseMul(lcrt); } diff --git a/ipcl/paillier_pubkey.cpp b/ipcl/paillier_pubkey.cpp index e3e80f1..67747c4 100644 --- a/ipcl/paillier_pubkey.cpp +++ b/ipcl/paillier_pubkey.cpp @@ -48,28 +48,28 @@ std::vector PaillierPublicKey::randIpp32u(int size) const { return addr; } -// length is Arbitery +// length is arbitrary BigNumber PaillierPublicKey::getRandom(int length) const { IppStatus stat; int size; - int seedBitSize = 160; - int seedSize = BITSIZE_WORD(seedBitSize); + constexpr int seedBitSize = 160; + constexpr int seedSize = BITSIZE_WORD(seedBitSize); stat = ippsPRNGGetSize(&size); ERROR_CHECK(stat == ippStsNoErr, "getRandom: get IppsPRNGState context error."); - auto pRand = std::vector(size); + auto rands = std::vector(size); stat = - ippsPRNGInit(seedBitSize, reinterpret_cast(pRand.data())); + ippsPRNGInit(seedBitSize, reinterpret_cast(rands.data())); ERROR_CHECK(stat == ippStsNoErr, "getRandom: init rand context error."); - auto&& seed = randIpp32u(seedSize); + auto seed = randIpp32u(seedSize); BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); stat = ippsPRNGSetSeed(BN(bseed), - reinterpret_cast(pRand.data())); + reinterpret_cast(rands.data())); ERROR_CHECK(stat == ippStsNoErr, "getRandom: set up seed value error."); // define length Big Numbers @@ -86,10 +86,9 @@ BigNumber PaillierPublicKey::getRandom(int length) const { int bnBitSize = length; ippsPRNGenRDRAND_BN(pBN, bnBitSize, - reinterpret_cast(pRand.data())); - BigNumber rand(pBN); + reinterpret_cast(rands.data())); - return rand; + return BigNumber{pBN}; } void PaillierPublicKey::enableDJN() { @@ -97,22 +96,23 @@ void PaillierPublicKey::enableDJN() { BigNumber rmod; do { int rand_bit = m_n.BitSize(); - BigNumber&& rand = getRandom(rand_bit + 128); + BigNumber rand = getRandom(rand_bit + 128); rmod = rand % m_n; gcd = rand.gcd(m_n); } while (gcd.compare(1)); - BigNumber&& rmod_sq = rmod * rmod; - BigNumber&& rmod_neg = rmod_sq * -1; - BigNumber&& h = rmod_neg % m_n; + BigNumber rmod_sq = rmod * rmod; + BigNumber rmod_neg = rmod_sq * -1; + BigNumber h = rmod_neg % m_n; m_hs = ipcl::ippModExp(h, m_n, m_nsquare); m_randbits = m_bits >> 1; // bits/2 m_enable_DJN = true; } -void PaillierPublicKey::apply_obfuscator( +void PaillierPublicKey::applyObfuscator( std::vector& obfuscator) const { + std::vector r(IPCL_CRYPTO_MB_SIZE); std::vector pown(IPCL_CRYPTO_MB_SIZE, m_n); std::vector base(IPCL_CRYPTO_MB_SIZE, m_hs); @@ -159,7 +159,7 @@ void PaillierPublicKey::raw_encrypt(std::vector& ciphertext, if (make_secure) { std::vector obfuscator(IPCL_CRYPTO_MB_SIZE); - apply_obfuscator(obfuscator); + applyObfuscator(obfuscator); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) ciphertext[i] = sq.ModMul(ciphertext[i], obfuscator[i]); @@ -179,9 +179,7 @@ void PaillierPublicKey::encrypt(std::vector& ciphertext, void PaillierPublicKey::encrypt(BigNumber& ciphertext, const BigNumber& value) const { // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 - BigNumber bn = value; - BigNumber sq = m_nsquare; - ciphertext = (m_n * bn + 1) % sq; + ciphertext = (m_n * value + 1) % m_nsquare; /*----- Path to caculate (n+1)^plaintext mod n^2 ------------ BigNumber bn(value); From 86b8a63fc9d7773af0bdcab1ce5b487281890cb3 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 11 Mar 2022 00:33:56 -0800 Subject: [PATCH 102/364] Add HE QAT Utils. --- he_qat/he_qat_utils.c | 66 +++++++++++++++++++++++++++++++++++ he_qat/include/he_qat_utils.h | 20 +++++++++++ misc/he_qat_misc.h | 30 ++++------------ 3 files changed, 93 insertions(+), 23 deletions(-) create mode 100644 he_qat/he_qat_utils.c create mode 100644 he_qat/include/he_qat_utils.h diff --git a/he_qat/he_qat_utils.c b/he_qat/he_qat_utils.c new file mode 100644 index 0000000..002847f --- /dev/null +++ b/he_qat/he_qat_utils.c @@ -0,0 +1,66 @@ +#include "he_qat_utils.h" + +#include +#include + +BIGNUM* generateTestBNData(int nbits) { + if (!RAND_status()) return NULL; +#ifdef _DESTINY_DEBUG_VERBOSE + printf("PRNG properly seeded.\n"); +#endif + + BIGNUM* bn = BN_new(); + + if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { + BN_free(bn); + printf("Error while generating BN random number: %lu\n", + ERR_get_error()); + return NULL; + } + + return bn; +} + +unsigned char* paddingZeros(BIGNUM* bn, int nbits) { + if (!bn) return NULL; + + // Returns same address if it fails + int num_bytes = BN_num_bytes(bn); + int bytes_left = nbits / 8 - num_bytes; + if (bytes_left <= 0) return NULL; + + // Returns same address if it fails + unsigned char* bin = NULL; + int len = bytes_left + num_bytes; + if (!(bin = (unsigned char*)OPENSSL_zalloc(len))) return NULL; + +#ifdef _DESTINY_DEBUG_VERBOSE + printf("Padding bn with %d bytes to total %d bytes\n", bytes_left, len); +#endif + BN_bn2binpad(bn, bin, len); + if (ERR_get_error()) { + OPENSSL_free(bin); + return NULL; + } + + return bin; +} + +void showHexBN(BIGNUM* bn, int nbits) { + int len = nbits / 8; + unsigned char* bin = (unsigned char*)OPENSSL_zalloc(len); + if (!bin) return; + if (BN_bn2binpad(bn, bin, len)) { + for (size_t i = 0; i < len; i++) printf("%d", bin[i]); + printf("\n"); + } + OPENSSL_free(bin); + return; +} + +void showHexBin(unsigned char* bin, int len) { + if (!bin) return; + for (size_t i = 0; i < len; i++) printf("%d", bin[i]); + printf("\n"); + return; +} diff --git a/he_qat/include/he_qat_utils.h b/he_qat/include/he_qat_utils.h new file mode 100644 index 0000000..ce43fb0 --- /dev/null +++ b/he_qat/include/he_qat_utils.h @@ -0,0 +1,20 @@ + +#ifndef HE_QAT_UTILS_H_ +#define HE_QAT_UTILS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +BIGNUM* generateTestBNData(int nbits); +unsigned char* paddingZeros(BIGNUM* bn, int nbits); +void showHexBN(BIGNUM* bn, int nbits); +void showHexBin(unsigned char* bin, int len); + +#ifdef __cplusplus +} // extern "C" { +#endif + +#endif // HE_QAT_UTILS_H_ diff --git a/misc/he_qat_misc.h b/misc/he_qat_misc.h index 01b5755..495347d 100644 --- a/misc/he_qat_misc.h +++ b/misc/he_qat_misc.h @@ -2,33 +2,19 @@ #ifndef HE_QAT_MISC_H_ #define HE_QAT_MISC_H_ -//#ifdef __cplusplus -// extern "C" { -//#endif - #include "he_qat_types.h" #include "bignum.h" #include -//#define LEN_OF_1024_BITS 128 -//#define LEN_OF_2048_BITS 256 -//#define msb_CAN_BE_ZERO -1 -//#define msb_IS_ONE 0 -//#define EVEN_RND_NUM 0 -//#define ODD_RND_NUM 1 -//#define BATCH_SIZE 1 - -BIGNUM* generateTestBNData(int nbits); -unsigned char* paddingZeros(BIGNUM* bn, int nbits); -void showHexBN(BIGNUM* bn, int nbits); -void showHexBin(unsigned char* bin, int len); - -//#ifdef __cplusplus /// @brief /// @function binToBigNumber -/// Converts/encapsulates QAT's raw large number data to/into a BigNumber -/// object. data will be changed to little endian format in this function, -/// therefore the +/// Convert QAT large number into little endian format and encapsulate it into a +/// BigNumber object. +/// @param[out] bn BigNumber object representing multi-precision number in +/// little endian format. +/// @param[in] data Large number of nbits precision in big endian format. +/// @param[in] nbits Number of bits. Has to be power of 2, e.g. 1024, 2048, +/// 4096, etc. HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, int nbits); /// @brief @@ -41,7 +27,5 @@ HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, /// represented in nbits. HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, const BigNumber& bn); -//} // extern "C" { -//#endif #endif // HE_QAT_MISC_H_ From 34330640aa590c903b29335e829ee806dc312c03 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 11 Mar 2022 00:35:31 -0800 Subject: [PATCH 103/364] Update refactor CMake build system. --- CMakeLists.txt | 215 +++++++++++++++++++++++++--------------- common/CMakeLists.txt | 13 ++- examples/CMakeLists.txt | 25 +++-- he_qat/CMakeLists.txt | 121 ++++++++++++++++++---- icp/CMakeLists.txt | 34 +++++++ misc/CMakeLists.txt | 41 +++++--- 6 files changed, 320 insertions(+), 129 deletions(-) create mode 100644 icp/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index fec91b0..a76c987 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,91 +1,146 @@ cmake_minimum_required(VERSION 3.13) - project(QATModExp LANGUAGES C CXX) +# The hekat or heqat (transcribed HqA.t) was an ancient Egyptian volume unit +# used to measure grain, bread, and beer. +project(HE_QAT VERSION 0.1.0 LANGUAGES C CXX) - set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED ON) set( - CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) +include(CheckCCompilerFlag) +include(CheckCXXCompilerFlag) +include(CMakePackageConfigHelpers) - include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) include( - CMakePackageConfigHelpers) +if(CMAKE_BUILD_TYPE) + set(RELEASE_TYPES + Debug + Release + RelWithDebInfo + MinSizeRel) + list(FIND RELEASE_TYPES ${CMAKE_BUILD_TYPE} INDEX_FOUND) + if(${INDEX_FOUND} EQUAL -1) + message( + FATAL_ERROR + "CMAKE_BUILD_TYPE must be one of Debug, Release, RelWithDebInfo, or MinSizeRel" + ) + endif() +else() + set(CMAKE_BUILD_TYPE Release) +endif() - set(HE_QAT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) set( - HE_QAT_SRC_DIR ${HE_QAT_ROOT_DIR} / - he_qat) set(HE_QAT_INC_DIR ${HE_QAT_ROOT_DIR} / he_qat / - include) +set(CMAKE_C_STANDARD 99) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_C_FLAGS "-O2") +set(CMAKE_CXX_FLAGS "-O2 -fpermissive") + +# What does it do? +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# When to use it? +set(CMAKE_POSITION_INDEPENDENT_CODE ON) +# Why? +set(CMAKE_INSTALL_MESSAGE LAZY) +# Why? +set(CMAKE_INSTALL_RPATH "\$ORIGIN") + +#if(NOT CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_LIST_DIR}/install) + #endif() +message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") + +# Which features or functions does it bring? +include(GNUInstallDirs) + +# What is CMAKE_ARCHIVE_OUTPUT_DIRECTORY? +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) + +# ------------------------------------------------------------------- + +option(HE_QAT_MISC "Enable miscellaneous features" ON) +option(HE_QAT_TEST "Enable testing" OFF) +option(HE_QAT_EXAMPLES "Enable examples" ON) +option(HE_QAT_BENCHMARK "Enable benchmark" OFF) +option(HE_QAT_DOCS "Enable document building" OFF) +option(HE_QAT_SHARED "Build shared library" ON) + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(HE_QAT_DEBUG ON) +else() + set(HE_QAT_DEBUG OFF) +endif() + +# Why? +set(HE_QAT_CMAKE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/he_qat") + +set(HE_QAT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(HE_QAT_SRC_DIR ${HE_QAT_ROOT_DIR}/he_qat) +set(HE_QAT_INC_DIR ${HE_QAT_ROOT_DIR}/he_qat/include) #OpenSSL installation - set(OPENSSL_INC_DIR / opt / openssl / - include) set(OPENSSL_LIB_DIR / opt / openssl / lib) - - set(COMMON_INC_DIR ${CMAKE_CURRENT_LIST_DIR} / include) - - set(CMAKE_INSTALL_PREFIX "install") - -#QAT lib installation - set(ICP_ROOT $ENV{ICP_ROOT}) set( - ICP_BUILDOUTPUT_PATH ${ICP_ROOT} / - build) set(ICP_BUILDSYSTEM_PATH ${ - ICP_ROOT} / - quickassist / - build_system) set(ICP_API_DIR ${ - ICP_ROOT} / - quickassist) - set(ICP_LAC_DIR ${ICP_ROOT} / quickassist / - lookaside / - access_layer) set(ICP_OSAL_DIR ${ - ICP_ROOT} / - quickassist / - utilities / oasl) - set(ICP_ADF_DIR ${ICP_ROOT} / - quickassist / lookaside / - access_layer / src / - qat_direct) set(CMN_ROOT ${ - ICP_ROOT} / - quickassist / - utilities / - libusdm_drv) - - list(APPEND COMMON_INC_DIR ${ - ICP_API_DIR} / - include ${ICP_LAC_DIR} / - include ${ICP_ADF_DIR} / - include ${CMN_ROOT}) - -#Macros for the test case - add_definitions(-DDO_CRYPTO) add_definitions( - -DUSER_SPACE) add_compile_options(-fPIC) +find_package(OpenSSL REQUIRED) + +# External dependencies +find_package(Threads REQUIRED) +set(CMAKE_THREAD_PREFER_PTHREAD ON) +set(THREADS_PREFER_PTHREAD_FLAG ON) +#set(OPENSSL_INC_DIR /opt/openssl/include) +#set(OPENSSL_LIB_DIR /opt/openssl/lib) + +set(COMMON_INC_DIR ${CMAKE_CURRENT_LIST_DIR}/include) +if(NOT CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_LIST_DIR}/install) +endif() + +# Include QAT lib API support +include(icp/CMakeLists.txt) #Common utility functions - add_subdirectory(common) - -#IPP Crypto installation - set(IPPCP_DIR - "/opt/ipp-crypto") - set(IPPCP_CMAKE_PREFIX_DIR - "${IPPCP_DIR}/" - "lib/cmake") - list( - APPEND - CMAKE_PREFIX_PATH - "${IPPCP_" - "CMAKE_" - "PREFIX_" - "DIR}") - find_package( - ippcp - REQUIRED) - -#Helper functions -#set(HE_QAT_MISC_INC_DIR ${COMMON_INC_DIR} ${CMAKE_CURRENT_LIST_DIR}) -#set(HE_QAT_MISC_INC_DIR ${COMMON_INC_DIR}) -#set(HE_QAT_MISC_SRC ${HE_QAT_SRC_DIR} / he_qat_misc.cpp) - add_subdirectory( - misc) - -#Library - add_subdirectory( - he_qat) +add_subdirectory(common) + +if(HE_QAT_MISC) + # IPP Crypto installation + if(NOT IPPCP_CMAKE_PREFIX_PATH) + set(IPPCP_DIR "/opt/ipp-crypto") + set(IPPCP_CMAKE_PREFIX_PATH "${IPPCP_DIR}/lib/cmake") + list(APPEND CMAKE_PREFIX_PATH "${IPPCP_CMAKE_PREFIX_PATH}") + endif() + + find_package(IPPCP REQUIRED) + + message(STATUS "IPPCP_LIBRARIES ${IPPCP_LIBRARIES}") + + # Helper functions + add_subdirectory(misc) +endif() + +# HE_QAT Library +add_subdirectory(he_qat) + +if(HE_QAT_TEST) + include(cmake/gtest.cmake) +endif() +if(HE_QAT_BENCHMARK) + include(cmake/gbenchmark.cmake) +endif() #Validation test examples - add_subdirectory( - examples) +if(HE_QAT_EXAMPLES) + add_subdirectory(examples) +endif() + +if(HE_QAT_TEST) + add_subdirectory(test) + add_custom_target(unittest COMMAND $ DEPENDS he_qat_unittest) +endif() + +if(HE_QAT_BENCHMARK) + add_subdirectory(benchmark) + add_custom_target(benchmark COMMAND $ DEPENDS he_qat_bench) +endif() + +if(HE_QAT_DOCS) + add_subdirectory(docs) +endif() + + + diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 4d7110e..b100dc6 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -1,10 +1,10 @@ - # Include directories -list(APPEND COMMON_INC_DIR - ${ICP_API_DIR}/include/dc - ${ICP_API_DIR}/include/lac -) +#list(APPEND COMMON_INC_DIR +# ${ICP_API_DIR}/include/dc +# ${ICP_API_DIR}/include/lac +#) message(STATUS "COMMON_INC_DIR: ${COMMON_INC_DIR}") +message(STATUS "ICP_INC_DIR: ${ICP_INC_DIR}") # Source files set(COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/cpa_sample_utils.c) @@ -12,8 +12,10 @@ set(COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/cpa_sample_utils.c) add_library(cpa_sample_utils ${COMMON_SRC}) target_include_directories(cpa_sample_utils PUBLIC $ # Public headers + PUBLIC $ # Public headers PUBLIC $ # Public headers PRIVATE ${COMMON_INC_DIR} # Private headers + PRIVATE ${ICP_INC_DIR} # Private headers ) target_link_libraries(cpa_sample_utils PRIVATE udev pthread crypto z) target_link_libraries(cpa_sample_utils PUBLIC ${ICP_BUILDOUTPUT_PATH}/libqat_s.so) @@ -21,3 +23,4 @@ target_link_libraries(cpa_sample_utils PUBLIC ${ICP_BUILDOUTPUT_PATH}/libusdm_dr set(COMMON_INC_DIR ${COMMON_INC_DIR} PARENT_SCOPE) + diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 0564fe7..8ef0881 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,24 +1,29 @@ -#add_definitions(-D_DESTINY_DEBUG_VERBOSE) -if (NOT HE_QAT_DEBUG_VERBOSE) - remove_definitions(-D_DESTINY_DEBUG_VERBOSE) +if(HE_QAT_DEBUG) + add_definitions(-D_DESTINY_DEBUG_VERBOSE) endif() add_executable(test_context test_context.c) -target_include_directories(test_context PUBLIC ${COMMON_INC_DIR} ${HE_QAT_MISC_INC_DIR}) +target_include_directories(test_context PUBLIC ${COMMON_INC_DIR}) +target_include_directories(test_context PUBLIC ${ICP_INC_DIR}) target_link_libraries(test_context PUBLIC he_qat) #target_link_libraries(test_context PUBLIC cpa_sample_utils) target_link_libraries(test_context PUBLIC z pthread ssl crypto qat_s usdm_drv_s) add_executable(test_bnModExpPerformOp test_bnModExpPerformOp.c) target_include_directories(test_bnModExpPerformOp PUBLIC ${COMMON_INC_DIR}) # ${HE_QAT_UTILS_INC_DIR}) +target_include_directories(test_bnModExpPerformOp PUBLIC ${ICP_INC_DIR}) target_link_libraries(test_bnModExpPerformOp PUBLIC he_qat) #target_link_libraries(test_bnModExpPerformOp PUBLIC cpa_sample_utils) target_link_libraries(test_bnModExpPerformOp PUBLIC z pthread ssl crypto qat_s usdm_drv_s) -add_compile_options(-fpermissive) -add_executable(test_bnConversion test_bnConversion.cpp) -target_include_directories(test_bnConversion PUBLIC ${COMMON_INC_DIR} ${HE_QAT_MISC_INC_DIR}) -target_link_libraries(test_bnConversion PUBLIC he_qat) -target_link_libraries(test_bnConversion PUBLIC he_qat_misc) -target_link_libraries(test_bnConversion PUBLIC z pthread ssl crypto qat_s usdm_drv_s) +if(HE_QAT_MISC) + add_compile_options(-fpermissive) + add_executable(test_bnConversion test_bnConversion.cpp) + target_include_directories(test_bnConversion PUBLIC ${COMMON_INC_DIR}) + target_include_directories(test_bnConversion PUBLIC ${ICP_INC_DIR}) + target_include_directories(test_bnConversion PUBLIC ${HE_QAT_MISC_INC_DIR}) + target_link_libraries(test_bnConversion PUBLIC he_qat) + target_link_libraries(test_bnConversion PUBLIC he_qat_misc IPPCP::ippcp IPPCP::crypto_mb) + target_link_libraries(test_bnConversion PUBLIC z OpenSSL::SSL Threads::Threads qat_s usdm_drv_s) +endif() diff --git a/he_qat/CMakeLists.txt b/he_qat/CMakeLists.txt index f4c4e04..8829678 100644 --- a/he_qat/CMakeLists.txt +++ b/he_qat/CMakeLists.txt @@ -1,23 +1,104 @@ -set(HE_QAT_SRC ${HE_QAT_SRC_DIR} / he_qat_bn_ops.c ${HE_QAT_SRC_DIR} / - he_qat_context.c) - - add_library(he_qat SHARED ${HE_QAT_SRC}) - - target_include_directories( - he_qat PUBLIC $< - BUILD_INTERFACE : ${COMMON_INC_DIR}> #Public headers PUBLIC - $ #Public headers PUBLIC $< - BUILD_INTERFACE : ${OPENSSL_INC_DIR}> #Public headers PUBLIC - $ #Public headers - PRIVATE $ { COMMON_INC_DIR } #Private headers PRIVATE - $ { OPENSSL_INC_DIR } #Private headers) +set(HE_QAT_SRC ${HE_QAT_SRC_DIR}/he_qat_bn_ops.c + ${HE_QAT_SRC_DIR}/he_qat_context.c + ${HE_QAT_SRC_DIR}/he_qat_utils.c +) + +if(HE_QAT_SHARED) + add_library(he_qat SHARED ${HE_QAT_SRC}) +else() + add_library(he_qat STATIC ${HE_QAT_SRC}) +endif() + +add_library(HE_QAT::he_qat ALIAS he_qat) +#add_library(he_qat SHARED ${HE_QAT_SRC}) + +target_include_directories(he_qat + PUBLIC $ #Public headers + PUBLIC $ #Public headers + PUBLIC $ #Public headers + PUBLIC $ #Public headers + PRIVATE ${COMMON_INC_DIR} #Private headers + PRIVATE ${ICP_INC_DIR} #Private headers + PRIVATE ${OPENSSL_INC_DIR} #Private headers +) #target_include_directories(he_qat PUBLIC ${HE_QAT_UTILS_INC_DIR}) - target_link_directories(he_qat PUBLIC ${ICP_BUILDOUTPUT_PATH}) - target_link_directories(he_qat PUBLIC ${OPENSSL_LIB_DIR}) - target_link_libraries(he_qat PRIVATE cpa_sample_utils) -#target_link_libraries(he_qat PRIVATE he_qat_utils) - target_link_libraries(he_qat PUBLIC qat_s usdm_drv_s) - target_link_libraries(he_qat PUBLIC crypto ssl) - target_link_libraries(he_qat PUBLIC z pthread) +install(DIRECTORY ${COMMON_INC_DIR}/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ + FILES_MATCHING + PATTERN "*.hpp" + PATTERN "*.h") + +install(DIRECTORY ${HE_QAT_INC_DIR}/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ + FILES_MATCHING + PATTERN "*.hpp" + PATTERN "*.h") + +target_link_directories(he_qat PUBLIC ${ICP_BUILDOUTPUT_PATH}) +target_link_directories(he_qat PUBLIC ${OPENSSL_LIB_DIR}) + +target_link_libraries(he_qat PUBLIC OpenSSL::SSL OpenSSL::Crypto Threads::Threads) +target_link_libraries(he_qat PRIVATE cpa_sample_utils) + +if(HE_QAT_MISC) + target_link_libraries(he_qat PRIVATE he_qat_misc) +endif() + +target_link_libraries(he_qat PUBLIC qat_s usdm_drv_s) +target_link_libraries(he_qat PUBLIC crypto ssl) +target_link_libraries(he_qat PUBLIC z) + + +set_target_properties(he_qat PROPERTIES POSITION_INDEPENDENT_CODE ON) +set_target_properties(he_qat PROPERTIES VERSION ${HE_QAT_VERSION}) + +if(HE_QAT_DEBUG) + set_target_properties(he_qat PROPERTIES OUTPUT_NAME "he_qat_debug") +else() + set_target_properties(he_qat PROPERTIES OUTPUT_NAME "he_qat") +endif() + + +install(TARGETS he_qat DESTINATION ${CMAKE_INSTALL_LIBDIR}) + +# config cmake config and target file +set(HE_QAT_TARGET_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/cmake/he_qat-${HE_QAT_VERSION}/HE_QATTargets.cmake) +set(HE_QAT_CONFIG_IN_FILENAME ${HE_QAT_CMAKE_PATH}/HE_QATConfig.cmake.in) +set(HE_QAT_CONFIG_FILENAME ${HE_QAT_ROOT_DIR}/cmake/he_qat-${HE_QAT_VERSION}/HE_QATConfig.cmake) +set(HE_QAT_CONFIG_VERSION_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/cmake/he_qat-${HE_QAT_VERSION}/HE_QATConfigVersion.cmake) +set(HE_QAT_CONFIG_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/he_qat-${HE_QAT_VERSION}/) + +install( + EXPORT HE_QATTargets + NAMESPACE HE_QAT:: + DESTINATION ${HE_QAT_CONFIG_INSTALL_DIR} +) + +write_basic_package_version_file( + ${HE_QAT_CONFIG_VERSION_FILENAME} + VERSION ${HE_QAT_VERSION} + COMPATIBILITY ExactVersion +) + +configure_package_config_file( + ${HE_QAT_CONFIG_IN_FILENAME} ${HE_QAT_CONFIG_FILENAME} + INSTALL_DESTINATION ${HE_QAT_CONFIG_INSTALL_DIR} +) + +install( + TARGETS he_qat + EXPORT HE_QATTargets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) + +install(FILES ${HE_QAT_CONFIG_FILENAME} + ${HE_QAT_CONFIG_VERSION_FILENAME} + DESTINATION ${HE_QAT_CONFIG_INSTALL_DIR}) + +export(EXPORT HE_QATTargets + FILE ${HE_QAT_TARGET_FILENAME}) + diff --git a/icp/CMakeLists.txt b/icp/CMakeLists.txt new file mode 100644 index 0000000..fbe3816 --- /dev/null +++ b/icp/CMakeLists.txt @@ -0,0 +1,34 @@ + +if(DEFINED ENV{ICP_ROOT}) + message(STATUS "Environment variable ICP_ROOT is defined as $ENV{ICP_ROOT}.") +else() + message(FATAL_ERROR "Environment variable ICP_ROOT must be defined. Try export ICP_ROOT=") +endif() + +set(ICP_ROOT $ENV{ICP_ROOT}) +set(ICP_BUILDOUTPUT_PATH ${ICP_ROOT}/build) +set(ICP_BUILDSYSTEM_PATH ${ICP_ROOT}/quickassist/build_system) +set(ICP_API_DIR ${ICP_ROOT}/quickassist) +set(ICP_LAC_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer) +set(ICP_OSAL_DIR ${ICP_ROOT}/quickassist/utilities/oasl) +set(ICP_ADF_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/qat_direct) +set(CMN_ROOT ${ICP_ROOT}/quickassist/utilities/libusdm_drv) + +#list(APPEND COMMON_INC_DIR ${ICP_API_DIR}/include +# ${ICP_LAC_DIR}/include +# ${ICP_ADF_DIR}/include +# ${CMN_ROOT} +#) + +set(ICP_INC_DIR ${ICP_API_DIR}/include + ${ICP_LAC_DIR}/include + ${ICP_ADF_DIR}/include + ${CMN_ROOT} + ${ICP_API_DIR}/include/dc + ${ICP_API_DIR}/include/lac) + +#Macros for the test case +add_definitions(-DDO_CRYPTO) +add_definitions(-DUSER_SPACE) +add_compile_options(-fPIC) + diff --git a/misc/CMakeLists.txt b/misc/CMakeLists.txt index fe218a4..68c0e1f 100644 --- a/misc/CMakeLists.txt +++ b/misc/CMakeLists.txt @@ -1,22 +1,35 @@ #Include directories #list(APPEND HE_QAT_MISC_INC_DIR -set(HE_QAT_MISC_INC_DIR ${COMMON_INC_DIR} ${HE_QAT_INC_DIR} ${ - CMAKE_CURRENT_LIST_DIR} ${IPPCP_DIR} / - include) message(STATUS "HE_QAT_MISC_INC_DIR: ${HE_QAT_MISC_INC_DIR}") +set(HE_QAT_MISC_INC_DIR ${COMMON_INC_DIR} + ${HE_QAT_INC_DIR} + ${CMAKE_CURRENT_LIST_DIR} + # ${IPPCP_DIR}/include +) + +message(STATUS "HE_QAT_MISC_INC_DIR: ${HE_QAT_MISC_INC_DIR}") #Source files #list(APPEND HE_QAT_MISC_SRC ${CMAKE_CURRENT_LIST_DIR} / utils.cpp - set(HE_QAT_MISC_SRC ${CMAKE_CURRENT_LIST_DIR} / - he_qat_misc.cpp ${CMAKE_CURRENT_LIST_DIR} / - utils.cpp ${CMAKE_CURRENT_LIST_DIR} / bignum.cpp) +set(HE_QAT_MISC_SRC ${CMAKE_CURRENT_LIST_DIR}/he_qat_misc.cpp + ${CMAKE_CURRENT_LIST_DIR}/utils.cpp + ${CMAKE_CURRENT_LIST_DIR}/bignum.cpp) + +add_library(he_qat_misc ${HE_QAT_MISC_SRC}) +target_include_directories(he_qat_misc PUBLIC $ #Public headers + PUBLIC $ #Public headers + PRIVATE ${HE_QAT_MISC_INC_DIR} #Private headers + PRIVATE ${ICP_INC_DIR} #Private headers +) +#target_link_directories(he_qat_misc PUBLIC ${IPPCP_DIR}/lib/intel64) +#target_link_libraries(he_qat_misc PRIVATE ippcpmx crypto_mb) +target_link_libraries(he_qat_misc PRIVATE IPPCP::ippcp IPPCP::crypto_mb) - add_library(he_qat_misc ${HE_QAT_MISC_SRC}) target_include_directories( - he_qat_misc PUBLIC $< - BUILD_INTERFACE : ${HE_QAT_MISC_INC_DIR}> #Public headers PUBLIC - $ #Public headers) - target_link_directories(he_qat_misc PUBLIC ${IPPCP_DIR} / lib / - intel64) - target_link_libraries(he_qat_misc PUBLIC ippcpmx crypto_mb) +install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ + FILES_MATCHING + PATTERN "*.hpp" + PATTERN "*.h") +install(TARGETS he_qat_misc DESTINATION ${CMAKE_INSTALL_LIBDIR}) -#set(HE_QAT_MISC_INC_DIR ${HE_QAT_MISC_INC_DIR} PARENT_SCOPE) +set(HE_QAT_MISC_INC_DIR ${HE_QAT_MISC_INC_DIR} PARENT_SCOPE) From e0ac7c3cc25ddd7be5240e7d66116756bbc8bdb4 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 11 Mar 2022 00:36:14 -0800 Subject: [PATCH 104/364] Update bnConversion. --- examples/test_bnConversion.cpp | 132 +-------------------------------- 1 file changed, 2 insertions(+), 130 deletions(-) diff --git a/examples/test_bnConversion.cpp b/examples/test_bnConversion.cpp index 9a38c0d..efac502 100644 --- a/examples/test_bnConversion.cpp +++ b/examples/test_bnConversion.cpp @@ -1,9 +1,9 @@ -#include "cpa_sample_utils.h" - #include "he_qat_misc.h" +#include "he_qat_utils.h" #include "he_qat_bn_ops.h" #include "he_qat_context.h" +#include "cpa_sample_utils.h" #ifdef __cplusplus extern "C" { @@ -21,133 +21,8 @@ extern "C" { #include #include "ippcp.h" -//#include "bignum.h" - -//#include #include -//#define LEN_OF_1024_BITS 128 -//#define LEN_OF_2048_BITS 256 -//#define msb_CAN_BE_ZERO -1 -//#define msb_IS_ONE 0 -//#define EVEN_RND_NUM 0 -//#define ODD_RND_NUM 1 -//#define BATCH_SIZE 1 - -// using namespace std; - -// int gDebugParam = 1; - -// BIGNUM* generateTestBNData(int nbits) { -// if (!RAND_status()) return NULL; -//#ifdef _DESTINY_DEBUG_VERBOSE -// printf("PRNG properly seeded.\n"); -//#endif -// -// BIGNUM* bn = BN_new(); -// -// if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { -// BN_free(bn); -// printf("Error while generating BN random number: %lu\n", -// ERR_get_error()); -// return NULL; -// } -// -// return bn; -//} -// -// unsigned char* paddingZeros(BIGNUM* bn, int nbits) { -// if (!bn) return NULL; -// -// // Returns same address if it fails -// int num_bytes = BN_num_bytes(bn); -// int bytes_left = nbits / 8 - num_bytes; -// if (bytes_left <= 0) return NULL; -// -// // Returns same address if it fails -// unsigned char* bin = NULL; -// int len = bytes_left + num_bytes; -// if (!(bin = (unsigned char*)OPENSSL_zalloc(len))) return NULL; -// -//#ifdef _DESTINY_DEBUG_VERBOSE -// printf("Padding bn with %d bytes to total %d bytes\n", bytes_left, len); -//#endif -// BN_bn2binpad(bn, bin, len); -// if (ERR_get_error()) { -// OPENSSL_free(bin); -// return NULL; -// } -// -// return bin; -//} -// -// void showHexBN(BIGNUM* bn, int nbits) { -// int len = nbits / 8; -// unsigned char* bin = (unsigned char*)OPENSSL_zalloc(len); -// if (!bin) return; -// if (BN_bn2binpad(bn, bin, len)) { -// for (size_t i = 0; i < len; i++) printf("%d", bin[i]); -// printf("\n"); -// } -// OPENSSL_free(bin); -// return; -//} -// -// void showHexBin(unsigned char* bin, int len) { -// if (!bin) return; -// for (size_t i = 0; i < len; i++) printf("%d", bin[i]); -// printf("\n"); -// return; -//} -// -///// @brief -///// @function binToBigNumber -//// -///// data will be changed to little endian format in this function, therefore -/// the -///// abscence of const in front -// HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, -// int nbits) { -// if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; -// int len_ = (nbits + 7) >> 3; // nbits/8; -// -// // Create BigNumber containg input data passed as argument -// bn = BigNumber(reinterpret_cast(data), -// BITSIZE_WORD(nbits)); Ipp32u* ref_bn_data_ = NULL; ippsRef_BN(NULL, NULL, -// &ref_bn_data_, BN(bn)); -// -// // Convert it to little endian format -// unsigned char* data_ = reinterpret_cast(ref_bn_data_); -// for (int i = 0; i < len_; i++) data_[i] = data[len_ - 1 - i]; -// -// return HE_QAT_STATUS_SUCCESS; -//} -// -///// @brief -///// @function bigNumberToBin -///// Converts/encapsulates big number data to/into an object of BigNumber's -///// type/class. -///// @param[out] data BigNumber object's raw data in big endian format. -///// @param[in] nbits Number of bits. Has to be power of 2, e.g. 1024, 2048, -///// 4096, etc. -///// @param[in] bn BigNumber object holding a multi-precision that can be -///// represented in nbits. -// HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, -// const BigNumber& bn) { -// if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; -// int len_ = (nbits + 7) >> 3; // nbits/8; -// -// // Extract raw vector of data in little endian format -// Ipp32u* ref_bn_data_ = NULL; -// ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); -// -// // Revert it to big endian format -// unsigned char* data_ = reinterpret_cast(ref_bn_data_); -// for (int i = 0; i < len_; i++) data[i] = data_[len_ - 1 - i]; -// -// return HE_QAT_STATUS_SUCCESS; -//} - int main(int argc, const char** argv) { const int bit_length = 1024; const size_t num_trials = 4; @@ -170,13 +45,10 @@ int main(int argc, const char** argv) { BN_CTX_start(ctx); for (unsigned int mod = 0; mod < num_trials; mod++) { - // BIGNUM* bn_mod = BN_new(); BIGNUM* bn_mod = generateTestBNData(bit_length); if (!bn_mod) continue; - // BN_set_word(bn_mod, mod); - char* bn_str = BN_bn2hex(bn_mod); printf("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); From cebf31dd4e42069108c107f516b297d2df6040cc Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 11 Mar 2022 10:13:26 -0800 Subject: [PATCH 105/364] Update build instructions in README.md. --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 808c353..ccf3d26 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,19 @@ This library is underconstruction and currently only offers acceleration of modu ``` export ICP_ROOT=$HOME/QAT -cmake -S . -B build +cmake -S . -B build -DHE_QAT_MISC=OFF cmake --build build +cmake --install build +``` + +`HE_QAT_MISC` enables IPP Crypto. If you want to enable that, follow the build instructions below: + +``` +git clone https://github.com/intel/ipp-crypto.git +cd ipp-crypto +CC=gcc CXX=g++ cmake CMakeLists.txt -B_build -DARCH=intel64 -DMERGED_BLD:BOOL=on -DCMAKE_INSTALL_PREFIX=/opt/ipp-crypto -DOPENSSL_INCLUDE_DIR=/opt/openssl/include -DOPENSSL_LIBRARIES=/opt/openssl/lib -DOPENSSL_ROOT_DIR=/opt/openssl -DCMAKE_ASM_NASM_COMPILER=/opt/nasm-2.15/bin/nasm +cmake --build _build -j +sudo cmake --install _build ``` ### Running Examples @@ -65,5 +76,6 @@ git pthread gcc >= 9.1 qatlib +ippcrypto ``` From 338146f2322115812b1a6adc42f31e387084cd1e Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Sat, 12 Mar 2022 05:53:21 +0800 Subject: [PATCH 106/364] Rename file names and class names(remove paillier_ prefix) (#54) * Rename file names(remove paillier_ prefix) * Rename class names(remove the Paillier prefix) * Renamed key_gen to keygen Co-authored-by: Sejun Kim --- benchmark/bench_cryptography.cpp | 2 +- benchmark/bench_ops.cpp | 4 +- ipcl/CMakeLists.txt | 8 ++-- .../ipcl/{paillier_keygen.hpp => keygen.hpp} | 12 +++--- .../ipcl/{paillier_ops.hpp => ops.hpp} | 19 ++++----- .../ipcl/{paillier_prikey.hpp => pri_key.hpp} | 20 ++++----- .../ipcl/{paillier_pubkey.hpp => pub_key.hpp} | 21 +++++----- ipcl/{paillier_keygen.cpp => keygen.cpp} | 7 ++-- ipcl/{paillier_ops.cpp => ops.cpp} | 11 +++-- ipcl/{paillier_prikey.cpp => pri_key.cpp} | 42 +++++++++---------- ipcl/{paillier_pubkey.cpp => pub_key.cpp} | 31 +++++++------- test/test_cryptography.cpp | 10 ++--- test/test_ops.cpp | 4 +- 13 files changed, 89 insertions(+), 102 deletions(-) rename ipcl/include/ipcl/{paillier_keygen.hpp => keygen.hpp} (75%) rename ipcl/include/ipcl/{paillier_ops.hpp => ops.hpp} (87%) rename ipcl/include/ipcl/{paillier_prikey.hpp => pri_key.hpp} (87%) rename ipcl/include/ipcl/{paillier_pubkey.hpp => pub_key.hpp} (86%) rename ipcl/{paillier_keygen.cpp => keygen.cpp} (93%) rename ipcl/{paillier_ops.cpp => ops.cpp} (93%) rename ipcl/{paillier_prikey.cpp => pri_key.cpp} (73%) rename ipcl/{paillier_pubkey.cpp => pub_key.cpp} (82%) diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index 06f28e2..b9ffb9d 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -8,7 +8,7 @@ #include #endif // IPCL_USE_OMP -#include "ipcl/paillier_keygen.hpp" +#include "ipcl/keygen.hpp" static void BM_KeyGen(benchmark::State& state) { int64_t n_length = state.range(0); diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index a9a43d2..bea62fa 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -9,8 +9,8 @@ #endif // IPCL_USE_OMP #include -#include "ipcl/paillier_keygen.hpp" -#include "ipcl/paillier_ops.hpp" +#include "ipcl/keygen.hpp" +#include "ipcl/ops.hpp" static void BM_Add_CTCT(benchmark::State& state) { size_t dsize = state.range(0); diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 4ad679f..a4b1ff5 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -1,10 +1,10 @@ # Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -set(IPCL_SRCS paillier_prikey.cpp - paillier_pubkey.cpp - paillier_ops.cpp - paillier_keygen.cpp +set(IPCL_SRCS pri_key.cpp + pub_key.cpp + ops.cpp + keygen.cpp bignum.cpp mod_exp.cpp ) diff --git a/ipcl/include/ipcl/paillier_keygen.hpp b/ipcl/include/ipcl/keygen.hpp similarity index 75% rename from ipcl/include/ipcl/paillier_keygen.hpp rename to ipcl/include/ipcl/keygen.hpp index e3dd6b3..c254db8 100644 --- a/ipcl/include/ipcl/paillier_keygen.hpp +++ b/ipcl/include/ipcl/keygen.hpp @@ -1,10 +1,10 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#ifndef IPCL_INCLUDE_IPCL_PAILLIER_KEYGEN_HPP_ -#define IPCL_INCLUDE_IPCL_PAILLIER_KEYGEN_HPP_ +#ifndef IPCL_INCLUDE_IPCL_KEYGEN_HPP_ +#define IPCL_INCLUDE_IPCL_KEYGEN_HPP_ -#include "ipcl/paillier_prikey.hpp" +#include "ipcl/pri_key.hpp" namespace ipcl { @@ -14,8 +14,8 @@ namespace ipcl { * priv_key: paillier private key */ struct keyPair { - PaillierPublicKey* pub_key; - PaillierPrivateKey* priv_key; + PublicKey* pub_key; + PrivateKey* priv_key; }; /** @@ -34,4 +34,4 @@ BigNumber getPrimeBN(int maxBitSize); keyPair generateKeypair(int64_t n_length, bool enable_DJN = true); } // namespace ipcl -#endif // IPCL_INCLUDE_IPCL_PAILLIER_KEYGEN_HPP_ +#endif // IPCL_INCLUDE_IPCL_KEYGEN_HPP_ diff --git a/ipcl/include/ipcl/paillier_ops.hpp b/ipcl/include/ipcl/ops.hpp similarity index 87% rename from ipcl/include/ipcl/paillier_ops.hpp rename to ipcl/include/ipcl/ops.hpp index f7d0d72..eb6a7b1 100644 --- a/ipcl/include/ipcl/paillier_ops.hpp +++ b/ipcl/include/ipcl/ops.hpp @@ -1,12 +1,12 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#ifndef IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ -#define IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ +#ifndef IPCL_INCLUDE_IPCL_OPS_HPP_ +#define IPCL_INCLUDE_IPCL_OPS_HPP_ #include -#include "ipcl/paillier_pubkey.hpp" +#include "ipcl/pub_key.hpp" #include "ipcl/util.hpp" namespace ipcl { @@ -18,8 +18,7 @@ class PaillierEncryptedNumber { * @param[in] pub_key paillier public key * @param[in] bn ciphertext encrypted by paillier public key */ - PaillierEncryptedNumber(const PaillierPublicKey* pub_key, - const BigNumber& bn); + PaillierEncryptedNumber(const PublicKey* pub_key, const BigNumber& bn); /** * PaillierEncryptedNumber constructor @@ -27,7 +26,7 @@ class PaillierEncryptedNumber { * @param[in] bn array of ciphertexts encrypted by paillier public key * @param[in] length size of array(default value is IPCL_CRYPTO_MB_SIZE) */ - PaillierEncryptedNumber(const PaillierPublicKey* pub_key, + PaillierEncryptedNumber(const PublicKey* pub_key, const std::vector& bn, size_t length = IPCL_CRYPTO_MB_SIZE); @@ -37,7 +36,7 @@ class PaillierEncryptedNumber { * @param[in] scalar array of integer scalars * @param[in] length size of array(default value is IPCL_CRYPTO_MB_SIZE) */ - PaillierEncryptedNumber(const PaillierPublicKey* pub_key, + PaillierEncryptedNumber(const PublicKey* pub_key, const std::vector& scalar, size_t length = IPCL_CRYPTO_MB_SIZE); @@ -100,7 +99,7 @@ class PaillierEncryptedNumber { /** * Get public key */ - PaillierPublicKey getPK() const { return *m_pubkey; } + PublicKey getPK() const { return *m_pubkey; } /** * Rotate PaillierEncryptedNumber @@ -129,7 +128,7 @@ class PaillierEncryptedNumber { private: bool b_isObfuscator; int m_available; - const PaillierPublicKey* m_pubkey; + const PublicKey* m_pubkey; size_t m_length; std::vector m_bn; @@ -140,4 +139,4 @@ class PaillierEncryptedNumber { }; } // namespace ipcl -#endif // IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ +#endif // IPCL_INCLUDE_IPCL_OPS_HPP_ diff --git a/ipcl/include/ipcl/paillier_prikey.hpp b/ipcl/include/ipcl/pri_key.hpp similarity index 87% rename from ipcl/include/ipcl/paillier_prikey.hpp rename to ipcl/include/ipcl/pri_key.hpp index 5ecfc3d..89acbe1 100644 --- a/ipcl/include/ipcl/paillier_prikey.hpp +++ b/ipcl/include/ipcl/pri_key.hpp @@ -1,25 +1,25 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#ifndef IPCL_INCLUDE_IPCL_PAILLIER_PRIKEY_HPP_ -#define IPCL_INCLUDE_IPCL_PAILLIER_PRIKEY_HPP_ +#ifndef IPCL_INCLUDE_IPCL_PRI_KEY_HPP_ +#define IPCL_INCLUDE_IPCL_PRI_KEY_HPP_ #include -#include "ipcl/paillier_ops.hpp" +#include "ipcl/ops.hpp" namespace ipcl { -class PaillierPrivateKey { +class PrivateKey { public: /** - * PaillierPrivateKey constructor + * PrivateKey constructor * @param[in] public_key paillier public key * @param[in] p p of private key in paillier scheme * @param[in] q q of private key in paillier scheme */ - PaillierPrivateKey(const PaillierPublicKey* public_key, const BigNumber& p, - const BigNumber& q); + PrivateKey(const PublicKey* public_key, const BigNumber& p, + const BigNumber& q); /** * Enable Chinese Remainder Theorem @@ -68,7 +68,7 @@ class PaillierPrivateKey { /** * Get public key */ - const PaillierPublicKey* getPubKey() const { return m_pubkey; } + const PublicKey* getPubKey() const { return m_pubkey; } /** * @brief Support function for ISO/IEC 18033-6 compliance check @@ -78,7 +78,7 @@ class PaillierPrivateKey { BigNumber getLambda() const { return m_lambda; } private: - const PaillierPublicKey* m_pubkey; + const PublicKey* m_pubkey; BigNumber m_n; BigNumber m_nsquare; BigNumber m_g; @@ -139,4 +139,4 @@ class PaillierPrivateKey { }; } // namespace ipcl -#endif // IPCL_INCLUDE_IPCL_PAILLIER_PRIKEY_HPP_ +#endif // IPCL_INCLUDE_IPCL_PRI_KEY_HPP_ diff --git a/ipcl/include/ipcl/paillier_pubkey.hpp b/ipcl/include/ipcl/pub_key.hpp similarity index 86% rename from ipcl/include/ipcl/paillier_pubkey.hpp rename to ipcl/include/ipcl/pub_key.hpp index 9b51247..bbdc2eb 100644 --- a/ipcl/include/ipcl/paillier_pubkey.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -1,8 +1,8 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#ifndef IPCL_INCLUDE_IPCL_PAILLIER_PUBKEY_HPP_ -#define IPCL_INCLUDE_IPCL_PAILLIER_PUBKEY_HPP_ +#ifndef IPCL_INCLUDE_IPCL_PUB_KEY_HPP_ +#define IPCL_INCLUDE_IPCL_PUB_KEY_HPP_ #include @@ -10,26 +10,25 @@ namespace ipcl { -class PaillierPublicKey { +class PublicKey { public: /** - * PaillierPublicKey constructor + * PublicKey constructor * @param[in] n n of public key in paillier scheme * @param[in] bits bit length of public key(default value is 1024) * @param[in] enableDJN_ enables DJN scheme(default value is false) */ - explicit PaillierPublicKey(const BigNumber& n, int bits = 1024, - bool enableDJN_ = false); + explicit PublicKey(const BigNumber& n, int bits = 1024, + bool enableDJN_ = false); /** - * PaillierPublicKey constructor + * PublicKey constructor * @param[in] n n of public key in paillier scheme * @param[in] bits bit length of public key(default value is 1024) * @param[in] enableDJN_ enables DJN scheme(default value is false) */ - explicit PaillierPublicKey(const Ipp32u n, int bits = 1024, - bool enableDJN_ = false) - : PaillierPublicKey(BigNumber(n), bits, enableDJN_) {} + explicit PublicKey(const Ipp32u n, int bits = 1024, bool enableDJN_ = false) + : PublicKey(BigNumber(n), bits, enableDJN_) {} /** * DJN enabling function @@ -141,4 +140,4 @@ class PaillierPublicKey { }; } // namespace ipcl -#endif // IPCL_INCLUDE_IPCL_PAILLIER_PUBKEY_HPP_ +#endif // IPCL_INCLUDE_IPCL_PUB_KEY_HPP_ diff --git a/ipcl/paillier_keygen.cpp b/ipcl/keygen.cpp similarity index 93% rename from ipcl/paillier_keygen.cpp rename to ipcl/keygen.cpp index 59ef948..665d12b 100644 --- a/ipcl/paillier_keygen.cpp +++ b/ipcl/keygen.cpp @@ -1,7 +1,7 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include "ipcl/paillier_keygen.hpp" +#include "ipcl/keygen.hpp" #include #include @@ -101,9 +101,8 @@ keyPair generateKeypair(int64_t n_length, bool enable_DJN) { else getNormalBN(n_length, p, q, n); - PaillierPublicKey* public_key = - new PaillierPublicKey(n, n_length, enable_DJN); - PaillierPrivateKey* private_key = new PaillierPrivateKey(public_key, p, q); + PublicKey* public_key = new PublicKey(n, n_length, enable_DJN); + PrivateKey* private_key = new PrivateKey(public_key, p, q); return keyPair{public_key, private_key}; } diff --git a/ipcl/paillier_ops.cpp b/ipcl/ops.cpp similarity index 93% rename from ipcl/paillier_ops.cpp rename to ipcl/ops.cpp index 0ca209b..a3b5094 100644 --- a/ipcl/paillier_ops.cpp +++ b/ipcl/ops.cpp @@ -1,7 +1,7 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include "ipcl/paillier_ops.hpp" +#include "ipcl/ops.hpp" #include @@ -10,8 +10,8 @@ namespace ipcl { // constructors // -PaillierEncryptedNumber::PaillierEncryptedNumber( - const PaillierPublicKey* pub_key, const BigNumber& bn) +PaillierEncryptedNumber::PaillierEncryptedNumber(const PublicKey* pub_key, + const BigNumber& bn) : b_isObfuscator(false), m_available(1), m_pubkey(pub_key), @@ -19,8 +19,7 @@ PaillierEncryptedNumber::PaillierEncryptedNumber( m_bn{bn} {} PaillierEncryptedNumber::PaillierEncryptedNumber( - const PaillierPublicKey* pub_key, const std::vector& bn, - size_t length) + const PublicKey* pub_key, const std::vector& bn, size_t length) : b_isObfuscator(false), m_pubkey(pub_key), m_available(IPCL_CRYPTO_MB_SIZE), @@ -28,7 +27,7 @@ PaillierEncryptedNumber::PaillierEncryptedNumber( m_bn{bn[0], bn[1], bn[2], bn[3], bn[4], bn[5], bn[6], bn[7]} {} PaillierEncryptedNumber::PaillierEncryptedNumber( - const PaillierPublicKey* pub_key, const std::vector& scalar, + const PublicKey* pub_key, const std::vector& scalar, size_t length) : b_isObfuscator(false), m_pubkey(pub_key), diff --git a/ipcl/paillier_prikey.cpp b/ipcl/pri_key.cpp similarity index 73% rename from ipcl/paillier_prikey.cpp rename to ipcl/pri_key.cpp index 5897e98..baf3db8 100644 --- a/ipcl/paillier_prikey.cpp +++ b/ipcl/pri_key.cpp @@ -1,7 +1,7 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include "ipcl/paillier_prikey.hpp" +#include "ipcl/pri_key.hpp" #include @@ -23,8 +23,8 @@ static inline BigNumber lcm(const BigNumber& p, const BigNumber& q) { return p * q / gcd; } -PaillierPrivateKey::PaillierPrivateKey(const PaillierPublicKey* public_key, - const BigNumber& p, const BigNumber& q) +PrivateKey::PrivateKey(const PublicKey* public_key, const BigNumber& p, + const BigNumber& q) : m_pubkey(public_key), m_n(m_pubkey->getN()), m_nsquare(m_pubkey->getNSQ()), @@ -49,13 +49,12 @@ PaillierPrivateKey::PaillierPrivateKey(const PaillierPublicKey* public_key, m_dwords(m_pubkey->getDwords()), m_enable_crt(true) { ERROR_CHECK(p * q == m_n, - "PaillierPrivateKey ctor: Public key does not match p * q."); - ERROR_CHECK(p != q, "PaillierPrivateKey ctor: p and q are same"); + "PrivateKey ctor: Public key does not match p * q."); + ERROR_CHECK(p != q, "PrivateKey ctor: p and q are same"); } -void PaillierPrivateKey::decryptRAW( - std::vector& plaintext, - const std::vector& ciphertext) const { +void PrivateKey::decryptRAW(std::vector& plaintext, + const std::vector& ciphertext) const { std::vector pow_lambda(IPCL_CRYPTO_MB_SIZE, m_lambda); std::vector modulo(IPCL_CRYPTO_MB_SIZE, m_nsquare); std::vector res = ipcl::ippModExp(ciphertext, pow_lambda, modulo); @@ -70,9 +69,8 @@ void PaillierPrivateKey::decryptRAW( } } -void PaillierPrivateKey::decrypt( - std::vector& plaintext, - const std::vector& ciphertext) const { +void PrivateKey::decrypt(std::vector& plaintext, + const std::vector& ciphertext) const { VEC_SIZE_CHECK(plaintext); VEC_SIZE_CHECK(ciphertext); @@ -82,9 +80,8 @@ void PaillierPrivateKey::decrypt( decryptRAW(plaintext, ciphertext); } -void PaillierPrivateKey::decrypt( - std::vector& plaintext, - const PaillierEncryptedNumber ciphertext) const { +void PrivateKey::decrypt(std::vector& plaintext, + const PaillierEncryptedNumber ciphertext) const { VEC_SIZE_CHECK(plaintext); // check key match ERROR_CHECK(ciphertext.getPK().getN() == m_pubkey->getN(), @@ -98,9 +95,8 @@ void PaillierPrivateKey::decrypt( } // CRT to calculate base^exp mod n^2 -void PaillierPrivateKey::decryptCRT( - std::vector& plaintext, - const std::vector& ciphertext) const { +void PrivateKey::decryptCRT(std::vector& plaintext, + const std::vector& ciphertext) const { std::vector basep(IPCL_CRYPTO_MB_SIZE), baseq(IPCL_CRYPTO_MB_SIZE); std::vector pm1(IPCL_CRYPTO_MB_SIZE, m_pminusone), qm1(IPCL_CRYPTO_MB_SIZE, m_qminusone); @@ -123,19 +119,19 @@ void PaillierPrivateKey::decryptCRT( } } -BigNumber PaillierPrivateKey::computeCRT(const BigNumber& mp, - const BigNumber& mq) const { +BigNumber PrivateKey::computeCRT(const BigNumber& mp, + const BigNumber& mq) const { BigNumber&& u = (mq - mp) * m_pinverse % m_q; return mp + (u * m_p); } -BigNumber PaillierPrivateKey::computeLfun(const BigNumber& a, - const BigNumber& b) const { +BigNumber PrivateKey::computeLfun(const BigNumber& a, + const BigNumber& b) const { return (a - 1) / b; } -BigNumber PaillierPrivateKey::computeHfun(const BigNumber& a, - const BigNumber& b) const { +BigNumber PrivateKey::computeHfun(const BigNumber& a, + const BigNumber& b) const { // Based on the fact a^b mod n = (a mod n)^b mod n BigNumber&& xm = a - 1; BigNumber&& base = m_g % b; diff --git a/ipcl/paillier_pubkey.cpp b/ipcl/pub_key.cpp similarity index 82% rename from ipcl/paillier_pubkey.cpp rename to ipcl/pub_key.cpp index e3e80f1..f162e68 100644 --- a/ipcl/paillier_pubkey.cpp +++ b/ipcl/pub_key.cpp @@ -1,7 +1,7 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include "ipcl/paillier_pubkey.hpp" +#include "ipcl/pub_key.hpp" #include @@ -26,8 +26,7 @@ static inline auto randomUniformUnsignedInt() { return dist(rng); } -PaillierPublicKey::PaillierPublicKey(const BigNumber& n, int bits, - bool enableDJN_) +PublicKey::PublicKey(const BigNumber& n, int bits, bool enableDJN_) : m_n(n), m_g(n + 1), m_nsquare(n * n), @@ -40,7 +39,7 @@ PaillierPublicKey::PaillierPublicKey(const BigNumber& n, int bits, } // array of 32-bit random, using rand() from stdlib -std::vector PaillierPublicKey::randIpp32u(int size) const { +std::vector PublicKey::randIpp32u(int size) const { std::vector addr(size); // TODO(skmono): check if copy of m_init_seed is needed for const unsigned int init_seed = m_init_seed; @@ -49,7 +48,7 @@ std::vector PaillierPublicKey::randIpp32u(int size) const { } // length is Arbitery -BigNumber PaillierPublicKey::getRandom(int length) const { +BigNumber PublicKey::getRandom(int length) const { IppStatus stat; int size; int seedBitSize = 160; @@ -92,7 +91,7 @@ BigNumber PaillierPublicKey::getRandom(int length) const { return rand; } -void PaillierPublicKey::enableDJN() { +void PublicKey::enableDJN() { BigNumber gcd; BigNumber rmod; do { @@ -111,8 +110,7 @@ void PaillierPublicKey::enableDJN() { m_enable_DJN = true; } -void PaillierPublicKey::apply_obfuscator( - std::vector& obfuscator) const { +void PublicKey::apply_obfuscator(std::vector& obfuscator) const { std::vector r(IPCL_CRYPTO_MB_SIZE); std::vector pown(IPCL_CRYPTO_MB_SIZE, m_n); std::vector base(IPCL_CRYPTO_MB_SIZE, m_hs); @@ -140,16 +138,16 @@ void PaillierPublicKey::apply_obfuscator( } } -void PaillierPublicKey::setRandom(const std::vector& r) { +void PublicKey::setRandom(const std::vector& r) { VEC_SIZE_CHECK(r); std::copy(r.begin(), r.end(), std::back_inserter(m_r)); m_testv = true; } -void PaillierPublicKey::raw_encrypt(std::vector& ciphertext, - const std::vector& plaintext, - bool make_secure) const { +void PublicKey::raw_encrypt(std::vector& ciphertext, + const std::vector& plaintext, + bool make_secure) const { // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 BigNumber sq = m_nsquare; for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { @@ -166,9 +164,9 @@ void PaillierPublicKey::raw_encrypt(std::vector& ciphertext, } } -void PaillierPublicKey::encrypt(std::vector& ciphertext, - const std::vector& value, - bool make_secure) const { +void PublicKey::encrypt(std::vector& ciphertext, + const std::vector& value, + bool make_secure) const { VEC_SIZE_CHECK(ciphertext); VEC_SIZE_CHECK(value); @@ -176,8 +174,7 @@ void PaillierPublicKey::encrypt(std::vector& ciphertext, } // Used for CT+PT, where PT do not need to add obfuscator -void PaillierPublicKey::encrypt(BigNumber& ciphertext, - const BigNumber& value) const { +void PublicKey::encrypt(BigNumber& ciphertext, const BigNumber& value) const { // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 BigNumber bn = value; BigNumber sq = m_nsquare; diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index c0cfe75..4632620 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -11,8 +11,8 @@ #endif // IPCL_USE_OMP #include "gtest/gtest.h" -#include "ipcl/paillier_keygen.hpp" -#include "ipcl/paillier_ops.hpp" +#include "ipcl/keygen.hpp" +#include "ipcl/ops.hpp" TEST(CryptoTest, CryptoTest) { ipcl::keyPair key = ipcl::generateKeypair(2048, true); @@ -124,10 +124,8 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { ipcl::BigNumber n = p * q; int n_length = n.BitSize(); - ipcl::PaillierPublicKey* public_key = - new ipcl::PaillierPublicKey(n, n_length); - ipcl::PaillierPrivateKey* private_key = - new ipcl::PaillierPrivateKey(public_key, p, q); + ipcl::PublicKey* public_key = new ipcl::PublicKey(n, n_length); + ipcl::PrivateKey* private_key = new ipcl::PrivateKey(public_key, p, q); ipcl::keyPair key = {public_key, private_key}; diff --git a/test/test_ops.cpp b/test/test_ops.cpp index c2ab740..3b28801 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -11,8 +11,8 @@ #endif // IPCL_USE_OMP #include "gtest/gtest.h" -#include "ipcl/paillier_keygen.hpp" -#include "ipcl/paillier_ops.hpp" +#include "ipcl/keygen.hpp" +#include "ipcl/ops.hpp" void CtPlusCt(std::vector& res, const std::vector& ct1, From 0aac79eafd41affb71a18f99189a98014d81e84f Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Fri, 11 Mar 2022 15:35:31 -0800 Subject: [PATCH 107/364] Refactoring applied (#55) --- README.md | 6 +- benchmark/bench_ops.cpp | 64 +++++++++---------- ipcl/bignum.cpp | 3 - ipcl/include/ipcl/bignum.h | 4 +- ipcl/include/ipcl/common.hpp | 2 +- ipcl/include/ipcl/mod_exp.hpp | 1 - ipcl/include/ipcl/ops.hpp | 52 +++++++--------- ipcl/include/ipcl/pri_key.hpp | 4 +- ipcl/include/ipcl/pub_key.hpp | 2 +- ipcl/include/ipcl/util.hpp | 14 ++--- ipcl/keygen.cpp | 18 +++--- ipcl/mod_exp.cpp | 36 ++++++----- ipcl/ops.cpp | 112 ++++++++++++++++++---------------- ipcl/pri_key.cpp | 31 +++++----- ipcl/pub_key.cpp | 35 +++++------ test/test_cryptography.cpp | 6 +- test/test_ops.cpp | 62 +++++++++---------- 17 files changed, 218 insertions(+), 234 deletions(-) diff --git a/README.md b/README.md index c05a834..ca17e85 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ We will keep working on adding more supported operating systems. ### Dependencies Must have dependencies include: ``` -cmake >=3.15.1 +cmake >= 3.15.1 git pthread g++ >= 7.0 or clang >= 10.0 @@ -54,8 +54,8 @@ g++ >= 7.0 or clang >= 10.0 The following libraries and tools are also required, ``` -nasm>=2.15 -OpenSSL>=1.1.0 +nasm >= 2.15 +OpenSSL >= 1.1.0 ``` For ```nasm```, please refer to the [Netwide Assembler](https://nasm.us/) for installation details. diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index bea62fa..5282223 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -35,9 +35,9 @@ static void BM_Add_CTCT(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, ct_b[i]); + ipcl::EncryptedNumber sum = pen_a + pen_b; } } } @@ -69,9 +69,9 @@ static void BM_Add_CTCT_buff8(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, ct_b[i]); + ipcl::EncryptedNumber sum = pen_a + pen_b; } } } @@ -100,8 +100,8 @@ static void BM_Add_CTPT(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber sum = pen_a + b[i]; } } } @@ -130,8 +130,8 @@ static void BM_Add_CTPT_buff8(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber sum = pen_a + b[i]; } } } @@ -160,9 +160,9 @@ static void BM_Mul_CTPT(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, b[i]); + ipcl::EncryptedNumber sum = pen_a * pen_b; } } } @@ -191,9 +191,9 @@ static void BM_Mul_CTPT_buff8(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, b[i]); + ipcl::EncryptedNumber sum = pen_a * pen_b; } } } @@ -228,9 +228,9 @@ static void BM_Add_CTCT_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, ct_b[i]); + ipcl::EncryptedNumber sum = pen_a + pen_b; } } } @@ -266,9 +266,9 @@ static void BM_Add_CTCT_buff8_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, ct_b[i]); + ipcl::EncryptedNumber sum = pen_a + pen_b; } } } @@ -298,8 +298,8 @@ static void BM_Add_CTPT_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber sum = pen_a + b[i]; } } } @@ -332,8 +332,8 @@ static void BM_Add_CTPT_buff8_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber sum = pen_a + b[i]; } } } @@ -363,9 +363,9 @@ static void BM_Mul_CTPT_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, b[i]); + ipcl::EncryptedNumber sum = pen_a * pen_b; } } } @@ -398,9 +398,9 @@ static void BM_Mul_CTPT_buff8_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, b[i]); + ipcl::EncryptedNumber sum = pen_a * pen_b; } } } diff --git a/ipcl/bignum.cpp b/ipcl/bignum.cpp index b0b578e..b5adab3 100644 --- a/ipcl/bignum.cpp +++ b/ipcl/bignum.cpp @@ -509,7 +509,4 @@ void BigNumber::num2char(std::vector& dest) const { dest.assign(bnData, bnData + len); } -int BITSIZE_WORD(int n) { return (((n) + 31) >> 5); } -int BITSIZE_DWORD(int n) { return (((n) + 63) >> 6); } - } // namespace ipcl diff --git a/ipcl/include/ipcl/bignum.h b/ipcl/include/ipcl/bignum.h index c150f5a..fe62dc1 100644 --- a/ipcl/include/ipcl/bignum.h +++ b/ipcl/include/ipcl/bignum.h @@ -128,8 +128,8 @@ class BigNumber { IppsBigNumState* m_pBN; }; -int BITSIZE_WORD(int n); -int BITSIZE_DWORD(int n); +constexpr int BITSIZE_WORD(int n) { return (((n) + 31) >> 5); } +constexpr int BITSIZE_DWORD(int n) { return (((n) + 63) >> 6); } } // namespace ipcl #endif // _BIGNUM_H_ diff --git a/ipcl/include/ipcl/common.hpp b/ipcl/include/ipcl/common.hpp index fecc02d..f954026 100644 --- a/ipcl/include/ipcl/common.hpp +++ b/ipcl/include/ipcl/common.hpp @@ -6,7 +6,7 @@ namespace ipcl { -#define IPCL_CRYPTO_MB_SIZE 8 +constexpr int IPCL_CRYPTO_MB_SIZE = 8; } // namespace ipcl #endif // IPCL_INCLUDE_IPCL_COMMON_HPP_ diff --git a/ipcl/include/ipcl/mod_exp.hpp b/ipcl/include/ipcl/mod_exp.hpp index e3b3ac4..810ff27 100644 --- a/ipcl/include/ipcl/mod_exp.hpp +++ b/ipcl/include/ipcl/mod_exp.hpp @@ -7,7 +7,6 @@ #include #include "ipcl/bignum.h" -#include "ipcl/util.hpp" namespace ipcl { /** diff --git a/ipcl/include/ipcl/ops.hpp b/ipcl/include/ipcl/ops.hpp index eb6a7b1..6aab2f8 100644 --- a/ipcl/include/ipcl/ops.hpp +++ b/ipcl/include/ipcl/ops.hpp @@ -11,87 +11,77 @@ namespace ipcl { -class PaillierEncryptedNumber { +class EncryptedNumber { public: /** - * PaillierEncryptedNumber constructor + * EncryptedNumber constructor * @param[in] pub_key paillier public key * @param[in] bn ciphertext encrypted by paillier public key */ - PaillierEncryptedNumber(const PublicKey* pub_key, const BigNumber& bn); + EncryptedNumber(const PublicKey* pub_key, const BigNumber& bn); /** - * PaillierEncryptedNumber constructor + * EncryptedNumber constructor * @param[in] pub_key paillier public key * @param[in] bn array of ciphertexts encrypted by paillier public key * @param[in] length size of array(default value is IPCL_CRYPTO_MB_SIZE) */ - PaillierEncryptedNumber(const PublicKey* pub_key, - const std::vector& bn, - size_t length = IPCL_CRYPTO_MB_SIZE); + EncryptedNumber(const PublicKey* pub_key, const std::vector& bn, + size_t length = IPCL_CRYPTO_MB_SIZE); /** - * PaillierEncryptedNumber constructor + * EncryptedNumber constructor * @param[in] pub_key paillier public key * @param[in] scalar array of integer scalars * @param[in] length size of array(default value is IPCL_CRYPTO_MB_SIZE) */ - PaillierEncryptedNumber(const PublicKey* pub_key, - const std::vector& scalar, - size_t length = IPCL_CRYPTO_MB_SIZE); + EncryptedNumber(const PublicKey* pub_key, const std::vector& scalar, + size_t length = IPCL_CRYPTO_MB_SIZE); /** * Arithmetic addition operator * @param[in] bn augend */ - PaillierEncryptedNumber operator+(const PaillierEncryptedNumber& bn) const; + EncryptedNumber operator+(const EncryptedNumber& bn) const; /** * Arithmetic addition operator * @param[in] other augend */ - PaillierEncryptedNumber operator+(const BigNumber& other) const; + EncryptedNumber operator+(const BigNumber& other) const; /** * Arithmetic addition operator * @param[in] other array of augend */ - PaillierEncryptedNumber operator+(const std::vector& other) const; + EncryptedNumber operator+(const std::vector& other) const; /** * Arithmetic multiply operator * @param[in] bn multiplicand */ - PaillierEncryptedNumber operator*(const PaillierEncryptedNumber& bn) const; + EncryptedNumber operator*(const EncryptedNumber& bn) const; /** * Arithmetic multiply operator * @param[in] other multiplicand */ - PaillierEncryptedNumber operator*(const BigNumber& other) const; + EncryptedNumber operator*(const BigNumber& other) const; /** * Apply obfuscator for ciphertext, obfuscated needed only when the ciphertext * is exposed */ - void apply_obfuscator() { - b_isObfuscator = true; - std::vector obfuscator(IPCL_CRYPTO_MB_SIZE); - m_pubkey->apply_obfuscator(obfuscator); - - BigNumber sq = m_pubkey->getNSQ(); - for (int i = 0; i < m_available; i++) - m_bn[i] = sq.ModMul(m_bn[i], obfuscator[i]); - } + void apply_obfuscator(); /** * Return ciphertext - * @param[in] idx index of ciphertext stored in PaillierEncryptedNumber + * @param[in] idx index of ciphertext stored in EncryptedNumber * (default = 0) */ BigNumber getBN(size_t idx = 0) const { ERROR_CHECK(m_available != 1 || idx <= 0, - "getBN: PaillierEncryptedNumber only has 1 BigNumber"); + "getBN: EncryptedNumber only has 1 BigNumber"); return m_bn[idx]; } @@ -102,10 +92,10 @@ class PaillierEncryptedNumber { PublicKey getPK() const { return *m_pubkey; } /** - * Rotate PaillierEncryptedNumber + * Rotate EncryptedNumber * @param[in] shift rotate length */ - PaillierEncryptedNumber rotate(int shift) const; + EncryptedNumber rotate(int shift) const; /** * Return entire ciphertext array @@ -114,12 +104,12 @@ class PaillierEncryptedNumber { std::vector getArrayBN() const { return m_bn; } /** - * Check if element in PaillierEncryptedNumber is single + * Check if element in EncryptedNumber is single */ bool isSingle() const { return m_available == 1; } /** - * Get size of array in PaillierEncryptedNumber + * Get size of array in EncryptedNumber */ size_t getLength() const { return m_length; } diff --git a/ipcl/include/ipcl/pri_key.hpp b/ipcl/include/ipcl/pri_key.hpp index 89acbe1..b3466eb 100644 --- a/ipcl/include/ipcl/pri_key.hpp +++ b/ipcl/include/ipcl/pri_key.hpp @@ -38,10 +38,10 @@ class PrivateKey { /** * Decrypt ciphertext * @param[out] plaintext output of the decryption - * @param[in] ciphertext PaillierEncryptedNumber to be decrypted + * @param[in] ciphertext EncryptedNumber to be decrypted */ void decrypt(std::vector& plaintext, - const PaillierEncryptedNumber ciphertext) const; + const EncryptedNumber ciphertext) const; const void* addr = static_cast(this); diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp index bbdc2eb..61ae905 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -81,7 +81,7 @@ class PublicKey { * Apply obfuscator for ciphertext * @param[out] obfuscator output of obfuscator with random value */ - void apply_obfuscator(std::vector& obfuscator) const; + void applyObfuscator(std::vector& obfuscator) const; /** * @brief Set the Random object for ISO/IEC 18033-6 compliance check diff --git a/ipcl/include/ipcl/util.hpp b/ipcl/include/ipcl/util.hpp index b56cf50..8bd0356 100644 --- a/ipcl/include/ipcl/util.hpp +++ b/ipcl/include/ipcl/util.hpp @@ -5,6 +5,7 @@ #define IPCL_INCLUDE_IPCL_UTIL_HPP_ #include +#include #include #include @@ -12,14 +13,11 @@ namespace ipcl { -static inline std::string build_log(const char* file, int line, - std::string msg) { - std::string log; - log = "\nFile: " + std::string(file); - log += "\nLine: " + std::to_string(line); - log += "\nError: " + msg; - - return log; +inline std::string build_log(const char* file, int line, + const std::string& msg) { + std::ostringstream log; + log << "\nFile: " << file << "\nLine: " << line << "\nError: " << msg; + return log.str(); } #define ERROR_CHECK(e, ...) \ diff --git a/ipcl/keygen.cpp b/ipcl/keygen.cpp index 665d12b..9a8dcbf 100644 --- a/ipcl/keygen.cpp +++ b/ipcl/keygen.cpp @@ -11,7 +11,7 @@ namespace ipcl { -#define N_BIT_SIZE_MAX 2048 +constexpr int N_BIT_SIZE_MAX = 2048; static void rand32u(std::vector& addr) { std::random_device dev; @@ -23,18 +23,18 @@ static void rand32u(std::vector& addr) { BigNumber getPrimeBN(int maxBitSize) { int PrimeSize; ippsPrimeGetSize(maxBitSize, &PrimeSize); - auto&& primeGen = std::vector(PrimeSize); + auto primeGen = std::vector(PrimeSize); ippsPrimeInit(maxBitSize, reinterpret_cast(primeGen.data())); // define Pseudo Random Generator (default settings) - int&& seedBitSize = 160; - int&& seedSize = BITSIZE_WORD(seedBitSize); + constexpr int seedBitSize = 160; + constexpr int seedSize = BITSIZE_WORD(seedBitSize); ippsPRNGGetSize(&PrimeSize); - auto&& rand = std::vector(PrimeSize); + auto rand = std::vector(PrimeSize); ippsPRNGInit(seedBitSize, reinterpret_cast(rand.data())); - auto&& seed = std::vector(seedSize); + auto seed = std::vector(seedSize); rand32u(seed); BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); @@ -76,10 +76,8 @@ static void getDJNBN(int64_t n_length, BigNumber& p, BigNumber& q, q = getPrimeBN(n_length / 2); } while (q == p || !p.TestBit(1)); // get q: q!=p and q mod 4 = 3 - BigNumber&& pminusone = p - 1; - BigNumber&& qminusone = q - 1; - gcd = pminusone.gcd(qminusone); - } while (gcd.compare(2)); // gcd(p-1,q-1)=2 + gcd = (p - 1).gcd(q - 1); // (p - 1) is a BigNumber + } while (gcd.compare(2)); // gcd(p-1,q-1)=2 n = p * q; } diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index f6cb1de..ea1c41c 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -7,6 +7,8 @@ #include +#include "ipcl/util.hpp" + namespace ipcl { static std::vector ippMBModExp(const std::vector& base, @@ -18,14 +20,15 @@ static std::vector ippMBModExp(const std::vector& base, mbx_status st = MBX_STATUS_OK; - int&& bits = m[0].BitSize(); - int&& dwords = BITSIZE_DWORD(bits); - int&& bufferLen = mbx_exp_BufferSize(bits); - auto&& pBuffer = std::vector(bufferLen); + int bits = m.front().BitSize(); + int dwords = BITSIZE_DWORD(bits); + int bufferLen = mbx_exp_BufferSize(bits); + auto buffer = std::vector(bufferLen); - std::vector out_x(IPCL_CRYPTO_MB_SIZE), b_array(IPCL_CRYPTO_MB_SIZE), - p_array(IPCL_CRYPTO_MB_SIZE); - int&& length = dwords * sizeof(int64u); + std::vector out_x(IPCL_CRYPTO_MB_SIZE); + std::vector b_array(IPCL_CRYPTO_MB_SIZE); + std::vector p_array(IPCL_CRYPTO_MB_SIZE); + int length = dwords * sizeof(int64u); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { out_x[i] = reinterpret_cast(alloca(length)); @@ -47,12 +50,13 @@ static std::vector ippMBModExp(const std::vector& base, * will be inconsistent with the length allocated by b_array/p_array, * resulting in data errors. */ - std::vector pow_b(IPCL_CRYPTO_MB_SIZE), pow_p(IPCL_CRYPTO_MB_SIZE), - pow_nsquare(IPCL_CRYPTO_MB_SIZE); - int bBitLen, pBitLen, nsqBitLen; + std::vector pow_b(IPCL_CRYPTO_MB_SIZE); + std::vector pow_p(IPCL_CRYPTO_MB_SIZE); + std::vector pow_nsquare(IPCL_CRYPTO_MB_SIZE); + int nsqBitLen; int expBitLen = 0; - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + for (int i = 0, bBitLen, pBitLen; i < IPCL_CRYPTO_MB_SIZE; i++) { ippsRef_BN(nullptr, &bBitLen, reinterpret_cast(&pow_b[i]), base[i]); ippsRef_BN(nullptr, &pBitLen, reinterpret_cast(&pow_p[i]), @@ -72,7 +76,7 @@ static std::vector ippMBModExp(const std::vector& base, */ st = mbx_exp_mb8(out_x.data(), b_array.data(), p_array.data(), expBitLen, reinterpret_cast(pow_nsquare.data()), nsqBitLen, - reinterpret_cast(pBuffer.data()), bufferLen); + reinterpret_cast(buffer.data()), bufferLen); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { ERROR_CHECK(MBX_STATUS_OK == MBX_GET_STS(st, i), @@ -82,7 +86,7 @@ static std::vector ippMBModExp(const std::vector& base, } // It is important to hold a copy of nsquare for thread-safe purpose - BigNumber bn_c(m[0]); + BigNumber bn_c(m.front()); std::vector res(IPCL_CRYPTO_MB_SIZE, 0); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { @@ -96,14 +100,14 @@ static std::vector ippMBModExp(const std::vector& base, static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, const BigNumber& m) { IppStatus stat = ippStsNoErr; - // It is important to declear res * bform bit length refer to ipp-crypto spec: + // It is important to declare res * bform bit length refer to ipp-crypto spec: // R should not be less than the data length of the modulus m BigNumber res(m); int bnBitLen; Ipp32u* pow_m; ippsRef_BN(nullptr, &bnBitLen, &pow_m, BN(m)); - int&& nlen = BITSIZE_WORD(bnBitLen); + int nlen = BITSIZE_WORD(bnBitLen); int size; // define and initialize Montgomery Engine over Modulus N @@ -111,7 +115,7 @@ static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: get the size of IppsMontState context error."); - auto&& pMont = std::vector(size); + auto pMont = std::vector(size); stat = ippsMontInit(IppsBinaryMethod, nlen, reinterpret_cast(pMont.data())); diff --git a/ipcl/ops.cpp b/ipcl/ops.cpp index a3b5094..2deaf5d 100644 --- a/ipcl/ops.cpp +++ b/ipcl/ops.cpp @@ -10,25 +10,25 @@ namespace ipcl { // constructors // -PaillierEncryptedNumber::PaillierEncryptedNumber(const PublicKey* pub_key, - const BigNumber& bn) +EncryptedNumber::EncryptedNumber(const PublicKey* pub_key, const BigNumber& bn) : b_isObfuscator(false), m_available(1), m_pubkey(pub_key), m_length(1), m_bn{bn} {} -PaillierEncryptedNumber::PaillierEncryptedNumber( - const PublicKey* pub_key, const std::vector& bn, size_t length) +EncryptedNumber::EncryptedNumber(const PublicKey* pub_key, + const std::vector& bn, + size_t length) : b_isObfuscator(false), m_pubkey(pub_key), m_available(IPCL_CRYPTO_MB_SIZE), m_length(length), m_bn{bn[0], bn[1], bn[2], bn[3], bn[4], bn[5], bn[6], bn[7]} {} -PaillierEncryptedNumber::PaillierEncryptedNumber( - const PublicKey* pub_key, const std::vector& scalar, - size_t length) +EncryptedNumber::EncryptedNumber(const PublicKey* pub_key, + const std::vector& scalar, + size_t length) : b_isObfuscator(false), m_pubkey(pub_key), m_available(IPCL_CRYPTO_MB_SIZE), @@ -37,117 +37,121 @@ PaillierEncryptedNumber::PaillierEncryptedNumber( scalar[4], scalar[5], scalar[6], scalar[7]} {} // CT+CT -PaillierEncryptedNumber PaillierEncryptedNumber::operator+( - const PaillierEncryptedNumber& other) const { +EncryptedNumber EncryptedNumber::operator+(const EncryptedNumber& other) const { ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), "operator+: two different public keys detected!!"); - PaillierEncryptedNumber a = *this; - PaillierEncryptedNumber b = other; + const auto& a = *this; + const auto& b = other; if (m_available == 1) { - BigNumber&& sum = a.raw_add(a.m_bn[0], b.m_bn[0]); - return PaillierEncryptedNumber(m_pubkey, sum); - } else { - std::vector sum(IPCL_CRYPTO_MB_SIZE); - for (int i = 0; i < m_available; i++) - sum[i] = a.raw_add(a.m_bn[i], b.m_bn[i]); - return PaillierEncryptedNumber(m_pubkey, sum); + BigNumber sum = a.raw_add(a.m_bn.front(), b.m_bn.front()); + return EncryptedNumber(m_pubkey, sum); } + std::vector sum(IPCL_CRYPTO_MB_SIZE); + for (int i = 0; i < m_available; i++) + sum[i] = a.raw_add(a.m_bn[i], b.m_bn[i]); + return EncryptedNumber(m_pubkey, sum); } // CT+PT -PaillierEncryptedNumber PaillierEncryptedNumber::operator+( - const BigNumber& other) const { - PaillierEncryptedNumber a = *this; +EncryptedNumber EncryptedNumber::operator+(const BigNumber& other) const { + const auto& a = *this; BigNumber b; a.m_pubkey->encrypt(b, other); - BigNumber&& sum = a.raw_add(a.m_bn[0], b); - return PaillierEncryptedNumber(m_pubkey, sum); + BigNumber sum = a.raw_add(a.m_bn.front(), b); + return EncryptedNumber(m_pubkey, sum); } // multi encrypted CT+PT -PaillierEncryptedNumber PaillierEncryptedNumber::operator+( +EncryptedNumber EncryptedNumber::operator+( const std::vector& other) const { VEC_SIZE_CHECK(other); - PaillierEncryptedNumber a = *this; + const auto& a = *this; std::vector b(IPCL_CRYPTO_MB_SIZE); std::vector sum(IPCL_CRYPTO_MB_SIZE); a.m_pubkey->encrypt(b, other, false); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) sum[i] = a.raw_add(a.m_bn[i], b[i]); - return PaillierEncryptedNumber(m_pubkey, sum); + return EncryptedNumber(m_pubkey, sum); } -// CT*PT PaillierEncryptedNumber store a plaintext integer, not an encrypted +// CT*PT EncryptedNumber store a plaintext integer, not an encrypted // integer -PaillierEncryptedNumber PaillierEncryptedNumber::operator*( - const PaillierEncryptedNumber& other) const { +EncryptedNumber EncryptedNumber::operator*(const EncryptedNumber& other) const { ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), "operator*: two different public keys detected!!"); - PaillierEncryptedNumber a = *this; - PaillierEncryptedNumber b = other; + const auto& a = *this; + const auto& b = other; if (m_available == 1) { - BigNumber&& product = a.raw_mul(a.m_bn[0], b.m_bn[0]); - return PaillierEncryptedNumber(m_pubkey, product); - } else { - std::vector&& product = a.raw_mul(a.m_bn, b.m_bn); - return PaillierEncryptedNumber(m_pubkey, product); + BigNumber product = a.raw_mul(a.m_bn.front(), b.m_bn.front()); + return EncryptedNumber(m_pubkey, product); } + + std::vector&& product = a.raw_mul(a.m_bn, b.m_bn); + return EncryptedNumber(m_pubkey, product); } // CT*PT -PaillierEncryptedNumber PaillierEncryptedNumber::operator*( - const BigNumber& other) const { - PaillierEncryptedNumber a = *this; +EncryptedNumber EncryptedNumber::operator*(const BigNumber& other) const { + const auto& a = *this; BigNumber b = other; - BigNumber&& product = a.raw_mul(a.m_bn[0], b); - return PaillierEncryptedNumber(m_pubkey, product); + BigNumber product = a.raw_mul(a.m_bn.front(), b); + return EncryptedNumber(m_pubkey, product); } -BigNumber PaillierEncryptedNumber::raw_add(const BigNumber& a, - const BigNumber& b) const { +BigNumber EncryptedNumber::raw_add(const BigNumber& a, + const BigNumber& b) const { // Hold a copy of nsquare for multi-threaded - BigNumber&& sq = m_pubkey->getNSQ(); + const BigNumber& sq = m_pubkey->getNSQ(); return a * b % sq; } -std::vector PaillierEncryptedNumber::raw_mul( +std::vector EncryptedNumber::raw_mul( const std::vector& a, const std::vector& b) const { std::vector sq(IPCL_CRYPTO_MB_SIZE, m_pubkey->getNSQ()); return ipcl::ippModExp(a, b, sq); } -BigNumber PaillierEncryptedNumber::raw_mul(const BigNumber& a, - const BigNumber& b) const { - BigNumber&& sq = m_pubkey->getNSQ(); +BigNumber EncryptedNumber::raw_mul(const BigNumber& a, + const BigNumber& b) const { + const BigNumber& sq = m_pubkey->getNSQ(); return ipcl::ippModExp(a, b, sq); } -PaillierEncryptedNumber PaillierEncryptedNumber::rotate(int shift) const { - ERROR_CHECK(m_available != 1, - "rotate: Cannot rotate single PaillierEncryptedNumber"); +EncryptedNumber EncryptedNumber::rotate(int shift) const { + ERROR_CHECK(m_available != 1, "rotate: Cannot rotate single EncryptedNumber"); ERROR_CHECK(shift >= -8 && shift <= 8, "rotate: Cannot shift more than 8 or -8"); if (shift == 0 || shift == 8 || shift == -8) - return PaillierEncryptedNumber(m_pubkey, m_bn); + return EncryptedNumber(m_pubkey, m_bn); if (shift > 0) shift = 8 - shift; else shift = -shift; - std::vector&& new_bn = getArrayBN(); + std::vector new_bn = getArrayBN(); std::rotate(std::begin(new_bn), std::begin(new_bn) + shift, std::end(new_bn)); - return PaillierEncryptedNumber(m_pubkey, new_bn); + return EncryptedNumber(m_pubkey, new_bn); +} + +void EncryptedNumber::apply_obfuscator() { + b_isObfuscator = true; + std::vector obfuscator(IPCL_CRYPTO_MB_SIZE); + m_pubkey->applyObfuscator(obfuscator); + + BigNumber sq = m_pubkey->getNSQ(); + for (int i = 0; i < m_available; i++) + m_bn[i] = sq.ModMul(m_bn[i], obfuscator[i]); } } // namespace ipcl diff --git a/ipcl/pri_key.cpp b/ipcl/pri_key.cpp index baf3db8..083c708 100644 --- a/ipcl/pri_key.cpp +++ b/ipcl/pri_key.cpp @@ -59,13 +59,10 @@ void PrivateKey::decryptRAW(std::vector& plaintext, std::vector modulo(IPCL_CRYPTO_MB_SIZE, m_nsquare); std::vector res = ipcl::ippModExp(ciphertext, pow_lambda, modulo); - BigNumber nn = m_n; - BigNumber xx = m_x; - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - BigNumber m = (res[i] - 1) / nn; - m = m * xx; - plaintext[i] = m % nn; + BigNumber m = (res[i] - 1) / m_n; + m *= m_x; + plaintext[i] = m % m_n; } } @@ -81,13 +78,13 @@ void PrivateKey::decrypt(std::vector& plaintext, } void PrivateKey::decrypt(std::vector& plaintext, - const PaillierEncryptedNumber ciphertext) const { + const EncryptedNumber ciphertext) const { VEC_SIZE_CHECK(plaintext); // check key match ERROR_CHECK(ciphertext.getPK().getN() == m_pubkey->getN(), "decrypt: public key mismatch error."); - std::vector&& res = ciphertext.getArrayBN(); + const std::vector& res = ciphertext.getArrayBN(); if (m_enable_crt) decryptCRT(plaintext, res); else @@ -109,19 +106,19 @@ void PrivateKey::decryptCRT(std::vector& plaintext, } // Based on the fact a^b mod n = (a mod n)^b mod n - std::vector&& resp = ipcl::ippModExp(basep, pm1, psq); - std::vector&& resq = ipcl::ippModExp(baseq, qm1, qsq); + std::vector resp = ipcl::ippModExp(basep, pm1, psq); + std::vector resq = ipcl::ippModExp(baseq, qm1, qsq); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - BigNumber&& dp = computeLfun(resp[i], m_p) * m_hp % m_p; - BigNumber&& dq = computeLfun(resq[i], m_q) * m_hq % m_q; + BigNumber dp = computeLfun(resp[i], m_p) * m_hp % m_p; + BigNumber dq = computeLfun(resq[i], m_q) * m_hq % m_q; plaintext[i] = computeCRT(dp, dq); } } BigNumber PrivateKey::computeCRT(const BigNumber& mp, const BigNumber& mq) const { - BigNumber&& u = (mq - mp) * m_pinverse % m_q; + BigNumber u = (mq - mp) * m_pinverse % m_q; return mp + (u * m_p); } @@ -133,10 +130,10 @@ BigNumber PrivateKey::computeLfun(const BigNumber& a, BigNumber PrivateKey::computeHfun(const BigNumber& a, const BigNumber& b) const { // Based on the fact a^b mod n = (a mod n)^b mod n - BigNumber&& xm = a - 1; - BigNumber&& base = m_g % b; - BigNumber&& pm = ipcl::ippModExp(base, xm, b); - BigNumber&& lcrt = computeLfun(pm, a); + BigNumber xm = a - 1; + BigNumber base = m_g % b; + BigNumber pm = ipcl::ippModExp(base, xm, b); + BigNumber lcrt = computeLfun(pm, a); return a.InverseMul(lcrt); } diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index f162e68..f3d347b 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -47,28 +47,28 @@ std::vector PublicKey::randIpp32u(int size) const { return addr; } -// length is Arbitery +// length is arbitrary BigNumber PublicKey::getRandom(int length) const { IppStatus stat; int size; - int seedBitSize = 160; - int seedSize = BITSIZE_WORD(seedBitSize); + constexpr int seedBitSize = 160; + constexpr int seedSize = BITSIZE_WORD(seedBitSize); stat = ippsPRNGGetSize(&size); ERROR_CHECK(stat == ippStsNoErr, "getRandom: get IppsPRNGState context error."); - auto pRand = std::vector(size); + auto rands = std::vector(size); stat = - ippsPRNGInit(seedBitSize, reinterpret_cast(pRand.data())); + ippsPRNGInit(seedBitSize, reinterpret_cast(rands.data())); ERROR_CHECK(stat == ippStsNoErr, "getRandom: init rand context error."); - auto&& seed = randIpp32u(seedSize); + auto seed = randIpp32u(seedSize); BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); stat = ippsPRNGSetSeed(BN(bseed), - reinterpret_cast(pRand.data())); + reinterpret_cast(rands.data())); ERROR_CHECK(stat == ippStsNoErr, "getRandom: set up seed value error."); // define length Big Numbers @@ -85,10 +85,9 @@ BigNumber PublicKey::getRandom(int length) const { int bnBitSize = length; ippsPRNGenRDRAND_BN(pBN, bnBitSize, - reinterpret_cast(pRand.data())); - BigNumber rand(pBN); + reinterpret_cast(rands.data())); - return rand; + return BigNumber{pBN}; } void PublicKey::enableDJN() { @@ -96,21 +95,21 @@ void PublicKey::enableDJN() { BigNumber rmod; do { int rand_bit = m_n.BitSize(); - BigNumber&& rand = getRandom(rand_bit + 128); + BigNumber rand = getRandom(rand_bit + 128); rmod = rand % m_n; gcd = rand.gcd(m_n); } while (gcd.compare(1)); - BigNumber&& rmod_sq = rmod * rmod; - BigNumber&& rmod_neg = rmod_sq * -1; - BigNumber&& h = rmod_neg % m_n; + BigNumber rmod_sq = rmod * rmod; + BigNumber rmod_neg = rmod_sq * -1; + BigNumber h = rmod_neg % m_n; m_hs = ipcl::ippModExp(h, m_n, m_nsquare); m_randbits = m_bits >> 1; // bits/2 m_enable_DJN = true; } -void PublicKey::apply_obfuscator(std::vector& obfuscator) const { +void PublicKey::applyObfuscator(std::vector& obfuscator) const { std::vector r(IPCL_CRYPTO_MB_SIZE); std::vector pown(IPCL_CRYPTO_MB_SIZE, m_n); std::vector base(IPCL_CRYPTO_MB_SIZE, m_hs); @@ -157,7 +156,7 @@ void PublicKey::raw_encrypt(std::vector& ciphertext, if (make_secure) { std::vector obfuscator(IPCL_CRYPTO_MB_SIZE); - apply_obfuscator(obfuscator); + applyObfuscator(obfuscator); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) ciphertext[i] = sq.ModMul(ciphertext[i], obfuscator[i]); @@ -176,9 +175,7 @@ void PublicKey::encrypt(std::vector& ciphertext, // Used for CT+PT, where PT do not need to add obfuscator void PublicKey::encrypt(BigNumber& ciphertext, const BigNumber& value) const { // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 - BigNumber bn = value; - BigNumber sq = m_nsquare; - ciphertext = (m_n * bn + 1) % sq; + ciphertext = (m_n * value + 1) % m_nsquare; /*----- Path to caculate (n+1)^plaintext mod n^2 ------------ BigNumber bn(value); diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index 4632620..931b0ac 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -217,9 +217,9 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { key.pub_key->encrypt(ct, ptbn); - ipcl::PaillierEncryptedNumber a(key.pub_key, ct[0]); - ipcl::PaillierEncryptedNumber b(key.pub_key, ct[1]); - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber a(key.pub_key, ct[0]); + ipcl::EncryptedNumber b(key.pub_key, ct[1]); + ipcl::EncryptedNumber sum = a + b; ipcl::BigNumber res = sum.getBN(); std::vector ct12(8); diff --git a/test/test_ops.cpp b/test/test_ops.cpp index 3b28801..c7a830a 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -19,9 +19,9 @@ void CtPlusCt(std::vector& res, const std::vector& ct2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); - ipcl::PaillierEncryptedNumber b(key.pub_key, ct2[i]); - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber a(key.pub_key, ct1[i]); + ipcl::EncryptedNumber b(key.pub_key, ct2[i]); + ipcl::EncryptedNumber sum = a + b; res[i] = sum.getBN(); } } @@ -30,9 +30,9 @@ void CtPlusCtArray(std::vector& res, const std::vector& ct1, const std::vector& ct2, const ipcl::keyPair key) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1); - ipcl::PaillierEncryptedNumber b(key.pub_key, ct2); - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber a(key.pub_key, ct1); + ipcl::EncryptedNumber b(key.pub_key, ct2); + ipcl::EncryptedNumber sum = a + b; res = sum.getArrayBN(); } @@ -40,9 +40,9 @@ void CtPlusPt(std::vector& res, const std::vector& ct1, const std::vector& pt2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); + ipcl::EncryptedNumber a(key.pub_key, ct1[i]); ipcl::BigNumber b = pt2[i]; - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber sum = a + b; res[i] = sum.getBN(); } } @@ -51,8 +51,8 @@ void CtPlusPtArray(std::vector& res, const std::vector& ct1, const std::vector& ptbn2, const ipcl::keyPair key) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1); - ipcl::PaillierEncryptedNumber sum = a + ptbn2; + ipcl::EncryptedNumber a(key.pub_key, ct1); + ipcl::EncryptedNumber sum = a + ptbn2; res = sum.getArrayBN(); } @@ -60,9 +60,9 @@ void CtMultiplyPt(std::vector& res, const std::vector& ct1, const std::vector& pt2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); - ipcl::PaillierEncryptedNumber b(key.pub_key, pt2[i]); - ipcl::PaillierEncryptedNumber sum = a * b; + ipcl::EncryptedNumber a(key.pub_key, ct1[i]); + ipcl::EncryptedNumber b(key.pub_key, pt2[i]); + ipcl::EncryptedNumber sum = a * b; res[i] = sum.getBN(); } } @@ -71,9 +71,9 @@ void CtMultiplyPtArray(std::vector& res, const std::vector& ct1, const std::vector& pt2, const ipcl::keyPair key) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1); - ipcl::PaillierEncryptedNumber b(key.pub_key, pt2); - ipcl::PaillierEncryptedNumber sum = a * b; + ipcl::EncryptedNumber a(key.pub_key, ct1); + ipcl::EncryptedNumber b(key.pub_key, pt2); + ipcl::EncryptedNumber sum = a * b; res = sum.getArrayBN(); } @@ -81,11 +81,11 @@ void AddSub(std::vector& res, const std::vector& ct1, const std::vector& ct2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); - ipcl::PaillierEncryptedNumber b(key.pub_key, ct2[i]); + ipcl::EncryptedNumber a(key.pub_key, ct1[i]); + ipcl::EncryptedNumber b(key.pub_key, ct2[i]); ipcl::BigNumber m1(2); a = a + b * m1; - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber sum = a + b; res[i] = sum.getBN(); } } @@ -418,9 +418,9 @@ void CtPlusCt_OMP(int num_threads, #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); - ipcl::PaillierEncryptedNumber b(key.pub_key, v_ct2[i][j]); - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); + ipcl::EncryptedNumber b(key.pub_key, v_ct2[i][j]); + ipcl::EncryptedNumber sum = a + b; v_sum[i][j] = sum.getBN(); } } @@ -435,8 +435,8 @@ void CtPlusPt_OMP(int num_threads, for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { ipcl::BigNumber b = v_pt2[i][j]; - ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); + ipcl::EncryptedNumber sum = a + b; v_sum[i][j] = sum.getBN(); } } @@ -449,12 +449,12 @@ void CtPlusPtArray_OMP(int num_threads, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); + ipcl::EncryptedNumber a(key.pub_key, v_ct1[i]); std::vector b(8); for (int j = 0; j < 8; j++) { b[j] = v_pt2[i][j]; } - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber sum = a + b; v_sum[i] = sum.getArrayBN(); } } @@ -467,9 +467,9 @@ void CtMultiplyPt_OMP(int num_threads, #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); + ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); ipcl::BigNumber b = v_pt2[i][j]; - ipcl::PaillierEncryptedNumber product = a * b; + ipcl::EncryptedNumber product = a * b; v_product[i][j] = product.getBN(); } } @@ -481,9 +481,9 @@ void CtMultiplyPtArray_OMP( const std::vector>& v_pt2, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); - ipcl::PaillierEncryptedNumber b(key.pub_key, v_pt2[i]); - ipcl::PaillierEncryptedNumber product = a * b; + ipcl::EncryptedNumber a(key.pub_key, v_ct1[i]); + ipcl::EncryptedNumber b(key.pub_key, v_pt2[i]); + ipcl::EncryptedNumber product = a * b; v_product[i] = product.getArrayBN(); } } From a94ae13d46422a72576831766a458eb26b9ff677 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Fri, 11 Mar 2022 15:46:39 -0800 Subject: [PATCH 108/364] v1.0 update --- benchmark/bench_cryptography.cpp | 2 +- benchmark/bench_ops.cpp | 68 +++++------ ipcl/CMakeLists.txt | 8 +- ipcl/include/ipcl/keygen.hpp | 37 ++++++ ipcl/include/ipcl/ops.hpp | 132 ++++++++++++++++++++++ ipcl/include/ipcl/pri_key.hpp | 142 +++++++++++++++++++++++ ipcl/include/ipcl/pub_key.hpp | 143 ++++++++++++++++++++++++ ipcl/include/ipcl/util.hpp | 8 +- ipcl/keygen.cpp | 108 ++++++++++++++++++ ipcl/mod_exp.cpp | 3 +- ipcl/ops.cpp | 157 ++++++++++++++++++++++++++ ipcl/pri_key.cpp | 140 +++++++++++++++++++++++ ipcl/pub_key.cpp | 186 +++++++++++++++++++++++++++++++ test/test_cryptography.cpp | 16 ++- test/test_ops.cpp | 66 +++++------ 15 files changed, 1129 insertions(+), 87 deletions(-) create mode 100644 ipcl/include/ipcl/keygen.hpp create mode 100644 ipcl/include/ipcl/ops.hpp create mode 100644 ipcl/include/ipcl/pri_key.hpp create mode 100644 ipcl/include/ipcl/pub_key.hpp create mode 100644 ipcl/keygen.cpp create mode 100644 ipcl/ops.cpp create mode 100644 ipcl/pri_key.cpp create mode 100644 ipcl/pub_key.cpp diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index 06f28e2..b9ffb9d 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -8,7 +8,7 @@ #include #endif // IPCL_USE_OMP -#include "ipcl/paillier_keygen.hpp" +#include "ipcl/keygen.hpp" static void BM_KeyGen(benchmark::State& state) { int64_t n_length = state.range(0); diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index a9a43d2..5282223 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -9,8 +9,8 @@ #endif // IPCL_USE_OMP #include -#include "ipcl/paillier_keygen.hpp" -#include "ipcl/paillier_ops.hpp" +#include "ipcl/keygen.hpp" +#include "ipcl/ops.hpp" static void BM_Add_CTCT(benchmark::State& state) { size_t dsize = state.range(0); @@ -35,9 +35,9 @@ static void BM_Add_CTCT(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, ct_b[i]); + ipcl::EncryptedNumber sum = pen_a + pen_b; } } } @@ -69,9 +69,9 @@ static void BM_Add_CTCT_buff8(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, ct_b[i]); + ipcl::EncryptedNumber sum = pen_a + pen_b; } } } @@ -100,8 +100,8 @@ static void BM_Add_CTPT(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber sum = pen_a + b[i]; } } } @@ -130,8 +130,8 @@ static void BM_Add_CTPT_buff8(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber sum = pen_a + b[i]; } } } @@ -160,9 +160,9 @@ static void BM_Mul_CTPT(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, b[i]); + ipcl::EncryptedNumber sum = pen_a * pen_b; } } } @@ -191,9 +191,9 @@ static void BM_Mul_CTPT_buff8(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, b[i]); + ipcl::EncryptedNumber sum = pen_a * pen_b; } } } @@ -228,9 +228,9 @@ static void BM_Add_CTCT_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, ct_b[i]); + ipcl::EncryptedNumber sum = pen_a + pen_b; } } } @@ -266,9 +266,9 @@ static void BM_Add_CTCT_buff8_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, ct_b[i]); + ipcl::EncryptedNumber sum = pen_a + pen_b; } } } @@ -298,8 +298,8 @@ static void BM_Add_CTPT_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber sum = pen_a + b[i]; } } } @@ -332,8 +332,8 @@ static void BM_Add_CTPT_buff8_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber sum = pen_a + b[i]; } } } @@ -363,9 +363,9 @@ static void BM_Mul_CTPT_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, b[i]); + ipcl::EncryptedNumber sum = pen_a * pen_b; } } } @@ -398,9 +398,9 @@ static void BM_Mul_CTPT_buff8_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, b[i]); + ipcl::EncryptedNumber sum = pen_a * pen_b; } } } diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 4ad679f..a4b1ff5 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -1,10 +1,10 @@ # Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -set(IPCL_SRCS paillier_prikey.cpp - paillier_pubkey.cpp - paillier_ops.cpp - paillier_keygen.cpp +set(IPCL_SRCS pri_key.cpp + pub_key.cpp + ops.cpp + keygen.cpp bignum.cpp mod_exp.cpp ) diff --git a/ipcl/include/ipcl/keygen.hpp b/ipcl/include/ipcl/keygen.hpp new file mode 100644 index 0000000..c254db8 --- /dev/null +++ b/ipcl/include/ipcl/keygen.hpp @@ -0,0 +1,37 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IPCL_INCLUDE_IPCL_KEYGEN_HPP_ +#define IPCL_INCLUDE_IPCL_KEYGEN_HPP_ + +#include "ipcl/pri_key.hpp" + +namespace ipcl { + +/** + * Paillier key structure contains a public key and private key + * pub_key: paillier public key + * priv_key: paillier private key + */ +struct keyPair { + PublicKey* pub_key; + PrivateKey* priv_key; +}; + +/** + * Generate prime number + * @param[in] maxBitSize Maximum bit length of to be generated prime number + * @return The function return a prime big number + */ +BigNumber getPrimeBN(int maxBitSize); + +/** + * Generate a public/private key pair + * @param[in] n_length Bit length of key size + * @param[in] enable_DJN Enable DJN (default=true) + * @return The function return the public and private key pair + */ +keyPair generateKeypair(int64_t n_length, bool enable_DJN = true); + +} // namespace ipcl +#endif // IPCL_INCLUDE_IPCL_KEYGEN_HPP_ diff --git a/ipcl/include/ipcl/ops.hpp b/ipcl/include/ipcl/ops.hpp new file mode 100644 index 0000000..6aab2f8 --- /dev/null +++ b/ipcl/include/ipcl/ops.hpp @@ -0,0 +1,132 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IPCL_INCLUDE_IPCL_OPS_HPP_ +#define IPCL_INCLUDE_IPCL_OPS_HPP_ + +#include + +#include "ipcl/pub_key.hpp" +#include "ipcl/util.hpp" + +namespace ipcl { + +class EncryptedNumber { + public: + /** + * EncryptedNumber constructor + * @param[in] pub_key paillier public key + * @param[in] bn ciphertext encrypted by paillier public key + */ + EncryptedNumber(const PublicKey* pub_key, const BigNumber& bn); + + /** + * EncryptedNumber constructor + * @param[in] pub_key paillier public key + * @param[in] bn array of ciphertexts encrypted by paillier public key + * @param[in] length size of array(default value is IPCL_CRYPTO_MB_SIZE) + */ + EncryptedNumber(const PublicKey* pub_key, const std::vector& bn, + size_t length = IPCL_CRYPTO_MB_SIZE); + + /** + * EncryptedNumber constructor + * @param[in] pub_key paillier public key + * @param[in] scalar array of integer scalars + * @param[in] length size of array(default value is IPCL_CRYPTO_MB_SIZE) + */ + EncryptedNumber(const PublicKey* pub_key, const std::vector& scalar, + size_t length = IPCL_CRYPTO_MB_SIZE); + + /** + * Arithmetic addition operator + * @param[in] bn augend + */ + EncryptedNumber operator+(const EncryptedNumber& bn) const; + + /** + * Arithmetic addition operator + * @param[in] other augend + */ + EncryptedNumber operator+(const BigNumber& other) const; + + /** + * Arithmetic addition operator + * @param[in] other array of augend + */ + EncryptedNumber operator+(const std::vector& other) const; + + /** + * Arithmetic multiply operator + * @param[in] bn multiplicand + */ + EncryptedNumber operator*(const EncryptedNumber& bn) const; + + /** + * Arithmetic multiply operator + * @param[in] other multiplicand + */ + EncryptedNumber operator*(const BigNumber& other) const; + + /** + * Apply obfuscator for ciphertext, obfuscated needed only when the ciphertext + * is exposed + */ + void apply_obfuscator(); + + /** + * Return ciphertext + * @param[in] idx index of ciphertext stored in EncryptedNumber + * (default = 0) + */ + BigNumber getBN(size_t idx = 0) const { + ERROR_CHECK(m_available != 1 || idx <= 0, + "getBN: EncryptedNumber only has 1 BigNumber"); + + return m_bn[idx]; + } + + /** + * Get public key + */ + PublicKey getPK() const { return *m_pubkey; } + + /** + * Rotate EncryptedNumber + * @param[in] shift rotate length + */ + EncryptedNumber rotate(int shift) const; + + /** + * Return entire ciphertext array + * @param[out] bn output array + */ + std::vector getArrayBN() const { return m_bn; } + + /** + * Check if element in EncryptedNumber is single + */ + bool isSingle() const { return m_available == 1; } + + /** + * Get size of array in EncryptedNumber + */ + size_t getLength() const { return m_length; } + + const void* addr = static_cast(this); + + private: + bool b_isObfuscator; + int m_available; + const PublicKey* m_pubkey; + size_t m_length; + std::vector m_bn; + + BigNumber raw_add(const BigNumber& a, const BigNumber& b) const; + BigNumber raw_mul(const BigNumber& a, const BigNumber& b) const; + std::vector raw_mul(const std::vector& a, + const std::vector& b) const; +}; + +} // namespace ipcl +#endif // IPCL_INCLUDE_IPCL_OPS_HPP_ diff --git a/ipcl/include/ipcl/pri_key.hpp b/ipcl/include/ipcl/pri_key.hpp new file mode 100644 index 0000000..b3466eb --- /dev/null +++ b/ipcl/include/ipcl/pri_key.hpp @@ -0,0 +1,142 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IPCL_INCLUDE_IPCL_PRI_KEY_HPP_ +#define IPCL_INCLUDE_IPCL_PRI_KEY_HPP_ + +#include + +#include "ipcl/ops.hpp" + +namespace ipcl { + +class PrivateKey { + public: + /** + * PrivateKey constructor + * @param[in] public_key paillier public key + * @param[in] p p of private key in paillier scheme + * @param[in] q q of private key in paillier scheme + */ + PrivateKey(const PublicKey* public_key, const BigNumber& p, + const BigNumber& q); + + /** + * Enable Chinese Remainder Theorem + * @param[in] crt Apply Chinese Remainder Theorem + */ + void enableCRT(bool crt) { m_enable_crt = crt; } + + /** + * Decrypt ciphertext + * @param[out] plaintext output of the decryption + * @param[in] ciphertext ciphertext to be decrypted + */ + void decrypt(std::vector& plaintext, + const std::vector& ciphertext) const; + + /** + * Decrypt ciphertext + * @param[out] plaintext output of the decryption + * @param[in] ciphertext EncryptedNumber to be decrypted + */ + void decrypt(std::vector& plaintext, + const EncryptedNumber ciphertext) const; + + const void* addr = static_cast(this); + + /** + * Get N of public key in paillier scheme + */ + BigNumber getN() const { return m_n; } + + /** + * Get p of private key in paillier scheme + */ + BigNumber getP() const { return m_p; } + + /** + * Get q of private key in paillier scheme + */ + BigNumber getQ() const { return m_q; } + + /** + * Get bits of key + */ + int getBits() const { return m_bits; } + + /** + * Get public key + */ + const PublicKey* getPubKey() const { return m_pubkey; } + + /** + * @brief Support function for ISO/IEC 18033-6 compliance check + * + * @return BigNumber + */ + BigNumber getLambda() const { return m_lambda; } + + private: + const PublicKey* m_pubkey; + BigNumber m_n; + BigNumber m_nsquare; + BigNumber m_g; + BigNumber m_p; + BigNumber m_q; + BigNumber m_pminusone; + BigNumber m_qminusone; + BigNumber m_psquare; + BigNumber m_qsquare; + BigNumber m_pinverse; + BigNumber m_hp; + BigNumber m_hq; + BigNumber m_lambda; + BigNumber m_x; + int m_bits; + int m_dwords; + bool m_enable_crt; + + /** + * Compute L function in paillier scheme + * @param[in] a input a + * @param[in] b input b + * @return the L function result of type BigNumber + */ + BigNumber computeLfun(const BigNumber& a, const BigNumber& b) const; + + /** + * Compute H function in paillier scheme + * @param[in] a input a + * @param[in] b input b + * @return the H function result of type BigNumber + */ + BigNumber computeHfun(const BigNumber& a, const BigNumber& b) const; + + /** + * Compute CRT function in paillier scheme + * @param[in] mp input mp + * @param[in] mq input mq + * @return the CRT result of type BigNumber + */ + BigNumber computeCRT(const BigNumber& mp, const BigNumber& mq) const; + + /** + * Raw decryption function without CRT optimization + * @param[out] plaintext output plaintext + * @param[in] ciphertext input ciphertext + */ + void decryptRAW(std::vector& plaintext, + const std::vector& ciphertext) const; + + /** + * Raw decryption function with CRT optimization + * @param[out] plaintext output plaintext + * @param[in] ciphertext input ciphertext + */ + void decryptCRT(std::vector& plaintext, + const std::vector& ciphertext) const; +}; + +} // namespace ipcl +#endif // IPCL_INCLUDE_IPCL_PRI_KEY_HPP_ diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp new file mode 100644 index 0000000..61ae905 --- /dev/null +++ b/ipcl/include/ipcl/pub_key.hpp @@ -0,0 +1,143 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IPCL_INCLUDE_IPCL_PUB_KEY_HPP_ +#define IPCL_INCLUDE_IPCL_PUB_KEY_HPP_ + +#include + +#include "ipcl/bignum.h" + +namespace ipcl { + +class PublicKey { + public: + /** + * PublicKey constructor + * @param[in] n n of public key in paillier scheme + * @param[in] bits bit length of public key(default value is 1024) + * @param[in] enableDJN_ enables DJN scheme(default value is false) + */ + explicit PublicKey(const BigNumber& n, int bits = 1024, + bool enableDJN_ = false); + + /** + * PublicKey constructor + * @param[in] n n of public key in paillier scheme + * @param[in] bits bit length of public key(default value is 1024) + * @param[in] enableDJN_ enables DJN scheme(default value is false) + */ + explicit PublicKey(const Ipp32u n, int bits = 1024, bool enableDJN_ = false) + : PublicKey(BigNumber(n), bits, enableDJN_) {} + + /** + * DJN enabling function + */ + void enableDJN(); + + /** + * Encrypt plaintext + * @param[out] ciphertext output of the encryption + * @param[in] value array of plaintext to be encrypted + * @param[in] make_secure apply obfuscator(default value is true) + */ + void encrypt(std::vector& ciphertext, + const std::vector& value, + bool make_secure = true) const; + + /** + * Encrypt plaintext + * @param[out] ciphertext output of the encryption + * @param[in] value plaintext to be encrypted + */ + void encrypt(BigNumber& ciphertext, const BigNumber& value) const; + + /** + * Get N of public key in paillier scheme + */ + BigNumber getN() const { return m_n; } + + /** + * Get NSQ of public key in paillier scheme + */ + BigNumber getNSQ() const { return m_nsquare; } + + /** + * Get G of public key in paillier scheme + */ + BigNumber getG() const { return m_g; } + + /** + * Get bits of key + */ + int getBits() const { return m_bits; } + + /** + * Get Dword of key + */ + int getDwords() const { return m_dwords; } + + /** + * Apply obfuscator for ciphertext + * @param[out] obfuscator output of obfuscator with random value + */ + void applyObfuscator(std::vector& obfuscator) const; + + /** + * @brief Set the Random object for ISO/IEC 18033-6 compliance check + * + * @param r + */ + void setRandom(const std::vector& r); + + const void* addr = static_cast(this); + + private: + BigNumber m_n; + BigNumber m_g; + BigNumber m_nsquare; + BigNumber m_hs; + int m_bits; + int m_randbits; + int m_dwords; + unsigned int m_init_seed; + bool m_enable_DJN; + std::vector m_r; + bool m_testv; + + /** + * Get random value + * @param[in] size size of random + * @return addr of random of type Ipp32u vector + */ + std::vector randIpp32u(int size) const; + + /** + * Raw encrypt function + * @param[out] ciphertext array output of the encryption + * @param[in] plaintext plaintext array to be encrypted + * @param[in] make_secure apply obfuscator(default value is true) + */ + void raw_encrypt(std::vector& ciphertext, + const std::vector& plaintext, + bool make_secure = true) const; + // /** + // * Raw Multi-buffered modular exponentiation + // * @param[in] base array base of the exponentiation + // * @param[in] pow arrya pow of the exponentiation + // * @param[in] m arrayodular + // * @return result of the modular exponentiation of type BigNumber vector + // */ + // std::vector raw_ippMultiBuffExp( + // const std::vector& base, const std::vector& + // pow, const std::vector& m) const; + /** + * Get random value + * @param[in] length bit length + * @return the random value of type BigNumber + */ + BigNumber getRandom(int length) const; +}; + +} // namespace ipcl +#endif // IPCL_INCLUDE_IPCL_PUB_KEY_HPP_ diff --git a/ipcl/include/ipcl/util.hpp b/ipcl/include/ipcl/util.hpp index 488e2e1..8bd0356 100644 --- a/ipcl/include/ipcl/util.hpp +++ b/ipcl/include/ipcl/util.hpp @@ -5,8 +5,8 @@ #define IPCL_INCLUDE_IPCL_UTIL_HPP_ #include -#include #include +#include #include #include "ipcl/common.hpp" @@ -14,11 +14,9 @@ namespace ipcl { inline std::string build_log(const char* file, int line, - const std::string& msg) { + const std::string& msg) { std::ostringstream log; - log << "\nFile: " << file - << "\nLine: " << line - << "\nError: " << msg; + log << "\nFile: " << file << "\nLine: " << line << "\nError: " << msg; return log.str(); } diff --git a/ipcl/keygen.cpp b/ipcl/keygen.cpp new file mode 100644 index 0000000..9a8dcbf --- /dev/null +++ b/ipcl/keygen.cpp @@ -0,0 +1,108 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/keygen.hpp" + +#include +#include +#include + +#include "ipcl/util.hpp" + +namespace ipcl { + +constexpr int N_BIT_SIZE_MAX = 2048; + +static void rand32u(std::vector& addr) { + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + for (auto& x : addr) x = (dist(rng) << 16) + dist(rng); +} + +BigNumber getPrimeBN(int maxBitSize) { + int PrimeSize; + ippsPrimeGetSize(maxBitSize, &PrimeSize); + auto primeGen = std::vector(PrimeSize); + ippsPrimeInit(maxBitSize, reinterpret_cast(primeGen.data())); + + // define Pseudo Random Generator (default settings) + constexpr int seedBitSize = 160; + constexpr int seedSize = BITSIZE_WORD(seedBitSize); + + ippsPRNGGetSize(&PrimeSize); + auto rand = std::vector(PrimeSize); + ippsPRNGInit(seedBitSize, reinterpret_cast(rand.data())); + + auto seed = std::vector(seedSize); + rand32u(seed); + BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); + + ippsPRNGSetSeed(BN(bseed), reinterpret_cast(rand.data())); + + // generate maxBit prime + BigNumber pBN(0, maxBitSize / 8); + while (ippStsNoErr != + ippsPrimeGen_BN(pBN, maxBitSize, 10, + reinterpret_cast(primeGen.data()), + ippsPRNGen, + reinterpret_cast(rand.data()))) { + } + + return pBN; +} + +static void getNormalBN(int64_t n_length, BigNumber& p, BigNumber& q, + BigNumber& n) { + for (int64_t len = 0; len != n_length; len = n.BitSize()) { + p = getPrimeBN(n_length / 2); + q = p; + while (q == p) { + q = getPrimeBN(n_length / 2); + } + n = p * q; + } +} + +static void getDJNBN(int64_t n_length, BigNumber& p, BigNumber& q, + BigNumber& n) { + BigNumber gcd; + do { + do { + p = getPrimeBN(n_length / 2); + } while (!p.TestBit(1)); // get p: p mod 4 = 3 + + do { + q = getPrimeBN(n_length / 2); + } while (q == p || !p.TestBit(1)); // get q: q!=p and q mod 4 = 3 + + gcd = (p - 1).gcd(q - 1); // (p - 1) is a BigNumber + } while (gcd.compare(2)); // gcd(p-1,q-1)=2 + + n = p * q; +} + +keyPair generateKeypair(int64_t n_length, bool enable_DJN) { + /* + https://www.intel.com/content/www/us/en/develop/documentation/ipp-crypto-reference/top/multi-buffer-cryptography-functions/modular-exponentiation/mbx-exp-1024-2048-3072-4096-mb8.html + modulus size = n * n (keySize * keySize ) + */ + ERROR_CHECK( + n_length <= N_BIT_SIZE_MAX, + "generateKeyPair: modulus size in bits should belong to either 1Kb, 2Kb, " + "3Kb or 4Kb range only, key size exceed the range!!!"); + + BigNumber p, q, n; + + if (enable_DJN) + getDJNBN(n_length, p, q, n); + else + getNormalBN(n_length, p, q, n); + + PublicKey* public_key = new PublicKey(n, n_length, enable_DJN); + PrivateKey* private_key = new PrivateKey(public_key, p, q); + + return keyPair{public_key, private_key}; +} + +} // namespace ipcl diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index 5bb680c..ea1c41c 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -2,12 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 #include "ipcl/mod_exp.hpp" -#include "ipcl/util.hpp" #include #include +#include "ipcl/util.hpp" + namespace ipcl { static std::vector ippMBModExp(const std::vector& base, diff --git a/ipcl/ops.cpp b/ipcl/ops.cpp new file mode 100644 index 0000000..2deaf5d --- /dev/null +++ b/ipcl/ops.cpp @@ -0,0 +1,157 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/ops.hpp" + +#include + +#include "ipcl/mod_exp.hpp" + +namespace ipcl { +// constructors +// +EncryptedNumber::EncryptedNumber(const PublicKey* pub_key, const BigNumber& bn) + : b_isObfuscator(false), + m_available(1), + m_pubkey(pub_key), + m_length(1), + m_bn{bn} {} + +EncryptedNumber::EncryptedNumber(const PublicKey* pub_key, + const std::vector& bn, + size_t length) + : b_isObfuscator(false), + m_pubkey(pub_key), + m_available(IPCL_CRYPTO_MB_SIZE), + m_length(length), + m_bn{bn[0], bn[1], bn[2], bn[3], bn[4], bn[5], bn[6], bn[7]} {} + +EncryptedNumber::EncryptedNumber(const PublicKey* pub_key, + const std::vector& scalar, + size_t length) + : b_isObfuscator(false), + m_pubkey(pub_key), + m_available(IPCL_CRYPTO_MB_SIZE), + m_length(length), + m_bn{scalar[0], scalar[1], scalar[2], scalar[3], + scalar[4], scalar[5], scalar[6], scalar[7]} {} + +// CT+CT +EncryptedNumber EncryptedNumber::operator+(const EncryptedNumber& other) const { + ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), + "operator+: two different public keys detected!!"); + + const auto& a = *this; + const auto& b = other; + + if (m_available == 1) { + BigNumber sum = a.raw_add(a.m_bn.front(), b.m_bn.front()); + return EncryptedNumber(m_pubkey, sum); + } + std::vector sum(IPCL_CRYPTO_MB_SIZE); + for (int i = 0; i < m_available; i++) + sum[i] = a.raw_add(a.m_bn[i], b.m_bn[i]); + return EncryptedNumber(m_pubkey, sum); +} + +// CT+PT +EncryptedNumber EncryptedNumber::operator+(const BigNumber& other) const { + const auto& a = *this; + BigNumber b; + a.m_pubkey->encrypt(b, other); + + BigNumber sum = a.raw_add(a.m_bn.front(), b); + return EncryptedNumber(m_pubkey, sum); +} + +// multi encrypted CT+PT +EncryptedNumber EncryptedNumber::operator+( + const std::vector& other) const { + VEC_SIZE_CHECK(other); + + const auto& a = *this; + + std::vector b(IPCL_CRYPTO_MB_SIZE); + std::vector sum(IPCL_CRYPTO_MB_SIZE); + a.m_pubkey->encrypt(b, other, false); + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) + sum[i] = a.raw_add(a.m_bn[i], b[i]); + return EncryptedNumber(m_pubkey, sum); +} + +// CT*PT EncryptedNumber store a plaintext integer, not an encrypted +// integer +EncryptedNumber EncryptedNumber::operator*(const EncryptedNumber& other) const { + ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), + "operator*: two different public keys detected!!"); + + const auto& a = *this; + const auto& b = other; + + if (m_available == 1) { + BigNumber product = a.raw_mul(a.m_bn.front(), b.m_bn.front()); + return EncryptedNumber(m_pubkey, product); + } + + std::vector&& product = a.raw_mul(a.m_bn, b.m_bn); + return EncryptedNumber(m_pubkey, product); +} + +// CT*PT +EncryptedNumber EncryptedNumber::operator*(const BigNumber& other) const { + const auto& a = *this; + + BigNumber b = other; + BigNumber product = a.raw_mul(a.m_bn.front(), b); + return EncryptedNumber(m_pubkey, product); +} + +BigNumber EncryptedNumber::raw_add(const BigNumber& a, + const BigNumber& b) const { + // Hold a copy of nsquare for multi-threaded + const BigNumber& sq = m_pubkey->getNSQ(); + return a * b % sq; +} + +std::vector EncryptedNumber::raw_mul( + const std::vector& a, const std::vector& b) const { + std::vector sq(IPCL_CRYPTO_MB_SIZE, m_pubkey->getNSQ()); + return ipcl::ippModExp(a, b, sq); +} + +BigNumber EncryptedNumber::raw_mul(const BigNumber& a, + const BigNumber& b) const { + const BigNumber& sq = m_pubkey->getNSQ(); + return ipcl::ippModExp(a, b, sq); +} + +EncryptedNumber EncryptedNumber::rotate(int shift) const { + ERROR_CHECK(m_available != 1, "rotate: Cannot rotate single EncryptedNumber"); + ERROR_CHECK(shift >= -8 && shift <= 8, + "rotate: Cannot shift more than 8 or -8"); + + if (shift == 0 || shift == 8 || shift == -8) + return EncryptedNumber(m_pubkey, m_bn); + + if (shift > 0) + shift = 8 - shift; + else + shift = -shift; + + std::vector new_bn = getArrayBN(); + + std::rotate(std::begin(new_bn), std::begin(new_bn) + shift, std::end(new_bn)); + return EncryptedNumber(m_pubkey, new_bn); +} + +void EncryptedNumber::apply_obfuscator() { + b_isObfuscator = true; + std::vector obfuscator(IPCL_CRYPTO_MB_SIZE); + m_pubkey->applyObfuscator(obfuscator); + + BigNumber sq = m_pubkey->getNSQ(); + for (int i = 0; i < m_available; i++) + m_bn[i] = sq.ModMul(m_bn[i], obfuscator[i]); +} + +} // namespace ipcl diff --git a/ipcl/pri_key.cpp b/ipcl/pri_key.cpp new file mode 100644 index 0000000..083c708 --- /dev/null +++ b/ipcl/pri_key.cpp @@ -0,0 +1,140 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/pri_key.hpp" + +#include + +#include + +#include "ipcl/mod_exp.hpp" +#include "ipcl/util.hpp" + +namespace ipcl { +/** + * Compute lcm for p and q + * @param[in] p p - 1 of private key + * @param[in] q q - 1 of private key + * @return the lcm result of type BigNumber + */ +static inline BigNumber lcm(const BigNumber& p, const BigNumber& q) { + BigNumber gcd(p); + ippsGcd_BN(BN(p), BN(q), BN(gcd)); + return p * q / gcd; +} + +PrivateKey::PrivateKey(const PublicKey* public_key, const BigNumber& p, + const BigNumber& q) + : m_pubkey(public_key), + m_n(m_pubkey->getN()), + m_nsquare(m_pubkey->getNSQ()), + m_g(m_pubkey->getG()), + m_p((q < p) ? q : p), + m_q((q < p) ? p : q), + m_pminusone(m_p - 1), + m_qminusone(m_q - 1), + m_psquare(m_p * m_p), + m_qsquare(m_q * m_q), + m_pinverse(m_q.InverseMul(m_p)), + m_hp(computeHfun(m_p, m_psquare)), + m_hq(computeHfun(m_q, m_qsquare)), + // lcm(P-1,Q-1) = (P-1)*(Q-1)/gcd(P-1,Q-1), gcd in ipp-crypto is + // ippsGcd_BN + m_lambda(lcm(m_pminusone, m_qminusone)), + // TODO(bwang30): check if ippsModInv_BN does the same thing with + // mpz_invert + m_x(m_n.InverseMul((ipcl::ippModExp(m_g, m_lambda, m_nsquare) - 1) / + m_n)), + m_bits(m_pubkey->getBits()), + m_dwords(m_pubkey->getDwords()), + m_enable_crt(true) { + ERROR_CHECK(p * q == m_n, + "PrivateKey ctor: Public key does not match p * q."); + ERROR_CHECK(p != q, "PrivateKey ctor: p and q are same"); +} + +void PrivateKey::decryptRAW(std::vector& plaintext, + const std::vector& ciphertext) const { + std::vector pow_lambda(IPCL_CRYPTO_MB_SIZE, m_lambda); + std::vector modulo(IPCL_CRYPTO_MB_SIZE, m_nsquare); + std::vector res = ipcl::ippModExp(ciphertext, pow_lambda, modulo); + + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + BigNumber m = (res[i] - 1) / m_n; + m *= m_x; + plaintext[i] = m % m_n; + } +} + +void PrivateKey::decrypt(std::vector& plaintext, + const std::vector& ciphertext) const { + VEC_SIZE_CHECK(plaintext); + VEC_SIZE_CHECK(ciphertext); + + if (m_enable_crt) + decryptCRT(plaintext, ciphertext); + else + decryptRAW(plaintext, ciphertext); +} + +void PrivateKey::decrypt(std::vector& plaintext, + const EncryptedNumber ciphertext) const { + VEC_SIZE_CHECK(plaintext); + // check key match + ERROR_CHECK(ciphertext.getPK().getN() == m_pubkey->getN(), + "decrypt: public key mismatch error."); + + const std::vector& res = ciphertext.getArrayBN(); + if (m_enable_crt) + decryptCRT(plaintext, res); + else + decryptRAW(plaintext, res); +} + +// CRT to calculate base^exp mod n^2 +void PrivateKey::decryptCRT(std::vector& plaintext, + const std::vector& ciphertext) const { + std::vector basep(IPCL_CRYPTO_MB_SIZE), baseq(IPCL_CRYPTO_MB_SIZE); + std::vector pm1(IPCL_CRYPTO_MB_SIZE, m_pminusone), + qm1(IPCL_CRYPTO_MB_SIZE, m_qminusone); + std::vector psq(IPCL_CRYPTO_MB_SIZE, m_psquare), + qsq(IPCL_CRYPTO_MB_SIZE, m_qsquare); + + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + basep[i] = ciphertext[i] % psq[i]; + baseq[i] = ciphertext[i] % qsq[i]; + } + + // Based on the fact a^b mod n = (a mod n)^b mod n + std::vector resp = ipcl::ippModExp(basep, pm1, psq); + std::vector resq = ipcl::ippModExp(baseq, qm1, qsq); + + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + BigNumber dp = computeLfun(resp[i], m_p) * m_hp % m_p; + BigNumber dq = computeLfun(resq[i], m_q) * m_hq % m_q; + plaintext[i] = computeCRT(dp, dq); + } +} + +BigNumber PrivateKey::computeCRT(const BigNumber& mp, + const BigNumber& mq) const { + BigNumber u = (mq - mp) * m_pinverse % m_q; + return mp + (u * m_p); +} + +BigNumber PrivateKey::computeLfun(const BigNumber& a, + const BigNumber& b) const { + return (a - 1) / b; +} + +BigNumber PrivateKey::computeHfun(const BigNumber& a, + const BigNumber& b) const { + // Based on the fact a^b mod n = (a mod n)^b mod n + BigNumber xm = a - 1; + BigNumber base = m_g % b; + BigNumber pm = ipcl::ippModExp(base, xm, b); + BigNumber lcrt = computeLfun(pm, a); + return a.InverseMul(lcrt); +} + +} // namespace ipcl diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp new file mode 100644 index 0000000..f3d347b --- /dev/null +++ b/ipcl/pub_key.cpp @@ -0,0 +1,186 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/pub_key.hpp" + +#include + +#include +#include +#include +#include + +#ifdef IPCL_CRYPTO_OMP +#include +#endif + +#include "ipcl/mod_exp.hpp" +#include "ipcl/util.hpp" + +namespace ipcl { + +static inline auto randomUniformUnsignedInt() { + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + return dist(rng); +} + +PublicKey::PublicKey(const BigNumber& n, int bits, bool enableDJN_) + : m_n(n), + m_g(n + 1), + m_nsquare(n * n), + m_bits(bits), + m_dwords(BITSIZE_DWORD(bits * 2)), + m_init_seed(randomUniformUnsignedInt()), + m_enable_DJN(false), + m_testv(false) { + if (enableDJN_) this->enableDJN(); // sets m_enable_DJN +} + +// array of 32-bit random, using rand() from stdlib +std::vector PublicKey::randIpp32u(int size) const { + std::vector addr(size); + // TODO(skmono): check if copy of m_init_seed is needed for const + unsigned int init_seed = m_init_seed; + for (auto& a : addr) a = (rand_r(&init_seed) << 16) + rand_r(&init_seed); + return addr; +} + +// length is arbitrary +BigNumber PublicKey::getRandom(int length) const { + IppStatus stat; + int size; + constexpr int seedBitSize = 160; + constexpr int seedSize = BITSIZE_WORD(seedBitSize); + + stat = ippsPRNGGetSize(&size); + ERROR_CHECK(stat == ippStsNoErr, + "getRandom: get IppsPRNGState context error."); + + auto rands = std::vector(size); + + stat = + ippsPRNGInit(seedBitSize, reinterpret_cast(rands.data())); + ERROR_CHECK(stat == ippStsNoErr, "getRandom: init rand context error."); + + auto seed = randIpp32u(seedSize); + BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); + + stat = ippsPRNGSetSeed(BN(bseed), + reinterpret_cast(rands.data())); + ERROR_CHECK(stat == ippStsNoErr, "getRandom: set up seed value error."); + + // define length Big Numbers + int bn_size = BITSIZE_WORD(length); + stat = ippsBigNumGetSize(bn_size, &size); + ERROR_CHECK(stat == ippStsNoErr, + "getRandom: get IppsBigNumState context error."); + + IppsBigNumState* pBN = reinterpret_cast(alloca(size)); + ERROR_CHECK(pBN != nullptr, "getRandom: big number alloca error"); + + stat = ippsBigNumInit(bn_size, pBN); + ERROR_CHECK(stat == ippStsNoErr, "getRandom: init big number context error."); + + int bnBitSize = length; + ippsPRNGenRDRAND_BN(pBN, bnBitSize, + reinterpret_cast(rands.data())); + + return BigNumber{pBN}; +} + +void PublicKey::enableDJN() { + BigNumber gcd; + BigNumber rmod; + do { + int rand_bit = m_n.BitSize(); + BigNumber rand = getRandom(rand_bit + 128); + rmod = rand % m_n; + gcd = rand.gcd(m_n); + } while (gcd.compare(1)); + + BigNumber rmod_sq = rmod * rmod; + BigNumber rmod_neg = rmod_sq * -1; + BigNumber h = rmod_neg % m_n; + m_hs = ipcl::ippModExp(h, m_n, m_nsquare); + m_randbits = m_bits >> 1; // bits/2 + + m_enable_DJN = true; +} + +void PublicKey::applyObfuscator(std::vector& obfuscator) const { + std::vector r(IPCL_CRYPTO_MB_SIZE); + std::vector pown(IPCL_CRYPTO_MB_SIZE, m_n); + std::vector base(IPCL_CRYPTO_MB_SIZE, m_hs); + std::vector sq(IPCL_CRYPTO_MB_SIZE, m_nsquare); + + VEC_SIZE_CHECK(obfuscator); + + if (m_enable_DJN) { + for (auto& r_ : r) { + r_ = getRandom(m_randbits); + } + obfuscator = ipcl::ippModExp(base, r, sq); + } else { + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + if (m_testv) { + r[i] = m_r[i]; + } else { + r[i] = getRandom(m_bits); + r[i] = r[i] % (m_n - 1) + 1; + } + pown[i] = m_n; + sq[i] = m_nsquare; + } + obfuscator = ipcl::ippModExp(r, pown, sq); + } +} + +void PublicKey::setRandom(const std::vector& r) { + VEC_SIZE_CHECK(r); + + std::copy(r.begin(), r.end(), std::back_inserter(m_r)); + m_testv = true; +} + +void PublicKey::raw_encrypt(std::vector& ciphertext, + const std::vector& plaintext, + bool make_secure) const { + // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 + BigNumber sq = m_nsquare; + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + BigNumber bn(plaintext[i]); + ciphertext[i] = (m_n * bn + 1) % sq; + } + + if (make_secure) { + std::vector obfuscator(IPCL_CRYPTO_MB_SIZE); + applyObfuscator(obfuscator); + + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) + ciphertext[i] = sq.ModMul(ciphertext[i], obfuscator[i]); + } +} + +void PublicKey::encrypt(std::vector& ciphertext, + const std::vector& value, + bool make_secure) const { + VEC_SIZE_CHECK(ciphertext); + VEC_SIZE_CHECK(value); + + raw_encrypt(ciphertext, value, make_secure); +} + +// Used for CT+PT, where PT do not need to add obfuscator +void PublicKey::encrypt(BigNumber& ciphertext, const BigNumber& value) const { + // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 + ciphertext = (m_n * value + 1) % m_nsquare; + + /*----- Path to caculate (n+1)^plaintext mod n^2 ------------ + BigNumber bn(value); + ciphertext = ippMontExp(m_g, bn, m_nsquare); + ---------------------------------------------------------- */ +} + +} // namespace ipcl diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index c0cfe75..931b0ac 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -11,8 +11,8 @@ #endif // IPCL_USE_OMP #include "gtest/gtest.h" -#include "ipcl/paillier_keygen.hpp" -#include "ipcl/paillier_ops.hpp" +#include "ipcl/keygen.hpp" +#include "ipcl/ops.hpp" TEST(CryptoTest, CryptoTest) { ipcl::keyPair key = ipcl::generateKeypair(2048, true); @@ -124,10 +124,8 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { ipcl::BigNumber n = p * q; int n_length = n.BitSize(); - ipcl::PaillierPublicKey* public_key = - new ipcl::PaillierPublicKey(n, n_length); - ipcl::PaillierPrivateKey* private_key = - new ipcl::PaillierPrivateKey(public_key, p, q); + ipcl::PublicKey* public_key = new ipcl::PublicKey(n, n_length); + ipcl::PrivateKey* private_key = new ipcl::PrivateKey(public_key, p, q); ipcl::keyPair key = {public_key, private_key}; @@ -219,9 +217,9 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { key.pub_key->encrypt(ct, ptbn); - ipcl::PaillierEncryptedNumber a(key.pub_key, ct[0]); - ipcl::PaillierEncryptedNumber b(key.pub_key, ct[1]); - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber a(key.pub_key, ct[0]); + ipcl::EncryptedNumber b(key.pub_key, ct[1]); + ipcl::EncryptedNumber sum = a + b; ipcl::BigNumber res = sum.getBN(); std::vector ct12(8); diff --git a/test/test_ops.cpp b/test/test_ops.cpp index c2ab740..c7a830a 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -11,17 +11,17 @@ #endif // IPCL_USE_OMP #include "gtest/gtest.h" -#include "ipcl/paillier_keygen.hpp" -#include "ipcl/paillier_ops.hpp" +#include "ipcl/keygen.hpp" +#include "ipcl/ops.hpp" void CtPlusCt(std::vector& res, const std::vector& ct1, const std::vector& ct2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); - ipcl::PaillierEncryptedNumber b(key.pub_key, ct2[i]); - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber a(key.pub_key, ct1[i]); + ipcl::EncryptedNumber b(key.pub_key, ct2[i]); + ipcl::EncryptedNumber sum = a + b; res[i] = sum.getBN(); } } @@ -30,9 +30,9 @@ void CtPlusCtArray(std::vector& res, const std::vector& ct1, const std::vector& ct2, const ipcl::keyPair key) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1); - ipcl::PaillierEncryptedNumber b(key.pub_key, ct2); - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber a(key.pub_key, ct1); + ipcl::EncryptedNumber b(key.pub_key, ct2); + ipcl::EncryptedNumber sum = a + b; res = sum.getArrayBN(); } @@ -40,9 +40,9 @@ void CtPlusPt(std::vector& res, const std::vector& ct1, const std::vector& pt2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); + ipcl::EncryptedNumber a(key.pub_key, ct1[i]); ipcl::BigNumber b = pt2[i]; - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber sum = a + b; res[i] = sum.getBN(); } } @@ -51,8 +51,8 @@ void CtPlusPtArray(std::vector& res, const std::vector& ct1, const std::vector& ptbn2, const ipcl::keyPair key) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1); - ipcl::PaillierEncryptedNumber sum = a + ptbn2; + ipcl::EncryptedNumber a(key.pub_key, ct1); + ipcl::EncryptedNumber sum = a + ptbn2; res = sum.getArrayBN(); } @@ -60,9 +60,9 @@ void CtMultiplyPt(std::vector& res, const std::vector& ct1, const std::vector& pt2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); - ipcl::PaillierEncryptedNumber b(key.pub_key, pt2[i]); - ipcl::PaillierEncryptedNumber sum = a * b; + ipcl::EncryptedNumber a(key.pub_key, ct1[i]); + ipcl::EncryptedNumber b(key.pub_key, pt2[i]); + ipcl::EncryptedNumber sum = a * b; res[i] = sum.getBN(); } } @@ -71,9 +71,9 @@ void CtMultiplyPtArray(std::vector& res, const std::vector& ct1, const std::vector& pt2, const ipcl::keyPair key) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1); - ipcl::PaillierEncryptedNumber b(key.pub_key, pt2); - ipcl::PaillierEncryptedNumber sum = a * b; + ipcl::EncryptedNumber a(key.pub_key, ct1); + ipcl::EncryptedNumber b(key.pub_key, pt2); + ipcl::EncryptedNumber sum = a * b; res = sum.getArrayBN(); } @@ -81,11 +81,11 @@ void AddSub(std::vector& res, const std::vector& ct1, const std::vector& ct2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); - ipcl::PaillierEncryptedNumber b(key.pub_key, ct2[i]); + ipcl::EncryptedNumber a(key.pub_key, ct1[i]); + ipcl::EncryptedNumber b(key.pub_key, ct2[i]); ipcl::BigNumber m1(2); a = a + b * m1; - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber sum = a + b; res[i] = sum.getBN(); } } @@ -418,9 +418,9 @@ void CtPlusCt_OMP(int num_threads, #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); - ipcl::PaillierEncryptedNumber b(key.pub_key, v_ct2[i][j]); - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); + ipcl::EncryptedNumber b(key.pub_key, v_ct2[i][j]); + ipcl::EncryptedNumber sum = a + b; v_sum[i][j] = sum.getBN(); } } @@ -435,8 +435,8 @@ void CtPlusPt_OMP(int num_threads, for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { ipcl::BigNumber b = v_pt2[i][j]; - ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); + ipcl::EncryptedNumber sum = a + b; v_sum[i][j] = sum.getBN(); } } @@ -449,12 +449,12 @@ void CtPlusPtArray_OMP(int num_threads, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); + ipcl::EncryptedNumber a(key.pub_key, v_ct1[i]); std::vector b(8); for (int j = 0; j < 8; j++) { b[j] = v_pt2[i][j]; } - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber sum = a + b; v_sum[i] = sum.getArrayBN(); } } @@ -467,9 +467,9 @@ void CtMultiplyPt_OMP(int num_threads, #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); + ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); ipcl::BigNumber b = v_pt2[i][j]; - ipcl::PaillierEncryptedNumber product = a * b; + ipcl::EncryptedNumber product = a * b; v_product[i][j] = product.getBN(); } } @@ -481,9 +481,9 @@ void CtMultiplyPtArray_OMP( const std::vector>& v_pt2, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); - ipcl::PaillierEncryptedNumber b(key.pub_key, v_pt2[i]); - ipcl::PaillierEncryptedNumber product = a * b; + ipcl::EncryptedNumber a(key.pub_key, v_ct1[i]); + ipcl::EncryptedNumber b(key.pub_key, v_pt2[i]); + ipcl::EncryptedNumber product = a * b; v_product[i] = product.getArrayBN(); } } From 7b76a16adc4a39c0158f19ed4f96ab1d6838f33a Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Fri, 11 Mar 2022 16:00:10 -0800 Subject: [PATCH 109/364] Removed old files --- ipcl/include/ipcl/paillier_keygen.hpp | 37 ----- ipcl/include/ipcl/paillier_ops.hpp | 135 ------------------ ipcl/include/ipcl/paillier_prikey.hpp | 142 ------------------- ipcl/include/ipcl/paillier_pubkey.hpp | 144 ------------------- ipcl/paillier_keygen.cpp | 109 --------------- ipcl/paillier_ops.cpp | 162 ---------------------- ipcl/paillier_prikey.cpp | 144 ------------------- ipcl/paillier_pubkey.cpp | 190 -------------------------- 8 files changed, 1063 deletions(-) delete mode 100644 ipcl/include/ipcl/paillier_keygen.hpp delete mode 100644 ipcl/include/ipcl/paillier_ops.hpp delete mode 100644 ipcl/include/ipcl/paillier_prikey.hpp delete mode 100644 ipcl/include/ipcl/paillier_pubkey.hpp delete mode 100644 ipcl/paillier_keygen.cpp delete mode 100644 ipcl/paillier_ops.cpp delete mode 100644 ipcl/paillier_prikey.cpp delete mode 100644 ipcl/paillier_pubkey.cpp diff --git a/ipcl/include/ipcl/paillier_keygen.hpp b/ipcl/include/ipcl/paillier_keygen.hpp deleted file mode 100644 index e3dd6b3..0000000 --- a/ipcl/include/ipcl/paillier_keygen.hpp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#ifndef IPCL_INCLUDE_IPCL_PAILLIER_KEYGEN_HPP_ -#define IPCL_INCLUDE_IPCL_PAILLIER_KEYGEN_HPP_ - -#include "ipcl/paillier_prikey.hpp" - -namespace ipcl { - -/** - * Paillier key structure contains a public key and private key - * pub_key: paillier public key - * priv_key: paillier private key - */ -struct keyPair { - PaillierPublicKey* pub_key; - PaillierPrivateKey* priv_key; -}; - -/** - * Generate prime number - * @param[in] maxBitSize Maximum bit length of to be generated prime number - * @return The function return a prime big number - */ -BigNumber getPrimeBN(int maxBitSize); - -/** - * Generate a public/private key pair - * @param[in] n_length Bit length of key size - * @param[in] enable_DJN Enable DJN (default=true) - * @return The function return the public and private key pair - */ -keyPair generateKeypair(int64_t n_length, bool enable_DJN = true); - -} // namespace ipcl -#endif // IPCL_INCLUDE_IPCL_PAILLIER_KEYGEN_HPP_ diff --git a/ipcl/include/ipcl/paillier_ops.hpp b/ipcl/include/ipcl/paillier_ops.hpp deleted file mode 100644 index 4fbb84b..0000000 --- a/ipcl/include/ipcl/paillier_ops.hpp +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#ifndef IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ -#define IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ - -#include - -#include "ipcl/paillier_pubkey.hpp" -#include "ipcl/util.hpp" - -namespace ipcl { - -class PaillierEncryptedNumber { - public: - /** - * PaillierEncryptedNumber constructor - * @param[in] pub_key paillier public key - * @param[in] bn ciphertext encrypted by paillier public key - */ - PaillierEncryptedNumber(const PaillierPublicKey* pub_key, - const BigNumber& bn); - - /** - * PaillierEncryptedNumber constructor - * @param[in] pub_key paillier public key - * @param[in] bn array of ciphertexts encrypted by paillier public key - * @param[in] length size of array(default value is IPCL_CRYPTO_MB_SIZE) - */ - PaillierEncryptedNumber(const PaillierPublicKey* pub_key, - const std::vector& bn, - size_t length = IPCL_CRYPTO_MB_SIZE); - - /** - * PaillierEncryptedNumber constructor - * @param[in] pub_key paillier public key - * @param[in] scalar array of integer scalars - * @param[in] length size of array(default value is IPCL_CRYPTO_MB_SIZE) - */ - PaillierEncryptedNumber(const PaillierPublicKey* pub_key, - const std::vector& scalar, - size_t length = IPCL_CRYPTO_MB_SIZE); - - /** - * Arithmetic addition operator - * @param[in] bn augend - */ - PaillierEncryptedNumber operator+(const PaillierEncryptedNumber& bn) const; - - /** - * Arithmetic addition operator - * @param[in] other augend - */ - PaillierEncryptedNumber operator+(const BigNumber& other) const; - - /** - * Arithmetic addition operator - * @param[in] other array of augend - */ - PaillierEncryptedNumber operator+(const std::vector& other) const; - - /** - * Arithmetic multiply operator - * @param[in] bn multiplicand - */ - PaillierEncryptedNumber operator*(const PaillierEncryptedNumber& bn) const; - - /** - * Arithmetic multiply operator - * @param[in] other multiplicand - */ - PaillierEncryptedNumber operator*(const BigNumber& other) const; - - /** - * Apply obfuscator for ciphertext, obfuscated needed only when the ciphertext - * is exposed - */ - void applyObfuscator(); - - /** - * Return ciphertext - * @param[in] idx index of ciphertext stored in PaillierEncryptedNumber - * (default = 0) - */ - BigNumber getBN(size_t idx = 0) const { - ERROR_CHECK(m_available != 1 || idx <= 0, - "getBN: PaillierEncryptedNumber only has 1 BigNumber"); - - return m_bn[idx]; - } - - /** - * Get public key - */ - PaillierPublicKey getPK() const { return *m_pubkey; } - - /** - * Rotate PaillierEncryptedNumber - * @param[in] shift rotate length - */ - PaillierEncryptedNumber rotate(int shift) const; - - /** - * Return entire ciphertext array - * @param[out] bn output array - */ - std::vector getArrayBN() const { return m_bn; } - - /** - * Check if element in PaillierEncryptedNumber is single - */ - bool isSingle() const { return m_available == 1; } - - /** - * Get size of array in PaillierEncryptedNumber - */ - size_t getLength() const { return m_length; } - - const void* addr = static_cast(this); - - private: - bool b_isObfuscator; - int m_available; - const PaillierPublicKey* m_pubkey; - size_t m_length; - std::vector m_bn; - - BigNumber raw_add(const BigNumber& a, const BigNumber& b) const; - BigNumber raw_mul(const BigNumber& a, const BigNumber& b) const; - std::vector raw_mul(const std::vector& a, - const std::vector& b) const; -}; - -} // namespace ipcl -#endif // IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ diff --git a/ipcl/include/ipcl/paillier_prikey.hpp b/ipcl/include/ipcl/paillier_prikey.hpp deleted file mode 100644 index 5ecfc3d..0000000 --- a/ipcl/include/ipcl/paillier_prikey.hpp +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#ifndef IPCL_INCLUDE_IPCL_PAILLIER_PRIKEY_HPP_ -#define IPCL_INCLUDE_IPCL_PAILLIER_PRIKEY_HPP_ - -#include - -#include "ipcl/paillier_ops.hpp" - -namespace ipcl { - -class PaillierPrivateKey { - public: - /** - * PaillierPrivateKey constructor - * @param[in] public_key paillier public key - * @param[in] p p of private key in paillier scheme - * @param[in] q q of private key in paillier scheme - */ - PaillierPrivateKey(const PaillierPublicKey* public_key, const BigNumber& p, - const BigNumber& q); - - /** - * Enable Chinese Remainder Theorem - * @param[in] crt Apply Chinese Remainder Theorem - */ - void enableCRT(bool crt) { m_enable_crt = crt; } - - /** - * Decrypt ciphertext - * @param[out] plaintext output of the decryption - * @param[in] ciphertext ciphertext to be decrypted - */ - void decrypt(std::vector& plaintext, - const std::vector& ciphertext) const; - - /** - * Decrypt ciphertext - * @param[out] plaintext output of the decryption - * @param[in] ciphertext PaillierEncryptedNumber to be decrypted - */ - void decrypt(std::vector& plaintext, - const PaillierEncryptedNumber ciphertext) const; - - const void* addr = static_cast(this); - - /** - * Get N of public key in paillier scheme - */ - BigNumber getN() const { return m_n; } - - /** - * Get p of private key in paillier scheme - */ - BigNumber getP() const { return m_p; } - - /** - * Get q of private key in paillier scheme - */ - BigNumber getQ() const { return m_q; } - - /** - * Get bits of key - */ - int getBits() const { return m_bits; } - - /** - * Get public key - */ - const PaillierPublicKey* getPubKey() const { return m_pubkey; } - - /** - * @brief Support function for ISO/IEC 18033-6 compliance check - * - * @return BigNumber - */ - BigNumber getLambda() const { return m_lambda; } - - private: - const PaillierPublicKey* m_pubkey; - BigNumber m_n; - BigNumber m_nsquare; - BigNumber m_g; - BigNumber m_p; - BigNumber m_q; - BigNumber m_pminusone; - BigNumber m_qminusone; - BigNumber m_psquare; - BigNumber m_qsquare; - BigNumber m_pinverse; - BigNumber m_hp; - BigNumber m_hq; - BigNumber m_lambda; - BigNumber m_x; - int m_bits; - int m_dwords; - bool m_enable_crt; - - /** - * Compute L function in paillier scheme - * @param[in] a input a - * @param[in] b input b - * @return the L function result of type BigNumber - */ - BigNumber computeLfun(const BigNumber& a, const BigNumber& b) const; - - /** - * Compute H function in paillier scheme - * @param[in] a input a - * @param[in] b input b - * @return the H function result of type BigNumber - */ - BigNumber computeHfun(const BigNumber& a, const BigNumber& b) const; - - /** - * Compute CRT function in paillier scheme - * @param[in] mp input mp - * @param[in] mq input mq - * @return the CRT result of type BigNumber - */ - BigNumber computeCRT(const BigNumber& mp, const BigNumber& mq) const; - - /** - * Raw decryption function without CRT optimization - * @param[out] plaintext output plaintext - * @param[in] ciphertext input ciphertext - */ - void decryptRAW(std::vector& plaintext, - const std::vector& ciphertext) const; - - /** - * Raw decryption function with CRT optimization - * @param[out] plaintext output plaintext - * @param[in] ciphertext input ciphertext - */ - void decryptCRT(std::vector& plaintext, - const std::vector& ciphertext) const; -}; - -} // namespace ipcl -#endif // IPCL_INCLUDE_IPCL_PAILLIER_PRIKEY_HPP_ diff --git a/ipcl/include/ipcl/paillier_pubkey.hpp b/ipcl/include/ipcl/paillier_pubkey.hpp deleted file mode 100644 index 228e107..0000000 --- a/ipcl/include/ipcl/paillier_pubkey.hpp +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#ifndef IPCL_INCLUDE_IPCL_PAILLIER_PUBKEY_HPP_ -#define IPCL_INCLUDE_IPCL_PAILLIER_PUBKEY_HPP_ - -#include - -#include "ipcl/bignum.h" - -namespace ipcl { - -class PaillierPublicKey { - public: - /** - * PaillierPublicKey constructor - * @param[in] n n of public key in paillier scheme - * @param[in] bits bit length of public key(default value is 1024) - * @param[in] enableDJN_ enables DJN scheme(default value is false) - */ - explicit PaillierPublicKey(const BigNumber& n, int bits = 1024, - bool enableDJN_ = false); - - /** - * PaillierPublicKey constructor - * @param[in] n n of public key in paillier scheme - * @param[in] bits bit length of public key(default value is 1024) - * @param[in] enableDJN_ enables DJN scheme(default value is false) - */ - explicit PaillierPublicKey(const Ipp32u n, int bits = 1024, - bool enableDJN_ = false) - : PaillierPublicKey(BigNumber(n), bits, enableDJN_) {} - - /** - * DJN enabling function - */ - void enableDJN(); - - /** - * Encrypt plaintext - * @param[out] ciphertext output of the encryption - * @param[in] value array of plaintext to be encrypted - * @param[in] make_secure apply obfuscator(default value is true) - */ - void encrypt(std::vector& ciphertext, - const std::vector& value, - bool make_secure = true) const; - - /** - * Encrypt plaintext - * @param[out] ciphertext output of the encryption - * @param[in] value plaintext to be encrypted - */ - void encrypt(BigNumber& ciphertext, const BigNumber& value) const; - - /** - * Get N of public key in paillier scheme - */ - BigNumber getN() const { return m_n; } - - /** - * Get NSQ of public key in paillier scheme - */ - BigNumber getNSQ() const { return m_nsquare; } - - /** - * Get G of public key in paillier scheme - */ - BigNumber getG() const { return m_g; } - - /** - * Get bits of key - */ - int getBits() const { return m_bits; } - - /** - * Get Dword of key - */ - int getDwords() const { return m_dwords; } - - /** - * Apply obfuscator for ciphertext - * @param[out] obfuscator output of obfuscator with random value - */ - void applyObfuscator(std::vector& obfuscator) const; - - /** - * @brief Set the Random object for ISO/IEC 18033-6 compliance check - * - * @param r - */ - void setRandom(const std::vector& r); - - const void* addr = static_cast(this); - - private: - BigNumber m_n; - BigNumber m_g; - BigNumber m_nsquare; - BigNumber m_hs; - int m_bits; - int m_randbits; - int m_dwords; - unsigned int m_init_seed; - bool m_enable_DJN; - std::vector m_r; - bool m_testv; - - /** - * Get random value - * @param[in] size size of random - * @return addr of random of type Ipp32u vector - */ - std::vector randIpp32u(int size) const; - - /** - * Raw encrypt function - * @param[out] ciphertext array output of the encryption - * @param[in] plaintext plaintext array to be encrypted - * @param[in] make_secure apply obfuscator(default value is true) - */ - void raw_encrypt(std::vector& ciphertext, - const std::vector& plaintext, - bool make_secure = true) const; - // /** - // * Raw Multi-buffered modular exponentiation - // * @param[in] base array base of the exponentiation - // * @param[in] pow arrya pow of the exponentiation - // * @param[in] m arrayodular - // * @return result of the modular exponentiation of type BigNumber vector - // */ - // std::vector raw_ippMultiBuffExp( - // const std::vector& base, const std::vector& - // pow, const std::vector& m) const; - /** - * Get random value - * @param[in] length bit length - * @return the random value of type BigNumber - */ - BigNumber getRandom(int length) const; -}; - -} // namespace ipcl -#endif // IPCL_INCLUDE_IPCL_PAILLIER_PUBKEY_HPP_ diff --git a/ipcl/paillier_keygen.cpp b/ipcl/paillier_keygen.cpp deleted file mode 100644 index 22d95b0..0000000 --- a/ipcl/paillier_keygen.cpp +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include "ipcl/paillier_keygen.hpp" - -#include -#include -#include - -#include "ipcl/util.hpp" - -namespace ipcl { - -constexpr int N_BIT_SIZE_MAX = 2048; - -static void rand32u(std::vector& addr) { - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - for (auto& x : addr) x = (dist(rng) << 16) + dist(rng); -} - -BigNumber getPrimeBN(int maxBitSize) { - int PrimeSize; - ippsPrimeGetSize(maxBitSize, &PrimeSize); - auto primeGen = std::vector(PrimeSize); - ippsPrimeInit(maxBitSize, reinterpret_cast(primeGen.data())); - - // define Pseudo Random Generator (default settings) - constexpr int seedBitSize = 160; - constexpr int seedSize = BITSIZE_WORD(seedBitSize); - - ippsPRNGGetSize(&PrimeSize); - auto rand = std::vector(PrimeSize); - ippsPRNGInit(seedBitSize, reinterpret_cast(rand.data())); - - auto seed = std::vector(seedSize); - rand32u(seed); - BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); - - ippsPRNGSetSeed(BN(bseed), reinterpret_cast(rand.data())); - - // generate maxBit prime - BigNumber pBN(0, maxBitSize / 8); - while (ippStsNoErr != - ippsPrimeGen_BN(pBN, maxBitSize, 10, - reinterpret_cast(primeGen.data()), - ippsPRNGen, - reinterpret_cast(rand.data()))) { - } - - return pBN; -} - -static void getNormalBN(int64_t n_length, BigNumber& p, BigNumber& q, - BigNumber& n) { - for (int64_t len = 0; len != n_length; len = n.BitSize()) { - p = getPrimeBN(n_length / 2); - q = p; - while (q == p) { - q = getPrimeBN(n_length / 2); - } - n = p * q; - } -} - -static void getDJNBN(int64_t n_length, BigNumber& p, BigNumber& q, - BigNumber& n) { - BigNumber gcd; - do { - do { - p = getPrimeBN(n_length / 2); - } while (!p.TestBit(1)); // get p: p mod 4 = 3 - - do { - q = getPrimeBN(n_length / 2); - } while (q == p || !p.TestBit(1)); // get q: q!=p and q mod 4 = 3 - - gcd = (p - 1).gcd(q -1); // (p - 1) is a BigNumer - } while (gcd.compare(2)); // gcd(p-1,q-1)=2 - - n = p * q; -} - -keyPair generateKeypair(int64_t n_length, bool enable_DJN) { - /* - https://www.intel.com/content/www/us/en/develop/documentation/ipp-crypto-reference/top/multi-buffer-cryptography-functions/modular-exponentiation/mbx-exp-1024-2048-3072-4096-mb8.html - modulus size = n * n (keySize * keySize ) - */ - ERROR_CHECK( - n_length <= N_BIT_SIZE_MAX, - "generateKeyPair: modulus size in bits should belong to either 1Kb, 2Kb, " - "3Kb or 4Kb range only, key size exceed the range!!!"); - - BigNumber p, q, n; - - if (enable_DJN) - getDJNBN(n_length, p, q, n); - else - getNormalBN(n_length, p, q, n); - - PaillierPublicKey* public_key = - new PaillierPublicKey(n, n_length, enable_DJN); - PaillierPrivateKey* private_key = new PaillierPrivateKey(public_key, p, q); - - return keyPair{public_key, private_key}; -} - -} // namespace ipcl diff --git a/ipcl/paillier_ops.cpp b/ipcl/paillier_ops.cpp deleted file mode 100644 index fd28835..0000000 --- a/ipcl/paillier_ops.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include "ipcl/paillier_ops.hpp" -#include "ipcl/mod_exp.hpp" - -#include - -namespace ipcl { -// constructors -// -PaillierEncryptedNumber::PaillierEncryptedNumber( - const PaillierPublicKey* pub_key, const BigNumber& bn) - : b_isObfuscator(false), - m_available(1), - m_pubkey(pub_key), - m_length(1), - m_bn{bn} {} - -PaillierEncryptedNumber::PaillierEncryptedNumber( - const PaillierPublicKey* pub_key, const std::vector& bn, - size_t length) - : b_isObfuscator(false), - m_pubkey(pub_key), - m_available(IPCL_CRYPTO_MB_SIZE), - m_length(length), - m_bn{bn[0], bn[1], bn[2], bn[3], bn[4], bn[5], bn[6], bn[7]} {} - -PaillierEncryptedNumber::PaillierEncryptedNumber( - const PaillierPublicKey* pub_key, const std::vector& scalar, - size_t length) - : b_isObfuscator(false), - m_pubkey(pub_key), - m_available(IPCL_CRYPTO_MB_SIZE), - m_length(length), - m_bn{scalar[0], scalar[1], scalar[2], scalar[3], - scalar[4], scalar[5], scalar[6], scalar[7]} {} - -// CT+CT -PaillierEncryptedNumber PaillierEncryptedNumber::operator+( - const PaillierEncryptedNumber& other) const { - ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), - "operator+: two different public keys detected!!"); - - const auto& a = *this; - const auto& b = other; - - if (m_available == 1) { - BigNumber sum = a.raw_add(a.m_bn.front(), b.m_bn.front()); - return PaillierEncryptedNumber(m_pubkey, sum); - } - - std::vector sum(IPCL_CRYPTO_MB_SIZE); - for (int i = 0; i < m_available; i++) - sum[i] = a.raw_add(a.m_bn[i], b.m_bn[i]); - return PaillierEncryptedNumber(m_pubkey, sum); -} - -// CT+PT -PaillierEncryptedNumber PaillierEncryptedNumber::operator+( - const BigNumber& other) const { - const auto& a = *this; - BigNumber b; - a.m_pubkey->encrypt(b, other); - - BigNumber sum = a.raw_add(a.m_bn.front(), b); - return PaillierEncryptedNumber(m_pubkey, sum); -} - -// multi encrypted CT+PT -PaillierEncryptedNumber PaillierEncryptedNumber::operator+( - const std::vector& other) const { - VEC_SIZE_CHECK(other); - - const auto& a = *this; - - std::vector b(IPCL_CRYPTO_MB_SIZE); - std::vector sum(IPCL_CRYPTO_MB_SIZE); - a.m_pubkey->encrypt(b, other, false); - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) - sum[i] = a.raw_add(a.m_bn[i], b[i]); - return PaillierEncryptedNumber(m_pubkey, sum); -} - -// CT*PT PaillierEncryptedNumber store a plaintext integer, not an encrypted -// integer -PaillierEncryptedNumber PaillierEncryptedNumber::operator*( - const PaillierEncryptedNumber& other) const { - ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), - "operator*: two different public keys detected!!"); - - const auto& a = *this; - const auto& b = other; - - if (m_available == 1) { - BigNumber product = a.raw_mul(a.m_bn.front(), b.m_bn.front()); - return PaillierEncryptedNumber(m_pubkey, product); - } - - std::vector product = a.raw_mul(a.m_bn, b.m_bn); - return PaillierEncryptedNumber(m_pubkey, product); -} - -// CT*PT -PaillierEncryptedNumber PaillierEncryptedNumber::operator*( - const BigNumber& other) const { - const auto& a = *this; - - BigNumber product = a.raw_mul(a.m_bn.front(), other); - return PaillierEncryptedNumber(m_pubkey, product); -} - -BigNumber PaillierEncryptedNumber::raw_add(const BigNumber& a, - const BigNumber& b) const { - // Hold a copy of nsquare for multi-threaded - const BigNumber& sq = m_pubkey->getNSQ(); - return a * b % sq; -} - -std::vector PaillierEncryptedNumber::raw_mul( - const std::vector& a, const std::vector& b) const { - std::vector sq(IPCL_CRYPTO_MB_SIZE, m_pubkey->getNSQ()); - return ipcl::ippModExp(a, b, sq); -} - -BigNumber PaillierEncryptedNumber::raw_mul(const BigNumber& a, - const BigNumber& b) const { - const BigNumber& sq = m_pubkey->getNSQ(); - return ipcl::ippModExp(a, b, sq); -} - -PaillierEncryptedNumber PaillierEncryptedNumber::rotate(int shift) const { - ERROR_CHECK(m_available != 1, - "rotate: Cannot rotate single PaillierEncryptedNumber"); - ERROR_CHECK(shift >= -8 && shift <= 8, - "rotate: Cannot shift more than 8 or -8"); - - if (shift == 0 || shift == 8 || shift == -8) - return PaillierEncryptedNumber(m_pubkey, m_bn); - - if (shift > 0) - shift = 8 - shift; - else - shift = -shift; - - std::vector new_bn = getArrayBN(); - - std::rotate(std::begin(new_bn), std::begin(new_bn) + shift, std::end(new_bn)); - return PaillierEncryptedNumber(m_pubkey, new_bn); -} - -void PaillierEncryptedNumber::applyObfuscator() { - b_isObfuscator = true; - std::vector obfuscator(IPCL_CRYPTO_MB_SIZE); - m_pubkey->applyObfuscator(obfuscator); - - const BigNumber& sq = m_pubkey->getNSQ(); - for (int i = 0; i < m_available; i++) - m_bn[i] = sq.ModMul(m_bn[i], obfuscator[i]); -} - -} // namespace ipcl diff --git a/ipcl/paillier_prikey.cpp b/ipcl/paillier_prikey.cpp deleted file mode 100644 index 0763726..0000000 --- a/ipcl/paillier_prikey.cpp +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include "ipcl/paillier_prikey.hpp" - -#include - -#include - -#include "ipcl/mod_exp.hpp" -#include "ipcl/util.hpp" - -namespace ipcl { -/** - * Compute lcm for p and q - * @param[in] p p - 1 of private key - * @param[in] q q - 1 of private key - * @return the lcm result of type BigNumber - */ -static inline BigNumber lcm(const BigNumber& p, const BigNumber& q) { - BigNumber gcd(p); - ippsGcd_BN(BN(p), BN(q), BN(gcd)); - return p * q / gcd; -} - -PaillierPrivateKey::PaillierPrivateKey(const PaillierPublicKey* public_key, - const BigNumber& p, const BigNumber& q) - : m_pubkey(public_key), - m_n(m_pubkey->getN()), - m_nsquare(m_pubkey->getNSQ()), - m_g(m_pubkey->getG()), - m_p((q < p) ? q : p), - m_q((q < p) ? p : q), - m_pminusone(m_p - 1), - m_qminusone(m_q - 1), - m_psquare(m_p * m_p), - m_qsquare(m_q * m_q), - m_pinverse(m_q.InverseMul(m_p)), - m_hp(computeHfun(m_p, m_psquare)), - m_hq(computeHfun(m_q, m_qsquare)), - // lcm(P-1,Q-1) = (P-1)*(Q-1)/gcd(P-1,Q-1), gcd in ipp-crypto is - // ippsGcd_BN - m_lambda(lcm(m_pminusone, m_qminusone)), - // TODO(bwang30): check if ippsModInv_BN does the same thing with - // mpz_invert - m_x(m_n.InverseMul((ipcl::ippModExp(m_g, m_lambda, m_nsquare) - 1) / - m_n)), - m_bits(m_pubkey->getBits()), - m_dwords(m_pubkey->getDwords()), - m_enable_crt(true) { - ERROR_CHECK(p * q == m_n, - "PaillierPrivateKey ctor: Public key does not match p * q."); - ERROR_CHECK(p != q, "PaillierPrivateKey ctor: p and q are same"); -} - -void PaillierPrivateKey::decryptRAW( - std::vector& plaintext, - const std::vector& ciphertext) const { - std::vector pow_lambda(IPCL_CRYPTO_MB_SIZE, m_lambda); - std::vector modulo(IPCL_CRYPTO_MB_SIZE, m_nsquare); - std::vector res = ipcl::ippModExp(ciphertext, pow_lambda, modulo); - - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - BigNumber m = (res[i] - 1) / m_n; - m *= m_x; - plaintext[i] = m % m_n; - } -} - -void PaillierPrivateKey::decrypt( - std::vector& plaintext, - const std::vector& ciphertext) const { - VEC_SIZE_CHECK(plaintext); - VEC_SIZE_CHECK(ciphertext); - - if (m_enable_crt) - decryptCRT(plaintext, ciphertext); - else - decryptRAW(plaintext, ciphertext); -} - -void PaillierPrivateKey::decrypt( - std::vector& plaintext, - const PaillierEncryptedNumber ciphertext) const { - VEC_SIZE_CHECK(plaintext); - // check key match - ERROR_CHECK(ciphertext.getPK().getN() == m_pubkey->getN(), - "decrypt: public key mismatch error."); - - const std::vector& res = ciphertext.getArrayBN(); - if (m_enable_crt) - decryptCRT(plaintext, res); - else - decryptRAW(plaintext, res); -} - -// CRT to calculate base^exp mod n^2 -void PaillierPrivateKey::decryptCRT( - std::vector& plaintext, - const std::vector& ciphertext) const { - std::vector basep(IPCL_CRYPTO_MB_SIZE), baseq(IPCL_CRYPTO_MB_SIZE); - std::vector pm1(IPCL_CRYPTO_MB_SIZE, m_pminusone), - qm1(IPCL_CRYPTO_MB_SIZE, m_qminusone); - std::vector psq(IPCL_CRYPTO_MB_SIZE, m_psquare), - qsq(IPCL_CRYPTO_MB_SIZE, m_qsquare); - - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - basep[i] = ciphertext[i] % psq[i]; - baseq[i] = ciphertext[i] % qsq[i]; - } - - // Based on the fact a^b mod n = (a mod n)^b mod n - std::vector resp = ipcl::ippModExp(basep, pm1, psq); - std::vector resq = ipcl::ippModExp(baseq, qm1, qsq); - - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - BigNumber dp = computeLfun(resp[i], m_p) * m_hp % m_p; - BigNumber dq = computeLfun(resq[i], m_q) * m_hq % m_q; - plaintext[i] = computeCRT(dp, dq); - } -} - -BigNumber PaillierPrivateKey::computeCRT(const BigNumber& mp, - const BigNumber& mq) const { - BigNumber u = (mq - mp) * m_pinverse % m_q; - return mp + (u * m_p); -} - -BigNumber PaillierPrivateKey::computeLfun(const BigNumber& a, - const BigNumber& b) const { - return (a - 1) / b; -} - -BigNumber PaillierPrivateKey::computeHfun(const BigNumber& a, - const BigNumber& b) const { - // Based on the fact a^b mod n = (a mod n)^b mod n - BigNumber xm = a - 1; - BigNumber base = m_g % b; - BigNumber pm = ipcl::ippModExp(base, xm, b); - BigNumber lcrt = computeLfun(pm, a); - return a.InverseMul(lcrt); -} - -} // namespace ipcl diff --git a/ipcl/paillier_pubkey.cpp b/ipcl/paillier_pubkey.cpp deleted file mode 100644 index 67747c4..0000000 --- a/ipcl/paillier_pubkey.cpp +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include "ipcl/paillier_pubkey.hpp" - -#include - -#include -#include -#include -#include - -#ifdef IPCL_CRYPTO_OMP -#include -#endif - -#include "ipcl/mod_exp.hpp" -#include "ipcl/util.hpp" - -namespace ipcl { - -static inline auto randomUniformUnsignedInt() { - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - return dist(rng); -} - -PaillierPublicKey::PaillierPublicKey(const BigNumber& n, int bits, - bool enableDJN_) - : m_n(n), - m_g(n + 1), - m_nsquare(n * n), - m_bits(bits), - m_dwords(BITSIZE_DWORD(bits * 2)), - m_init_seed(randomUniformUnsignedInt()), - m_enable_DJN(false), - m_testv(false) { - if (enableDJN_) this->enableDJN(); // sets m_enable_DJN -} - -// array of 32-bit random, using rand() from stdlib -std::vector PaillierPublicKey::randIpp32u(int size) const { - std::vector addr(size); - // TODO(skmono): check if copy of m_init_seed is needed for const - unsigned int init_seed = m_init_seed; - for (auto& a : addr) a = (rand_r(&init_seed) << 16) + rand_r(&init_seed); - return addr; -} - -// length is arbitrary -BigNumber PaillierPublicKey::getRandom(int length) const { - IppStatus stat; - int size; - constexpr int seedBitSize = 160; - constexpr int seedSize = BITSIZE_WORD(seedBitSize); - - stat = ippsPRNGGetSize(&size); - ERROR_CHECK(stat == ippStsNoErr, - "getRandom: get IppsPRNGState context error."); - - auto rands = std::vector(size); - - stat = - ippsPRNGInit(seedBitSize, reinterpret_cast(rands.data())); - ERROR_CHECK(stat == ippStsNoErr, "getRandom: init rand context error."); - - auto seed = randIpp32u(seedSize); - BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); - - stat = ippsPRNGSetSeed(BN(bseed), - reinterpret_cast(rands.data())); - ERROR_CHECK(stat == ippStsNoErr, "getRandom: set up seed value error."); - - // define length Big Numbers - int bn_size = BITSIZE_WORD(length); - stat = ippsBigNumGetSize(bn_size, &size); - ERROR_CHECK(stat == ippStsNoErr, - "getRandom: get IppsBigNumState context error."); - - IppsBigNumState* pBN = reinterpret_cast(alloca(size)); - ERROR_CHECK(pBN != nullptr, "getRandom: big number alloca error"); - - stat = ippsBigNumInit(bn_size, pBN); - ERROR_CHECK(stat == ippStsNoErr, "getRandom: init big number context error."); - - int bnBitSize = length; - ippsPRNGenRDRAND_BN(pBN, bnBitSize, - reinterpret_cast(rands.data())); - - return BigNumber{pBN}; -} - -void PaillierPublicKey::enableDJN() { - BigNumber gcd; - BigNumber rmod; - do { - int rand_bit = m_n.BitSize(); - BigNumber rand = getRandom(rand_bit + 128); - rmod = rand % m_n; - gcd = rand.gcd(m_n); - } while (gcd.compare(1)); - - BigNumber rmod_sq = rmod * rmod; - BigNumber rmod_neg = rmod_sq * -1; - BigNumber h = rmod_neg % m_n; - m_hs = ipcl::ippModExp(h, m_n, m_nsquare); - m_randbits = m_bits >> 1; // bits/2 - - m_enable_DJN = true; -} - -void PaillierPublicKey::applyObfuscator( - std::vector& obfuscator) const { - - std::vector r(IPCL_CRYPTO_MB_SIZE); - std::vector pown(IPCL_CRYPTO_MB_SIZE, m_n); - std::vector base(IPCL_CRYPTO_MB_SIZE, m_hs); - std::vector sq(IPCL_CRYPTO_MB_SIZE, m_nsquare); - - VEC_SIZE_CHECK(obfuscator); - - if (m_enable_DJN) { - for (auto& r_ : r) { - r_ = getRandom(m_randbits); - } - obfuscator = ipcl::ippModExp(base, r, sq); - } else { - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - if (m_testv) { - r[i] = m_r[i]; - } else { - r[i] = getRandom(m_bits); - r[i] = r[i] % (m_n - 1) + 1; - } - pown[i] = m_n; - sq[i] = m_nsquare; - } - obfuscator = ipcl::ippModExp(r, pown, sq); - } -} - -void PaillierPublicKey::setRandom(const std::vector& r) { - VEC_SIZE_CHECK(r); - - std::copy(r.begin(), r.end(), std::back_inserter(m_r)); - m_testv = true; -} - -void PaillierPublicKey::raw_encrypt(std::vector& ciphertext, - const std::vector& plaintext, - bool make_secure) const { - // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 - BigNumber sq = m_nsquare; - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - BigNumber bn(plaintext[i]); - ciphertext[i] = (m_n * bn + 1) % sq; - } - - if (make_secure) { - std::vector obfuscator(IPCL_CRYPTO_MB_SIZE); - applyObfuscator(obfuscator); - - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) - ciphertext[i] = sq.ModMul(ciphertext[i], obfuscator[i]); - } -} - -void PaillierPublicKey::encrypt(std::vector& ciphertext, - const std::vector& value, - bool make_secure) const { - VEC_SIZE_CHECK(ciphertext); - VEC_SIZE_CHECK(value); - - raw_encrypt(ciphertext, value, make_secure); -} - -// Used for CT+PT, where PT do not need to add obfuscator -void PaillierPublicKey::encrypt(BigNumber& ciphertext, - const BigNumber& value) const { - // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 - ciphertext = (m_n * value + 1) % m_nsquare; - - /*----- Path to caculate (n+1)^plaintext mod n^2 ------------ - BigNumber bn(value); - ciphertext = ippMontExp(m_g, bn, m_nsquare); - ---------------------------------------------------------- */ -} - -} // namespace ipcl From 7126bb92e38817eb0a5ad26448996a680d25b535 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 11 Mar 2022 20:21:46 -0800 Subject: [PATCH 110/364] Replace examples for samples. --- example/README.md | 7 +++ examples/CMakeLists.txt | 29 ----------- samples/CMakeLists.txt | 49 +++++++++++++++++++ {examples => samples}/test_bnConversion.cpp | 14 +++--- .../test_bnModExpPerformOp.c | 0 {examples => samples}/test_context.c | 0 6 files changed, 63 insertions(+), 36 deletions(-) create mode 100644 example/README.md delete mode 100644 examples/CMakeLists.txt create mode 100644 samples/CMakeLists.txt rename {examples => samples}/test_bnConversion.cpp (96%) rename {examples => samples}/test_bnModExpPerformOp.c (100%) rename {examples => samples}/test_context.c (100%) diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..9bd68d2 --- /dev/null +++ b/example/README.md @@ -0,0 +1,7 @@ +# Building and running + +``` +cmake -S . -B build -DCMAKE_PREFIX_PATH=../install/lib/cmake +cmake --build build +./build/example +``` diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt deleted file mode 100644 index 8ef0881..0000000 --- a/examples/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ - -if(HE_QAT_DEBUG) - add_definitions(-D_DESTINY_DEBUG_VERBOSE) -endif() - -add_executable(test_context test_context.c) -target_include_directories(test_context PUBLIC ${COMMON_INC_DIR}) -target_include_directories(test_context PUBLIC ${ICP_INC_DIR}) -target_link_libraries(test_context PUBLIC he_qat) -#target_link_libraries(test_context PUBLIC cpa_sample_utils) -target_link_libraries(test_context PUBLIC z pthread ssl crypto qat_s usdm_drv_s) - -add_executable(test_bnModExpPerformOp test_bnModExpPerformOp.c) -target_include_directories(test_bnModExpPerformOp PUBLIC ${COMMON_INC_DIR}) # ${HE_QAT_UTILS_INC_DIR}) -target_include_directories(test_bnModExpPerformOp PUBLIC ${ICP_INC_DIR}) -target_link_libraries(test_bnModExpPerformOp PUBLIC he_qat) -#target_link_libraries(test_bnModExpPerformOp PUBLIC cpa_sample_utils) -target_link_libraries(test_bnModExpPerformOp PUBLIC z pthread ssl crypto qat_s usdm_drv_s) - -if(HE_QAT_MISC) - add_compile_options(-fpermissive) - add_executable(test_bnConversion test_bnConversion.cpp) - target_include_directories(test_bnConversion PUBLIC ${COMMON_INC_DIR}) - target_include_directories(test_bnConversion PUBLIC ${ICP_INC_DIR}) - target_include_directories(test_bnConversion PUBLIC ${HE_QAT_MISC_INC_DIR}) - target_link_libraries(test_bnConversion PUBLIC he_qat) - target_link_libraries(test_bnConversion PUBLIC he_qat_misc IPPCP::ippcp IPPCP::crypto_mb) - target_link_libraries(test_bnConversion PUBLIC z OpenSSL::SSL Threads::Threads qat_s usdm_drv_s) -endif() diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt new file mode 100644 index 0000000..7938585 --- /dev/null +++ b/samples/CMakeLists.txt @@ -0,0 +1,49 @@ + +if(HE_QAT_DEBUG) + add_definitions(-D_DESTINY_DEBUG_VERBOSE) +endif() + +# ------------------------------------------------------------------------------------------- + +add_executable(test_context test_context.c) + +target_include_directories(test_context PUBLIC ${COMMON_INC_DIR}) +#target_include_directories(test_context PUBLIC ${HE_QAT_INC_DIR}) +target_include_directories(test_context PUBLIC ${ICP_INC_DIR}) + +target_link_libraries(test_context PUBLIC he_qat) + +install(TARGETS test_context RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + +# ------------------------------------------------------------------------------------------- + +add_executable(test_bnModExpPerformOp test_bnModExpPerformOp.c) + +target_include_directories(test_bnModExpPerformOp PUBLIC ${COMMON_INC_DIR}) # ${HE_QAT_UTILS_INC_DIR}) +#target_include_directories(test_bnModExpPerformOp PUBLIC ${HE_QAT_INC_DIR}) +target_include_directories(test_bnModExpPerformOp PUBLIC ${ICP_INC_DIR}) + +target_link_libraries(test_bnModExpPerformOp PUBLIC he_qat) +target_link_libraries(test_bnModExpPerformOp PUBLIC OpenSSL::SSL) # OpenSSL::Crypto) +target_link_libraries(test_bnModExpPerformOp PUBLIC IPPCP::ippcp) + +install(TARGETS test_bnModExpPerformOp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + +# ------------------------------------------------------------------------------------------- + +if(HE_QAT_MISC) + add_compile_options(-fpermissive) + + add_executable(test_bnConversion test_bnConversion.cpp) + + target_include_directories(test_bnConversion PUBLIC ${COMMON_INC_DIR}) + target_include_directories(test_bnConversion PUBLIC ${ICP_INC_DIR}) + target_include_directories(test_bnConversion PUBLIC ${HE_QAT_MISC_INC_DIR}) + + target_link_libraries(test_bnConversion PUBLIC he_qat) + target_link_libraries(test_bnConversion PUBLIC he_qat_misc) + target_link_libraries(test_bnConversion PUBLIC IPPCP::ippcp) # IPPCP::crypto_mb) + target_link_libraries(test_bnConversion PUBLIC OpenSSL::SSL) # OpenSSL::Crypto) + + install(TARGETS test_bnConversion RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +endif() diff --git a/examples/test_bnConversion.cpp b/samples/test_bnConversion.cpp similarity index 96% rename from examples/test_bnConversion.cpp rename to samples/test_bnConversion.cpp index efac502..6282951 100644 --- a/examples/test_bnConversion.cpp +++ b/samples/test_bnConversion.cpp @@ -5,22 +5,22 @@ #include "he_qat_context.h" #include "cpa_sample_utils.h" -#ifdef __cplusplus -extern "C" { -#endif +//#ifdef __cplusplus +//extern "C" { +//#endif #include #include #include #include -#ifdef __cplusplus -} -#endif +//#ifdef __cplusplus +//} +//#endif #include -#include "ippcp.h" +//#include "ippcp.h" #include int main(int argc, const char** argv) { diff --git a/examples/test_bnModExpPerformOp.c b/samples/test_bnModExpPerformOp.c similarity index 100% rename from examples/test_bnModExpPerformOp.c rename to samples/test_bnModExpPerformOp.c diff --git a/examples/test_context.c b/samples/test_context.c similarity index 100% rename from examples/test_context.c rename to samples/test_context.c From 1432655e2c0d833cec141d5786e099d1dcb28b7f Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 11 Mar 2022 20:23:41 -0800 Subject: [PATCH 111/364] Add toy example for demonstration on how to use it as 3rd party. --- example/CMakeLists.txt | 25 +++++ example/example.cpp | 207 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 232 insertions(+) create mode 100644 example/CMakeLists.txt create mode 100644 example/example.cpp diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt new file mode 100644 index 0000000..388f815 --- /dev/null +++ b/example/CMakeLists.txt @@ -0,0 +1,25 @@ +project(he_qat_example LANGUAGES C CXX) + +cmake_minimum_required(VERSION 3.13) + +set(CMAKE_CXX_STANDARD 11) +set(HE_QAT_HINT_DIR ${CMAKE_PREFIX_PATH}) +message(STATUS "CMAKE_PREFIX_PATH ${HE_QAT_HINT_DIR}") +# Example using source +find_package(HE_QAT 0.1.0 + HINTS ${HE_QAT_HINT_DIR} + REQUIRED) +if (NOT TARGET HE_QAT::he_qat) + message(FATAL_ERROR "TARGET HE_QAT::he_qat not found") +endif() + +find_package(OpenSSL REQUIRED) + +include(../icp/CMakeLists.txt) + +add_definitions(-fpermissive) +add_executable(example example.cpp) +target_include_directories(example PRIVATE ${ICP_INC_DIR}) +target_link_libraries(example PRIVATE HE_QAT::he_qat) +target_link_libraries(example PRIVATE qat_s) +target_link_libraries(example PRIVATE OpenSSL::SSL) diff --git a/example/example.cpp b/example/example.cpp new file mode 100644 index 0000000..e4a6294 --- /dev/null +++ b/example/example.cpp @@ -0,0 +1,207 @@ + +#include "he_qat_bn_ops.h" +#include "he_qat_context.h" +#include "cpa_sample_utils.h" + +#include +#include +#include +#include + +#define LEN_OF_1024_BITS 128 +#define LEN_OF_2048_BITS 256 +#define msb_CAN_BE_ZERO -1 +#define msb_IS_ONE 0 +#define EVEN_RND_NUM 0 +#define ODD_RND_NUM 1 +#define BATCH_SIZE 1 + +BIGNUM* generateTestBNData(int nbits) { + if (!RAND_status()) return NULL; +#ifdef _DESTINY_DEBUG_VERBOSE + printf("PRNG properly seeded.\n"); +#endif + + BIGNUM* bn = BN_new(); + + if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { + BN_free(bn); + printf("Error while generating BN random number: %lu\n", + ERR_get_error()); + return NULL; + } + + return bn; +} + +unsigned char* paddingZeros(BIGNUM* bn, int nbits) { + if (!bn) return NULL; + + // Returns same address if it fails + int num_bytes = BN_num_bytes(bn); + int bytes_left = nbits / 8 - num_bytes; + if (bytes_left <= 0) return NULL; + + // Returns same address if it fails + unsigned char* bin = NULL; + int len = bytes_left + num_bytes; + if (!(bin = OPENSSL_zalloc(len))) return NULL; + +#ifdef _DESTINY_DEBUG_VERBOSE + printf("Padding bn with %d bytes to total %d bytes\n", bytes_left, len); +#endif + BN_bn2binpad(bn, bin, len); + if (ERR_get_error()) { + OPENSSL_free(bin); + return NULL; + } + + return bin; +} + +void showHexBN(BIGNUM* bn, int nbits) { + int len = nbits / 8; + unsigned char* bin = OPENSSL_zalloc(len); + if (!bin) return; + if (BN_bn2binpad(bn, bin, len)) { + for (size_t i = 0; i < len; i++) printf("%d", bin[i]); + printf("\n"); + } + OPENSSL_free(bin); + return; +} + +void showHexBin(unsigned char* bin, int len) { + if (!bin) return; + for (size_t i = 0; i < len; i++) printf("%d", bin[i]); + printf("\n"); + return; +} + +int main(int argc, const char** argv) { + const int bit_length = 4096; // 1024; + const size_t num_trials = 100; + + double avg_speed_up = 0.0; + double ssl_avg_time = 0.0; + double qat_avg_time = 0.0; + + clock_t start = CLOCKS_PER_SEC; + clock_t ssl_elapsed = CLOCKS_PER_SEC; + clock_t qat_elapsed = CLOCKS_PER_SEC; + + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + // Set up QAT runtime context + acquire_qat_devices(); + + // Set up OpenSSL context (as baseline) + BN_CTX* ctx = BN_CTX_new(); + BN_CTX_start(ctx); + + for (size_t mod = 0; mod < num_trials; mod++) { + BIGNUM* bn_mod = generateTestBNData(bit_length); + + if (!bn_mod) continue; + +#ifdef _DESTINY_DEBUG_VERBOSE + char* bn_str = BN_bn2hex(bn_mod); + printf("Generated modulus: %s num_bytes: %d num_bits: %d\n", bn_str, + BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); + OPENSSL_free(bn_str); +#endif + // bn_exponent in [0..bn_mod] + BIGNUM* bn_exponent = BN_new(); + if (!BN_rand_range(bn_exponent, bn_mod)) { + BN_free(bn_mod); + continue; + } + + BIGNUM* bn_base = generateTestBNData(bit_length); + + // Perform OpenSSL ModExp Op + BIGNUM* ssl_res = BN_new(); + start = clock(); + BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); + ssl_elapsed = clock() - start; + + if (!ERR_get_error()) { +#ifdef _DESTINY_DEBUG_VERBOSE + bn_str = BN_bn2hex(ssl_res); + printf("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", bn_str, + BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); + showHexBN(ssl_res, bit_length); + OPENSSL_free(bn_str); +#endif + } else { + printf("Modular exponentiation failed.\n"); + } + +#ifdef _DESTINY_DEBUG_VERBOSE + PRINT_DBG("\nStarting QAT bnModExp...\n"); +#endif + + // printf("OpenSSL: %.1lfus\t", ssl_elapsed / (CLOCKS_PER_SEC / + // 1000000.0)); + + // Perform QAT ModExp Op + BIGNUM* qat_res = BN_new(); + start = clock(); + for (unsigned int j = 0; j < BATCH_SIZE; j++) + status = bnModExpPerformOp(qat_res, bn_base, bn_exponent, bn_mod, + bit_length); + getBnModExpRequest(BATCH_SIZE); + qat_elapsed = clock() - start; + + ssl_avg_time = (mod * ssl_avg_time + + (ssl_elapsed / (CLOCKS_PER_SEC / 1000000.0))) / + (mod + 1); + qat_avg_time = + (mod * qat_avg_time + + (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0)) / BATCH_SIZE) / + (mod + 1); + avg_speed_up = + (mod * avg_speed_up + + (ssl_elapsed / (CLOCKS_PER_SEC / 1000000.0)) / + ((qat_elapsed / (CLOCKS_PER_SEC / 1000000.0)) / BATCH_SIZE)) / + (mod + 1); + + printf( + "Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", + (mod + 1), ssl_avg_time, qat_avg_time, avg_speed_up); + + // printf("QAT: %.1lfus\t", qat_elapsed / (CLOCKS_PER_SEC / + // 1000000.0)); printf("Speed Up: %.1lfx\t", (ssl_elapsed / + // (CLOCKS_PER_SEC / 1000000.0) / BATCH_SIZE) / (qat_elapsed / + // (CLOCKS_PER_SEC / 1000000.0) / BATCH_SIZE) ); + + if (HE_QAT_STATUS_SUCCESS != status) { + PRINT_ERR("\nQAT bnModExpOp failed\n"); + } +#ifdef _DESTINY_DEBUG_VERBOSE + else { + PRINT_DBG("\nQAT bnModExpOp finished\n"); + } +#endif + + if (BN_cmp(qat_res, ssl_res) != 0) + printf("\t** FAIL **\n"); + else + printf("\t** PASS **\n"); + + BN_free(ssl_res); + BN_free(qat_res); + + BN_free(bn_mod); + BN_free(bn_base); + BN_free(bn_exponent); + } + + // Tear down OpenSSL context + BN_CTX_end(ctx); + + // Tear down QAT runtime context + release_qat_devices(); + + return (int)status; +} From e37f8a08f5fe959b28ac78a718484a2f2b319ca5 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 11 Mar 2022 20:24:37 -0800 Subject: [PATCH 112/364] Refactor and update build system. --- CMakeLists.txt | 21 ++++++++++++++++++--- common/CMakeLists.txt | 8 ++++---- he_qat/CMakeLists.txt | 27 ++++++++++++--------------- 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a76c987..a330763 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,7 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) option(HE_QAT_MISC "Enable miscellaneous features" ON) option(HE_QAT_TEST "Enable testing" OFF) -option(HE_QAT_EXAMPLES "Enable examples" ON) +option(HE_QAT_SAMPLES "Enable examples" ON) option(HE_QAT_BENCHMARK "Enable benchmark" OFF) option(HE_QAT_DOCS "Enable document building" OFF) option(HE_QAT_SHARED "Build shared library" ON) @@ -76,6 +76,19 @@ set(HE_QAT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) set(HE_QAT_SRC_DIR ${HE_QAT_ROOT_DIR}/he_qat) set(HE_QAT_INC_DIR ${HE_QAT_ROOT_DIR}/he_qat/include) +set(HE_QAT_FORWARD_CMAKE_ARGS + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} + -DCMAKE_CXX_STANDARD_REQUIRED=${CMAKE_CXX_STANDARD_REQUIRED} + -DCMAKE_CXX_EXTENSIONS=${CMAKE_CXX_EXTENSIONS} + -DCMAKE_EXPORT_COMPILE_COMMANDS=${CMAKE_EXPORT_COMPILE_COMMANDS} + -DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE} + -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} +) + + #OpenSSL installation find_package(OpenSSL REQUIRED) @@ -86,6 +99,8 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) #set(OPENSSL_INC_DIR /opt/openssl/include) #set(OPENSSL_LIB_DIR /opt/openssl/lib) +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/he_qat) + set(COMMON_INC_DIR ${CMAKE_CURRENT_LIST_DIR}/include) if(NOT CMAKE_INSTALL_PREFIX) set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_LIST_DIR}/install) @@ -124,8 +139,8 @@ if(HE_QAT_BENCHMARK) endif() #Validation test examples -if(HE_QAT_EXAMPLES) - add_subdirectory(examples) +if(HE_QAT_SAMPLES) + add_subdirectory(samples) endif() if(HE_QAT_TEST) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index b100dc6..226e0fc 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -12,14 +12,14 @@ set(COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/cpa_sample_utils.c) add_library(cpa_sample_utils ${COMMON_SRC}) target_include_directories(cpa_sample_utils PUBLIC $ # Public headers - PUBLIC $ # Public headers + # PUBLIC $ # Public headers PUBLIC $ # Public headers PRIVATE ${COMMON_INC_DIR} # Private headers PRIVATE ${ICP_INC_DIR} # Private headers ) -target_link_libraries(cpa_sample_utils PRIVATE udev pthread crypto z) -target_link_libraries(cpa_sample_utils PUBLIC ${ICP_BUILDOUTPUT_PATH}/libqat_s.so) -target_link_libraries(cpa_sample_utils PUBLIC ${ICP_BUILDOUTPUT_PATH}/libusdm_drv_s.so) +target_link_libraries(cpa_sample_utils PRIVATE udev z) +target_link_libraries(cpa_sample_utils PRIVATE ${ICP_BUILDOUTPUT_PATH}/libqat_s.so) +target_link_libraries(cpa_sample_utils PRIVATE ${ICP_BUILDOUTPUT_PATH}/libusdm_drv_s.so) set(COMMON_INC_DIR ${COMMON_INC_DIR} PARENT_SCOPE) diff --git a/he_qat/CMakeLists.txt b/he_qat/CMakeLists.txt index 8829678..aded1b4 100644 --- a/he_qat/CMakeLists.txt +++ b/he_qat/CMakeLists.txt @@ -16,11 +16,11 @@ add_library(HE_QAT::he_qat ALIAS he_qat) target_include_directories(he_qat PUBLIC $ #Public headers PUBLIC $ #Public headers - PUBLIC $ #Public headers + # PUBLIC $ #Public headers PUBLIC $ #Public headers PRIVATE ${COMMON_INC_DIR} #Private headers PRIVATE ${ICP_INC_DIR} #Private headers - PRIVATE ${OPENSSL_INC_DIR} #Private headers + #PRIVATE ${OPENSSL_INC_DIR} #Private headers ) #target_include_directories(he_qat PUBLIC ${HE_QAT_UTILS_INC_DIR}) @@ -37,20 +37,15 @@ install(DIRECTORY ${HE_QAT_INC_DIR}/ PATTERN "*.h") target_link_directories(he_qat PUBLIC ${ICP_BUILDOUTPUT_PATH}) -target_link_directories(he_qat PUBLIC ${OPENSSL_LIB_DIR}) - -target_link_libraries(he_qat PUBLIC OpenSSL::SSL OpenSSL::Crypto Threads::Threads) +#target_link_directories(he_qat PUBLIC ${OPENSSL_LIB_DIR}) +target_link_libraries(he_qat PRIVATE OpenSSL::SSL Threads::Threads) target_link_libraries(he_qat PRIVATE cpa_sample_utils) - +target_link_libraries(he_qat PRIVATE qat_s usdm_drv_s) +target_link_libraries(he_qat PRIVATE z) if(HE_QAT_MISC) target_link_libraries(he_qat PRIVATE he_qat_misc) endif() -target_link_libraries(he_qat PUBLIC qat_s usdm_drv_s) -target_link_libraries(he_qat PUBLIC crypto ssl) -target_link_libraries(he_qat PUBLIC z) - - set_target_properties(he_qat PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(he_qat PROPERTIES VERSION ${HE_QAT_VERSION}) @@ -63,15 +58,17 @@ endif() install(TARGETS he_qat DESTINATION ${CMAKE_INSTALL_LIBDIR}) +include(CMakePackageConfigHelpers) + # config cmake config and target file -set(HE_QAT_TARGET_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/cmake/he_qat-${HE_QAT_VERSION}/HE_QATTargets.cmake) +set(HE_QAT_TARGET_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/cmake/he_qat-${HE_QAT_VERSION}/he_qatTargets.cmake) set(HE_QAT_CONFIG_IN_FILENAME ${HE_QAT_CMAKE_PATH}/HE_QATConfig.cmake.in) set(HE_QAT_CONFIG_FILENAME ${HE_QAT_ROOT_DIR}/cmake/he_qat-${HE_QAT_VERSION}/HE_QATConfig.cmake) set(HE_QAT_CONFIG_VERSION_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/cmake/he_qat-${HE_QAT_VERSION}/HE_QATConfigVersion.cmake) set(HE_QAT_CONFIG_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/he_qat-${HE_QAT_VERSION}/) install( - EXPORT HE_QATTargets + EXPORT he_qatTargets NAMESPACE HE_QAT:: DESTINATION ${HE_QAT_CONFIG_INSTALL_DIR} ) @@ -89,7 +86,7 @@ configure_package_config_file( install( TARGETS he_qat - EXPORT HE_QATTargets + EXPORT he_qatTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} @@ -99,6 +96,6 @@ install(FILES ${HE_QAT_CONFIG_FILENAME} ${HE_QAT_CONFIG_VERSION_FILENAME} DESTINATION ${HE_QAT_CONFIG_INSTALL_DIR}) -export(EXPORT HE_QATTargets +export(EXPORT he_qatTargets FILE ${HE_QAT_TARGET_FILENAME}) From 865cf89dd5b216e06467ccd1913d9b81db0438a2 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 11 Mar 2022 20:25:24 -0800 Subject: [PATCH 113/364] Add script to run all samples. --- run.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/run.sh b/run.sh index bd01707..bc1c383 100755 --- a/run.sh +++ b/run.sh @@ -2,5 +2,7 @@ export ICP_ROOT=$HOME/QAT export LD_LIBRARY_PATH=$PWD/install/lib:$ICP_ROOT/build:$LD_LIBRARY_PATH pushd ./install/bin -./qat_modexp_validation +./test_context +./test_bnModExpPerformOp +./test_bnConversion popd From cce10b7627625b179239fceb197d38b85c6132ac Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 15 Mar 2022 10:45:40 -0700 Subject: [PATCH 114/364] Update CMakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a330763..40c4df3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,7 +99,7 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) #set(OPENSSL_INC_DIR /opt/openssl/include) #set(OPENSSL_LIB_DIR /opt/openssl/lib) -set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/he_qat) +#set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/he_qat) set(COMMON_INC_DIR ${CMAKE_CURRENT_LIST_DIR}/include) if(NOT CMAKE_INSTALL_PREFIX) From 78aec6c6f5a931d5fa9a0e3692303af1917c10cc Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 15 Mar 2022 11:17:47 -0700 Subject: [PATCH 115/364] Add cmake/he_qat. --- cmake/he_qat/HE_QATConfig.cmake.in | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 cmake/he_qat/HE_QATConfig.cmake.in diff --git a/cmake/he_qat/HE_QATConfig.cmake.in b/cmake/he_qat/HE_QATConfig.cmake.in new file mode 100644 index 0000000..81dc91c --- /dev/null +++ b/cmake/he_qat/HE_QATConfig.cmake.in @@ -0,0 +1,21 @@ +# Copyright (C) 2021 Intel Corporation + +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) + +include(${CMAKE_CURRENT_LIST_DIR}/he_qatTargets.cmake) + +if(TARGET HE_QAT::he_qat) + set(HE_QAT_FOUND TRUE) + message(STATUS "Intel Homomorphic Encryption Acceleration Library for QAT found") +else() + message(STATUS "Intel Homomorphic Encryption Acceleraiton Library for QAT not found") +endif() + +set(HE_QAT_VERSION "@HE_QAT_VERSION") +set(HE_QAT_VERSION_MAJOR "@HE_QAT_VERSION_MAJOR") +set(HE_QAT_VERSION_MINOR "@HE_QAT_VERSION") +set(HE_QAT_VERSION_PATCH "@HE_QAT_VERSION") + +set(HE_QAT_DEBUG "@HE_QAT_DEBUG") From 5b215e76dcd7c125b194b7c685a66c8264e56468 Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Wed, 16 Mar 2022 03:18:42 +0800 Subject: [PATCH 116/364] update qat branch (#59) * Rename file names and class names(remove paillier_ prefix) (#54) * Rename file names(remove paillier_ prefix) * Rename class names(remove the Paillier prefix) * Renamed key_gen to keygen Co-authored-by: Sejun Kim (cherry picked from commit 338146f2322115812b1a6adc42f31e387084cd1e) * Refactoring applied (#55) (cherry picked from commit 0aac79eafd41affb71a18f99189a98014d81e84f) Co-authored-by: Sejun Kim --- README.md | 6 +- benchmark/bench_cryptography.cpp | 2 +- benchmark/bench_ops.cpp | 68 ++++---- ipcl/CMakeLists.txt | 8 +- ipcl/bignum.cpp | 3 - ipcl/include/ipcl/bignum.h | 4 +- ipcl/include/ipcl/common.hpp | 2 +- .../ipcl/{paillier_keygen.hpp => keygen.hpp} | 12 +- ipcl/include/ipcl/mod_exp.hpp | 1 - .../ipcl/{paillier_ops.hpp => ops.hpp} | 65 +++----- .../ipcl/{paillier_prikey.hpp => pri_key.hpp} | 24 +-- .../ipcl/{paillier_pubkey.hpp => pub_key.hpp} | 23 ++- ipcl/include/ipcl/util.hpp | 14 +- ipcl/{paillier_keygen.cpp => keygen.cpp} | 25 ++- ipcl/mod_exp.cpp | 36 ++-- ipcl/ops.cpp | 157 ++++++++++++++++++ ipcl/paillier_ops.cpp | 154 ----------------- ipcl/{paillier_prikey.cpp => pri_key.cpp} | 71 ++++---- ipcl/{paillier_pubkey.cpp => pub_key.cpp} | 64 ++++--- test/test_cryptography.cpp | 16 +- test/test_ops.cpp | 66 ++++---- 21 files changed, 396 insertions(+), 425 deletions(-) rename ipcl/include/ipcl/{paillier_keygen.hpp => keygen.hpp} (75%) rename ipcl/include/ipcl/{paillier_ops.hpp => ops.hpp} (52%) rename ipcl/include/ipcl/{paillier_prikey.hpp => pri_key.hpp} (83%) rename ipcl/include/ipcl/{paillier_pubkey.hpp => pub_key.hpp} (85%) rename ipcl/{paillier_keygen.cpp => keygen.cpp} (81%) create mode 100644 ipcl/ops.cpp delete mode 100644 ipcl/paillier_ops.cpp rename ipcl/{paillier_prikey.cpp => pri_key.cpp} (60%) rename ipcl/{paillier_pubkey.cpp => pub_key.cpp} (71%) diff --git a/README.md b/README.md index c05a834..ca17e85 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ We will keep working on adding more supported operating systems. ### Dependencies Must have dependencies include: ``` -cmake >=3.15.1 +cmake >= 3.15.1 git pthread g++ >= 7.0 or clang >= 10.0 @@ -54,8 +54,8 @@ g++ >= 7.0 or clang >= 10.0 The following libraries and tools are also required, ``` -nasm>=2.15 -OpenSSL>=1.1.0 +nasm >= 2.15 +OpenSSL >= 1.1.0 ``` For ```nasm```, please refer to the [Netwide Assembler](https://nasm.us/) for installation details. diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index 06f28e2..b9ffb9d 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -8,7 +8,7 @@ #include #endif // IPCL_USE_OMP -#include "ipcl/paillier_keygen.hpp" +#include "ipcl/keygen.hpp" static void BM_KeyGen(benchmark::State& state) { int64_t n_length = state.range(0); diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index a9a43d2..5282223 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -9,8 +9,8 @@ #endif // IPCL_USE_OMP #include -#include "ipcl/paillier_keygen.hpp" -#include "ipcl/paillier_ops.hpp" +#include "ipcl/keygen.hpp" +#include "ipcl/ops.hpp" static void BM_Add_CTCT(benchmark::State& state) { size_t dsize = state.range(0); @@ -35,9 +35,9 @@ static void BM_Add_CTCT(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, ct_b[i]); + ipcl::EncryptedNumber sum = pen_a + pen_b; } } } @@ -69,9 +69,9 @@ static void BM_Add_CTCT_buff8(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, ct_b[i]); + ipcl::EncryptedNumber sum = pen_a + pen_b; } } } @@ -100,8 +100,8 @@ static void BM_Add_CTPT(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber sum = pen_a + b[i]; } } } @@ -130,8 +130,8 @@ static void BM_Add_CTPT_buff8(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber sum = pen_a + b[i]; } } } @@ -160,9 +160,9 @@ static void BM_Mul_CTPT(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, b[i]); + ipcl::EncryptedNumber sum = pen_a * pen_b; } } } @@ -191,9 +191,9 @@ static void BM_Mul_CTPT_buff8(benchmark::State& state) { for (auto _ : state) { for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, b[i]); + ipcl::EncryptedNumber sum = pen_a * pen_b; } } } @@ -228,9 +228,9 @@ static void BM_Add_CTCT_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, ct_b[i]); + ipcl::EncryptedNumber sum = pen_a + pen_b; } } } @@ -266,9 +266,9 @@ static void BM_Add_CTCT_buff8_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, ct_b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, ct_b[i]); + ipcl::EncryptedNumber sum = pen_a + pen_b; } } } @@ -298,8 +298,8 @@ static void BM_Add_CTPT_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber sum = pen_a + b[i]; } } } @@ -332,8 +332,8 @@ static void BM_Add_CTPT_buff8_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber sum = pen_a + b[i]; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber sum = pen_a + b[i]; } } } @@ -363,9 +363,9 @@ static void BM_Mul_CTPT_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, b[i]); + ipcl::EncryptedNumber sum = pen_a * pen_b; } } } @@ -398,9 +398,9 @@ static void BM_Mul_CTPT_buff8_OMP(benchmark::State& state) { for (auto _ : state) { #pragma omp parallel for for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::PaillierEncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::PaillierEncryptedNumber pen_b(key.pub_key, b[i]); - ipcl::PaillierEncryptedNumber sum = pen_a * pen_b; + ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); + ipcl::EncryptedNumber pen_b(key.pub_key, b[i]); + ipcl::EncryptedNumber sum = pen_a * pen_b; } } } diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 4ad679f..a4b1ff5 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -1,10 +1,10 @@ # Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -set(IPCL_SRCS paillier_prikey.cpp - paillier_pubkey.cpp - paillier_ops.cpp - paillier_keygen.cpp +set(IPCL_SRCS pri_key.cpp + pub_key.cpp + ops.cpp + keygen.cpp bignum.cpp mod_exp.cpp ) diff --git a/ipcl/bignum.cpp b/ipcl/bignum.cpp index b0b578e..b5adab3 100644 --- a/ipcl/bignum.cpp +++ b/ipcl/bignum.cpp @@ -509,7 +509,4 @@ void BigNumber::num2char(std::vector& dest) const { dest.assign(bnData, bnData + len); } -int BITSIZE_WORD(int n) { return (((n) + 31) >> 5); } -int BITSIZE_DWORD(int n) { return (((n) + 63) >> 6); } - } // namespace ipcl diff --git a/ipcl/include/ipcl/bignum.h b/ipcl/include/ipcl/bignum.h index c150f5a..fe62dc1 100644 --- a/ipcl/include/ipcl/bignum.h +++ b/ipcl/include/ipcl/bignum.h @@ -128,8 +128,8 @@ class BigNumber { IppsBigNumState* m_pBN; }; -int BITSIZE_WORD(int n); -int BITSIZE_DWORD(int n); +constexpr int BITSIZE_WORD(int n) { return (((n) + 31) >> 5); } +constexpr int BITSIZE_DWORD(int n) { return (((n) + 63) >> 6); } } // namespace ipcl #endif // _BIGNUM_H_ diff --git a/ipcl/include/ipcl/common.hpp b/ipcl/include/ipcl/common.hpp index fecc02d..f954026 100644 --- a/ipcl/include/ipcl/common.hpp +++ b/ipcl/include/ipcl/common.hpp @@ -6,7 +6,7 @@ namespace ipcl { -#define IPCL_CRYPTO_MB_SIZE 8 +constexpr int IPCL_CRYPTO_MB_SIZE = 8; } // namespace ipcl #endif // IPCL_INCLUDE_IPCL_COMMON_HPP_ diff --git a/ipcl/include/ipcl/paillier_keygen.hpp b/ipcl/include/ipcl/keygen.hpp similarity index 75% rename from ipcl/include/ipcl/paillier_keygen.hpp rename to ipcl/include/ipcl/keygen.hpp index e3dd6b3..c254db8 100644 --- a/ipcl/include/ipcl/paillier_keygen.hpp +++ b/ipcl/include/ipcl/keygen.hpp @@ -1,10 +1,10 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#ifndef IPCL_INCLUDE_IPCL_PAILLIER_KEYGEN_HPP_ -#define IPCL_INCLUDE_IPCL_PAILLIER_KEYGEN_HPP_ +#ifndef IPCL_INCLUDE_IPCL_KEYGEN_HPP_ +#define IPCL_INCLUDE_IPCL_KEYGEN_HPP_ -#include "ipcl/paillier_prikey.hpp" +#include "ipcl/pri_key.hpp" namespace ipcl { @@ -14,8 +14,8 @@ namespace ipcl { * priv_key: paillier private key */ struct keyPair { - PaillierPublicKey* pub_key; - PaillierPrivateKey* priv_key; + PublicKey* pub_key; + PrivateKey* priv_key; }; /** @@ -34,4 +34,4 @@ BigNumber getPrimeBN(int maxBitSize); keyPair generateKeypair(int64_t n_length, bool enable_DJN = true); } // namespace ipcl -#endif // IPCL_INCLUDE_IPCL_PAILLIER_KEYGEN_HPP_ +#endif // IPCL_INCLUDE_IPCL_KEYGEN_HPP_ diff --git a/ipcl/include/ipcl/mod_exp.hpp b/ipcl/include/ipcl/mod_exp.hpp index e3b3ac4..810ff27 100644 --- a/ipcl/include/ipcl/mod_exp.hpp +++ b/ipcl/include/ipcl/mod_exp.hpp @@ -7,7 +7,6 @@ #include #include "ipcl/bignum.h" -#include "ipcl/util.hpp" namespace ipcl { /** diff --git a/ipcl/include/ipcl/paillier_ops.hpp b/ipcl/include/ipcl/ops.hpp similarity index 52% rename from ipcl/include/ipcl/paillier_ops.hpp rename to ipcl/include/ipcl/ops.hpp index f7d0d72..6aab2f8 100644 --- a/ipcl/include/ipcl/paillier_ops.hpp +++ b/ipcl/include/ipcl/ops.hpp @@ -1,98 +1,87 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#ifndef IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ -#define IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ +#ifndef IPCL_INCLUDE_IPCL_OPS_HPP_ +#define IPCL_INCLUDE_IPCL_OPS_HPP_ #include -#include "ipcl/paillier_pubkey.hpp" +#include "ipcl/pub_key.hpp" #include "ipcl/util.hpp" namespace ipcl { -class PaillierEncryptedNumber { +class EncryptedNumber { public: /** - * PaillierEncryptedNumber constructor + * EncryptedNumber constructor * @param[in] pub_key paillier public key * @param[in] bn ciphertext encrypted by paillier public key */ - PaillierEncryptedNumber(const PaillierPublicKey* pub_key, - const BigNumber& bn); + EncryptedNumber(const PublicKey* pub_key, const BigNumber& bn); /** - * PaillierEncryptedNumber constructor + * EncryptedNumber constructor * @param[in] pub_key paillier public key * @param[in] bn array of ciphertexts encrypted by paillier public key * @param[in] length size of array(default value is IPCL_CRYPTO_MB_SIZE) */ - PaillierEncryptedNumber(const PaillierPublicKey* pub_key, - const std::vector& bn, - size_t length = IPCL_CRYPTO_MB_SIZE); + EncryptedNumber(const PublicKey* pub_key, const std::vector& bn, + size_t length = IPCL_CRYPTO_MB_SIZE); /** - * PaillierEncryptedNumber constructor + * EncryptedNumber constructor * @param[in] pub_key paillier public key * @param[in] scalar array of integer scalars * @param[in] length size of array(default value is IPCL_CRYPTO_MB_SIZE) */ - PaillierEncryptedNumber(const PaillierPublicKey* pub_key, - const std::vector& scalar, - size_t length = IPCL_CRYPTO_MB_SIZE); + EncryptedNumber(const PublicKey* pub_key, const std::vector& scalar, + size_t length = IPCL_CRYPTO_MB_SIZE); /** * Arithmetic addition operator * @param[in] bn augend */ - PaillierEncryptedNumber operator+(const PaillierEncryptedNumber& bn) const; + EncryptedNumber operator+(const EncryptedNumber& bn) const; /** * Arithmetic addition operator * @param[in] other augend */ - PaillierEncryptedNumber operator+(const BigNumber& other) const; + EncryptedNumber operator+(const BigNumber& other) const; /** * Arithmetic addition operator * @param[in] other array of augend */ - PaillierEncryptedNumber operator+(const std::vector& other) const; + EncryptedNumber operator+(const std::vector& other) const; /** * Arithmetic multiply operator * @param[in] bn multiplicand */ - PaillierEncryptedNumber operator*(const PaillierEncryptedNumber& bn) const; + EncryptedNumber operator*(const EncryptedNumber& bn) const; /** * Arithmetic multiply operator * @param[in] other multiplicand */ - PaillierEncryptedNumber operator*(const BigNumber& other) const; + EncryptedNumber operator*(const BigNumber& other) const; /** * Apply obfuscator for ciphertext, obfuscated needed only when the ciphertext * is exposed */ - void apply_obfuscator() { - b_isObfuscator = true; - std::vector obfuscator(IPCL_CRYPTO_MB_SIZE); - m_pubkey->apply_obfuscator(obfuscator); - - BigNumber sq = m_pubkey->getNSQ(); - for (int i = 0; i < m_available; i++) - m_bn[i] = sq.ModMul(m_bn[i], obfuscator[i]); - } + void apply_obfuscator(); /** * Return ciphertext - * @param[in] idx index of ciphertext stored in PaillierEncryptedNumber + * @param[in] idx index of ciphertext stored in EncryptedNumber * (default = 0) */ BigNumber getBN(size_t idx = 0) const { ERROR_CHECK(m_available != 1 || idx <= 0, - "getBN: PaillierEncryptedNumber only has 1 BigNumber"); + "getBN: EncryptedNumber only has 1 BigNumber"); return m_bn[idx]; } @@ -100,13 +89,13 @@ class PaillierEncryptedNumber { /** * Get public key */ - PaillierPublicKey getPK() const { return *m_pubkey; } + PublicKey getPK() const { return *m_pubkey; } /** - * Rotate PaillierEncryptedNumber + * Rotate EncryptedNumber * @param[in] shift rotate length */ - PaillierEncryptedNumber rotate(int shift) const; + EncryptedNumber rotate(int shift) const; /** * Return entire ciphertext array @@ -115,12 +104,12 @@ class PaillierEncryptedNumber { std::vector getArrayBN() const { return m_bn; } /** - * Check if element in PaillierEncryptedNumber is single + * Check if element in EncryptedNumber is single */ bool isSingle() const { return m_available == 1; } /** - * Get size of array in PaillierEncryptedNumber + * Get size of array in EncryptedNumber */ size_t getLength() const { return m_length; } @@ -129,7 +118,7 @@ class PaillierEncryptedNumber { private: bool b_isObfuscator; int m_available; - const PaillierPublicKey* m_pubkey; + const PublicKey* m_pubkey; size_t m_length; std::vector m_bn; @@ -140,4 +129,4 @@ class PaillierEncryptedNumber { }; } // namespace ipcl -#endif // IPCL_INCLUDE_IPCL_PAILLIER_OPS_HPP_ +#endif // IPCL_INCLUDE_IPCL_OPS_HPP_ diff --git a/ipcl/include/ipcl/paillier_prikey.hpp b/ipcl/include/ipcl/pri_key.hpp similarity index 83% rename from ipcl/include/ipcl/paillier_prikey.hpp rename to ipcl/include/ipcl/pri_key.hpp index 5ecfc3d..b3466eb 100644 --- a/ipcl/include/ipcl/paillier_prikey.hpp +++ b/ipcl/include/ipcl/pri_key.hpp @@ -1,25 +1,25 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#ifndef IPCL_INCLUDE_IPCL_PAILLIER_PRIKEY_HPP_ -#define IPCL_INCLUDE_IPCL_PAILLIER_PRIKEY_HPP_ +#ifndef IPCL_INCLUDE_IPCL_PRI_KEY_HPP_ +#define IPCL_INCLUDE_IPCL_PRI_KEY_HPP_ #include -#include "ipcl/paillier_ops.hpp" +#include "ipcl/ops.hpp" namespace ipcl { -class PaillierPrivateKey { +class PrivateKey { public: /** - * PaillierPrivateKey constructor + * PrivateKey constructor * @param[in] public_key paillier public key * @param[in] p p of private key in paillier scheme * @param[in] q q of private key in paillier scheme */ - PaillierPrivateKey(const PaillierPublicKey* public_key, const BigNumber& p, - const BigNumber& q); + PrivateKey(const PublicKey* public_key, const BigNumber& p, + const BigNumber& q); /** * Enable Chinese Remainder Theorem @@ -38,10 +38,10 @@ class PaillierPrivateKey { /** * Decrypt ciphertext * @param[out] plaintext output of the decryption - * @param[in] ciphertext PaillierEncryptedNumber to be decrypted + * @param[in] ciphertext EncryptedNumber to be decrypted */ void decrypt(std::vector& plaintext, - const PaillierEncryptedNumber ciphertext) const; + const EncryptedNumber ciphertext) const; const void* addr = static_cast(this); @@ -68,7 +68,7 @@ class PaillierPrivateKey { /** * Get public key */ - const PaillierPublicKey* getPubKey() const { return m_pubkey; } + const PublicKey* getPubKey() const { return m_pubkey; } /** * @brief Support function for ISO/IEC 18033-6 compliance check @@ -78,7 +78,7 @@ class PaillierPrivateKey { BigNumber getLambda() const { return m_lambda; } private: - const PaillierPublicKey* m_pubkey; + const PublicKey* m_pubkey; BigNumber m_n; BigNumber m_nsquare; BigNumber m_g; @@ -139,4 +139,4 @@ class PaillierPrivateKey { }; } // namespace ipcl -#endif // IPCL_INCLUDE_IPCL_PAILLIER_PRIKEY_HPP_ +#endif // IPCL_INCLUDE_IPCL_PRI_KEY_HPP_ diff --git a/ipcl/include/ipcl/paillier_pubkey.hpp b/ipcl/include/ipcl/pub_key.hpp similarity index 85% rename from ipcl/include/ipcl/paillier_pubkey.hpp rename to ipcl/include/ipcl/pub_key.hpp index 9b51247..61ae905 100644 --- a/ipcl/include/ipcl/paillier_pubkey.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -1,8 +1,8 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#ifndef IPCL_INCLUDE_IPCL_PAILLIER_PUBKEY_HPP_ -#define IPCL_INCLUDE_IPCL_PAILLIER_PUBKEY_HPP_ +#ifndef IPCL_INCLUDE_IPCL_PUB_KEY_HPP_ +#define IPCL_INCLUDE_IPCL_PUB_KEY_HPP_ #include @@ -10,26 +10,25 @@ namespace ipcl { -class PaillierPublicKey { +class PublicKey { public: /** - * PaillierPublicKey constructor + * PublicKey constructor * @param[in] n n of public key in paillier scheme * @param[in] bits bit length of public key(default value is 1024) * @param[in] enableDJN_ enables DJN scheme(default value is false) */ - explicit PaillierPublicKey(const BigNumber& n, int bits = 1024, - bool enableDJN_ = false); + explicit PublicKey(const BigNumber& n, int bits = 1024, + bool enableDJN_ = false); /** - * PaillierPublicKey constructor + * PublicKey constructor * @param[in] n n of public key in paillier scheme * @param[in] bits bit length of public key(default value is 1024) * @param[in] enableDJN_ enables DJN scheme(default value is false) */ - explicit PaillierPublicKey(const Ipp32u n, int bits = 1024, - bool enableDJN_ = false) - : PaillierPublicKey(BigNumber(n), bits, enableDJN_) {} + explicit PublicKey(const Ipp32u n, int bits = 1024, bool enableDJN_ = false) + : PublicKey(BigNumber(n), bits, enableDJN_) {} /** * DJN enabling function @@ -82,7 +81,7 @@ class PaillierPublicKey { * Apply obfuscator for ciphertext * @param[out] obfuscator output of obfuscator with random value */ - void apply_obfuscator(std::vector& obfuscator) const; + void applyObfuscator(std::vector& obfuscator) const; /** * @brief Set the Random object for ISO/IEC 18033-6 compliance check @@ -141,4 +140,4 @@ class PaillierPublicKey { }; } // namespace ipcl -#endif // IPCL_INCLUDE_IPCL_PAILLIER_PUBKEY_HPP_ +#endif // IPCL_INCLUDE_IPCL_PUB_KEY_HPP_ diff --git a/ipcl/include/ipcl/util.hpp b/ipcl/include/ipcl/util.hpp index b56cf50..8bd0356 100644 --- a/ipcl/include/ipcl/util.hpp +++ b/ipcl/include/ipcl/util.hpp @@ -5,6 +5,7 @@ #define IPCL_INCLUDE_IPCL_UTIL_HPP_ #include +#include #include #include @@ -12,14 +13,11 @@ namespace ipcl { -static inline std::string build_log(const char* file, int line, - std::string msg) { - std::string log; - log = "\nFile: " + std::string(file); - log += "\nLine: " + std::to_string(line); - log += "\nError: " + msg; - - return log; +inline std::string build_log(const char* file, int line, + const std::string& msg) { + std::ostringstream log; + log << "\nFile: " << file << "\nLine: " << line << "\nError: " << msg; + return log.str(); } #define ERROR_CHECK(e, ...) \ diff --git a/ipcl/paillier_keygen.cpp b/ipcl/keygen.cpp similarity index 81% rename from ipcl/paillier_keygen.cpp rename to ipcl/keygen.cpp index 59ef948..9a8dcbf 100644 --- a/ipcl/paillier_keygen.cpp +++ b/ipcl/keygen.cpp @@ -1,7 +1,7 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include "ipcl/paillier_keygen.hpp" +#include "ipcl/keygen.hpp" #include #include @@ -11,7 +11,7 @@ namespace ipcl { -#define N_BIT_SIZE_MAX 2048 +constexpr int N_BIT_SIZE_MAX = 2048; static void rand32u(std::vector& addr) { std::random_device dev; @@ -23,18 +23,18 @@ static void rand32u(std::vector& addr) { BigNumber getPrimeBN(int maxBitSize) { int PrimeSize; ippsPrimeGetSize(maxBitSize, &PrimeSize); - auto&& primeGen = std::vector(PrimeSize); + auto primeGen = std::vector(PrimeSize); ippsPrimeInit(maxBitSize, reinterpret_cast(primeGen.data())); // define Pseudo Random Generator (default settings) - int&& seedBitSize = 160; - int&& seedSize = BITSIZE_WORD(seedBitSize); + constexpr int seedBitSize = 160; + constexpr int seedSize = BITSIZE_WORD(seedBitSize); ippsPRNGGetSize(&PrimeSize); - auto&& rand = std::vector(PrimeSize); + auto rand = std::vector(PrimeSize); ippsPRNGInit(seedBitSize, reinterpret_cast(rand.data())); - auto&& seed = std::vector(seedSize); + auto seed = std::vector(seedSize); rand32u(seed); BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); @@ -76,10 +76,8 @@ static void getDJNBN(int64_t n_length, BigNumber& p, BigNumber& q, q = getPrimeBN(n_length / 2); } while (q == p || !p.TestBit(1)); // get q: q!=p and q mod 4 = 3 - BigNumber&& pminusone = p - 1; - BigNumber&& qminusone = q - 1; - gcd = pminusone.gcd(qminusone); - } while (gcd.compare(2)); // gcd(p-1,q-1)=2 + gcd = (p - 1).gcd(q - 1); // (p - 1) is a BigNumber + } while (gcd.compare(2)); // gcd(p-1,q-1)=2 n = p * q; } @@ -101,9 +99,8 @@ keyPair generateKeypair(int64_t n_length, bool enable_DJN) { else getNormalBN(n_length, p, q, n); - PaillierPublicKey* public_key = - new PaillierPublicKey(n, n_length, enable_DJN); - PaillierPrivateKey* private_key = new PaillierPrivateKey(public_key, p, q); + PublicKey* public_key = new PublicKey(n, n_length, enable_DJN); + PrivateKey* private_key = new PrivateKey(public_key, p, q); return keyPair{public_key, private_key}; } diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index f6cb1de..ea1c41c 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -7,6 +7,8 @@ #include +#include "ipcl/util.hpp" + namespace ipcl { static std::vector ippMBModExp(const std::vector& base, @@ -18,14 +20,15 @@ static std::vector ippMBModExp(const std::vector& base, mbx_status st = MBX_STATUS_OK; - int&& bits = m[0].BitSize(); - int&& dwords = BITSIZE_DWORD(bits); - int&& bufferLen = mbx_exp_BufferSize(bits); - auto&& pBuffer = std::vector(bufferLen); + int bits = m.front().BitSize(); + int dwords = BITSIZE_DWORD(bits); + int bufferLen = mbx_exp_BufferSize(bits); + auto buffer = std::vector(bufferLen); - std::vector out_x(IPCL_CRYPTO_MB_SIZE), b_array(IPCL_CRYPTO_MB_SIZE), - p_array(IPCL_CRYPTO_MB_SIZE); - int&& length = dwords * sizeof(int64u); + std::vector out_x(IPCL_CRYPTO_MB_SIZE); + std::vector b_array(IPCL_CRYPTO_MB_SIZE); + std::vector p_array(IPCL_CRYPTO_MB_SIZE); + int length = dwords * sizeof(int64u); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { out_x[i] = reinterpret_cast(alloca(length)); @@ -47,12 +50,13 @@ static std::vector ippMBModExp(const std::vector& base, * will be inconsistent with the length allocated by b_array/p_array, * resulting in data errors. */ - std::vector pow_b(IPCL_CRYPTO_MB_SIZE), pow_p(IPCL_CRYPTO_MB_SIZE), - pow_nsquare(IPCL_CRYPTO_MB_SIZE); - int bBitLen, pBitLen, nsqBitLen; + std::vector pow_b(IPCL_CRYPTO_MB_SIZE); + std::vector pow_p(IPCL_CRYPTO_MB_SIZE); + std::vector pow_nsquare(IPCL_CRYPTO_MB_SIZE); + int nsqBitLen; int expBitLen = 0; - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + for (int i = 0, bBitLen, pBitLen; i < IPCL_CRYPTO_MB_SIZE; i++) { ippsRef_BN(nullptr, &bBitLen, reinterpret_cast(&pow_b[i]), base[i]); ippsRef_BN(nullptr, &pBitLen, reinterpret_cast(&pow_p[i]), @@ -72,7 +76,7 @@ static std::vector ippMBModExp(const std::vector& base, */ st = mbx_exp_mb8(out_x.data(), b_array.data(), p_array.data(), expBitLen, reinterpret_cast(pow_nsquare.data()), nsqBitLen, - reinterpret_cast(pBuffer.data()), bufferLen); + reinterpret_cast(buffer.data()), bufferLen); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { ERROR_CHECK(MBX_STATUS_OK == MBX_GET_STS(st, i), @@ -82,7 +86,7 @@ static std::vector ippMBModExp(const std::vector& base, } // It is important to hold a copy of nsquare for thread-safe purpose - BigNumber bn_c(m[0]); + BigNumber bn_c(m.front()); std::vector res(IPCL_CRYPTO_MB_SIZE, 0); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { @@ -96,14 +100,14 @@ static std::vector ippMBModExp(const std::vector& base, static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, const BigNumber& m) { IppStatus stat = ippStsNoErr; - // It is important to declear res * bform bit length refer to ipp-crypto spec: + // It is important to declare res * bform bit length refer to ipp-crypto spec: // R should not be less than the data length of the modulus m BigNumber res(m); int bnBitLen; Ipp32u* pow_m; ippsRef_BN(nullptr, &bnBitLen, &pow_m, BN(m)); - int&& nlen = BITSIZE_WORD(bnBitLen); + int nlen = BITSIZE_WORD(bnBitLen); int size; // define and initialize Montgomery Engine over Modulus N @@ -111,7 +115,7 @@ static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: get the size of IppsMontState context error."); - auto&& pMont = std::vector(size); + auto pMont = std::vector(size); stat = ippsMontInit(IppsBinaryMethod, nlen, reinterpret_cast(pMont.data())); diff --git a/ipcl/ops.cpp b/ipcl/ops.cpp new file mode 100644 index 0000000..2deaf5d --- /dev/null +++ b/ipcl/ops.cpp @@ -0,0 +1,157 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/ops.hpp" + +#include + +#include "ipcl/mod_exp.hpp" + +namespace ipcl { +// constructors +// +EncryptedNumber::EncryptedNumber(const PublicKey* pub_key, const BigNumber& bn) + : b_isObfuscator(false), + m_available(1), + m_pubkey(pub_key), + m_length(1), + m_bn{bn} {} + +EncryptedNumber::EncryptedNumber(const PublicKey* pub_key, + const std::vector& bn, + size_t length) + : b_isObfuscator(false), + m_pubkey(pub_key), + m_available(IPCL_CRYPTO_MB_SIZE), + m_length(length), + m_bn{bn[0], bn[1], bn[2], bn[3], bn[4], bn[5], bn[6], bn[7]} {} + +EncryptedNumber::EncryptedNumber(const PublicKey* pub_key, + const std::vector& scalar, + size_t length) + : b_isObfuscator(false), + m_pubkey(pub_key), + m_available(IPCL_CRYPTO_MB_SIZE), + m_length(length), + m_bn{scalar[0], scalar[1], scalar[2], scalar[3], + scalar[4], scalar[5], scalar[6], scalar[7]} {} + +// CT+CT +EncryptedNumber EncryptedNumber::operator+(const EncryptedNumber& other) const { + ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), + "operator+: two different public keys detected!!"); + + const auto& a = *this; + const auto& b = other; + + if (m_available == 1) { + BigNumber sum = a.raw_add(a.m_bn.front(), b.m_bn.front()); + return EncryptedNumber(m_pubkey, sum); + } + std::vector sum(IPCL_CRYPTO_MB_SIZE); + for (int i = 0; i < m_available; i++) + sum[i] = a.raw_add(a.m_bn[i], b.m_bn[i]); + return EncryptedNumber(m_pubkey, sum); +} + +// CT+PT +EncryptedNumber EncryptedNumber::operator+(const BigNumber& other) const { + const auto& a = *this; + BigNumber b; + a.m_pubkey->encrypt(b, other); + + BigNumber sum = a.raw_add(a.m_bn.front(), b); + return EncryptedNumber(m_pubkey, sum); +} + +// multi encrypted CT+PT +EncryptedNumber EncryptedNumber::operator+( + const std::vector& other) const { + VEC_SIZE_CHECK(other); + + const auto& a = *this; + + std::vector b(IPCL_CRYPTO_MB_SIZE); + std::vector sum(IPCL_CRYPTO_MB_SIZE); + a.m_pubkey->encrypt(b, other, false); + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) + sum[i] = a.raw_add(a.m_bn[i], b[i]); + return EncryptedNumber(m_pubkey, sum); +} + +// CT*PT EncryptedNumber store a plaintext integer, not an encrypted +// integer +EncryptedNumber EncryptedNumber::operator*(const EncryptedNumber& other) const { + ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), + "operator*: two different public keys detected!!"); + + const auto& a = *this; + const auto& b = other; + + if (m_available == 1) { + BigNumber product = a.raw_mul(a.m_bn.front(), b.m_bn.front()); + return EncryptedNumber(m_pubkey, product); + } + + std::vector&& product = a.raw_mul(a.m_bn, b.m_bn); + return EncryptedNumber(m_pubkey, product); +} + +// CT*PT +EncryptedNumber EncryptedNumber::operator*(const BigNumber& other) const { + const auto& a = *this; + + BigNumber b = other; + BigNumber product = a.raw_mul(a.m_bn.front(), b); + return EncryptedNumber(m_pubkey, product); +} + +BigNumber EncryptedNumber::raw_add(const BigNumber& a, + const BigNumber& b) const { + // Hold a copy of nsquare for multi-threaded + const BigNumber& sq = m_pubkey->getNSQ(); + return a * b % sq; +} + +std::vector EncryptedNumber::raw_mul( + const std::vector& a, const std::vector& b) const { + std::vector sq(IPCL_CRYPTO_MB_SIZE, m_pubkey->getNSQ()); + return ipcl::ippModExp(a, b, sq); +} + +BigNumber EncryptedNumber::raw_mul(const BigNumber& a, + const BigNumber& b) const { + const BigNumber& sq = m_pubkey->getNSQ(); + return ipcl::ippModExp(a, b, sq); +} + +EncryptedNumber EncryptedNumber::rotate(int shift) const { + ERROR_CHECK(m_available != 1, "rotate: Cannot rotate single EncryptedNumber"); + ERROR_CHECK(shift >= -8 && shift <= 8, + "rotate: Cannot shift more than 8 or -8"); + + if (shift == 0 || shift == 8 || shift == -8) + return EncryptedNumber(m_pubkey, m_bn); + + if (shift > 0) + shift = 8 - shift; + else + shift = -shift; + + std::vector new_bn = getArrayBN(); + + std::rotate(std::begin(new_bn), std::begin(new_bn) + shift, std::end(new_bn)); + return EncryptedNumber(m_pubkey, new_bn); +} + +void EncryptedNumber::apply_obfuscator() { + b_isObfuscator = true; + std::vector obfuscator(IPCL_CRYPTO_MB_SIZE); + m_pubkey->applyObfuscator(obfuscator); + + BigNumber sq = m_pubkey->getNSQ(); + for (int i = 0; i < m_available; i++) + m_bn[i] = sq.ModMul(m_bn[i], obfuscator[i]); +} + +} // namespace ipcl diff --git a/ipcl/paillier_ops.cpp b/ipcl/paillier_ops.cpp deleted file mode 100644 index 0ca209b..0000000 --- a/ipcl/paillier_ops.cpp +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include "ipcl/paillier_ops.hpp" - -#include - -#include "ipcl/mod_exp.hpp" - -namespace ipcl { -// constructors -// -PaillierEncryptedNumber::PaillierEncryptedNumber( - const PaillierPublicKey* pub_key, const BigNumber& bn) - : b_isObfuscator(false), - m_available(1), - m_pubkey(pub_key), - m_length(1), - m_bn{bn} {} - -PaillierEncryptedNumber::PaillierEncryptedNumber( - const PaillierPublicKey* pub_key, const std::vector& bn, - size_t length) - : b_isObfuscator(false), - m_pubkey(pub_key), - m_available(IPCL_CRYPTO_MB_SIZE), - m_length(length), - m_bn{bn[0], bn[1], bn[2], bn[3], bn[4], bn[5], bn[6], bn[7]} {} - -PaillierEncryptedNumber::PaillierEncryptedNumber( - const PaillierPublicKey* pub_key, const std::vector& scalar, - size_t length) - : b_isObfuscator(false), - m_pubkey(pub_key), - m_available(IPCL_CRYPTO_MB_SIZE), - m_length(length), - m_bn{scalar[0], scalar[1], scalar[2], scalar[3], - scalar[4], scalar[5], scalar[6], scalar[7]} {} - -// CT+CT -PaillierEncryptedNumber PaillierEncryptedNumber::operator+( - const PaillierEncryptedNumber& other) const { - ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), - "operator+: two different public keys detected!!"); - - PaillierEncryptedNumber a = *this; - PaillierEncryptedNumber b = other; - - if (m_available == 1) { - BigNumber&& sum = a.raw_add(a.m_bn[0], b.m_bn[0]); - return PaillierEncryptedNumber(m_pubkey, sum); - } else { - std::vector sum(IPCL_CRYPTO_MB_SIZE); - for (int i = 0; i < m_available; i++) - sum[i] = a.raw_add(a.m_bn[i], b.m_bn[i]); - return PaillierEncryptedNumber(m_pubkey, sum); - } -} - -// CT+PT -PaillierEncryptedNumber PaillierEncryptedNumber::operator+( - const BigNumber& other) const { - PaillierEncryptedNumber a = *this; - BigNumber b; - a.m_pubkey->encrypt(b, other); - - BigNumber&& sum = a.raw_add(a.m_bn[0], b); - return PaillierEncryptedNumber(m_pubkey, sum); -} - -// multi encrypted CT+PT -PaillierEncryptedNumber PaillierEncryptedNumber::operator+( - const std::vector& other) const { - VEC_SIZE_CHECK(other); - - PaillierEncryptedNumber a = *this; - - std::vector b(IPCL_CRYPTO_MB_SIZE); - std::vector sum(IPCL_CRYPTO_MB_SIZE); - a.m_pubkey->encrypt(b, other, false); - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) - sum[i] = a.raw_add(a.m_bn[i], b[i]); - return PaillierEncryptedNumber(m_pubkey, sum); -} - -// CT*PT PaillierEncryptedNumber store a plaintext integer, not an encrypted -// integer -PaillierEncryptedNumber PaillierEncryptedNumber::operator*( - const PaillierEncryptedNumber& other) const { - ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), - "operator*: two different public keys detected!!"); - - PaillierEncryptedNumber a = *this; - PaillierEncryptedNumber b = other; - - if (m_available == 1) { - BigNumber&& product = a.raw_mul(a.m_bn[0], b.m_bn[0]); - return PaillierEncryptedNumber(m_pubkey, product); - } else { - std::vector&& product = a.raw_mul(a.m_bn, b.m_bn); - return PaillierEncryptedNumber(m_pubkey, product); - } -} - -// CT*PT -PaillierEncryptedNumber PaillierEncryptedNumber::operator*( - const BigNumber& other) const { - PaillierEncryptedNumber a = *this; - - BigNumber b = other; - BigNumber&& product = a.raw_mul(a.m_bn[0], b); - return PaillierEncryptedNumber(m_pubkey, product); -} - -BigNumber PaillierEncryptedNumber::raw_add(const BigNumber& a, - const BigNumber& b) const { - // Hold a copy of nsquare for multi-threaded - BigNumber&& sq = m_pubkey->getNSQ(); - return a * b % sq; -} - -std::vector PaillierEncryptedNumber::raw_mul( - const std::vector& a, const std::vector& b) const { - std::vector sq(IPCL_CRYPTO_MB_SIZE, m_pubkey->getNSQ()); - return ipcl::ippModExp(a, b, sq); -} - -BigNumber PaillierEncryptedNumber::raw_mul(const BigNumber& a, - const BigNumber& b) const { - BigNumber&& sq = m_pubkey->getNSQ(); - return ipcl::ippModExp(a, b, sq); -} - -PaillierEncryptedNumber PaillierEncryptedNumber::rotate(int shift) const { - ERROR_CHECK(m_available != 1, - "rotate: Cannot rotate single PaillierEncryptedNumber"); - ERROR_CHECK(shift >= -8 && shift <= 8, - "rotate: Cannot shift more than 8 or -8"); - - if (shift == 0 || shift == 8 || shift == -8) - return PaillierEncryptedNumber(m_pubkey, m_bn); - - if (shift > 0) - shift = 8 - shift; - else - shift = -shift; - - std::vector&& new_bn = getArrayBN(); - - std::rotate(std::begin(new_bn), std::begin(new_bn) + shift, std::end(new_bn)); - return PaillierEncryptedNumber(m_pubkey, new_bn); -} - -} // namespace ipcl diff --git a/ipcl/paillier_prikey.cpp b/ipcl/pri_key.cpp similarity index 60% rename from ipcl/paillier_prikey.cpp rename to ipcl/pri_key.cpp index 5897e98..083c708 100644 --- a/ipcl/paillier_prikey.cpp +++ b/ipcl/pri_key.cpp @@ -1,7 +1,7 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include "ipcl/paillier_prikey.hpp" +#include "ipcl/pri_key.hpp" #include @@ -23,8 +23,8 @@ static inline BigNumber lcm(const BigNumber& p, const BigNumber& q) { return p * q / gcd; } -PaillierPrivateKey::PaillierPrivateKey(const PaillierPublicKey* public_key, - const BigNumber& p, const BigNumber& q) +PrivateKey::PrivateKey(const PublicKey* public_key, const BigNumber& p, + const BigNumber& q) : m_pubkey(public_key), m_n(m_pubkey->getN()), m_nsquare(m_pubkey->getNSQ()), @@ -49,30 +49,25 @@ PaillierPrivateKey::PaillierPrivateKey(const PaillierPublicKey* public_key, m_dwords(m_pubkey->getDwords()), m_enable_crt(true) { ERROR_CHECK(p * q == m_n, - "PaillierPrivateKey ctor: Public key does not match p * q."); - ERROR_CHECK(p != q, "PaillierPrivateKey ctor: p and q are same"); + "PrivateKey ctor: Public key does not match p * q."); + ERROR_CHECK(p != q, "PrivateKey ctor: p and q are same"); } -void PaillierPrivateKey::decryptRAW( - std::vector& plaintext, - const std::vector& ciphertext) const { +void PrivateKey::decryptRAW(std::vector& plaintext, + const std::vector& ciphertext) const { std::vector pow_lambda(IPCL_CRYPTO_MB_SIZE, m_lambda); std::vector modulo(IPCL_CRYPTO_MB_SIZE, m_nsquare); std::vector res = ipcl::ippModExp(ciphertext, pow_lambda, modulo); - BigNumber nn = m_n; - BigNumber xx = m_x; - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - BigNumber m = (res[i] - 1) / nn; - m = m * xx; - plaintext[i] = m % nn; + BigNumber m = (res[i] - 1) / m_n; + m *= m_x; + plaintext[i] = m % m_n; } } -void PaillierPrivateKey::decrypt( - std::vector& plaintext, - const std::vector& ciphertext) const { +void PrivateKey::decrypt(std::vector& plaintext, + const std::vector& ciphertext) const { VEC_SIZE_CHECK(plaintext); VEC_SIZE_CHECK(ciphertext); @@ -82,15 +77,14 @@ void PaillierPrivateKey::decrypt( decryptRAW(plaintext, ciphertext); } -void PaillierPrivateKey::decrypt( - std::vector& plaintext, - const PaillierEncryptedNumber ciphertext) const { +void PrivateKey::decrypt(std::vector& plaintext, + const EncryptedNumber ciphertext) const { VEC_SIZE_CHECK(plaintext); // check key match ERROR_CHECK(ciphertext.getPK().getN() == m_pubkey->getN(), "decrypt: public key mismatch error."); - std::vector&& res = ciphertext.getArrayBN(); + const std::vector& res = ciphertext.getArrayBN(); if (m_enable_crt) decryptCRT(plaintext, res); else @@ -98,9 +92,8 @@ void PaillierPrivateKey::decrypt( } // CRT to calculate base^exp mod n^2 -void PaillierPrivateKey::decryptCRT( - std::vector& plaintext, - const std::vector& ciphertext) const { +void PrivateKey::decryptCRT(std::vector& plaintext, + const std::vector& ciphertext) const { std::vector basep(IPCL_CRYPTO_MB_SIZE), baseq(IPCL_CRYPTO_MB_SIZE); std::vector pm1(IPCL_CRYPTO_MB_SIZE, m_pminusone), qm1(IPCL_CRYPTO_MB_SIZE, m_qminusone); @@ -113,34 +106,34 @@ void PaillierPrivateKey::decryptCRT( } // Based on the fact a^b mod n = (a mod n)^b mod n - std::vector&& resp = ipcl::ippModExp(basep, pm1, psq); - std::vector&& resq = ipcl::ippModExp(baseq, qm1, qsq); + std::vector resp = ipcl::ippModExp(basep, pm1, psq); + std::vector resq = ipcl::ippModExp(baseq, qm1, qsq); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - BigNumber&& dp = computeLfun(resp[i], m_p) * m_hp % m_p; - BigNumber&& dq = computeLfun(resq[i], m_q) * m_hq % m_q; + BigNumber dp = computeLfun(resp[i], m_p) * m_hp % m_p; + BigNumber dq = computeLfun(resq[i], m_q) * m_hq % m_q; plaintext[i] = computeCRT(dp, dq); } } -BigNumber PaillierPrivateKey::computeCRT(const BigNumber& mp, - const BigNumber& mq) const { - BigNumber&& u = (mq - mp) * m_pinverse % m_q; +BigNumber PrivateKey::computeCRT(const BigNumber& mp, + const BigNumber& mq) const { + BigNumber u = (mq - mp) * m_pinverse % m_q; return mp + (u * m_p); } -BigNumber PaillierPrivateKey::computeLfun(const BigNumber& a, - const BigNumber& b) const { +BigNumber PrivateKey::computeLfun(const BigNumber& a, + const BigNumber& b) const { return (a - 1) / b; } -BigNumber PaillierPrivateKey::computeHfun(const BigNumber& a, - const BigNumber& b) const { +BigNumber PrivateKey::computeHfun(const BigNumber& a, + const BigNumber& b) const { // Based on the fact a^b mod n = (a mod n)^b mod n - BigNumber&& xm = a - 1; - BigNumber&& base = m_g % b; - BigNumber&& pm = ipcl::ippModExp(base, xm, b); - BigNumber&& lcrt = computeLfun(pm, a); + BigNumber xm = a - 1; + BigNumber base = m_g % b; + BigNumber pm = ipcl::ippModExp(base, xm, b); + BigNumber lcrt = computeLfun(pm, a); return a.InverseMul(lcrt); } diff --git a/ipcl/paillier_pubkey.cpp b/ipcl/pub_key.cpp similarity index 71% rename from ipcl/paillier_pubkey.cpp rename to ipcl/pub_key.cpp index e3e80f1..f3d347b 100644 --- a/ipcl/paillier_pubkey.cpp +++ b/ipcl/pub_key.cpp @@ -1,7 +1,7 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include "ipcl/paillier_pubkey.hpp" +#include "ipcl/pub_key.hpp" #include @@ -26,8 +26,7 @@ static inline auto randomUniformUnsignedInt() { return dist(rng); } -PaillierPublicKey::PaillierPublicKey(const BigNumber& n, int bits, - bool enableDJN_) +PublicKey::PublicKey(const BigNumber& n, int bits, bool enableDJN_) : m_n(n), m_g(n + 1), m_nsquare(n * n), @@ -40,7 +39,7 @@ PaillierPublicKey::PaillierPublicKey(const BigNumber& n, int bits, } // array of 32-bit random, using rand() from stdlib -std::vector PaillierPublicKey::randIpp32u(int size) const { +std::vector PublicKey::randIpp32u(int size) const { std::vector addr(size); // TODO(skmono): check if copy of m_init_seed is needed for const unsigned int init_seed = m_init_seed; @@ -48,28 +47,28 @@ std::vector PaillierPublicKey::randIpp32u(int size) const { return addr; } -// length is Arbitery -BigNumber PaillierPublicKey::getRandom(int length) const { +// length is arbitrary +BigNumber PublicKey::getRandom(int length) const { IppStatus stat; int size; - int seedBitSize = 160; - int seedSize = BITSIZE_WORD(seedBitSize); + constexpr int seedBitSize = 160; + constexpr int seedSize = BITSIZE_WORD(seedBitSize); stat = ippsPRNGGetSize(&size); ERROR_CHECK(stat == ippStsNoErr, "getRandom: get IppsPRNGState context error."); - auto pRand = std::vector(size); + auto rands = std::vector(size); stat = - ippsPRNGInit(seedBitSize, reinterpret_cast(pRand.data())); + ippsPRNGInit(seedBitSize, reinterpret_cast(rands.data())); ERROR_CHECK(stat == ippStsNoErr, "getRandom: init rand context error."); - auto&& seed = randIpp32u(seedSize); + auto seed = randIpp32u(seedSize); BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); stat = ippsPRNGSetSeed(BN(bseed), - reinterpret_cast(pRand.data())); + reinterpret_cast(rands.data())); ERROR_CHECK(stat == ippStsNoErr, "getRandom: set up seed value error."); // define length Big Numbers @@ -86,33 +85,31 @@ BigNumber PaillierPublicKey::getRandom(int length) const { int bnBitSize = length; ippsPRNGenRDRAND_BN(pBN, bnBitSize, - reinterpret_cast(pRand.data())); - BigNumber rand(pBN); + reinterpret_cast(rands.data())); - return rand; + return BigNumber{pBN}; } -void PaillierPublicKey::enableDJN() { +void PublicKey::enableDJN() { BigNumber gcd; BigNumber rmod; do { int rand_bit = m_n.BitSize(); - BigNumber&& rand = getRandom(rand_bit + 128); + BigNumber rand = getRandom(rand_bit + 128); rmod = rand % m_n; gcd = rand.gcd(m_n); } while (gcd.compare(1)); - BigNumber&& rmod_sq = rmod * rmod; - BigNumber&& rmod_neg = rmod_sq * -1; - BigNumber&& h = rmod_neg % m_n; + BigNumber rmod_sq = rmod * rmod; + BigNumber rmod_neg = rmod_sq * -1; + BigNumber h = rmod_neg % m_n; m_hs = ipcl::ippModExp(h, m_n, m_nsquare); m_randbits = m_bits >> 1; // bits/2 m_enable_DJN = true; } -void PaillierPublicKey::apply_obfuscator( - std::vector& obfuscator) const { +void PublicKey::applyObfuscator(std::vector& obfuscator) const { std::vector r(IPCL_CRYPTO_MB_SIZE); std::vector pown(IPCL_CRYPTO_MB_SIZE, m_n); std::vector base(IPCL_CRYPTO_MB_SIZE, m_hs); @@ -140,16 +137,16 @@ void PaillierPublicKey::apply_obfuscator( } } -void PaillierPublicKey::setRandom(const std::vector& r) { +void PublicKey::setRandom(const std::vector& r) { VEC_SIZE_CHECK(r); std::copy(r.begin(), r.end(), std::back_inserter(m_r)); m_testv = true; } -void PaillierPublicKey::raw_encrypt(std::vector& ciphertext, - const std::vector& plaintext, - bool make_secure) const { +void PublicKey::raw_encrypt(std::vector& ciphertext, + const std::vector& plaintext, + bool make_secure) const { // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 BigNumber sq = m_nsquare; for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { @@ -159,16 +156,16 @@ void PaillierPublicKey::raw_encrypt(std::vector& ciphertext, if (make_secure) { std::vector obfuscator(IPCL_CRYPTO_MB_SIZE); - apply_obfuscator(obfuscator); + applyObfuscator(obfuscator); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) ciphertext[i] = sq.ModMul(ciphertext[i], obfuscator[i]); } } -void PaillierPublicKey::encrypt(std::vector& ciphertext, - const std::vector& value, - bool make_secure) const { +void PublicKey::encrypt(std::vector& ciphertext, + const std::vector& value, + bool make_secure) const { VEC_SIZE_CHECK(ciphertext); VEC_SIZE_CHECK(value); @@ -176,12 +173,9 @@ void PaillierPublicKey::encrypt(std::vector& ciphertext, } // Used for CT+PT, where PT do not need to add obfuscator -void PaillierPublicKey::encrypt(BigNumber& ciphertext, - const BigNumber& value) const { +void PublicKey::encrypt(BigNumber& ciphertext, const BigNumber& value) const { // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 - BigNumber bn = value; - BigNumber sq = m_nsquare; - ciphertext = (m_n * bn + 1) % sq; + ciphertext = (m_n * value + 1) % m_nsquare; /*----- Path to caculate (n+1)^plaintext mod n^2 ------------ BigNumber bn(value); diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index c0cfe75..931b0ac 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -11,8 +11,8 @@ #endif // IPCL_USE_OMP #include "gtest/gtest.h" -#include "ipcl/paillier_keygen.hpp" -#include "ipcl/paillier_ops.hpp" +#include "ipcl/keygen.hpp" +#include "ipcl/ops.hpp" TEST(CryptoTest, CryptoTest) { ipcl::keyPair key = ipcl::generateKeypair(2048, true); @@ -124,10 +124,8 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { ipcl::BigNumber n = p * q; int n_length = n.BitSize(); - ipcl::PaillierPublicKey* public_key = - new ipcl::PaillierPublicKey(n, n_length); - ipcl::PaillierPrivateKey* private_key = - new ipcl::PaillierPrivateKey(public_key, p, q); + ipcl::PublicKey* public_key = new ipcl::PublicKey(n, n_length); + ipcl::PrivateKey* private_key = new ipcl::PrivateKey(public_key, p, q); ipcl::keyPair key = {public_key, private_key}; @@ -219,9 +217,9 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { key.pub_key->encrypt(ct, ptbn); - ipcl::PaillierEncryptedNumber a(key.pub_key, ct[0]); - ipcl::PaillierEncryptedNumber b(key.pub_key, ct[1]); - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber a(key.pub_key, ct[0]); + ipcl::EncryptedNumber b(key.pub_key, ct[1]); + ipcl::EncryptedNumber sum = a + b; ipcl::BigNumber res = sum.getBN(); std::vector ct12(8); diff --git a/test/test_ops.cpp b/test/test_ops.cpp index c2ab740..c7a830a 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -11,17 +11,17 @@ #endif // IPCL_USE_OMP #include "gtest/gtest.h" -#include "ipcl/paillier_keygen.hpp" -#include "ipcl/paillier_ops.hpp" +#include "ipcl/keygen.hpp" +#include "ipcl/ops.hpp" void CtPlusCt(std::vector& res, const std::vector& ct1, const std::vector& ct2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); - ipcl::PaillierEncryptedNumber b(key.pub_key, ct2[i]); - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber a(key.pub_key, ct1[i]); + ipcl::EncryptedNumber b(key.pub_key, ct2[i]); + ipcl::EncryptedNumber sum = a + b; res[i] = sum.getBN(); } } @@ -30,9 +30,9 @@ void CtPlusCtArray(std::vector& res, const std::vector& ct1, const std::vector& ct2, const ipcl::keyPair key) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1); - ipcl::PaillierEncryptedNumber b(key.pub_key, ct2); - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber a(key.pub_key, ct1); + ipcl::EncryptedNumber b(key.pub_key, ct2); + ipcl::EncryptedNumber sum = a + b; res = sum.getArrayBN(); } @@ -40,9 +40,9 @@ void CtPlusPt(std::vector& res, const std::vector& ct1, const std::vector& pt2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); + ipcl::EncryptedNumber a(key.pub_key, ct1[i]); ipcl::BigNumber b = pt2[i]; - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber sum = a + b; res[i] = sum.getBN(); } } @@ -51,8 +51,8 @@ void CtPlusPtArray(std::vector& res, const std::vector& ct1, const std::vector& ptbn2, const ipcl::keyPair key) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1); - ipcl::PaillierEncryptedNumber sum = a + ptbn2; + ipcl::EncryptedNumber a(key.pub_key, ct1); + ipcl::EncryptedNumber sum = a + ptbn2; res = sum.getArrayBN(); } @@ -60,9 +60,9 @@ void CtMultiplyPt(std::vector& res, const std::vector& ct1, const std::vector& pt2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); - ipcl::PaillierEncryptedNumber b(key.pub_key, pt2[i]); - ipcl::PaillierEncryptedNumber sum = a * b; + ipcl::EncryptedNumber a(key.pub_key, ct1[i]); + ipcl::EncryptedNumber b(key.pub_key, pt2[i]); + ipcl::EncryptedNumber sum = a * b; res[i] = sum.getBN(); } } @@ -71,9 +71,9 @@ void CtMultiplyPtArray(std::vector& res, const std::vector& ct1, const std::vector& pt2, const ipcl::keyPair key) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1); - ipcl::PaillierEncryptedNumber b(key.pub_key, pt2); - ipcl::PaillierEncryptedNumber sum = a * b; + ipcl::EncryptedNumber a(key.pub_key, ct1); + ipcl::EncryptedNumber b(key.pub_key, pt2); + ipcl::EncryptedNumber sum = a * b; res = sum.getArrayBN(); } @@ -81,11 +81,11 @@ void AddSub(std::vector& res, const std::vector& ct1, const std::vector& ct2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, ct1[i]); - ipcl::PaillierEncryptedNumber b(key.pub_key, ct2[i]); + ipcl::EncryptedNumber a(key.pub_key, ct1[i]); + ipcl::EncryptedNumber b(key.pub_key, ct2[i]); ipcl::BigNumber m1(2); a = a + b * m1; - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber sum = a + b; res[i] = sum.getBN(); } } @@ -418,9 +418,9 @@ void CtPlusCt_OMP(int num_threads, #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); - ipcl::PaillierEncryptedNumber b(key.pub_key, v_ct2[i][j]); - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); + ipcl::EncryptedNumber b(key.pub_key, v_ct2[i][j]); + ipcl::EncryptedNumber sum = a + b; v_sum[i][j] = sum.getBN(); } } @@ -435,8 +435,8 @@ void CtPlusPt_OMP(int num_threads, for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { ipcl::BigNumber b = v_pt2[i][j]; - ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); + ipcl::EncryptedNumber sum = a + b; v_sum[i][j] = sum.getBN(); } } @@ -449,12 +449,12 @@ void CtPlusPtArray_OMP(int num_threads, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); + ipcl::EncryptedNumber a(key.pub_key, v_ct1[i]); std::vector b(8); for (int j = 0; j < 8; j++) { b[j] = v_pt2[i][j]; } - ipcl::PaillierEncryptedNumber sum = a + b; + ipcl::EncryptedNumber sum = a + b; v_sum[i] = sum.getArrayBN(); } } @@ -467,9 +467,9 @@ void CtMultiplyPt_OMP(int num_threads, #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i][j]); + ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); ipcl::BigNumber b = v_pt2[i][j]; - ipcl::PaillierEncryptedNumber product = a * b; + ipcl::EncryptedNumber product = a * b; v_product[i][j] = product.getBN(); } } @@ -481,9 +481,9 @@ void CtMultiplyPtArray_OMP( const std::vector>& v_pt2, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - ipcl::PaillierEncryptedNumber a(key.pub_key, v_ct1[i]); - ipcl::PaillierEncryptedNumber b(key.pub_key, v_pt2[i]); - ipcl::PaillierEncryptedNumber product = a * b; + ipcl::EncryptedNumber a(key.pub_key, v_ct1[i]); + ipcl::EncryptedNumber b(key.pub_key, v_pt2[i]); + ipcl::EncryptedNumber product = a * b; v_product[i] = product.getArrayBN(); } } From 55d39038b74f7ed90eb568f42e2533b2716caba6 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Tue, 15 Mar 2022 14:22:53 -0700 Subject: [PATCH 117/364] Modifed benchmark cases for larger inputs - Addresses #60 (#61) --- benchmark/bench_cryptography.cpp | 45 +++++++++++------------------- benchmark/bench_ops.cpp | 48 ++++++++++++++++---------------- 2 files changed, 41 insertions(+), 52 deletions(-) diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index b9ffb9d..74b4bca 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -27,9 +27,8 @@ static void BM_Encrypt(benchmark::State& state) { std::vector> ct(dsize, std::vector(8)); - for (size_t i = 0; i < dsize; ++i) { - pt[i][0] = ipcl::BigNumber((unsigned int)i); - } + for (size_t i = 0; i < dsize; ++i) + pt[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); for (auto _ : state) { for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -47,10 +46,8 @@ static void BM_Encrypt_buff8(benchmark::State& state) { std::vector> ct(dsize / 8, std::vector(8)); - for (size_t i = 0; i < dsize / 8; ++i) { - for (size_t j = 0; j < 8; ++j) - pt[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); - } + for (size_t i = 0; i < dsize; ++i) + pt[i / 8][i & 7] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); for (auto _ : state) { for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -73,9 +70,8 @@ static void BM_Decrypt(benchmark::State& state) { std::vector> de_ct( dsize, std::vector(8)); - for (size_t i = 0; i < dsize; ++i) { - pt[i][0] = ipcl::BigNumber((unsigned int)i); - } + for (size_t i = 0; i < dsize; ++i) + pt[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -99,10 +95,8 @@ static void BM_Decrypt_buff8(benchmark::State& state) { std::vector> de_ct( dsize / 8, std::vector(8)); - for (size_t i = 0; i < dsize / 8; ++i) { - for (size_t j = 0; j < 8; ++j) - pt[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); - } + for (size_t i = 0; i < dsize; ++i) + pt[i / 8][i & 7] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -127,9 +121,8 @@ static void BM_Encrypt_OMP(benchmark::State& state) { std::vector> ct(dsize, std::vector(8)); - for (size_t i = 0; i < dsize; ++i) { - pt[i][0] = ipcl::BigNumber((unsigned int)i); - } + for (size_t i = 0; i < dsize; ++i) + pt[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); for (auto _ : state) { #pragma omp parallel for @@ -150,10 +143,8 @@ static void BM_Encrypt_buff8_OMP(benchmark::State& state) { std::vector> ct(dsize / 8, std::vector(8)); - for (size_t i = 0; i < dsize / 8; ++i) { - for (size_t j = 0; j < 8; ++j) - pt[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); - } + for (size_t i = 0; i < dsize; ++i) + pt[i / 8][i & 7] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); for (auto _ : state) { #pragma omp parallel for @@ -176,9 +167,9 @@ static void BM_Decrypt_OMP(benchmark::State& state) { std::vector(8)); std::vector> de_ct( dsize, std::vector(8)); - for (size_t i = 0; i < dsize; ++i) { - pt[i][0] = ipcl::BigNumber((unsigned int)i); - } + + for (size_t i = 0; i < dsize; ++i) + pt[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -206,10 +197,8 @@ static void BM_Decrypt_buff8_OMP(benchmark::State& state) { std::vector> de_ct( dsize / 8, std::vector(8)); - for (size_t i = 0; i < dsize / 8; ++i) { - for (size_t j = 0; j < 8; ++j) - pt[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); - } + for (size_t i = 0; i < dsize; ++i) + pt[i / 8][i & 7] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index 5282223..d3bc8c0 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -26,10 +26,10 @@ static void BM_Add_CTCT(benchmark::State& state) { dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)i); + a[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); key.pub_key->encrypt(ct_a[i], a[i]); - b[i][0] = ipcl::BigNumber((unsigned int)i); + b[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); key.pub_key->encrypt(ct_b[i], b[i]); } @@ -59,8 +59,8 @@ static void BM_Add_CTCT_buff8(benchmark::State& state) { for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -93,8 +93,8 @@ static void BM_Add_CTPT(benchmark::State& state) { dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)i); - b[i][0] = ipcl::BigNumber((unsigned int)i); + a[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); + b[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); key.pub_key->encrypt(ct_a[i], a[i]); } @@ -121,8 +121,8 @@ static void BM_Add_CTPT_buff8(benchmark::State& state) { for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -153,8 +153,8 @@ static void BM_Mul_CTPT(benchmark::State& state) { dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)i); - b[i][0] = ipcl::BigNumber((unsigned int)i); + a[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); + b[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); key.pub_key->encrypt(ct_a[i], a[i]); } @@ -182,8 +182,8 @@ static void BM_Mul_CTPT_buff8(benchmark::State& state) { for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -218,10 +218,10 @@ static void BM_Add_CTCT_OMP(benchmark::State& state) { dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)i); + a[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); key.pub_key->encrypt(ct_a[i], a[i]); - b[i][0] = ipcl::BigNumber((unsigned int)i); + b[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); key.pub_key->encrypt(ct_b[i], b[i]); } @@ -255,8 +255,8 @@ static void BM_Add_CTCT_buff8_OMP(benchmark::State& state) { for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -290,8 +290,8 @@ static void BM_Add_CTPT_OMP(benchmark::State& state) { dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)i); - b[i][0] = ipcl::BigNumber((unsigned int)i); + a[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); + b[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); key.pub_key->encrypt(ct_a[i], a[i]); } @@ -322,8 +322,8 @@ static void BM_Add_CTPT_buff8_OMP(benchmark::State& state) { for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -355,8 +355,8 @@ static void BM_Mul_CTPT_OMP(benchmark::State& state) { dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)i); - b[i][0] = ipcl::BigNumber((unsigned int)i); + a[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); + b[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); key.pub_key->encrypt(ct_a[i], a[i]); } @@ -388,8 +388,8 @@ static void BM_Mul_CTPT_buff8_OMP(benchmark::State& state) { for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); } key.pub_key->encrypt(ct_a[i], a[i]); From 995ee5d85b921c84b29d86c6f7ad73a0b9aea80a Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 15 Mar 2022 18:32:56 -0700 Subject: [PATCH 118/364] Enable different ModExp callback func to support different ModExp interfaces. --- he_qat/he_qat_bn_ops.c | 17 ++++------------- he_qat/include/he_qat_bn_ops.h | 1 + he_qat/include/he_qat_types.h | 2 +- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index 5535c32..5cc52ea 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -75,12 +75,6 @@ static void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { _buffer->next_free_slot %= HE_QAT_BUFFER_SIZE; _buffer->count++; - /* now: either b->occupied < BSIZE and b->nextin is the index - of the next empty slot in the buffer, or - b->occupied == BSIZE and b->nextin is the index of the - next (occupied) slot that will be emptied by a consumer - (such as b->nextin == b->nextout) */ - pthread_cond_signal(&_buffer->any_more_data); pthread_mutex_unlock(&_buffer->mutex); } @@ -105,12 +99,6 @@ static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) { _buffer->next_data_slot %= HE_QAT_BUFFER_SIZE; _buffer->count--; - /* now: either b->occupied > 0 and b->nextout is the index - of the next occupied slot in the buffer, or - b->occupied == 0 and b->nextout is the index of the next - (empty) slot that will be filled by a producer (such as - b->nextout == b->nextin) */ - pthread_cond_signal(&_buffer->any_free_slot); pthread_mutex_unlock(&_buffer->mutex); @@ -220,7 +208,8 @@ void* start_perform_op(void* _inst_config) { switch (request->op_type) { // Select appropriate action case HE_QAT_OP_MODEXP: - status = cpaCyLnModExp(config->inst_handle, lnModExpCallback, + status = cpaCyLnModExp(config->inst_handle, + (CpaCyGenFlatBufCbFunc)request->callback_func, //lnModExpCallback, (void*)request, (CpaCyLnModExpOpData*)request->op_data, &request->op_result); @@ -423,6 +412,7 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, } request->op_type = HE_QAT_OP_MODEXP; + request->callback_func = (void*)lnModExpCallback; request->op_status = status; request->op_output = (void*)r; @@ -626,6 +616,7 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, } request->op_type = HE_QAT_OP_MODEXP; + request->callback_func = (void*)HE_QAT_bnModExpCallback; request->op_status = status; request->op_output = (void*)r; diff --git a/he_qat/include/he_qat_bn_ops.h b/he_qat/include/he_qat_bn_ops.h index 47afe7d..bba1dba 100644 --- a/he_qat/include/he_qat_bn_ops.h +++ b/he_qat/include/he_qat_bn_ops.h @@ -33,6 +33,7 @@ typedef struct { // CpaCyLnModExpOpData op_data; void* op_data; void* op_output; + void* callback_func; HE_QAT_STATUS request_status; pthread_mutex_t mutex; pthread_cond_t ready; diff --git a/he_qat/include/he_qat_types.h b/he_qat/include/he_qat_types.h index 743d9f7..fa97f1a 100644 --- a/he_qat/include/he_qat_types.h +++ b/he_qat/include/he_qat_types.h @@ -13,7 +13,7 @@ extern "C" { #include -#define HE_QAT_BUFFER_SIZE 16 +#define HE_QAT_BUFFER_SIZE 8 // Type definitions typedef enum { HE_QAT_SYNC = 1, HE_QAT_ASYNC = 2 } HE_QAT_EXEC_MODE; From a2164a1bd9b02abb60b99569769b53a6fb84456f Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 15 Mar 2022 18:35:14 -0700 Subject: [PATCH 119/364] Add sample showing how the BigNumber ModExp on QAT is supported. --- samples/CMakeLists.txt | 15 +++ samples/test_bnModExp.cpp | 221 +++++++++++++++++++++++++++++++ samples/test_bnModExpPerformOp.c | 75 +---------- 3 files changed, 239 insertions(+), 72 deletions(-) create mode 100644 samples/test_bnModExp.cpp diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 7938585..deb43ec 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -34,6 +34,7 @@ install(TARGETS test_bnModExpPerformOp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDI if(HE_QAT_MISC) add_compile_options(-fpermissive) + # Sample showing how to convert from/to BigNumber to/from CpaFlatBuffer add_executable(test_bnConversion test_bnConversion.cpp) target_include_directories(test_bnConversion PUBLIC ${COMMON_INC_DIR}) @@ -46,4 +47,18 @@ if(HE_QAT_MISC) target_link_libraries(test_bnConversion PUBLIC OpenSSL::SSL) # OpenSSL::Crypto) install(TARGETS test_bnConversion RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + + # Sample demonstrating how to use bnModExp with BigNumber type + add_executable(test_bnModExp test_bnModExp.cpp) + + target_include_directories(test_bnModExp PUBLIC ${COMMON_INC_DIR}) + target_include_directories(test_bnModExp PUBLIC ${ICP_INC_DIR}) + target_include_directories(test_bnModExp PUBLIC ${HE_QAT_MISC_INC_DIR}) + + target_link_libraries(test_bnModExp PUBLIC he_qat) + target_link_libraries(test_bnModExp PUBLIC he_qat_misc) + target_link_libraries(test_bnModExp PUBLIC IPPCP::ippcp) # IPPCP::crypto_mb) + target_link_libraries(test_bnModExp PUBLIC OpenSSL::SSL) # OpenSSL::Crypto) + + install(TARGETS test_bnModExp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() diff --git a/samples/test_bnModExp.cpp b/samples/test_bnModExp.cpp new file mode 100644 index 0000000..189dd2d --- /dev/null +++ b/samples/test_bnModExp.cpp @@ -0,0 +1,221 @@ + +#include "he_qat_misc.h" +#include "he_qat_utils.h" +#include "he_qat_bn_ops.h" +#include "he_qat_context.h" +#include "cpa_sample_utils.h" + +#include +#include +#include +#include + +#include +#include + +#ifdef _DESTINY_DEBUG_VERBOSE +int gDebugParam = 1; +#endif + +const unsigned int BATCH_SIZE = 1; + +int main(int argc, const char** argv) { + const int bit_length = 2048; + const size_t num_trials = 4; + + double avg_speed_up = 0.0; + double ssl_avg_time = 0.0; + double qat_avg_time = 0.0; + + clock_t start = CLOCKS_PER_SEC; + clock_t ssl_elapsed = CLOCKS_PER_SEC; + clock_t qat_elapsed = CLOCKS_PER_SEC; + + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + // Set up QAT runtime context + acquire_qat_devices(); + + // Set up OpenSSL context (as baseline) + BN_CTX* ctx = BN_CTX_new(); + BN_CTX_start(ctx); + + for (unsigned int mod = 0; mod < num_trials; mod++) { + // Generate modulus number + BIGNUM* bn_mod = generateTestBNData(bit_length); + + if (!bn_mod) continue; + + char* bn_str = BN_bn2hex(bn_mod); + printf("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, + BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); + OPENSSL_free(bn_str); + + // Generate exponent in [0..bn_mod] + BIGNUM* bn_exponent = BN_new(); + if (!BN_rand_range(bn_exponent, bn_mod)) { + BN_free(bn_mod); + continue; + } + + // Generate base number + BIGNUM* bn_base = generateTestBNData(bit_length); + + // Perform OpenSSL ModExp Op + BIGNUM* ssl_res = BN_new(); + start = clock(); + BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); + ssl_elapsed = clock() - start; + + int len_ = (bit_length + 7) >> 3; + + // Start QAT timer (including data conversion overhead) + start = clock(); + + unsigned char* bn_base_data_ = + (unsigned char*)calloc(len_, sizeof(unsigned char)); + if (NULL == bn_base_data_) exit(1); + BN_bn2binpad(bn_base, bn_base_data_, len_); + unsigned char* bn_mod_data_ = + (unsigned char*)calloc(len_, sizeof(unsigned char)); + if (NULL == bn_mod_data_) exit(1); + BN_bn2binpad(bn_mod, bn_mod_data_, len_); + unsigned char* bn_exponent_data_ = + (unsigned char*)calloc(len_, sizeof(unsigned char)); + if (NULL == bn_exponent_data_) exit(1); + BN_bn2binpad(bn_exponent, bn_exponent_data_, len_); + unsigned char* bn_remainder_data_ = + (unsigned char*)calloc(len_, sizeof(unsigned char)); + if (NULL == bn_remainder_data_) exit(1); + + clock_t cvt_elapsed = clock() - start; + + // Simulate input number in BigNumber representation + BigNumber big_num_base((Ipp32u)0); + BigNumber big_num_mod((Ipp32u)0); + BigNumber big_num_exponent((Ipp32u)0); + status = binToBigNumber(big_num_base, bn_base_data_, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("Failed at binToBigNumber()\n"); + exit(1); + } + status = binToBigNumber(big_num_mod, bn_mod_data_, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("Failed at binToBigNumber()\n"); + exit(1); + } + status = binToBigNumber(big_num_exponent, bn_exponent_data_, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("Failed at binToBigNumber()\n"); + exit(1); + } + + // Reset numbers to 0 + memset(bn_base_data_,0,len_); + memset(bn_mod_data_,0,len_); + memset(bn_exponent_data_,0,len_); + // Make sure variables are reset + if (memcmp(bn_base_data_, bn_mod_data_, len_) || + memcmp(bn_base_data_, bn_exponent_data_, len_)) { + PRINT_ERR("Pointers are not reset to zero!"); + exit(1); + } + + start = clock(); + status = bigNumberToBin(bn_base_data_, bit_length, big_num_base); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("bn_base_data_: failed at bignumbertobin()\n"); + exit(1); + } + status = bigNumberToBin(bn_mod_data_, bit_length, big_num_mod); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("bn_base_data_: failed at bignumbertobin()\n"); + exit(1); + } + status = bigNumberToBin(bn_exponent_data_, bit_length, big_num_exponent); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("bn_base_data_: failed at bignumbertobin()\n"); + exit(1); + } + cvt_elapsed += (clock() - start); + + // Perform BigNumber modular exponentiation on QAT + start = clock(); + status = HE_QAT_bnModExp(bn_remainder_data_, bn_base_data_, + bn_exponent_data_, bn_mod_data_, bit_length); + getBnModExpRequest(BATCH_SIZE); + qat_elapsed = clock() - start; + + printf("BigNumber data conversion overhead: %.1lfus.\n", + (cvt_elapsed / (CLOCKS_PER_SEC / 1000000.0))); + printf("BigNumber modular exponentiation on QAT: %.1lfus.\n", + (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); + qat_elapsed += cvt_elapsed; + + BIGNUM* qat_res = BN_new(); + BN_bin2bn(bn_remainder_data_, len_, qat_res); + + if (HE_QAT_STATUS_SUCCESS != status) { + PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); + } +#ifdef _DESTINY_DEBUG_VERBOSE + else { + PRINT_DBG("\nQAT bnModExpOp finished\n"); + } +#endif + + start = clock(); + BigNumber big_num((Ipp32u)0); + status = binToBigNumber(big_num, bn_remainder_data_, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("bn_remainder_data_: Failed at bigNumberToBin()\n"); + exit(1); + } + qat_elapsed += (clock() - start); + printf("BigNumber ModExp total time: %.1lfus.\n", + (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); + +#ifdef _DESTINY_DEBUG_VERBOSE + bn_str = BN_bn2hex(qat_res); + printf("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, + BN_num_bytes(qat_res), BN_num_bits(qat_res)); +#endif + +#ifdef _DESTINY_DEBUG_VERBOSE + int bit_len = 0; + ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); + std::string str; + big_num.num2hex(str); + printf("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, + bit_len); + printf("---------------------################-----------------------\n"); +#endif + + if (BN_cmp(qat_res, ssl_res) != 0) + printf("\t** FAIL **\n"); + else + printf("\t** PASS **\n"); + + BN_free(bn_mod); + BN_free(bn_base); + BN_free(bn_exponent); + BN_free(qat_res); + BN_free(ssl_res); + +// OPENSSL_free(bn_str); + + free(bn_mod_data_); + free(bn_base_data_); + free(bn_exponent_data_); + free(bn_remainder_data_); + + } + + // Tear down OpenSSL context + BN_CTX_end(ctx); + + // Tear down QAT runtime context + release_qat_devices(); + + return (int)status; +} diff --git a/samples/test_bnModExpPerformOp.c b/samples/test_bnModExpPerformOp.c index 3561f53..cb41d51 100644 --- a/samples/test_bnModExpPerformOp.c +++ b/samples/test_bnModExpPerformOp.c @@ -1,6 +1,6 @@ #include "cpa_sample_utils.h" - +#include "he_qat_utils.h" #include "he_qat_bn_ops.h" #include "he_qat_context.h" @@ -9,77 +9,8 @@ #include #include -#define LEN_OF_1024_BITS 128 -#define LEN_OF_2048_BITS 256 -#define msb_CAN_BE_ZERO -1 -#define msb_IS_ONE 0 -#define EVEN_RND_NUM 0 -#define ODD_RND_NUM 1 -#define BATCH_SIZE 1 - -// int gDebugParam = 1; - -BIGNUM* generateTestBNData(int nbits) { - if (!RAND_status()) return NULL; -#ifdef _DESTINY_DEBUG_VERBOSE - printf("PRNG properly seeded.\n"); -#endif - - BIGNUM* bn = BN_new(); - - if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { - BN_free(bn); - printf("Error while generating BN random number: %lu\n", - ERR_get_error()); - return NULL; - } - - return bn; -} - -unsigned char* paddingZeros(BIGNUM* bn, int nbits) { - if (!bn) return NULL; - - // Returns same address if it fails - int num_bytes = BN_num_bytes(bn); - int bytes_left = nbits / 8 - num_bytes; - if (bytes_left <= 0) return NULL; - - // Returns same address if it fails - unsigned char* bin = NULL; - int len = bytes_left + num_bytes; - if (!(bin = OPENSSL_zalloc(len))) return NULL; - -#ifdef _DESTINY_DEBUG_VERBOSE - printf("Padding bn with %d bytes to total %d bytes\n", bytes_left, len); -#endif - BN_bn2binpad(bn, bin, len); - if (ERR_get_error()) { - OPENSSL_free(bin); - return NULL; - } - - return bin; -} - -void showHexBN(BIGNUM* bn, int nbits) { - int len = nbits / 8; - unsigned char* bin = OPENSSL_zalloc(len); - if (!bin) return; - if (BN_bn2binpad(bn, bin, len)) { - for (size_t i = 0; i < len; i++) printf("%d", bin[i]); - printf("\n"); - } - OPENSSL_free(bin); - return; -} - -void showHexBin(unsigned char* bin, int len) { - if (!bin) return; - for (size_t i = 0; i < len; i++) printf("%d", bin[i]); - printf("\n"); - return; -} +int gDebugParam = 1; // Active in Debug mode +const unsigned int BATCH_SIZE = 1; int main(int argc, const char** argv) { const int bit_length = 4096; // 1024; From a0448fabec454e8047f9ef1be0c953a1d75d85e5 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 15 Mar 2022 22:24:50 -0700 Subject: [PATCH 120/364] Minor change to common/CMakeLists.txt --- common/CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 226e0fc..6ce9dce 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -11,8 +11,8 @@ set(COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/cpa_sample_utils.c) add_library(cpa_sample_utils ${COMMON_SRC}) target_include_directories(cpa_sample_utils - PUBLIC $ # Public headers - # PUBLIC $ # Public headers + PRIVATE $ # Public headers + PRIVATE $ # Public headers PUBLIC $ # Public headers PRIVATE ${COMMON_INC_DIR} # Private headers PRIVATE ${ICP_INC_DIR} # Private headers @@ -21,6 +21,8 @@ target_link_libraries(cpa_sample_utils PRIVATE udev z) target_link_libraries(cpa_sample_utils PRIVATE ${ICP_BUILDOUTPUT_PATH}/libqat_s.so) target_link_libraries(cpa_sample_utils PRIVATE ${ICP_BUILDOUTPUT_PATH}/libusdm_drv_s.so) +install(TARGETS cpa_sample_utils DESTINATION ${CMAKE_INSTALL_LIBDIR}) + set(COMMON_INC_DIR ${COMMON_INC_DIR} PARENT_SCOPE) From 296caa21ff6a32d54f829ca01f7b64210d89ea06 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 16 Mar 2022 10:35:24 -0700 Subject: [PATCH 121/364] Unset and parameterize CMAKE_PREFIX_PATH to find IPP Crypto (IPPCP_PREFIX_PATH). --- CMakeLists.txt | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 40c4df3..968294d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,9 +43,9 @@ set(CMAKE_INSTALL_MESSAGE LAZY) # Why? set(CMAKE_INSTALL_RPATH "\$ORIGIN") -#if(NOT CMAKE_INSTALL_PREFIX) - set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_LIST_DIR}/install) - #endif() +if(NOT CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_LIST_DIR}/install) +endif() message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") # Which features or functions does it bring? @@ -76,6 +76,17 @@ set(HE_QAT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) set(HE_QAT_SRC_DIR ${HE_QAT_ROOT_DIR}/he_qat) set(HE_QAT_INC_DIR ${HE_QAT_ROOT_DIR}/he_qat/include) +if(HE_QAT_MISC) + # IPP Crypto installation + if(IPPCP_PREFIX_PATH) + #set(IPPCP_DIR "/opt/ipp-crypto") + #set(IPPCP_CMAKE_PREFIX_PATH "${IPPCP_DIR}/lib/cmake") + list(APPEND CMAKE_PREFIX_PATH "${IPPCP_PREFIX_PATH}") + endif() + find_package(IPPCP REQUIRED) + message(STATUS "IPPCP_LIBRARIES ${IPPCP_LIBRARIES}") +endif() + set(HE_QAT_FORWARD_CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} @@ -112,19 +123,8 @@ include(icp/CMakeLists.txt) #Common utility functions add_subdirectory(common) +# Helper functions for BigNumber if(HE_QAT_MISC) - # IPP Crypto installation - if(NOT IPPCP_CMAKE_PREFIX_PATH) - set(IPPCP_DIR "/opt/ipp-crypto") - set(IPPCP_CMAKE_PREFIX_PATH "${IPPCP_DIR}/lib/cmake") - list(APPEND CMAKE_PREFIX_PATH "${IPPCP_CMAKE_PREFIX_PATH}") - endif() - - find_package(IPPCP REQUIRED) - - message(STATUS "IPPCP_LIBRARIES ${IPPCP_LIBRARIES}") - - # Helper functions add_subdirectory(misc) endif() From 79fb0f1524ee7cd06ddf42ab418e52e25fa98dcd Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 16 Mar 2022 15:22:33 -0700 Subject: [PATCH 122/364] Remove IPPCP dependency from samples/test_bnModExpPerformOp --- samples/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 7938585..8302a74 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -25,7 +25,7 @@ target_include_directories(test_bnModExpPerformOp PUBLIC ${ICP_INC_DIR}) target_link_libraries(test_bnModExpPerformOp PUBLIC he_qat) target_link_libraries(test_bnModExpPerformOp PUBLIC OpenSSL::SSL) # OpenSSL::Crypto) -target_link_libraries(test_bnModExpPerformOp PUBLIC IPPCP::ippcp) +#target_link_libraries(test_bnModExpPerformOp PUBLIC IPPCP::ippcp) install(TARGETS test_bnModExpPerformOp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) From c0942d5f160ae51f463233925d9532234213db4c Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 15 Mar 2022 22:24:50 -0700 Subject: [PATCH 123/364] Minor change to common/CMakeLists.txt --- common/CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 226e0fc..6ce9dce 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -11,8 +11,8 @@ set(COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/cpa_sample_utils.c) add_library(cpa_sample_utils ${COMMON_SRC}) target_include_directories(cpa_sample_utils - PUBLIC $ # Public headers - # PUBLIC $ # Public headers + PRIVATE $ # Public headers + PRIVATE $ # Public headers PUBLIC $ # Public headers PRIVATE ${COMMON_INC_DIR} # Private headers PRIVATE ${ICP_INC_DIR} # Private headers @@ -21,6 +21,8 @@ target_link_libraries(cpa_sample_utils PRIVATE udev z) target_link_libraries(cpa_sample_utils PRIVATE ${ICP_BUILDOUTPUT_PATH}/libqat_s.so) target_link_libraries(cpa_sample_utils PRIVATE ${ICP_BUILDOUTPUT_PATH}/libusdm_drv_s.so) +install(TARGETS cpa_sample_utils DESTINATION ${CMAKE_INSTALL_LIBDIR}) + set(COMMON_INC_DIR ${COMMON_INC_DIR} PARENT_SCOPE) From 23aed9093202f119faf3b7a27168d798e7b033a6 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 16 Mar 2022 10:35:24 -0700 Subject: [PATCH 124/364] Unset and parameterize CMAKE_PREFIX_PATH to find IPP Crypto (IPPCP_PREFIX_PATH). --- CMakeLists.txt | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 40c4df3..968294d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,9 +43,9 @@ set(CMAKE_INSTALL_MESSAGE LAZY) # Why? set(CMAKE_INSTALL_RPATH "\$ORIGIN") -#if(NOT CMAKE_INSTALL_PREFIX) - set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_LIST_DIR}/install) - #endif() +if(NOT CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_LIST_DIR}/install) +endif() message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") # Which features or functions does it bring? @@ -76,6 +76,17 @@ set(HE_QAT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) set(HE_QAT_SRC_DIR ${HE_QAT_ROOT_DIR}/he_qat) set(HE_QAT_INC_DIR ${HE_QAT_ROOT_DIR}/he_qat/include) +if(HE_QAT_MISC) + # IPP Crypto installation + if(IPPCP_PREFIX_PATH) + #set(IPPCP_DIR "/opt/ipp-crypto") + #set(IPPCP_CMAKE_PREFIX_PATH "${IPPCP_DIR}/lib/cmake") + list(APPEND CMAKE_PREFIX_PATH "${IPPCP_PREFIX_PATH}") + endif() + find_package(IPPCP REQUIRED) + message(STATUS "IPPCP_LIBRARIES ${IPPCP_LIBRARIES}") +endif() + set(HE_QAT_FORWARD_CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} @@ -112,19 +123,8 @@ include(icp/CMakeLists.txt) #Common utility functions add_subdirectory(common) +# Helper functions for BigNumber if(HE_QAT_MISC) - # IPP Crypto installation - if(NOT IPPCP_CMAKE_PREFIX_PATH) - set(IPPCP_DIR "/opt/ipp-crypto") - set(IPPCP_CMAKE_PREFIX_PATH "${IPPCP_DIR}/lib/cmake") - list(APPEND CMAKE_PREFIX_PATH "${IPPCP_CMAKE_PREFIX_PATH}") - endif() - - find_package(IPPCP REQUIRED) - - message(STATUS "IPPCP_LIBRARIES ${IPPCP_LIBRARIES}") - - # Helper functions add_subdirectory(misc) endif() From 0531b4537ba3ec5b24086fca31d4794b3b4e9434 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 16 Mar 2022 15:22:33 -0700 Subject: [PATCH 125/364] Remove IPPCP dependency from samples/test_bnModExpPerformOp --- samples/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index deb43ec..4311833 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -25,7 +25,7 @@ target_include_directories(test_bnModExpPerformOp PUBLIC ${ICP_INC_DIR}) target_link_libraries(test_bnModExpPerformOp PUBLIC he_qat) target_link_libraries(test_bnModExpPerformOp PUBLIC OpenSSL::SSL) # OpenSSL::Crypto) -target_link_libraries(test_bnModExpPerformOp PUBLIC IPPCP::ippcp) +#target_link_libraries(test_bnModExpPerformOp PUBLIC IPPCP::ippcp) install(TARGETS test_bnModExpPerformOp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) From a961e7eacfe0b3b784b007367bfcccfb72ba42b1 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 16 Mar 2022 19:50:05 -0700 Subject: [PATCH 126/364] Fix potential segfault. --- he_qat/he_qat_bn_ops.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index 5cc52ea..f53ca5e 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -456,11 +456,15 @@ void getBnModExpRequest(unsigned int batch_size) { if (task->op_result.pData) { PHYS_CONTIG_FREE(task->op_result.pData); } - free(he_qat_buffer.data[block_at_index]); - he_qat_buffer.data[block_at_index] = NULL; + // Move forward to wait for the next request that will be offloaded pthread_mutex_unlock(&task->mutex); - block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; + + // Fix segmentation fault? + free(he_qat_buffer.data[block_at_index]); + he_qat_buffer.data[block_at_index] = NULL; + + block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; } while (++j < batch_size); return; } From 38b707a306e2a6790aecf49fe2e4b3ce13a6b763 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 18 Mar 2022 14:54:04 -0700 Subject: [PATCH 127/364] Add asynchronous support. --- CMakeLists.txt | 12 +++- he_qat/he_qat_bn_ops.c | 118 +++++++++++---------------------- he_qat/include/he_qat_bn_ops.h | 2 +- 3 files changed, 49 insertions(+), 83 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 968294d..7a81a79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,7 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) # ------------------------------------------------------------------- option(HE_QAT_MISC "Enable miscellaneous features" ON) +option(HE_QAT_SYNC "Enable synchronous mode execution" OFF) option(HE_QAT_TEST "Enable testing" OFF) option(HE_QAT_SAMPLES "Enable examples" ON) option(HE_QAT_BENCHMARK "Enable benchmark" OFF) @@ -79,14 +80,21 @@ set(HE_QAT_INC_DIR ${HE_QAT_ROOT_DIR}/he_qat/include) if(HE_QAT_MISC) # IPP Crypto installation if(IPPCP_PREFIX_PATH) - #set(IPPCP_DIR "/opt/ipp-crypto") - #set(IPPCP_CMAKE_PREFIX_PATH "${IPPCP_DIR}/lib/cmake") + list(APPEND CMAKE_PREFIX_PATH "${IPPCP_PREFIX_PATH}") + else() + # Default to this + set(IPPCP_DIR "/opt/ipp-crypto") + set(IPPCP_PREFIX_PATH "${IPPCP_DIR}/lib/cmake") list(APPEND CMAKE_PREFIX_PATH "${IPPCP_PREFIX_PATH}") endif() find_package(IPPCP REQUIRED) message(STATUS "IPPCP_LIBRARIES ${IPPCP_LIBRARIES}") endif() +if(HE_QAT_SYNC) + add_definitions(-DHE_QAT_SYNC_MODE) +endif() + set(HE_QAT_FORWARD_CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index f53ca5e..99a2a93 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -12,6 +12,12 @@ #include #include +#ifdef HE_QAT_SYNC_MODE +#pragma message "Synchronous execution mode." +#else +#pragma message "Asynchronous execution mode." +#endif + // Global buffer for the runtime environment HE_QAT_RequestBuffer he_qat_buffer; @@ -48,12 +54,10 @@ static void lnModExpCallback(void* pCallbackTag, // This type can be variable } // Make it synchronous and blocking pthread_cond_signal(&request->ready); +#ifdef HE_QAT_SYNC_MODE COMPLETE((struct COMPLETION_STRUCT*)&request->callback); +#endif } - // Asynchronous call needs to send wake-up signal to semaphore - // if (NULL != pCallbackTag) { - // COMPLETE((struct COMPLETION_STRUCT *)pCallbackTag); - // } return; } @@ -86,15 +90,16 @@ static void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) { void* item = NULL; pthread_mutex_lock(&_buffer->mutex); + // Wait while buffer is empty while (_buffer->count <= 0) pthread_cond_wait(&_buffer->any_more_data, &_buffer->mutex); assert(_buffer->count > 0); - // printf("[%02d]:",_buffer->next_data_slot); item = _buffer->data[_buffer->next_data_slot++]; - // Asynchronous mode: Make copy of request so that the buffer can be reused + // TODO(fdiasmor): for multithreading mode + // Make copy of request so that the buffer can be reused _buffer->next_data_slot %= HE_QAT_BUFFER_SIZE; _buffer->count--; @@ -130,15 +135,6 @@ static void* start_inst_polling(void* _inst_config) { pthread_exit(NULL); } -/// @brief This function -/// @function stop_inst_polling -/// Stop polling instances and halt polling thread. -static void stop_inst_polling(HE_QAT_InstConfig* config) { - config->polling = 0; - OS_SLEEP(10); - return; -} - /// @brief /// @function perform_op /// Offload operation to QAT endpoints; for example, large number modular @@ -199,9 +195,9 @@ void* start_perform_op(void* _inst_config) { pthread_cond_signal(&config->ready); continue; } - +#ifdef HE_QAT_SYNC_MODE COMPLETION_INIT(&request->callback); - +#endif unsigned retry = 0; do { // Realize the type of operation from data @@ -225,30 +221,26 @@ void* start_perform_op(void* _inst_config) { // Ensure every call to perform operation is blocking for each endpoint if (CPA_STATUS_SUCCESS == status) { - // printf("Success at submission\n"); - // Wait until the callback function has been called +#ifdef HE_QAT_SYNC_MODE + // Wait until the callback function has been called if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { request->op_status = CPA_STATUS_FAIL; request->request_status = HE_QAT_STATUS_FAIL; // Review it printf("Failed in COMPLETION WAIT\n"); - // request->request_status = HE_QAT_STATUS_INCOMPLETE; - } // else printf("Completed ModExp.\n"); + } // Destroy synchronization object COMPLETION_DESTROY(&request->callback); - } +#endif + } else { + request->op_status = CPA_STATUS_FAIL; + request->request_status = HE_QAT_STATUS_FAIL; // Review it + } // Wake up any blocked call to stop_perform_op, signaling that now it is // safe to terminate running instances. Check if this detereorate // performance. pthread_cond_signal(&config->ready); - // printf("Wake up stop_perform_op\n"); - // Update the status of the request - // request->op_status = status; - // if (CPA_STATUS_SUCCESS != status) - // request->request_status = HE_QAT_FAIL; - // else - // request->request_status = HE_QAT_READY; } pthread_exit(NULL); } @@ -306,7 +298,7 @@ void stop_perform_op(HE_QAT_InstConfig* config, unsigned num_inst) { HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int nbits) { // Unpack data and copy to QAT friendly memory space - int len = nbits / 8; + int len = (nbits + 7) >> 3; // nbits / 8; Cpa8U* pBase = NULL; Cpa8U* pModulus = NULL; @@ -416,14 +408,12 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, request->op_status = status; request->op_output = (void*)r; - // Ensure calls are synchronous and blocking + // Ensure calls are synchronized at exit (blocking) pthread_mutex_init(&request->mutex, NULL); pthread_cond_init(&request->ready, NULL); // Submit request using producer function - // printf("Submit request \n"); submit_request(&he_qat_buffer, (void*)request); - // printf("Submitted\n"); return HE_QAT_STATUS_SUCCESS; } @@ -433,12 +423,14 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, void getBnModExpRequest(unsigned int batch_size) { static unsigned long block_at_index = 0; unsigned int j = 0; - do { - // Buffer read may be safe for single-threaded blocking calls only. - // Note: Not tested on multithreaded environment. - HE_QAT_TaskRequest* task = - (HE_QAT_TaskRequest*)he_qat_buffer.data[block_at_index]; - // Block and synchronize: Wait for the most recently offloaded request + + do { + // Buffer read may be safe for single-threaded blocking calls only. + // Note: Not tested on multithreaded environment. + HE_QAT_TaskRequest* task = + (HE_QAT_TaskRequest*)he_qat_buffer.data[block_at_index]; + + // Block and synchronize: Wait for the most recently offloaded request // to complete processing pthread_mutex_lock( &task->mutex); // mutex only needed for the conditional variable @@ -466,47 +458,13 @@ void getBnModExpRequest(unsigned int batch_size) { block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; } while (++j < batch_size); - return; -} -/* - unsigned int finish = 0; - // TODO: @fdiasmor Introduce global variable that record at which upcoming -request it currently is while (0 == finish) { finish = 1; for (unsigned int i = -0; i < HE_QAT_BUFFER_SIZE && finish; i++) { HE_QAT_TaskRequest *task = -(HE_QAT_TaskRequest *) he_qat_buffer.data[i]; - // TODO: @fdiasmor Check if not NULL before read. - if (NULL == task) continue; - - finish = (HE_QAT_READY == task->request_status); - if (finish) { // ? 1 : 0; - // Set output results to original format - BIGNUM *r = BN_bin2bn(task->op_result.pData, -task->op_result.dataLenInBytes, (BIGNUM *) task->op_output); - - // Free up QAT temporary memory - CpaCyLnModExpOpData *op_data = (CpaCyLnModExpOpData *) -task->op_data; if (op_data) { PHYS_CONTIG_FREE(op_data->base.pData); - PHYS_CONTIG_FREE(op_data->exponent.pData); - PHYS_CONTIG_FREE(op_data->modulus.pData); - } - if (task->op_result.pData) { - PHYS_CONTIG_FREE(task->op_result.pData); - } - - // Destroy synchronization object - COMPLETION_DESTROY(&task->callback); - } - } - // printf("getBnModExpRequest end\n"); - } - return ; + return; } -*/ /// @brief /// @function -/// Callback function for lnIppModExpPerformOp. It performs any data processing +/// Callback function for HE_QAT_bnModExp. It performs any data processing /// required after the modular exponentiation. static void HE_QAT_bnModExpCallback( void* pCallbackTag, // This type can be variable @@ -524,20 +482,22 @@ static void HE_QAT_bnModExpCallback( request->op_status = status; if (CPA_STATUS_SUCCESS == status) { if (pOpData == request->op_data) { - // printf("pOpData is same as input\n"); + // printf("pOpData is same as input\n"); // Mark request as complete or ready to be used request->request_status = HE_QAT_STATUS_READY; // Copy compute results to output destination memcpy(request->op_output, request->op_result.pData, request->op_result.dataLenInBytes); } else { - // printf("pOpData is NOT same as input\n"); + // printf("pOpData is NOT same as input\n"); request->request_status = HE_QAT_STATUS_FAIL; } } // Make it synchronous and blocking pthread_cond_signal(&request->ready); +#ifdef HE_QAT_SYNC_MODE COMPLETE((struct COMPLETION_STRUCT*)&request->callback); +#endif } return; @@ -624,14 +584,12 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, request->op_status = status; request->op_output = (void*)r; - // Ensure calls are synchronous and blocking + // Ensure calls are synchronized at exit (blocking) pthread_mutex_init(&request->mutex, NULL); pthread_cond_init(&request->ready, NULL); // Submit request using producer function - // printf("Submit request \n"); submit_request(&he_qat_buffer, (void*)request); - // printf("Submitted\n"); return HE_QAT_STATUS_SUCCESS; } diff --git a/he_qat/include/he_qat_bn_ops.h b/he_qat/include/he_qat_bn_ops.h index bba1dba..6b17f79 100644 --- a/he_qat/include/he_qat_bn_ops.h +++ b/he_qat/include/he_qat_bn_ops.h @@ -34,7 +34,7 @@ typedef struct { void* op_data; void* op_output; void* callback_func; - HE_QAT_STATUS request_status; + volatile HE_QAT_STATUS request_status; pthread_mutex_t mutex; pthread_cond_t ready; } HE_QAT_TaskRequest; From c82a3272fcafa454d0c5223b11e0656e59c3751d Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 18 Mar 2022 14:54:38 -0700 Subject: [PATCH 128/364] Reduce polling time interval. --- include/cpa_sample_utils.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/cpa_sample_utils.h b/include/cpa_sample_utils.h index 5c28ae6..a35b557 100644 --- a/include/cpa_sample_utils.h +++ b/include/cpa_sample_utils.h @@ -314,8 +314,11 @@ static __inline CpaStatus sampleSleep(Cpa32U ms) #ifdef USER_SPACE int ret = 0; struct timespec resTime, remTime; - resTime.tv_sec = ms / 1000; - resTime.tv_nsec = (ms % 1000) * 1000000; + //resTime.tv_sec = ms / 1000; + //resTime.tv_nsec = (ms % 1000) * 1000000; + // microseconds + resTime.tv_sec = ms / 1000000; + resTime.tv_nsec = (ms % 1000000) * 1000; do { ret = nanosleep(&resTime, &remTime); From ce47b67ca212dae262df431c07ab0f31a5412fc4 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 18 Mar 2022 14:55:16 -0700 Subject: [PATCH 129/364] Update performance test with chrono. --- samples/test_bnModExp.cpp | 92 +++++++++++++++++++++++++++------------ 1 file changed, 65 insertions(+), 27 deletions(-) diff --git a/samples/test_bnModExp.cpp b/samples/test_bnModExp.cpp index 189dd2d..2370463 100644 --- a/samples/test_bnModExp.cpp +++ b/samples/test_bnModExp.cpp @@ -5,6 +5,7 @@ #include "he_qat_context.h" #include "cpa_sample_utils.h" +#include #include #include #include @@ -17,19 +18,21 @@ int gDebugParam = 1; #endif -const unsigned int BATCH_SIZE = 1; +const unsigned int BATCH_SIZE = 8; + +using namespace std::chrono; int main(int argc, const char** argv) { const int bit_length = 2048; - const size_t num_trials = 4; + const size_t num_trials = 100; double avg_speed_up = 0.0; double ssl_avg_time = 0.0; double qat_avg_time = 0.0; - clock_t start = CLOCKS_PER_SEC; - clock_t ssl_elapsed = CLOCKS_PER_SEC; - clock_t qat_elapsed = CLOCKS_PER_SEC; +// clock_t start = CLOCKS_PER_SEC; +// clock_t ssl_elapsed = CLOCKS_PER_SEC; +// clock_t qat_elapsed = CLOCKS_PER_SEC; HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; @@ -47,9 +50,11 @@ int main(int argc, const char** argv) { if (!bn_mod) continue; char* bn_str = BN_bn2hex(bn_mod); - printf("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, +#ifdef _DESTINY_DEBUG_VERBOSE + printf("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); - OPENSSL_free(bn_str); +#endif + OPENSSL_free(bn_str); // Generate exponent in [0..bn_mod] BIGNUM* bn_exponent = BN_new(); @@ -63,15 +68,18 @@ int main(int argc, const char** argv) { // Perform OpenSSL ModExp Op BIGNUM* ssl_res = BN_new(); - start = clock(); + auto start = high_resolution_clock::now(); + //start = clock(); BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); - ssl_elapsed = clock() - start; + auto stop = high_resolution_clock::now(); + auto ssl_duration = duration_cast(stop-start); + //ssl_elapsed = clock() - start; int len_ = (bit_length + 7) >> 3; // Start QAT timer (including data conversion overhead) - start = clock(); - +// start = clock(); + start = high_resolution_clock::now(); unsigned char* bn_base_data_ = (unsigned char*)calloc(len_, sizeof(unsigned char)); if (NULL == bn_base_data_) exit(1); @@ -87,8 +95,9 @@ int main(int argc, const char** argv) { unsigned char* bn_remainder_data_ = (unsigned char*)calloc(len_, sizeof(unsigned char)); if (NULL == bn_remainder_data_) exit(1); - - clock_t cvt_elapsed = clock() - start; + stop = high_resolution_clock::now(); + auto cvt_duration = duration_cast(stop-start); +// clock_t cvt_elapsed = clock() - start; // Simulate input number in BigNumber representation BigNumber big_num_base((Ipp32u)0); @@ -121,7 +130,8 @@ int main(int argc, const char** argv) { exit(1); } - start = clock(); + //start = clock(); + start = high_resolution_clock::now(); status = bigNumberToBin(bn_base_data_, bit_length, big_num_base); if (HE_QAT_STATUS_SUCCESS != status) { printf("bn_base_data_: failed at bignumbertobin()\n"); @@ -137,20 +147,48 @@ int main(int argc, const char** argv) { printf("bn_base_data_: failed at bignumbertobin()\n"); exit(1); } - cvt_elapsed += (clock() - start); + //cvt_elapsed += (clock() - start); + cvt_duration += duration_cast(high_resolution_clock::now()-start); // Perform BigNumber modular exponentiation on QAT - start = clock(); - status = HE_QAT_bnModExp(bn_remainder_data_, bn_base_data_, + //start = clock(); + + start = high_resolution_clock::now(); + for (unsigned int b = 0; b < BATCH_SIZE; b++) + status = HE_QAT_bnModExp(bn_remainder_data_, bn_base_data_, bn_exponent_data_, bn_mod_data_, bit_length); getBnModExpRequest(BATCH_SIZE); - qat_elapsed = clock() - start; + stop = high_resolution_clock::now(); + auto qat_duration = duration_cast(stop-start); + + ssl_avg_time = (mod * ssl_avg_time + + ((double)(ssl_duration.count()))) / + (mod + 1); + qat_avg_time = + (mod * qat_avg_time + + ((double) (qat_duration.count()))/ BATCH_SIZE) / + (mod + 1); + avg_speed_up = + (mod * avg_speed_up + + (ssl_duration.count()/(double)(qat_duration.count()/BATCH_SIZE)))/(mod + 1); + //qat_elapsed = clock() - start; + + //printf("BigNumber data conversion overhead: %.1lfus.\n", + // (cvt_elapsed / (CLOCKS_PER_SEC / 1000000.0))); + //printf("BigNumber modular exponentiation on QAT: %.1lfus.\n", + // (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); + //qat_elapsed += cvt_elapsed; + printf("Overhead: %.1luus", + cvt_duration.count()); + printf("\tOpenSSL: %.1lfus", + ssl_avg_time); + printf("\tQAT: %.1lfus", + qat_avg_time); + printf("\tSpeed-up: %.1lfx", + avg_speed_up); + //qat_elapsed += cvt_elapsed; + - printf("BigNumber data conversion overhead: %.1lfus.\n", - (cvt_elapsed / (CLOCKS_PER_SEC / 1000000.0))); - printf("BigNumber modular exponentiation on QAT: %.1lfus.\n", - (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); - qat_elapsed += cvt_elapsed; BIGNUM* qat_res = BN_new(); BN_bin2bn(bn_remainder_data_, len_, qat_res); @@ -164,16 +202,16 @@ int main(int argc, const char** argv) { } #endif - start = clock(); + //start = clock(); BigNumber big_num((Ipp32u)0); status = binToBigNumber(big_num, bn_remainder_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { printf("bn_remainder_data_: Failed at bigNumberToBin()\n"); exit(1); } - qat_elapsed += (clock() - start); - printf("BigNumber ModExp total time: %.1lfus.\n", - (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); + //qat_elapsed += (clock() - start); + //printf("BigNumber ModExp total time: %.1lfus.\n", + // (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); #ifdef _DESTINY_DEBUG_VERBOSE bn_str = BN_bn2hex(qat_res); From 85ec96b91da8a43bb975bb5c63a195af2c43a874 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Mon, 21 Mar 2022 20:24:28 -0700 Subject: [PATCH 130/364] Fixed typo in mod_exp --- ipcl/mod_exp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index ea1c41c..db97401 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -125,7 +125,7 @@ static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, ippsMontSet(pow_m, nlen, reinterpret_cast(pMont.data())); ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: set Mont input error."); - // encode base into Montfomery form + // encode base into Montgomery form BigNumber bform(m); stat = ippsMontForm(BN(base), reinterpret_cast(pMont.data()), BN(bform)); From 2cb58f196c2cdba3ddb853d78ab40c00ffbb899a Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 22 Mar 2022 23:44:02 -0700 Subject: [PATCH 131/364] Add support to measure performance of requests. --- CMakeLists.txt | 5 ++ he_qat/he_qat_bn_ops.c | 139 +++++++++++++++++++++++---------- he_qat/include/he_qat_bn_ops.h | 8 ++ 3 files changed, 112 insertions(+), 40 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a81a79..e16f21f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,6 +58,7 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) option(HE_QAT_MISC "Enable miscellaneous features" ON) option(HE_QAT_SYNC "Enable synchronous mode execution" OFF) +option(HE_QAT_PERF "Show request performance" OFF) option(HE_QAT_TEST "Enable testing" OFF) option(HE_QAT_SAMPLES "Enable examples" ON) option(HE_QAT_BENCHMARK "Enable benchmark" OFF) @@ -95,6 +96,10 @@ if(HE_QAT_SYNC) add_definitions(-DHE_QAT_SYNC_MODE) endif() +if(HE_QAT_PERF) + add_definitions(-DHE_QAT_PERF) +endif() + set(HE_QAT_FORWARD_CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index 99a2a93..7e097f5 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -9,6 +9,12 @@ #include "he_qat_types.h" #include "he_qat_bn_ops.h" +#ifdef HE_QAT_PERF +#include +struct timeval start_time, end_time; +double time_taken = 0.0; +#endif + #include #include @@ -40,7 +46,6 @@ static void lnModExpCallback(void* pCallbackTag, // This type can be variable request->op_status = status; if (CPA_STATUS_SUCCESS == status) { if (pOpData == request->op_data) { - // printf("pOpData is same as input\n"); // Mark request as complete or ready to be used request->request_status = HE_QAT_STATUS_READY; @@ -48,7 +53,6 @@ static void lnModExpCallback(void* pCallbackTag, // This type can be variable request->op_result.dataLenInBytes, (BIGNUM*)request->op_output); } else { - // printf("pOpData is NOT same as input\n"); request->request_status = HE_QAT_STATUS_FAIL; } } @@ -204,7 +208,10 @@ void* start_perform_op(void* _inst_config) { switch (request->op_type) { // Select appropriate action case HE_QAT_OP_MODEXP: - status = cpaCyLnModExp(config->inst_handle, +#ifdef HE_QAT_PERF + gettimeofday(&request->start,NULL); +#endif + status = cpaCyLnModExp(config->inst_handle, (CpaCyGenFlatBufCbFunc)request->callback_func, //lnModExpCallback, (void*)request, (CpaCyLnModExpOpData*)request->op_data, @@ -216,11 +223,11 @@ void* start_perform_op(void* _inst_config) { retry = HE_QAT_MAX_RETRY; break; } - } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); // Ensure every call to perform operation is blocking for each endpoint if (CPA_STATUS_SUCCESS == status) { +// printf("retry_count = %d\n",retry_count); #ifdef HE_QAT_SYNC_MODE // Wait until the callback function has been called if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { @@ -418,46 +425,93 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, return HE_QAT_STATUS_SUCCESS; } + // Maybe it will be useful to pass the number of requests to retrieve // Pass post-processing function as argument to bring output to expected type void getBnModExpRequest(unsigned int batch_size) { static unsigned long block_at_index = 0; unsigned int j = 0; +#ifdef HE_QAT_PERF + gettimeofday(&start_time,NULL); +#endif do { // Buffer read may be safe for single-threaded blocking calls only. // Note: Not tested on multithreaded environment. HE_QAT_TaskRequest* task = (HE_QAT_TaskRequest*)he_qat_buffer.data[block_at_index]; - - // Block and synchronize: Wait for the most recently offloaded request - // to complete processing - pthread_mutex_lock( - &task->mutex); // mutex only needed for the conditional variable - while (HE_QAT_STATUS_READY != task->request_status) - pthread_cond_wait(&task->ready, &task->mutex); - // Free up QAT temporary memory - CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; - if (op_data) { - PHYS_CONTIG_FREE(op_data->base.pData); - PHYS_CONTIG_FREE(op_data->exponent.pData); - PHYS_CONTIG_FREE(op_data->modulus.pData); - } - free(task->op_data); - task->op_data = NULL; - if (task->op_result.pData) { - PHYS_CONTIG_FREE(task->op_result.pData); - } - - // Move forward to wait for the next request that will be offloaded - pthread_mutex_unlock(&task->mutex); - - // Fix segmentation fault? - free(he_qat_buffer.data[block_at_index]); - he_qat_buffer.data[block_at_index] = NULL; - block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; - } while (++j < batch_size); + if (NULL == task) + continue; + + if (HE_QAT_STATUS_READY == task->request_status) j++; + else continue; + +#ifdef HE_QAT_PERF + time_taken = (task->end.tv_sec - task->start.tv_sec)*1e6; + time_taken = (time_taken + (task->end.tv_usec - task->start.tv_usec));//*1e-6; + printf("Request %u\tElapsed Time: %.1lfus\n",j,time_taken); +#endif + // Free up QAT temporary memory + CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; + if (op_data) { + PHYS_CONTIG_FREE(op_data->base.pData); + PHYS_CONTIG_FREE(op_data->exponent.pData); + PHYS_CONTIG_FREE(op_data->modulus.pData); + } + free(task->op_data); + task->op_data = NULL; + if (task->op_result.pData) { + PHYS_CONTIG_FREE(task->op_result.pData); + } + + // Fix segmentation fault? + free(he_qat_buffer.data[block_at_index]); + he_qat_buffer.data[block_at_index] = NULL; + + block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; + } while(j < batch_size); + +// // Block and synchronize: Wait for the most recently offloaded request +// // to complete processing +// pthread_mutex_lock( +// &task->mutex); // mutex only needed for the conditional variable +// while (HE_QAT_STATUS_READY != task->request_status) +// pthread_cond_wait(&task->ready, &task->mutex); +// +// time_taken = (task->end.tv_sec - task->start.tv_sec)*1e6; +// time_taken = (time_taken + (task->end.tv_usec - task->start.tv_usec));//*1e-6; +// printf("%u time: %.1lfus\n",j,time_taken); +// +// // Free up QAT temporary memory +// CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; +// if (op_data) { +// PHYS_CONTIG_FREE(op_data->base.pData); +// PHYS_CONTIG_FREE(op_data->exponent.pData); +// PHYS_CONTIG_FREE(op_data->modulus.pData); +// } +// free(task->op_data); +// task->op_data = NULL; +// if (task->op_result.pData) { +// PHYS_CONTIG_FREE(task->op_result.pData); +// } +// +// // Move forward to wait for the next request that will be offloaded +// pthread_mutex_unlock(&task->mutex); +// +// // Fix segmentation fault? +// free(he_qat_buffer.data[block_at_index]); +// he_qat_buffer.data[block_at_index] = NULL; +// +// block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; +// } while (++j < batch_size); + +#ifdef HE_QAT_PERF + gettimeofday(&end_time,NULL); + time_taken = (end_time.tv_sec - start_time.tv_sec)*1e6; + time_taken = (time_taken + (end_time.tv_usec - start_time.tv_usec));//*1e-6; + printf("Batch Wall Time: %.1lfus\n",time_taken); +#endif return; } @@ -477,19 +531,20 @@ static void HE_QAT_bnModExpCallback( if (NULL != pCallbackTag) { // Read request data request = (HE_QAT_TaskRequest*)pCallbackTag; - + // Collect the device output in pOut request->op_status = status; if (CPA_STATUS_SUCCESS == status) { if (pOpData == request->op_data) { - // printf("pOpData is same as input\n"); // Mark request as complete or ready to be used request->request_status = HE_QAT_STATUS_READY; // Copy compute results to output destination memcpy(request->op_output, request->op_result.pData, request->op_result.dataLenInBytes); - } else { - // printf("pOpData is NOT same as input\n"); +#ifdef HE_QAT_PERF + gettimeofday(&request->end,NULL); +#endif + } else { request->request_status = HE_QAT_STATUS_FAIL; } } @@ -519,7 +574,8 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, // TODO(fdiasmor): Try it with 8-byte alignment. CpaStatus status = CPA_STATUS_FAIL; - status = PHYS_CONTIG_ALLOC(&pBase, len); + //status = PHYS_CONTIG_ALLOC(&pBase, len); + status = PHYS_CONTIG_ALLOC_ALIGNED(&pBase, len, 8); if (CPA_STATUS_SUCCESS == status && NULL != pBase) { memcpy(pBase, b, len); } else { @@ -527,7 +583,8 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, return HE_QAT_STATUS_FAIL; } - status = PHYS_CONTIG_ALLOC(&pExponent, len); + //status = PHYS_CONTIG_ALLOC(&pExponent, len); + status = PHYS_CONTIG_ALLOC_ALIGNED(&pExponent, len, 8); if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { memcpy(pExponent, e, len); } else { @@ -535,7 +592,8 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, return HE_QAT_STATUS_FAIL; } - status = PHYS_CONTIG_ALLOC(&pModulus, len); + //status = PHYS_CONTIG_ALLOC(&pModulus, len); + status = PHYS_CONTIG_ALLOC_ALIGNED(&pModulus, len, 8); if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { memcpy(pModulus, m, len); } else { @@ -569,7 +627,8 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, op_data->modulus.dataLenInBytes = len; request->op_data = (void*)op_data; - status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); + //status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); + status = PHYS_CONTIG_ALLOC_ALIGNED(&request->op_result.pData, len, 8); if (CPA_STATUS_SUCCESS == status && NULL != request->op_result.pData) { request->op_result.dataLenInBytes = len; } else { diff --git a/he_qat/include/he_qat_bn_ops.h b/he_qat/include/he_qat_bn_ops.h index 6b17f79..0d75da5 100644 --- a/he_qat/include/he_qat_bn_ops.h +++ b/he_qat/include/he_qat_bn_ops.h @@ -16,6 +16,10 @@ extern "C" { #include "cpa_sample_utils.h" #include +#ifdef HE_QAT_PERF +#include +#endif + //#include #include @@ -37,6 +41,10 @@ typedef struct { volatile HE_QAT_STATUS request_status; pthread_mutex_t mutex; pthread_cond_t ready; +#ifdef HE_QAT_PERF + struct timeval start; + struct timeval end; +#endif } HE_QAT_TaskRequest; /// @brief From 6175d51c3d84616090198de4dba2beed5d2c24bb Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 22 Mar 2022 23:48:13 -0700 Subject: [PATCH 132/364] Modify context to accept load/launch multiple instances. --- he_qat/he_qat_context.c | 72 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 8 deletions(-) diff --git a/he_qat/he_qat_context.c b/he_qat/he_qat_context.c index ecfccc8..be13b3d 100644 --- a/he_qat/he_qat_context.c +++ b/he_qat/he_qat_context.c @@ -18,6 +18,14 @@ #include "icp_sal_user.h" #include "icp_sal_poll.h" +#ifdef USER_SPACE +#define MAX_INSTANCES 1024 +#else +#define MAX_INSTANCES 1 +#endif + +#define NUM_ACTIVE_INSTANCES 1 + // Global variable declarations HE_QAT_Inst he_qat_instances[HE_QAT_MAX_NUM_INST]; pthread_attr_t he_qat_inst_attr[HE_QAT_MAX_NUM_INST]; @@ -30,6 +38,49 @@ extern void stop_perform_op(void* _inst_config, unsigned num_inst); CpaInstanceHandle handle = NULL; +static CpaInstanceHandle get_qat_instance() +{ + static CpaInstanceHandle cyInstHandles[MAX_INSTANCES]; + static Cpa16U numInstances = 0; + static Cpa16U nextInstance = 0; + CpaStatus status = CPA_STATUS_SUCCESS; + + if (0 == numInstances) { + //*pCyInstHandle = NULL; + status = cpaCyGetNumInstances(&numInstances); + if (numInstances >= MAX_INSTANCES) { + numInstances = MAX_INSTANCES; + } + if (numInstances >= NUM_ACTIVE_INSTANCES) { + numInstances = NUM_ACTIVE_INSTANCES; + } + + printf("Found %d CyInstances.\n",numInstances); + printf("Next Instance: %d.\n",nextInstance); + + if ((status == CPA_STATUS_SUCCESS) && (numInstances > 0)) { + status = cpaCyGetInstances(numInstances, cyInstHandles); + if (status == CPA_STATUS_SUCCESS) + return cyInstHandles[nextInstance]; + //*pCyInstHandle = cyInstHandles[0]; + } + + if (0 == numInstances) { + PRINT_ERR("No instances found for 'SSL'\n"); + PRINT_ERR("Please check your section names"); + PRINT_ERR(" in the config file.\n"); + PRINT_ERR("Also make sure to use config file version 2.\n"); + } + + return NULL; + } + + nextInstance = ((nextInstance + 1) % numInstances); + printf("Next Instance: %d.\n",nextInstance); + return cyInstHandles[nextInstance]; + +} + /// @brief /// @function acquire_qat_devices /// Acquire QAT instances and set up QAT execution environment. @@ -59,12 +110,15 @@ HE_QAT_STATUS acquire_qat_devices() { #endif // Potential out-of-scope hazard for segmentation fault - CpaInstanceHandle _inst_handle = NULL; + CpaInstanceHandle _inst_handle[NUM_ACTIVE_INSTANCES];// = NULL; // TODO: @fdiasmor Create a CyGetInstance that retrieves more than one. - sampleCyGetInstance(&_inst_handle); - if (_inst_handle == NULL) { - printf("Failed to find QAT endpoints.\n"); - return HE_QAT_STATUS_FAIL; + //sampleCyGetInstance(&_inst_handle); + for (unsigned int i = 0; i < NUM_ACTIVE_INSTANCES; i++) { + _inst_handle[i] = get_qat_instance(); + if (_inst_handle[i] == NULL) { + printf("Failed to find QAT endpoints.\n"); + return HE_QAT_STATUS_FAIL; + } } // sampleCyGetInstance(&handle); @@ -89,7 +143,8 @@ HE_QAT_STATUS acquire_qat_devices() { // Creating QAT instances (consumer threads) to process op requests pthread_attr_t attr; cpu_set_t cpus; - for (int i = 0; i < HE_QAT_SYNC; i++) { + //for (int i = 0; i < HE_QAT_SYNC; i++) { + for (int i = 0; i < NUM_ACTIVE_INSTANCES; i++) { CPU_ZERO(&cpus); CPU_SET(i, &cpus); pthread_attr_init(&he_qat_inst_attr[i]); @@ -108,7 +163,7 @@ HE_QAT_STATUS acquire_qat_devices() { pthread_mutex_init(&he_qat_inst_config[i].mutex, NULL); // he_qat_inst_config[i].ready = PTHREAD_COND_INITIALIZER; pthread_cond_init(&he_qat_inst_config[i].ready, NULL); - he_qat_inst_config[i].inst_handle = _inst_handle; + he_qat_inst_config[i].inst_handle = _inst_handle[i]; he_qat_inst_config[i].attr = &he_qat_inst_attr[i]; pthread_create(&he_qat_instances[i], he_qat_inst_config[i].attr, start_perform_op, (void*)&he_qat_inst_config[i]); @@ -118,7 +173,8 @@ HE_QAT_STATUS acquire_qat_devices() { #endif // Dispatch the qat instances to run independently in the background - for (int i = 0; i < HE_QAT_SYNC; i++) { + //for (int i = 0; i < HE_QAT_SYNC; i++) { + for (int i = 0; i < NUM_ACTIVE_INSTANCES; i++) { pthread_detach(he_qat_instances[i]); } #ifdef _DESTINY_DEBUG_VERBOSE From 6e7167fa0f8648841e4c9a459fbe4aa82f3e8022 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 23 Mar 2022 14:07:53 -0700 Subject: [PATCH 133/364] Increase buffer size to support multiple instances and devices. --- he_qat/include/he_qat_types.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/he_qat/include/he_qat_types.h b/he_qat/include/he_qat_types.h index fa97f1a..f35bfda 100644 --- a/he_qat/include/he_qat_types.h +++ b/he_qat/include/he_qat_types.h @@ -13,7 +13,7 @@ extern "C" { #include -#define HE_QAT_BUFFER_SIZE 8 +#define HE_QAT_BUFFER_SIZE 64 // Type definitions typedef enum { HE_QAT_SYNC = 1, HE_QAT_ASYNC = 2 } HE_QAT_EXEC_MODE; @@ -41,6 +41,7 @@ typedef struct { } HE_QAT_RequestBuffer; typedef struct { + int inst_id; CpaInstanceHandle inst_handle; pthread_attr_t* attr; HE_QAT_RequestBuffer* he_qat_buffer; From 627d9ade350113126b6ea11169cc9f2ea3d68b65 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 23 Mar 2022 14:19:22 -0700 Subject: [PATCH 134/364] Complete basic multiple instance support. --- he_qat/he_qat_context.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/he_qat/he_qat_context.c b/he_qat/he_qat_context.c index be13b3d..1f7833e 100644 --- a/he_qat/he_qat_context.c +++ b/he_qat/he_qat_context.c @@ -24,13 +24,16 @@ #define MAX_INSTANCES 1 #endif -#define NUM_ACTIVE_INSTANCES 1 +#define NUM_ACTIVE_INSTANCES 16 // Global variable declarations -HE_QAT_Inst he_qat_instances[HE_QAT_MAX_NUM_INST]; -pthread_attr_t he_qat_inst_attr[HE_QAT_MAX_NUM_INST]; -HE_QAT_InstConfig he_qat_inst_config[HE_QAT_MAX_NUM_INST]; +//HE_QAT_Inst he_qat_instances[HE_QAT_MAX_NUM_INST]; +//pthread_attr_t he_qat_inst_attr[HE_QAT_MAX_NUM_INST]; +//HE_QAT_InstConfig he_qat_inst_config[HE_QAT_MAX_NUM_INST]; // HE_QAT_RequestBuffer he_qat_buffer; +HE_QAT_Inst he_qat_instances[NUM_ACTIVE_INSTANCES]; +pthread_attr_t he_qat_inst_attr[NUM_ACTIVE_INSTANCES]; +HE_QAT_InstConfig he_qat_inst_config[NUM_ACTIVE_INSTANCES]; extern HE_QAT_RequestBuffer he_qat_buffer; extern void* start_perform_op(void* _inst_config); @@ -164,6 +167,7 @@ HE_QAT_STATUS acquire_qat_devices() { // he_qat_inst_config[i].ready = PTHREAD_COND_INITIALIZER; pthread_cond_init(&he_qat_inst_config[i].ready, NULL); he_qat_inst_config[i].inst_handle = _inst_handle[i]; + he_qat_inst_config[i].inst_id = i; he_qat_inst_config[i].attr = &he_qat_inst_attr[i]; pthread_create(&he_qat_instances[i], he_qat_inst_config[i].attr, start_perform_op, (void*)&he_qat_inst_config[i]); @@ -202,7 +206,7 @@ HE_QAT_STATUS release_qat_devices() { // } // } - stop_perform_op(he_qat_inst_config, HE_QAT_SYNC); + stop_perform_op(he_qat_inst_config, NUM_ACTIVE_INSTANCES); #ifdef _DESTINY_DEBUG_VERBOSE printf("Stopped polling and processing threads.\n"); #endif From b93e5313ce280048482cb3bde97ad113662a5597 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 23 Mar 2022 14:25:20 -0700 Subject: [PATCH 135/364] Hardware configuration to support multiple instances and devices on 2-socket servers. --- config/4xxx_dev0.conf | 212 ++++++++++++++++++++++++++++++++++++++++++ config/4xxx_dev1.conf | 212 ++++++++++++++++++++++++++++++++++++++++++ config/4xxx_dev2.conf | 212 ++++++++++++++++++++++++++++++++++++++++++ config/4xxx_dev3.conf | 212 ++++++++++++++++++++++++++++++++++++++++++ config/4xxx_dev4.conf | 212 ++++++++++++++++++++++++++++++++++++++++++ config/4xxx_dev5.conf | 212 ++++++++++++++++++++++++++++++++++++++++++ config/4xxx_dev6.conf | 212 ++++++++++++++++++++++++++++++++++++++++++ config/4xxx_dev7.conf | 212 ++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 1696 insertions(+) create mode 100644 config/4xxx_dev0.conf create mode 100644 config/4xxx_dev1.conf create mode 100644 config/4xxx_dev2.conf create mode 100644 config/4xxx_dev3.conf create mode 100644 config/4xxx_dev4.conf create mode 100644 config/4xxx_dev5.conf create mode 100644 config/4xxx_dev6.conf create mode 100644 config/4xxx_dev7.conf diff --git a/config/4xxx_dev0.conf b/config/4xxx_dev0.conf new file mode 100644 index 0000000..d42e88b --- /dev/null +++ b/config/4xxx_dev0.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 64 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 2 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 0 + +# Crypto - User instance #1 +Cy1Name = "SSL1" +Cy1IsPolled = 1 +# List of core affinities +Cy1CoreAffinity = 1 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/4xxx_dev1.conf b/config/4xxx_dev1.conf new file mode 100644 index 0000000..0bd474f --- /dev/null +++ b/config/4xxx_dev1.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 64 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 2 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 2 + +# Crypto - User instance #1 +Cy1Name = "SSL1" +Cy1IsPolled = 1 +# List of core affinities +Cy1CoreAffinity = 3 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/4xxx_dev2.conf b/config/4xxx_dev2.conf new file mode 100644 index 0000000..517587b --- /dev/null +++ b/config/4xxx_dev2.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 64 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 2 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 4 + +# Crypto - User instance #1 +Cy1Name = "SSL1" +Cy1IsPolled = 1 +# List of core affinities +Cy1CoreAffinity = 5 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/4xxx_dev3.conf b/config/4xxx_dev3.conf new file mode 100644 index 0000000..34a153e --- /dev/null +++ b/config/4xxx_dev3.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 64 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 2 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 6 + +# Crypto - User instance #1 +Cy1Name = "SSL1" +Cy1IsPolled = 1 +# List of core affinities +Cy1CoreAffinity = 7 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/4xxx_dev4.conf b/config/4xxx_dev4.conf new file mode 100644 index 0000000..b1062cc --- /dev/null +++ b/config/4xxx_dev4.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 64 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 2 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 56 + +# Crypto - User instance #1 +Cy1Name = "SSL1" +Cy1IsPolled = 1 +# List of core affinities +Cy1CoreAffinity = 57 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/4xxx_dev5.conf b/config/4xxx_dev5.conf new file mode 100644 index 0000000..041b640 --- /dev/null +++ b/config/4xxx_dev5.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 64 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 2 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 58 + +# Crypto - User instance #1 +Cy1Name = "SSL1" +Cy1IsPolled = 1 +# List of core affinities +Cy1CoreAffinity = 59 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/4xxx_dev6.conf b/config/4xxx_dev6.conf new file mode 100644 index 0000000..e889dc2 --- /dev/null +++ b/config/4xxx_dev6.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 64 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 2 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 60 + +# Crypto - User instance #1 +Cy1Name = "SSL1" +Cy1IsPolled = 1 +# List of core affinities +Cy1CoreAffinity = 61 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/4xxx_dev7.conf b/config/4xxx_dev7.conf new file mode 100644 index 0000000..b796db3 --- /dev/null +++ b/config/4xxx_dev7.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 64 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 2 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 62 + +# Crypto - User instance #1 +Cy1Name = "SSL1" +Cy1IsPolled = 1 +# List of core affinities +Cy1CoreAffinity = 63 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 From 168e4fb6ba91d9689274cb6d320a4072799b1dd4 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 23 Mar 2022 14:26:10 -0700 Subject: [PATCH 136/364] Update multiple-instance/device test case. --- samples/test_bnModExp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/test_bnModExp.cpp b/samples/test_bnModExp.cpp index 2370463..4f9e09a 100644 --- a/samples/test_bnModExp.cpp +++ b/samples/test_bnModExp.cpp @@ -23,7 +23,7 @@ const unsigned int BATCH_SIZE = 8; using namespace std::chrono; int main(int argc, const char** argv) { - const int bit_length = 2048; + const int bit_length = 4096; const size_t num_trials = 100; double avg_speed_up = 0.0; From 0d13030445eaefa07a4057680bcebd60ce32e487 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 23 Mar 2022 14:46:59 -0700 Subject: [PATCH 137/364] Add HE_QAT_DEBUG option/definition. --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e16f21f..63ebcb3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,6 +67,7 @@ option(HE_QAT_SHARED "Build shared library" ON) if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(HE_QAT_DEBUG ON) + add_definitions(-DHE_QAT_DEBUG) else() set(HE_QAT_DEBUG OFF) endif() @@ -97,7 +98,7 @@ if(HE_QAT_SYNC) endif() if(HE_QAT_PERF) - add_definitions(-DHE_QAT_PERF) + add_definitions(-DHE_QAT_PERF) endif() set(HE_QAT_FORWARD_CMAKE_ARGS From 82fa0dc5217ddbb28397475084d89a51e22de810 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 23 Mar 2022 14:48:02 -0700 Subject: [PATCH 138/364] Update he_qat_bn_ops.c implementation. --- he_qat/he_qat_bn_ops.c | 134 ++++++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 63 deletions(-) diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index 7e097f5..ebdee72 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -133,7 +133,7 @@ static void* start_inst_polling(void* _inst_config) { config->polling = 1; while (config->polling) { icp_sal_CyPollInstance(config->inst_handle, 0); - OS_SLEEP(10); + OS_SLEEP(50); } pthread_exit(NULL); @@ -208,6 +208,9 @@ void* start_perform_op(void* _inst_config) { switch (request->op_type) { // Select appropriate action case HE_QAT_OP_MODEXP: +#ifdef HE_QAT_DEBUG + printf("Enqueue request to instance #%d\n",config->inst_id); +#endif #ifdef HE_QAT_PERF gettimeofday(&request->start,NULL); #endif @@ -220,6 +223,9 @@ void* start_perform_op(void* _inst_config) { break; case HE_QAT_OP_NONE: default: +#ifdef HE_QAT_DEBUG + printf("HE_QAT_OP_NONE to instance #%d\n",config->inst_id); +#endif retry = HE_QAT_MAX_RETRY; break; } @@ -269,24 +275,24 @@ void stop_perform_op(HE_QAT_InstConfig* config, unsigned num_inst) { CpaStatus status = CPA_STATUS_FAIL; for (unsigned i = 0; i < num_inst; i++) { pthread_mutex_lock(&config[i].mutex); -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG printf("Try teardown HE QAT instance #%d.\n", i); #endif while (0 == config[i].active) { pthread_cond_wait(&config[i].ready, &config[i].mutex); } if (CPA_STATUS_SUCCESS == config[i].status && config[i].active) { -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG printf("Stop polling and running threads #%d\n", i); #endif config[i].polling = 0; config[i].running = 0; OS_SLEEP(10); -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG printf("Stop cpaCyInstance #%d\n", i); #endif if (config[i].inst_handle == NULL) continue; -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG printf("cpaCyStopInstance\n"); #endif status = cpaCyStopInstance(config[i].inst_handle); @@ -443,68 +449,70 @@ void getBnModExpRequest(unsigned int batch_size) { if (NULL == task) continue; - - if (HE_QAT_STATUS_READY == task->request_status) j++; - else continue; +// +// if (HE_QAT_STATUS_READY == task->request_status) j++; +// else continue; +// +//#ifdef HE_QAT_PERF +// time_taken = (task->end.tv_sec - task->start.tv_sec)*1e6; +// time_taken = (time_taken + (task->end.tv_usec - task->start.tv_usec));//*1e-6; +// printf("Request %u\tElapsed Time: %.1lfus\n",j,time_taken); +//#endif +// // Free up QAT temporary memory +// CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; +// if (op_data) { +// PHYS_CONTIG_FREE(op_data->base.pData); +// PHYS_CONTIG_FREE(op_data->exponent.pData); +// PHYS_CONTIG_FREE(op_data->modulus.pData); +// } +// free(task->op_data); +// task->op_data = NULL; +// if (task->op_result.pData) { +// PHYS_CONTIG_FREE(task->op_result.pData); +// } +// +// // Fix segmentation fault? +// free(he_qat_buffer.data[block_at_index]); +// he_qat_buffer.data[block_at_index] = NULL; +// +// block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; +// } while(j < batch_size); + + // Block and synchronize: Wait for the most recently offloaded request + // to complete processing + pthread_mutex_lock( + &task->mutex); // mutex only needed for the conditional variable + while (HE_QAT_STATUS_READY != task->request_status) + pthread_cond_wait(&task->ready, &task->mutex); #ifdef HE_QAT_PERF - time_taken = (task->end.tv_sec - task->start.tv_sec)*1e6; - time_taken = (time_taken + (task->end.tv_usec - task->start.tv_usec));//*1e-6; - printf("Request %u\tElapsed Time: %.1lfus\n",j,time_taken); + time_taken = (task->end.tv_sec - task->start.tv_sec)*1e6; + time_taken = (time_taken + (task->end.tv_usec - task->start.tv_usec));//*1e-6; + printf("%u time: %.1lfus\n",j,time_taken); #endif + // Free up QAT temporary memory - CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; - if (op_data) { - PHYS_CONTIG_FREE(op_data->base.pData); - PHYS_CONTIG_FREE(op_data->exponent.pData); - PHYS_CONTIG_FREE(op_data->modulus.pData); - } - free(task->op_data); - task->op_data = NULL; - if (task->op_result.pData) { - PHYS_CONTIG_FREE(task->op_result.pData); - } - - // Fix segmentation fault? - free(he_qat_buffer.data[block_at_index]); - he_qat_buffer.data[block_at_index] = NULL; - - block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; - } while(j < batch_size); - -// // Block and synchronize: Wait for the most recently offloaded request -// // to complete processing -// pthread_mutex_lock( -// &task->mutex); // mutex only needed for the conditional variable -// while (HE_QAT_STATUS_READY != task->request_status) -// pthread_cond_wait(&task->ready, &task->mutex); -// -// time_taken = (task->end.tv_sec - task->start.tv_sec)*1e6; -// time_taken = (time_taken + (task->end.tv_usec - task->start.tv_usec));//*1e-6; -// printf("%u time: %.1lfus\n",j,time_taken); -// -// // Free up QAT temporary memory -// CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; -// if (op_data) { -// PHYS_CONTIG_FREE(op_data->base.pData); -// PHYS_CONTIG_FREE(op_data->exponent.pData); -// PHYS_CONTIG_FREE(op_data->modulus.pData); -// } -// free(task->op_data); -// task->op_data = NULL; -// if (task->op_result.pData) { -// PHYS_CONTIG_FREE(task->op_result.pData); -// } -// -// // Move forward to wait for the next request that will be offloaded -// pthread_mutex_unlock(&task->mutex); -// -// // Fix segmentation fault? -// free(he_qat_buffer.data[block_at_index]); -// he_qat_buffer.data[block_at_index] = NULL; -// -// block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; -// } while (++j < batch_size); + CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; + if (op_data) { + PHYS_CONTIG_FREE(op_data->base.pData); + PHYS_CONTIG_FREE(op_data->exponent.pData); + PHYS_CONTIG_FREE(op_data->modulus.pData); + } + free(task->op_data); + task->op_data = NULL; + if (task->op_result.pData) { + PHYS_CONTIG_FREE(task->op_result.pData); + } + + // Move forward to wait for the next request that will be offloaded + pthread_mutex_unlock(&task->mutex); + + // Fix segmentation fault? + free(he_qat_buffer.data[block_at_index]); + he_qat_buffer.data[block_at_index] = NULL; + + block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; + } while (++j < batch_size); #ifdef HE_QAT_PERF gettimeofday(&end_time,NULL); From fc3b7037106692fb4397a2cc5abe7bac981e6784 Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Fri, 25 Mar 2022 05:58:54 +0800 Subject: [PATCH 139/364] Fix google test/benchmark pthread missiong issue (#66) * Fix google test/benchmark pthread missiong issue * Code clean: remove useless function declaration --- benchmark/CMakeLists.txt | 2 +- ipcl/include/ipcl/pub_key.hpp | 11 +---------- test/CMakeLists.txt | 2 +- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index ae35824..dc122fe 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -12,7 +12,7 @@ target_include_directories(bench_ipcl PRIVATE ) target_link_libraries(bench_ipcl PRIVATE - ipcl libgbenchmark Threads::Threads + ipcl -pthread libgbenchmark ) # enable OpenMP benchmarks diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp index 61ae905..c7d1a99 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -121,16 +121,7 @@ class PublicKey { void raw_encrypt(std::vector& ciphertext, const std::vector& plaintext, bool make_secure = true) const; - // /** - // * Raw Multi-buffered modular exponentiation - // * @param[in] base array base of the exponentiation - // * @param[in] pow arrya pow of the exponentiation - // * @param[in] m arrayodular - // * @return result of the modular exponentiation of type BigNumber vector - // */ - // std::vector raw_ippMultiBuffExp( - // const std::vector& base, const std::vector& - // pow, const std::vector& m) const; + /** * Get random value * @param[in] length bit length diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bb24a5f..bca944a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -12,7 +12,7 @@ target_include_directories(unittest_ipcl PRIVATE ${IPCL_INC_DIR} ) target_link_libraries(unittest_ipcl PRIVATE - ipcl libgtest Threads::Threads + ipcl -pthread libgtest ) # enable OpenMP unittests From c306a780a9601a2427b5216d4d43074a3d6aa6f1 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 28 Mar 2022 10:57:09 -0700 Subject: [PATCH 140/364] Change constant that defines number of active instances. --- he_qat/he_qat_context.c | 2 +- he_qat/include/he_qat_context.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/he_qat/he_qat_context.c b/he_qat/he_qat_context.c index 1f7833e..d8df22a 100644 --- a/he_qat/he_qat_context.c +++ b/he_qat/he_qat_context.c @@ -24,7 +24,7 @@ #define MAX_INSTANCES 1 #endif -#define NUM_ACTIVE_INSTANCES 16 +#define NUM_ACTIVE_INSTANCES 8 // Global variable declarations //HE_QAT_Inst he_qat_instances[HE_QAT_MAX_NUM_INST]; diff --git a/he_qat/include/he_qat_context.h b/he_qat/include/he_qat_context.h index 3c56c62..96195c1 100644 --- a/he_qat/include/he_qat_context.h +++ b/he_qat/include/he_qat_context.h @@ -11,7 +11,7 @@ extern "C" { #include "he_qat_types.h" #include -#define HE_QAT_MAX_NUM_INST 8 +//#define HE_QAT_MAX_NUM_INST 8 // const unsigned HE_QAT_MAX_NUM_INST = 8 /// @brief From 501d30eb976cf4722243eeb294aef790069fe91c Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 28 Mar 2022 11:29:41 -0700 Subject: [PATCH 141/364] Increase buffer to 128. --- he_qat/include/he_qat_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/he_qat/include/he_qat_types.h b/he_qat/include/he_qat_types.h index f35bfda..3eec5dd 100644 --- a/he_qat/include/he_qat_types.h +++ b/he_qat/include/he_qat_types.h @@ -13,7 +13,7 @@ extern "C" { #include -#define HE_QAT_BUFFER_SIZE 64 +#define HE_QAT_BUFFER_SIZE 128 // Type definitions typedef enum { HE_QAT_SYNC = 1, HE_QAT_ASYNC = 2 } HE_QAT_EXEC_MODE; From 6d37729ed8eea57491ab47522c5c669c3e4ccb21 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 28 Mar 2022 11:31:14 -0700 Subject: [PATCH 142/364] Enable getBnModExpRequest with no conditional variables. --- he_qat/he_qat_bn_ops.c | 120 ++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index ebdee72..76cd184 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -449,70 +449,70 @@ void getBnModExpRequest(unsigned int batch_size) { if (NULL == task) continue; -// -// if (HE_QAT_STATUS_READY == task->request_status) j++; -// else continue; -// -//#ifdef HE_QAT_PERF -// time_taken = (task->end.tv_sec - task->start.tv_sec)*1e6; -// time_taken = (time_taken + (task->end.tv_usec - task->start.tv_usec));//*1e-6; -// printf("Request %u\tElapsed Time: %.1lfus\n",j,time_taken); -//#endif -// // Free up QAT temporary memory -// CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; -// if (op_data) { -// PHYS_CONTIG_FREE(op_data->base.pData); -// PHYS_CONTIG_FREE(op_data->exponent.pData); -// PHYS_CONTIG_FREE(op_data->modulus.pData); -// } -// free(task->op_data); -// task->op_data = NULL; -// if (task->op_result.pData) { -// PHYS_CONTIG_FREE(task->op_result.pData); -// } -// -// // Fix segmentation fault? -// free(he_qat_buffer.data[block_at_index]); -// he_qat_buffer.data[block_at_index] = NULL; -// -// block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; -// } while(j < batch_size); - - // Block and synchronize: Wait for the most recently offloaded request - // to complete processing - pthread_mutex_lock( - &task->mutex); // mutex only needed for the conditional variable - while (HE_QAT_STATUS_READY != task->request_status) - pthread_cond_wait(&task->ready, &task->mutex); + + if (HE_QAT_STATUS_READY == task->request_status) j++; + else continue; #ifdef HE_QAT_PERF - time_taken = (task->end.tv_sec - task->start.tv_sec)*1e6; - time_taken = (time_taken + (task->end.tv_usec - task->start.tv_usec));//*1e-6; - printf("%u time: %.1lfus\n",j,time_taken); + time_taken = (task->end.tv_sec - task->start.tv_sec)*1e6; + time_taken = (time_taken + (task->end.tv_usec - task->start.tv_usec));//*1e-6; + printf("Request %u\tElapsed Time: %.1lfus\n",j,time_taken); #endif - // Free up QAT temporary memory - CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; - if (op_data) { - PHYS_CONTIG_FREE(op_data->base.pData); - PHYS_CONTIG_FREE(op_data->exponent.pData); - PHYS_CONTIG_FREE(op_data->modulus.pData); - } - free(task->op_data); - task->op_data = NULL; - if (task->op_result.pData) { - PHYS_CONTIG_FREE(task->op_result.pData); - } - - // Move forward to wait for the next request that will be offloaded - pthread_mutex_unlock(&task->mutex); - - // Fix segmentation fault? - free(he_qat_buffer.data[block_at_index]); - he_qat_buffer.data[block_at_index] = NULL; - - block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; - } while (++j < batch_size); + CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; + if (op_data) { + PHYS_CONTIG_FREE(op_data->base.pData); + PHYS_CONTIG_FREE(op_data->exponent.pData); + PHYS_CONTIG_FREE(op_data->modulus.pData); + } + free(task->op_data); + task->op_data = NULL; + if (task->op_result.pData) { + PHYS_CONTIG_FREE(task->op_result.pData); + } + + // Fix segmentation fault? + free(he_qat_buffer.data[block_at_index]); + he_qat_buffer.data[block_at_index] = NULL; + + block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; + } while(j < batch_size); + +// // Block and synchronize: Wait for the most recently offloaded request +// // to complete processing +// pthread_mutex_lock( +// &task->mutex); // mutex only needed for the conditional variable +// while (HE_QAT_STATUS_READY != task->request_status) +// pthread_cond_wait(&task->ready, &task->mutex); +// +//#ifdef HE_QAT_PERF +// time_taken = (task->end.tv_sec - task->start.tv_sec)*1e6; +// time_taken = (time_taken + (task->end.tv_usec - task->start.tv_usec));//*1e-6; +// printf("%u time: %.1lfus\n",j,time_taken); +//#endif +// +// // Free up QAT temporary memory +// CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; +// if (op_data) { +// PHYS_CONTIG_FREE(op_data->base.pData); +// PHYS_CONTIG_FREE(op_data->exponent.pData); +// PHYS_CONTIG_FREE(op_data->modulus.pData); +// } +// free(task->op_data); +// task->op_data = NULL; +// if (task->op_result.pData) { +// PHYS_CONTIG_FREE(task->op_result.pData); +// } +// +// // Move forward to wait for the next request that will be offloaded +// pthread_mutex_unlock(&task->mutex); +// +// // Fix segmentation fault? +// free(he_qat_buffer.data[block_at_index]); +// he_qat_buffer.data[block_at_index] = NULL; +// +// block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; +// } while (++j < batch_size); #ifdef HE_QAT_PERF gettimeofday(&end_time,NULL); From 5b9c0f208c99828e40087777a684b43cab138995 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 28 Mar 2022 11:54:27 -0700 Subject: [PATCH 143/364] Device configuraiton: 1 logical instance per QAT endpoint for dual socket systems. --- config/1inst1dev/4xxx_dev0.conf | 212 ++++++++++++++++++++++++++++++++ config/1inst1dev/4xxx_dev1.conf | 212 ++++++++++++++++++++++++++++++++ config/1inst1dev/4xxx_dev2.conf | 212 ++++++++++++++++++++++++++++++++ config/1inst1dev/4xxx_dev3.conf | 212 ++++++++++++++++++++++++++++++++ config/1inst1dev/4xxx_dev4.conf | 212 ++++++++++++++++++++++++++++++++ config/1inst1dev/4xxx_dev5.conf | 212 ++++++++++++++++++++++++++++++++ config/1inst1dev/4xxx_dev6.conf | 212 ++++++++++++++++++++++++++++++++ config/1inst1dev/4xxx_dev7.conf | 212 ++++++++++++++++++++++++++++++++ 8 files changed, 1696 insertions(+) create mode 100644 config/1inst1dev/4xxx_dev0.conf create mode 100644 config/1inst1dev/4xxx_dev1.conf create mode 100644 config/1inst1dev/4xxx_dev2.conf create mode 100644 config/1inst1dev/4xxx_dev3.conf create mode 100644 config/1inst1dev/4xxx_dev4.conf create mode 100644 config/1inst1dev/4xxx_dev5.conf create mode 100644 config/1inst1dev/4xxx_dev6.conf create mode 100644 config/1inst1dev/4xxx_dev7.conf diff --git a/config/1inst1dev/4xxx_dev0.conf b/config/1inst1dev/4xxx_dev0.conf new file mode 100644 index 0000000..51c9c39 --- /dev/null +++ b/config/1inst1dev/4xxx_dev0.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 256 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 1 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 0 + +## Crypto - User instance #1 +#Cy1Name = "SSL1" +#Cy1IsPolled = 1 +## List of core affinities +#Cy1CoreAffinity = 1 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/1inst1dev/4xxx_dev1.conf b/config/1inst1dev/4xxx_dev1.conf new file mode 100644 index 0000000..056b430 --- /dev/null +++ b/config/1inst1dev/4xxx_dev1.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 256 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 1 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 1 + +## Crypto - User instance #1 +#Cy1Name = "SSL1" +#Cy1IsPolled = 1 +## List of core affinities +#Cy1CoreAffinity = 3 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/1inst1dev/4xxx_dev2.conf b/config/1inst1dev/4xxx_dev2.conf new file mode 100644 index 0000000..8325bc9 --- /dev/null +++ b/config/1inst1dev/4xxx_dev2.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 256 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 1 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 2 + +## Crypto - User instance #1 +#Cy1Name = "SSL1" +#Cy1IsPolled = 1 +## List of core affinities +#Cy1CoreAffinity = 5 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/1inst1dev/4xxx_dev3.conf b/config/1inst1dev/4xxx_dev3.conf new file mode 100644 index 0000000..f0ac925 --- /dev/null +++ b/config/1inst1dev/4xxx_dev3.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 256 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 1 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 3 + +## Crypto - User instance #1 +#Cy1Name = "SSL1" +#Cy1IsPolled = 1 +## List of core affinities +#Cy1CoreAffinity = 7 +# +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/1inst1dev/4xxx_dev4.conf b/config/1inst1dev/4xxx_dev4.conf new file mode 100644 index 0000000..91aa45e --- /dev/null +++ b/config/1inst1dev/4xxx_dev4.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 256 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 1 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 56 + +## Crypto - User instance #1 +#Cy1Name = "SSL1" +#Cy1IsPolled = 1 +## List of core affinities +#Cy1CoreAffinity = 57 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/1inst1dev/4xxx_dev5.conf b/config/1inst1dev/4xxx_dev5.conf new file mode 100644 index 0000000..bedce9d --- /dev/null +++ b/config/1inst1dev/4xxx_dev5.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 256 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 1 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 57 + +## Crypto - User instance #1 +#Cy1Name = "SSL1" +#Cy1IsPolled = 1 +## List of core affinities +#Cy1CoreAffinity = 59 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/1inst1dev/4xxx_dev6.conf b/config/1inst1dev/4xxx_dev6.conf new file mode 100644 index 0000000..8e099f0 --- /dev/null +++ b/config/1inst1dev/4xxx_dev6.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 256 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 1 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 58 + +## Crypto - User instance #1 +#Cy1Name = "SSL1" +#Cy1IsPolled = 1 +## List of core affinities +#Cy1CoreAffinity = 61 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/1inst1dev/4xxx_dev7.conf b/config/1inst1dev/4xxx_dev7.conf new file mode 100644 index 0000000..b39ce63 --- /dev/null +++ b/config/1inst1dev/4xxx_dev7.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 256 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 1 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 59 + +## Crypto - User instance #1 +#Cy1Name = "SSL1" +#Cy1IsPolled = 1 +## List of core affinities +#Cy1CoreAffinity = 63 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 From 7f5736161a0205af216f90b22b3e80734434afd5 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 28 Mar 2022 11:55:20 -0700 Subject: [PATCH 144/364] Device configuraiton: 2 logical instances per QAT endpoint for dual socket systems. --- config/2inst1dev/4xxx_dev0.conf | 212 ++++++++++++++++++++++++++++++++ config/2inst1dev/4xxx_dev1.conf | 212 ++++++++++++++++++++++++++++++++ config/2inst1dev/4xxx_dev2.conf | 212 ++++++++++++++++++++++++++++++++ config/2inst1dev/4xxx_dev3.conf | 212 ++++++++++++++++++++++++++++++++ config/2inst1dev/4xxx_dev4.conf | 212 ++++++++++++++++++++++++++++++++ config/2inst1dev/4xxx_dev5.conf | 212 ++++++++++++++++++++++++++++++++ config/2inst1dev/4xxx_dev6.conf | 212 ++++++++++++++++++++++++++++++++ config/2inst1dev/4xxx_dev7.conf | 212 ++++++++++++++++++++++++++++++++ 8 files changed, 1696 insertions(+) create mode 100644 config/2inst1dev/4xxx_dev0.conf create mode 100644 config/2inst1dev/4xxx_dev1.conf create mode 100644 config/2inst1dev/4xxx_dev2.conf create mode 100644 config/2inst1dev/4xxx_dev3.conf create mode 100644 config/2inst1dev/4xxx_dev4.conf create mode 100644 config/2inst1dev/4xxx_dev5.conf create mode 100644 config/2inst1dev/4xxx_dev6.conf create mode 100644 config/2inst1dev/4xxx_dev7.conf diff --git a/config/2inst1dev/4xxx_dev0.conf b/config/2inst1dev/4xxx_dev0.conf new file mode 100644 index 0000000..4e8e87d --- /dev/null +++ b/config/2inst1dev/4xxx_dev0.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 256 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 2 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 0 + +# Crypto - User instance #1 +Cy1Name = "SSL1" +Cy1IsPolled = 1 +# List of core affinities +Cy1CoreAffinity = 1 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/2inst1dev/4xxx_dev1.conf b/config/2inst1dev/4xxx_dev1.conf new file mode 100644 index 0000000..659ac07 --- /dev/null +++ b/config/2inst1dev/4xxx_dev1.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 256 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 2 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 2 + +# Crypto - User instance #1 +Cy1Name = "SSL1" +Cy1IsPolled = 1 +# List of core affinities +Cy1CoreAffinity = 3 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/2inst1dev/4xxx_dev2.conf b/config/2inst1dev/4xxx_dev2.conf new file mode 100644 index 0000000..f66a2e8 --- /dev/null +++ b/config/2inst1dev/4xxx_dev2.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 256 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 2 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 4 + +# Crypto - User instance #1 +Cy1Name = "SSL1" +Cy1IsPolled = 1 +# List of core affinities +Cy1CoreAffinity = 5 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/2inst1dev/4xxx_dev3.conf b/config/2inst1dev/4xxx_dev3.conf new file mode 100644 index 0000000..0a97044 --- /dev/null +++ b/config/2inst1dev/4xxx_dev3.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 256 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 2 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 6 + +# Crypto - User instance #1 +Cy1Name = "SSL1" +Cy1IsPolled = 1 +# List of core affinities +Cy1CoreAffinity = 7 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/2inst1dev/4xxx_dev4.conf b/config/2inst1dev/4xxx_dev4.conf new file mode 100644 index 0000000..b572b74 --- /dev/null +++ b/config/2inst1dev/4xxx_dev4.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 256 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 2 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 56 + +# Crypto - User instance #1 +Cy1Name = "SSL1" +Cy1IsPolled = 1 +# List of core affinities +Cy1CoreAffinity = 57 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/2inst1dev/4xxx_dev5.conf b/config/2inst1dev/4xxx_dev5.conf new file mode 100644 index 0000000..545ccfd --- /dev/null +++ b/config/2inst1dev/4xxx_dev5.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 256 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 2 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 58 + +# Crypto - User instance #1 +Cy1Name = "SSL1" +Cy1IsPolled = 1 +# List of core affinities +Cy1CoreAffinity = 59 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/2inst1dev/4xxx_dev6.conf b/config/2inst1dev/4xxx_dev6.conf new file mode 100644 index 0000000..41b0df2 --- /dev/null +++ b/config/2inst1dev/4xxx_dev6.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 256 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 2 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 60 + +# Crypto - User instance #1 +Cy1Name = "SSL1" +Cy1IsPolled = 1 +# List of core affinities +Cy1CoreAffinity = 61 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/config/2inst1dev/4xxx_dev7.conf b/config/2inst1dev/4xxx_dev7.conf new file mode 100644 index 0000000..09d014b --- /dev/null +++ b/config/2inst1dev/4xxx_dev7.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 256 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 2 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 62 + +# Crypto - User instance #1 +Cy1Name = "SSL1" +Cy1IsPolled = 1 +# List of core affinities +Cy1CoreAffinity = 63 + +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 2 +# +## Crypto - User instance #0 +#Cy3Name = "SSL3" +#Cy3IsPolled = 1 +## List of core affinities +#Cy3CoreAffinity = 3 +# +## Crypto - User instance #1 +#Cy4Name = "SSL4" +#Cy4IsPolled = 1 +## List of core affinities +#Cy4CoreAffinity = 4 +# +## Crypto - User instance #2 +#Cy5Name = "SSL5" +#Cy5IsPolled = 1 +## List of core affinities +#Cy5CoreAffinity = 5 +# +## Crypto - User instance #1 +#Cy6Name = "SSL6" +#Cy6IsPolled = 1 +## List of core affinities +#Cy6CoreAffinity = 6 +# +## Crypto - User instance #2 +#Cy7Name = "SSL7" +#Cy7IsPolled = 1 +## List of core affinities +#Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 From 39b07f427d56481b66012d8ddf603b807765577a Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 28 Mar 2022 13:25:51 -0700 Subject: [PATCH 145/364] Device configuraiton: 8 logical instances for single QAT endpoint. --- config/8inst/4xxx_dev0.conf | 212 ++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 config/8inst/4xxx_dev0.conf diff --git a/config/8inst/4xxx_dev0.conf b/config/8inst/4xxx_dev0.conf new file mode 100644 index 0000000..15f0abe --- /dev/null +++ b/config/8inst/4xxx_dev0.conf @@ -0,0 +1,212 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 256 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 8 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 0 + +# Crypto - User instance #1 +Cy1Name = "SSL1" +Cy1IsPolled = 1 +# List of core affinities +Cy1CoreAffinity = 1 + +# Crypto - User instance #2 +Cy2Name = "SSL2" +Cy2IsPolled = 1 +# List of core affinities +Cy2CoreAffinity = 2 + +# Crypto - User instance #0 +Cy3Name = "SSL3" +Cy3IsPolled = 1 +# List of core affinities +Cy3CoreAffinity = 3 + +# Crypto - User instance #1 +Cy4Name = "SSL4" +Cy4IsPolled = 1 +# List of core affinities +Cy4CoreAffinity = 4 + +# Crypto - User instance #2 +Cy5Name = "SSL5" +Cy5IsPolled = 1 +# List of core affinities +Cy5CoreAffinity = 5 + +# Crypto - User instance #1 +Cy6Name = "SSL6" +Cy6IsPolled = 1 +# List of core affinities +Cy6CoreAffinity = 6 + +# Crypto - User instance #2 +Cy7Name = "SSL7" +Cy7IsPolled = 1 +# List of core affinities +Cy7CoreAffinity = 7 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 From 166b339dd91b13adc7c6b7afeefc37a77bce94e6 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 28 Mar 2022 14:00:43 -0700 Subject: [PATCH 146/364] Remove old device configuration. --- config/4xxx_dev0.conf | 212 ------------------------------------------ config/4xxx_dev1.conf | 212 ------------------------------------------ config/4xxx_dev2.conf | 212 ------------------------------------------ config/4xxx_dev3.conf | 212 ------------------------------------------ config/4xxx_dev4.conf | 212 ------------------------------------------ config/4xxx_dev5.conf | 212 ------------------------------------------ config/4xxx_dev6.conf | 212 ------------------------------------------ config/4xxx_dev7.conf | 212 ------------------------------------------ 8 files changed, 1696 deletions(-) delete mode 100644 config/4xxx_dev0.conf delete mode 100644 config/4xxx_dev1.conf delete mode 100644 config/4xxx_dev2.conf delete mode 100644 config/4xxx_dev3.conf delete mode 100644 config/4xxx_dev4.conf delete mode 100644 config/4xxx_dev5.conf delete mode 100644 config/4xxx_dev6.conf delete mode 100644 config/4xxx_dev7.conf diff --git a/config/4xxx_dev0.conf b/config/4xxx_dev0.conf deleted file mode 100644 index d42e88b..0000000 --- a/config/4xxx_dev0.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 64 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 2 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 0 - -# Crypto - User instance #1 -Cy1Name = "SSL1" -Cy1IsPolled = 1 -# List of core affinities -Cy1CoreAffinity = 1 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/4xxx_dev1.conf b/config/4xxx_dev1.conf deleted file mode 100644 index 0bd474f..0000000 --- a/config/4xxx_dev1.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 64 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 2 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 2 - -# Crypto - User instance #1 -Cy1Name = "SSL1" -Cy1IsPolled = 1 -# List of core affinities -Cy1CoreAffinity = 3 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/4xxx_dev2.conf b/config/4xxx_dev2.conf deleted file mode 100644 index 517587b..0000000 --- a/config/4xxx_dev2.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 64 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 2 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 4 - -# Crypto - User instance #1 -Cy1Name = "SSL1" -Cy1IsPolled = 1 -# List of core affinities -Cy1CoreAffinity = 5 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/4xxx_dev3.conf b/config/4xxx_dev3.conf deleted file mode 100644 index 34a153e..0000000 --- a/config/4xxx_dev3.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 64 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 2 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 6 - -# Crypto - User instance #1 -Cy1Name = "SSL1" -Cy1IsPolled = 1 -# List of core affinities -Cy1CoreAffinity = 7 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/4xxx_dev4.conf b/config/4xxx_dev4.conf deleted file mode 100644 index b1062cc..0000000 --- a/config/4xxx_dev4.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 64 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 2 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 56 - -# Crypto - User instance #1 -Cy1Name = "SSL1" -Cy1IsPolled = 1 -# List of core affinities -Cy1CoreAffinity = 57 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/4xxx_dev5.conf b/config/4xxx_dev5.conf deleted file mode 100644 index 041b640..0000000 --- a/config/4xxx_dev5.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 64 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 2 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 58 - -# Crypto - User instance #1 -Cy1Name = "SSL1" -Cy1IsPolled = 1 -# List of core affinities -Cy1CoreAffinity = 59 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/4xxx_dev6.conf b/config/4xxx_dev6.conf deleted file mode 100644 index e889dc2..0000000 --- a/config/4xxx_dev6.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 64 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 2 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 60 - -# Crypto - User instance #1 -Cy1Name = "SSL1" -Cy1IsPolled = 1 -# List of core affinities -Cy1CoreAffinity = 61 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/4xxx_dev7.conf b/config/4xxx_dev7.conf deleted file mode 100644 index b796db3..0000000 --- a/config/4xxx_dev7.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 64 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 2 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 62 - -# Crypto - User instance #1 -Cy1Name = "SSL1" -Cy1IsPolled = 1 -# List of core affinities -Cy1CoreAffinity = 63 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 From 97bd7aea7995caadf0237b6bca1c64473ec9586e Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Mon, 28 Mar 2022 16:55:49 -0700 Subject: [PATCH 147/364] Skmono/test nonavx512 perf (#69) * Added IPCL_DEBUG_DISABLE_AVX512IFMA flag for benchmark purposes * Revised benchmark inputs init values * Moved avx512ifma detection to root CMakeLists --- CMakeLists.txt | 16 ++++++- benchmark/bench_ops.cpp | 96 ++++++++++++++++++++--------------------- ipcl/CMakeLists.txt | 10 ----- ipcl/mod_exp.cpp | 6 +-- 4 files changed, 64 insertions(+), 64 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7918c0c..8fef7f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,7 +53,7 @@ option(IPCL_BENCHMARK "Enable benchmark" ON) option(IPCL_ENABLE_OMP "Enable OpenMP testing/benchmarking" ON) option(IPCL_DOCS "Enable document building" OFF) option(IPCL_SHARED "Build shared library" ON) - +option(IPCL_DEBUG_DISABLE_AVX512IFMA "(Debugging) Disable usage of AVX512IFMA instructions" OFF) if(IPCL_ENABLE_OMP) add_compile_definitions(IPCL_USE_OMP) endif() @@ -92,6 +92,20 @@ set(IPCL_FORWARD_CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ) +# check whether cpu support avx512 flag +if(IPCL_DEBUG_DISABLE_AVX512IFMA) + message(STATUS "Support AVX512IFMA: False") +else() + set(CPU_AVX512_FLAG "avx512ifma") + execute_process(COMMAND lscpu COMMAND grep ${CPU_AVX512_FLAG} OUTPUT_VARIABLE CPU_ENABLE_AVX512) + if("${CPU_ENABLE_AVX512}" STREQUAL "") + message(STATUS "Support AVX512IFMA: False") + else() + message(STATUS "Support AVX512IFMA: True") + add_compile_definitions(IPCL_CRYPTO_MB_MOD_EXP) + endif() +endif() + # find package for OpenSSL and Threads set(OPENSSL_USE_STATIC_LIBS TRUE) find_package(Threads REQUIRED) diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index d3bc8c0..369e3ae 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -16,10 +16,10 @@ static void BM_Add_CTCT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, - std::vector(8)); - std::vector> b(dsize, - std::vector(8)); + std::vector> a( + dsize, std::vector(8, 65535)); + std::vector> b( + dsize, std::vector(8, 65535)); std::vector> ct_a( dsize, std::vector(8)); std::vector> ct_b( @@ -48,10 +48,10 @@ static void BM_Add_CTCT_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize / 8, - std::vector(8)); - std::vector> b(dsize / 8, - std::vector(8)); + std::vector> a( + dsize / 8, std::vector(8, 65535)); + std::vector> b( + dsize / 8, std::vector(8, 65535)); std::vector> ct_a( dsize / 8, std::vector(8)); std::vector> ct_b( @@ -85,10 +85,10 @@ static void BM_Add_CTPT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, - std::vector(8)); - std::vector> b(dsize, - std::vector(8)); + std::vector> a( + dsize, std::vector(8, 65535)); + std::vector> b( + dsize, std::vector(8, 65535)); std::vector> ct_a( dsize, std::vector(8)); @@ -112,10 +112,10 @@ static void BM_Add_CTPT_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize / 8, - std::vector(8)); - std::vector> b(dsize / 8, - std::vector(8)); + std::vector> a( + dsize / 8, std::vector(8, 65535)); + std::vector> b( + dsize / 8, std::vector(8, 65535)); std::vector> ct_a( dsize / 8, std::vector(8)); @@ -145,10 +145,10 @@ static void BM_Mul_CTPT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, - std::vector(8)); - std::vector> b(dsize, - std::vector(8)); + std::vector> a( + dsize, std::vector(8, 65535)); + std::vector> b( + dsize, std::vector(8, 65535)); std::vector> ct_a( dsize, std::vector(8)); @@ -173,10 +173,10 @@ static void BM_Mul_CTPT_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize / 8, - std::vector(8)); - std::vector> b(dsize / 8, - std::vector(8)); + std::vector> a( + dsize / 8, std::vector(8, 65535)); + std::vector> b( + dsize / 8, std::vector(8, 65535)); std::vector> ct_a( dsize / 8, std::vector(8)); @@ -208,10 +208,10 @@ static void BM_Add_CTCT_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, - std::vector(8)); - std::vector> b(dsize, - std::vector(8)); + std::vector> a( + dsize, std::vector(8, 65535)); + std::vector> b( + dsize, std::vector(8, 65535)); std::vector> ct_a( dsize, std::vector(8)); std::vector> ct_b( @@ -244,10 +244,10 @@ static void BM_Add_CTCT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize / 8, - std::vector(8)); - std::vector> b(dsize / 8, - std::vector(8)); + std::vector> a( + dsize / 8, std::vector(8, 65535)); + std::vector> b( + dsize / 8, std::vector(8, 65535)); std::vector> ct_a( dsize / 8, std::vector(8)); std::vector> ct_b( @@ -282,10 +282,10 @@ static void BM_Add_CTPT_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, - std::vector(8)); - std::vector> b(dsize, - std::vector(8)); + std::vector> a( + dsize, std::vector(8, 65535)); + std::vector> b( + dsize, std::vector(8, 65535)); std::vector> ct_a( dsize, std::vector(8)); @@ -313,10 +313,10 @@ static void BM_Add_CTPT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize / 8, - std::vector(8)); - std::vector> b(dsize / 8, - std::vector(8)); + std::vector> a( + dsize / 8, std::vector(8, 65535)); + std::vector> b( + dsize / 8, std::vector(8, 65535)); std::vector> ct_a( dsize / 8, std::vector(8)); @@ -347,10 +347,10 @@ static void BM_Mul_CTPT_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, - std::vector(8)); - std::vector> b(dsize, - std::vector(8)); + std::vector> a( + dsize, std::vector(8, 65535)); + std::vector> b( + dsize, std::vector(8, 65535)); std::vector> ct_a( dsize, std::vector(8)); @@ -379,10 +379,10 @@ static void BM_Mul_CTPT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize / 8, - std::vector(8)); - std::vector> b(dsize / 8, - std::vector(8)); + std::vector> a( + dsize / 8, std::vector(8, 65535)); + std::vector> b( + dsize / 8, std::vector(8, 65535)); std::vector> ct_a( dsize / 8, std::vector(8)); diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index a4b1ff5..6bf7a0c 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -54,16 +54,6 @@ else() target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) endif() -# check whether cpu support avx512 flag -set(CPU_AVX512_FLAG "avx512ifma") -execute_process(COMMAND lscpu COMMAND grep ${CPU_AVX512_FLAG} OUTPUT_VARIABLE CPU_ENABLE_AVX512) -if("${CPU_ENABLE_AVX512}" STREQUAL "") - message(STATUS "Support AVX512IFMA: False") -else() - message(STATUS "Support AVX512IFMA: True") - add_compile_definitions(IPCL_CRYPTO_MB_MOD_EXP) -endif() - set_target_properties(ipcl PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(ipcl PROPERTIES VERSION ${IPCL_VERSION}) if(IPCL_DEBUG) diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index db97401..b578b60 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -156,12 +156,8 @@ std::vector ippModExp(const std::vector& base, return ippMBModExp(base, pow, m); #else std::vector res(IPCL_CRYPTO_MB_SIZE); -#ifdef IPCL_USE_OMP -#pragma omp parallel for -#endif - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) res[i] = ippSBModExp(base[i], pow[i], m[i]); - } return res; #endif } From 63dd399dc3787da6d9e1bce750d5e5f3eee00810 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 29 Mar 2022 16:17:32 -0700 Subject: [PATCH 148/364] Increase HE QAT buffer to 256 (facilitates support higher batch sizes). --- he_qat/include/he_qat_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/he_qat/include/he_qat_types.h b/he_qat/include/he_qat_types.h index 3eec5dd..d2b9dfa 100644 --- a/he_qat/include/he_qat_types.h +++ b/he_qat/include/he_qat_types.h @@ -13,7 +13,7 @@ extern "C" { #include -#define HE_QAT_BUFFER_SIZE 128 +#define HE_QAT_BUFFER_SIZE 256 // Type definitions typedef enum { HE_QAT_SYNC = 1, HE_QAT_ASYNC = 2 } HE_QAT_EXEC_MODE; From 14dad798ee27cf62223b979728d08295cdf6db8d Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 29 Mar 2022 16:19:31 -0700 Subject: [PATCH 149/364] Reset sample batch size to reflect total number of pke slices on a dual socket system. --- samples/test_bnModExp.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/samples/test_bnModExp.cpp b/samples/test_bnModExp.cpp index 4f9e09a..9a88b16 100644 --- a/samples/test_bnModExp.cpp +++ b/samples/test_bnModExp.cpp @@ -18,13 +18,13 @@ int gDebugParam = 1; #endif -const unsigned int BATCH_SIZE = 8; +const unsigned int BATCH_SIZE = 48; using namespace std::chrono; int main(int argc, const char** argv) { const int bit_length = 4096; - const size_t num_trials = 100; + const size_t num_trials = 10000; double avg_speed_up = 0.0; double ssl_avg_time = 0.0; @@ -178,6 +178,7 @@ int main(int argc, const char** argv) { //printf("BigNumber modular exponentiation on QAT: %.1lfus.\n", // (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); //qat_elapsed += cvt_elapsed; + printf("Request #%u\t",mod+1); printf("Overhead: %.1luus", cvt_duration.count()); printf("\tOpenSSL: %.1lfus", From e352da9c78f355bbfd383a6203dfca7f2b9a2c7e Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 29 Mar 2022 16:20:47 -0700 Subject: [PATCH 150/364] Add debug traces to track multiple instances activity. --- he_qat/he_qat_bn_ops.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index 76cd184..638dc5c 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -71,8 +71,14 @@ static void lnModExpCallback(void* pCallbackTag, // This type can be variable /// Thread-safe producer implementation for the shared request buffer. /// Stores requests in a buffer that will be offload to QAT devices. static void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { +#ifdef HE_QAT_DEBUG + printf("Lock write request\n"); +#endif pthread_mutex_lock(&_buffer->mutex); +#ifdef HE_QAT_DEBUG + printf("Wait lock write request. [buffer size: %d]\n",_buffer->count); +#endif while (_buffer->count >= HE_QAT_BUFFER_SIZE) pthread_cond_wait(&_buffer->any_free_slot, &_buffer->mutex); @@ -85,6 +91,9 @@ static void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { pthread_cond_signal(&_buffer->any_more_data); pthread_mutex_unlock(&_buffer->mutex); +#ifdef HE_QAT_DEBUG + printf("Unlocked write request. [buffer size: %d]\n",_buffer->count); +#endif } /// @brief @@ -191,6 +200,9 @@ void* start_perform_op(void* _inst_config) { config->running = 1; config->active = 1; while (config->running) { +#ifdef HE_QAT_DEBUG + printf("Try reading request from buffer. Inst #%d\n",config->inst_id); +#endif // Try consume data from butter to perform requested operation HE_QAT_TaskRequest* request = (HE_QAT_TaskRequest*)read_request(&he_qat_buffer); @@ -209,7 +221,7 @@ void* start_perform_op(void* _inst_config) { // Select appropriate action case HE_QAT_OP_MODEXP: #ifdef HE_QAT_DEBUG - printf("Enqueue request to instance #%d\n",config->inst_id); + printf("Offload request using instance #%d\n",config->inst_id); #endif #ifdef HE_QAT_PERF gettimeofday(&request->start,NULL); @@ -254,6 +266,9 @@ void* start_perform_op(void* _inst_config) { // safe to terminate running instances. Check if this detereorate // performance. pthread_cond_signal(&config->ready); +#ifdef HE_QAT_DEBUG + printf("Offloading completed by instance #%d\n",config->inst_id); +#endif } pthread_exit(NULL); } @@ -544,7 +559,7 @@ static void HE_QAT_bnModExpCallback( request->op_status = status; if (CPA_STATUS_SUCCESS == status) { if (pOpData == request->op_data) { - // Mark request as complete or ready to be used + // Mark request as complete or ready to be used request->request_status = HE_QAT_STATUS_READY; // Copy compute results to output destination memcpy(request->op_output, request->op_result.pData, @@ -568,6 +583,10 @@ static void HE_QAT_bnModExpCallback( HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, unsigned char* e, unsigned char* m, int nbits) { +#ifdef HE_QAT_DEBUG + static unsigned long long req_count = 0; + //printf("Wait lock write request. [buffer size: %d]\n",_buffer->count); +#endif // Unpack data and copy to QAT friendly memory space int len = nbits / 8; @@ -655,6 +674,10 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, pthread_mutex_init(&request->mutex, NULL); pthread_cond_init(&request->ready, NULL); +#ifdef HE_QAT_DEBUG + printf("BN ModExp interface call for request #%llu\n",++req_count); +#endif + // Submit request using producer function submit_request(&he_qat_buffer, (void*)request); From 355819723c4f92355655fee0522b89021a0043e7 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 29 Mar 2022 16:39:37 -0700 Subject: [PATCH 151/364] Fix to the lost wake-up problem with multiple instances. --- he_qat/he_qat_bn_ops.c | 100 ++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 62 deletions(-) diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index 638dc5c..edee73f 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -42,6 +42,7 @@ static void lnModExpCallback(void* pCallbackTag, // This type can be variable // Read request data request = (HE_QAT_TaskRequest*)pCallbackTag; + pthread_mutex_lock(&request->mutex); // Collect the device output in pOut request->op_status = status; if (CPA_STATUS_SUCCESS == status) { @@ -58,6 +59,7 @@ static void lnModExpCallback(void* pCallbackTag, // This type can be variable } // Make it synchronous and blocking pthread_cond_signal(&request->ready); + pthread_mutex_unlock(&request->mutex); #ifdef HE_QAT_SYNC_MODE COMPLETE((struct COMPLETION_STRUCT*)&request->callback); #endif @@ -265,7 +267,7 @@ void* start_perform_op(void* _inst_config) { // Wake up any blocked call to stop_perform_op, signaling that now it is // safe to terminate running instances. Check if this detereorate // performance. - pthread_cond_signal(&config->ready); + pthread_cond_signal(&config->ready); // Prone to the lost wake-up problem #ifdef HE_QAT_DEBUG printf("Offloading completed by instance #%d\n",config->inst_id); #endif @@ -462,72 +464,44 @@ void getBnModExpRequest(unsigned int batch_size) { HE_QAT_TaskRequest* task = (HE_QAT_TaskRequest*)he_qat_buffer.data[block_at_index]; - if (NULL == task) - continue; + //if (NULL == task) + // continue; - if (HE_QAT_STATUS_READY == task->request_status) j++; - else continue; + // Block and synchronize: Wait for the most recently offloaded request + // to complete processing + pthread_mutex_lock( + &task->mutex); // mutex only needed for the conditional variable + while (HE_QAT_STATUS_READY != task->request_status) + pthread_cond_wait(&task->ready, &task->mutex); #ifdef HE_QAT_PERF - time_taken = (task->end.tv_sec - task->start.tv_sec)*1e6; - time_taken = (time_taken + (task->end.tv_usec - task->start.tv_usec));//*1e-6; - printf("Request %u\tElapsed Time: %.1lfus\n",j,time_taken); + time_taken = (task->end.tv_sec - task->start.tv_sec)*1e6; + time_taken = (time_taken + (task->end.tv_usec - task->start.tv_usec));//*1e-6; + printf("%u time: %.1lfus\n",j,time_taken); #endif + // Free up QAT temporary memory - CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; - if (op_data) { - PHYS_CONTIG_FREE(op_data->base.pData); - PHYS_CONTIG_FREE(op_data->exponent.pData); - PHYS_CONTIG_FREE(op_data->modulus.pData); - } - free(task->op_data); - task->op_data = NULL; - if (task->op_result.pData) { - PHYS_CONTIG_FREE(task->op_result.pData); - } - - // Fix segmentation fault? - free(he_qat_buffer.data[block_at_index]); - he_qat_buffer.data[block_at_index] = NULL; - - block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; - } while(j < batch_size); - -// // Block and synchronize: Wait for the most recently offloaded request -// // to complete processing -// pthread_mutex_lock( -// &task->mutex); // mutex only needed for the conditional variable -// while (HE_QAT_STATUS_READY != task->request_status) -// pthread_cond_wait(&task->ready, &task->mutex); -// -//#ifdef HE_QAT_PERF -// time_taken = (task->end.tv_sec - task->start.tv_sec)*1e6; -// time_taken = (time_taken + (task->end.tv_usec - task->start.tv_usec));//*1e-6; -// printf("%u time: %.1lfus\n",j,time_taken); -//#endif -// -// // Free up QAT temporary memory -// CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; -// if (op_data) { -// PHYS_CONTIG_FREE(op_data->base.pData); -// PHYS_CONTIG_FREE(op_data->exponent.pData); -// PHYS_CONTIG_FREE(op_data->modulus.pData); -// } -// free(task->op_data); -// task->op_data = NULL; -// if (task->op_result.pData) { -// PHYS_CONTIG_FREE(task->op_result.pData); -// } -// -// // Move forward to wait for the next request that will be offloaded -// pthread_mutex_unlock(&task->mutex); -// -// // Fix segmentation fault? -// free(he_qat_buffer.data[block_at_index]); -// he_qat_buffer.data[block_at_index] = NULL; -// -// block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; -// } while (++j < batch_size); + CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; + if (op_data) { + PHYS_CONTIG_FREE(op_data->base.pData); + PHYS_CONTIG_FREE(op_data->exponent.pData); + PHYS_CONTIG_FREE(op_data->modulus.pData); + } + free(task->op_data); + task->op_data = NULL; + if (task->op_result.pData) { + PHYS_CONTIG_FREE(task->op_result.pData); + } + + // Move forward to wait for the next request that will be offloaded + pthread_mutex_unlock(&task->mutex); + + // Fix segmentation fault? + free(he_qat_buffer.data[block_at_index]); + he_qat_buffer.data[block_at_index] = NULL; + + block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; + } while (++j < batch_size); #ifdef HE_QAT_PERF gettimeofday(&end_time,NULL); @@ -555,6 +529,7 @@ static void HE_QAT_bnModExpCallback( // Read request data request = (HE_QAT_TaskRequest*)pCallbackTag; + pthread_mutex_lock(&request->mutex); // Collect the device output in pOut request->op_status = status; if (CPA_STATUS_SUCCESS == status) { @@ -573,6 +548,7 @@ static void HE_QAT_bnModExpCallback( } // Make it synchronous and blocking pthread_cond_signal(&request->ready); + pthread_mutex_unlock(&request->mutex); #ifdef HE_QAT_SYNC_MODE COMPLETE((struct COMPLETION_STRUCT*)&request->callback); #endif From 2a4b145e55300a1fef8a129984cd5aac11a2b590 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 29 Mar 2022 16:41:56 -0700 Subject: [PATCH 152/364] Clang-format source files. --- he_qat/he_qat_bn_ops.c | 107 ++++++++++----------- he_qat/he_qat_context.c | 50 +++++----- he_qat/include/he_qat_bn_ops.h | 2 +- samples/test_bnConversion.cpp | 2 +- samples/test_bnModExp.cpp | 155 +++++++++++++++---------------- samples/test_bnModExpPerformOp.c | 2 +- 6 files changed, 158 insertions(+), 160 deletions(-) diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index edee73f..90f3257 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -13,7 +13,7 @@ #include struct timeval start_time, end_time; double time_taken = 0.0; -#endif +#endif #include #include @@ -79,7 +79,7 @@ static void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { pthread_mutex_lock(&_buffer->mutex); #ifdef HE_QAT_DEBUG - printf("Wait lock write request. [buffer size: %d]\n",_buffer->count); + printf("Wait lock write request. [buffer size: %d]\n", _buffer->count); #endif while (_buffer->count >= HE_QAT_BUFFER_SIZE) pthread_cond_wait(&_buffer->any_free_slot, &_buffer->mutex); @@ -94,7 +94,7 @@ static void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { pthread_cond_signal(&_buffer->any_more_data); pthread_mutex_unlock(&_buffer->mutex); #ifdef HE_QAT_DEBUG - printf("Unlocked write request. [buffer size: %d]\n",_buffer->count); + printf("Unlocked write request. [buffer size: %d]\n", _buffer->count); #endif } @@ -113,7 +113,7 @@ static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) { item = _buffer->data[_buffer->next_data_slot++]; - // TODO(fdiasmor): for multithreading mode + // TODO(fdiasmor): for multithreading mode // Make copy of request so that the buffer can be reused _buffer->next_data_slot %= HE_QAT_BUFFER_SIZE; @@ -203,7 +203,7 @@ void* start_perform_op(void* _inst_config) { config->active = 1; while (config->running) { #ifdef HE_QAT_DEBUG - printf("Try reading request from buffer. Inst #%d\n",config->inst_id); + printf("Try reading request from buffer. Inst #%d\n", config->inst_id); #endif // Try consume data from butter to perform requested operation HE_QAT_TaskRequest* request = @@ -223,22 +223,23 @@ void* start_perform_op(void* _inst_config) { // Select appropriate action case HE_QAT_OP_MODEXP: #ifdef HE_QAT_DEBUG - printf("Offload request using instance #%d\n",config->inst_id); + printf("Offload request using instance #%d\n", config->inst_id); #endif #ifdef HE_QAT_PERF - gettimeofday(&request->start,NULL); + gettimeofday(&request->start, NULL); #endif - status = cpaCyLnModExp(config->inst_handle, - (CpaCyGenFlatBufCbFunc)request->callback_func, //lnModExpCallback, - (void*)request, - (CpaCyLnModExpOpData*)request->op_data, - &request->op_result); + status = cpaCyLnModExp( + config->inst_handle, + (CpaCyGenFlatBufCbFunc) + request->callback_func, // lnModExpCallback, + (void*)request, (CpaCyLnModExpOpData*)request->op_data, + &request->op_result); retry++; break; case HE_QAT_OP_NONE: default: #ifdef HE_QAT_DEBUG - printf("HE_QAT_OP_NONE to instance #%d\n",config->inst_id); + printf("HE_QAT_OP_NONE to instance #%d\n", config->inst_id); #endif retry = HE_QAT_MAX_RETRY; break; @@ -249,7 +250,7 @@ void* start_perform_op(void* _inst_config) { if (CPA_STATUS_SUCCESS == status) { // printf("retry_count = %d\n",retry_count); #ifdef HE_QAT_SYNC_MODE - // Wait until the callback function has been called + // Wait until the callback function has been called if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { request->op_status = CPA_STATUS_FAIL; request->request_status = HE_QAT_STATUS_FAIL; // Review it @@ -262,14 +263,15 @@ void* start_perform_op(void* _inst_config) { } else { request->op_status = CPA_STATUS_FAIL; request->request_status = HE_QAT_STATUS_FAIL; // Review it - } + } // Wake up any blocked call to stop_perform_op, signaling that now it is // safe to terminate running instances. Check if this detereorate // performance. - pthread_cond_signal(&config->ready); // Prone to the lost wake-up problem + pthread_cond_signal( + &config->ready); // Prone to the lost wake-up problem #ifdef HE_QAT_DEBUG - printf("Offloading completed by instance #%d\n",config->inst_id); + printf("Offloading completed by instance #%d\n", config->inst_id); #endif } pthread_exit(NULL); @@ -328,7 +330,7 @@ void stop_perform_op(HE_QAT_InstConfig* config, unsigned num_inst) { HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int nbits) { // Unpack data and copy to QAT friendly memory space - int len = (nbits + 7) >> 3; // nbits / 8; + int len = (nbits + 7) >> 3; // nbits / 8; Cpa8U* pBase = NULL; Cpa8U* pModulus = NULL; @@ -448,25 +450,24 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, return HE_QAT_STATUS_SUCCESS; } - // Maybe it will be useful to pass the number of requests to retrieve // Pass post-processing function as argument to bring output to expected type void getBnModExpRequest(unsigned int batch_size) { static unsigned long block_at_index = 0; unsigned int j = 0; - + #ifdef HE_QAT_PERF - gettimeofday(&start_time,NULL); + gettimeofday(&start_time, NULL); #endif - do { - // Buffer read may be safe for single-threaded blocking calls only. - // Note: Not tested on multithreaded environment. - HE_QAT_TaskRequest* task = - (HE_QAT_TaskRequest*)he_qat_buffer.data[block_at_index]; - - //if (NULL == task) + do { + // Buffer read may be safe for single-threaded blocking calls only. + // Note: Not tested on multithreaded environment. + HE_QAT_TaskRequest* task = + (HE_QAT_TaskRequest*)he_qat_buffer.data[block_at_index]; + + // if (NULL == task) // continue; - + // Block and synchronize: Wait for the most recently offloaded request // to complete processing pthread_mutex_lock( @@ -475,9 +476,10 @@ void getBnModExpRequest(unsigned int batch_size) { pthread_cond_wait(&task->ready, &task->mutex); #ifdef HE_QAT_PERF - time_taken = (task->end.tv_sec - task->start.tv_sec)*1e6; - time_taken = (time_taken + (task->end.tv_usec - task->start.tv_usec));//*1e-6; - printf("%u time: %.1lfus\n",j,time_taken); + time_taken = (task->end.tv_sec - task->start.tv_sec) * 1e6; + time_taken = + (time_taken + (task->end.tv_usec - task->start.tv_usec)); //*1e-6; + printf("%u time: %.1lfus\n", j, time_taken); #endif // Free up QAT temporary memory @@ -495,19 +497,20 @@ void getBnModExpRequest(unsigned int batch_size) { // Move forward to wait for the next request that will be offloaded pthread_mutex_unlock(&task->mutex); - - // Fix segmentation fault? - free(he_qat_buffer.data[block_at_index]); + + // Fix segmentation fault? + free(he_qat_buffer.data[block_at_index]); he_qat_buffer.data[block_at_index] = NULL; - - block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; + + block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; } while (++j < batch_size); #ifdef HE_QAT_PERF - gettimeofday(&end_time,NULL); - time_taken = (end_time.tv_sec - start_time.tv_sec)*1e6; - time_taken = (time_taken + (end_time.tv_usec - start_time.tv_usec));//*1e-6; - printf("Batch Wall Time: %.1lfus\n",time_taken); + gettimeofday(&end_time, NULL); + time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; + time_taken = + (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; + printf("Batch Wall Time: %.1lfus\n", time_taken); #endif return; @@ -528,21 +531,21 @@ static void HE_QAT_bnModExpCallback( if (NULL != pCallbackTag) { // Read request data request = (HE_QAT_TaskRequest*)pCallbackTag; - + pthread_mutex_lock(&request->mutex); // Collect the device output in pOut request->op_status = status; if (CPA_STATUS_SUCCESS == status) { if (pOpData == request->op_data) { - // Mark request as complete or ready to be used + // Mark request as complete or ready to be used request->request_status = HE_QAT_STATUS_READY; // Copy compute results to output destination memcpy(request->op_output, request->op_result.pData, request->op_result.dataLenInBytes); #ifdef HE_QAT_PERF - gettimeofday(&request->end,NULL); + gettimeofday(&request->end, NULL); #endif - } else { + } else { request->request_status = HE_QAT_STATUS_FAIL; } } @@ -551,7 +554,7 @@ static void HE_QAT_bnModExpCallback( pthread_mutex_unlock(&request->mutex); #ifdef HE_QAT_SYNC_MODE COMPLETE((struct COMPLETION_STRUCT*)&request->callback); -#endif +#endif } return; @@ -561,7 +564,7 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, unsigned char* e, unsigned char* m, int nbits) { #ifdef HE_QAT_DEBUG static unsigned long long req_count = 0; - //printf("Wait lock write request. [buffer size: %d]\n",_buffer->count); + // printf("Wait lock write request. [buffer size: %d]\n",_buffer->count); #endif // Unpack data and copy to QAT friendly memory space int len = nbits / 8; @@ -577,7 +580,7 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, // TODO(fdiasmor): Try it with 8-byte alignment. CpaStatus status = CPA_STATUS_FAIL; - //status = PHYS_CONTIG_ALLOC(&pBase, len); + // status = PHYS_CONTIG_ALLOC(&pBase, len); status = PHYS_CONTIG_ALLOC_ALIGNED(&pBase, len, 8); if (CPA_STATUS_SUCCESS == status && NULL != pBase) { memcpy(pBase, b, len); @@ -586,7 +589,7 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, return HE_QAT_STATUS_FAIL; } - //status = PHYS_CONTIG_ALLOC(&pExponent, len); + // status = PHYS_CONTIG_ALLOC(&pExponent, len); status = PHYS_CONTIG_ALLOC_ALIGNED(&pExponent, len, 8); if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { memcpy(pExponent, e, len); @@ -595,7 +598,7 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, return HE_QAT_STATUS_FAIL; } - //status = PHYS_CONTIG_ALLOC(&pModulus, len); + // status = PHYS_CONTIG_ALLOC(&pModulus, len); status = PHYS_CONTIG_ALLOC_ALIGNED(&pModulus, len, 8); if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { memcpy(pModulus, m, len); @@ -630,7 +633,7 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, op_data->modulus.dataLenInBytes = len; request->op_data = (void*)op_data; - //status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); + // status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); status = PHYS_CONTIG_ALLOC_ALIGNED(&request->op_result.pData, len, 8); if (CPA_STATUS_SUCCESS == status && NULL != request->op_result.pData) { request->op_result.dataLenInBytes = len; @@ -651,7 +654,7 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, pthread_cond_init(&request->ready, NULL); #ifdef HE_QAT_DEBUG - printf("BN ModExp interface call for request #%llu\n",++req_count); + printf("BN ModExp interface call for request #%llu\n", ++req_count); #endif // Submit request using producer function diff --git a/he_qat/he_qat_context.c b/he_qat/he_qat_context.c index d8df22a..ab04e67 100644 --- a/he_qat/he_qat_context.c +++ b/he_qat/he_qat_context.c @@ -27,9 +27,9 @@ #define NUM_ACTIVE_INSTANCES 8 // Global variable declarations -//HE_QAT_Inst he_qat_instances[HE_QAT_MAX_NUM_INST]; -//pthread_attr_t he_qat_inst_attr[HE_QAT_MAX_NUM_INST]; -//HE_QAT_InstConfig he_qat_inst_config[HE_QAT_MAX_NUM_INST]; +// HE_QAT_Inst he_qat_instances[HE_QAT_MAX_NUM_INST]; +// pthread_attr_t he_qat_inst_attr[HE_QAT_MAX_NUM_INST]; +// HE_QAT_InstConfig he_qat_inst_config[HE_QAT_MAX_NUM_INST]; // HE_QAT_RequestBuffer he_qat_buffer; HE_QAT_Inst he_qat_instances[NUM_ACTIVE_INSTANCES]; pthread_attr_t he_qat_inst_attr[NUM_ACTIVE_INSTANCES]; @@ -41,8 +41,7 @@ extern void stop_perform_op(void* _inst_config, unsigned num_inst); CpaInstanceHandle handle = NULL; -static CpaInstanceHandle get_qat_instance() -{ +static CpaInstanceHandle get_qat_instance() { static CpaInstanceHandle cyInstHandles[MAX_INSTANCES]; static Cpa16U numInstances = 0; static Cpa16U nextInstance = 0; @@ -54,20 +53,20 @@ static CpaInstanceHandle get_qat_instance() if (numInstances >= MAX_INSTANCES) { numInstances = MAX_INSTANCES; } - if (numInstances >= NUM_ACTIVE_INSTANCES) { - numInstances = NUM_ACTIVE_INSTANCES; - } + if (numInstances >= NUM_ACTIVE_INSTANCES) { + numInstances = NUM_ACTIVE_INSTANCES; + } - printf("Found %d CyInstances.\n",numInstances); - printf("Next Instance: %d.\n",nextInstance); + printf("Found %d CyInstances.\n", numInstances); + printf("Next Instance: %d.\n", nextInstance); if ((status == CPA_STATUS_SUCCESS) && (numInstances > 0)) { status = cpaCyGetInstances(numInstances, cyInstHandles); if (status == CPA_STATUS_SUCCESS) - return cyInstHandles[nextInstance]; - //*pCyInstHandle = cyInstHandles[0]; + return cyInstHandles[nextInstance]; + //*pCyInstHandle = cyInstHandles[0]; } - + if (0 == numInstances) { PRINT_ERR("No instances found for 'SSL'\n"); PRINT_ERR("Please check your section names"); @@ -75,13 +74,12 @@ static CpaInstanceHandle get_qat_instance() PRINT_ERR("Also make sure to use config file version 2.\n"); } - return NULL; - } + return NULL; + } nextInstance = ((nextInstance + 1) % numInstances); - printf("Next Instance: %d.\n",nextInstance); + printf("Next Instance: %d.\n", nextInstance); return cyInstHandles[nextInstance]; - } /// @brief @@ -113,15 +111,15 @@ HE_QAT_STATUS acquire_qat_devices() { #endif // Potential out-of-scope hazard for segmentation fault - CpaInstanceHandle _inst_handle[NUM_ACTIVE_INSTANCES];// = NULL; + CpaInstanceHandle _inst_handle[NUM_ACTIVE_INSTANCES]; // = NULL; // TODO: @fdiasmor Create a CyGetInstance that retrieves more than one. - //sampleCyGetInstance(&_inst_handle); + // sampleCyGetInstance(&_inst_handle); for (unsigned int i = 0; i < NUM_ACTIVE_INSTANCES; i++) { - _inst_handle[i] = get_qat_instance(); - if (_inst_handle[i] == NULL) { - printf("Failed to find QAT endpoints.\n"); - return HE_QAT_STATUS_FAIL; - } + _inst_handle[i] = get_qat_instance(); + if (_inst_handle[i] == NULL) { + printf("Failed to find QAT endpoints.\n"); + return HE_QAT_STATUS_FAIL; + } } // sampleCyGetInstance(&handle); @@ -146,7 +144,7 @@ HE_QAT_STATUS acquire_qat_devices() { // Creating QAT instances (consumer threads) to process op requests pthread_attr_t attr; cpu_set_t cpus; - //for (int i = 0; i < HE_QAT_SYNC; i++) { + // for (int i = 0; i < HE_QAT_SYNC; i++) { for (int i = 0; i < NUM_ACTIVE_INSTANCES; i++) { CPU_ZERO(&cpus); CPU_SET(i, &cpus); @@ -177,7 +175,7 @@ HE_QAT_STATUS acquire_qat_devices() { #endif // Dispatch the qat instances to run independently in the background - //for (int i = 0; i < HE_QAT_SYNC; i++) { + // for (int i = 0; i < HE_QAT_SYNC; i++) { for (int i = 0; i < NUM_ACTIVE_INSTANCES; i++) { pthread_detach(he_qat_instances[i]); } diff --git a/he_qat/include/he_qat_bn_ops.h b/he_qat/include/he_qat_bn_ops.h index 0d75da5..7ad679c 100644 --- a/he_qat/include/he_qat_bn_ops.h +++ b/he_qat/include/he_qat_bn_ops.h @@ -37,7 +37,7 @@ typedef struct { // CpaCyLnModExpOpData op_data; void* op_data; void* op_output; - void* callback_func; + void* callback_func; volatile HE_QAT_STATUS request_status; pthread_mutex_t mutex; pthread_cond_t ready; diff --git a/samples/test_bnConversion.cpp b/samples/test_bnConversion.cpp index 6282951..892662d 100644 --- a/samples/test_bnConversion.cpp +++ b/samples/test_bnConversion.cpp @@ -6,7 +6,7 @@ #include "cpa_sample_utils.h" //#ifdef __cplusplus -//extern "C" { +// extern "C" { //#endif #include diff --git a/samples/test_bnModExp.cpp b/samples/test_bnModExp.cpp index 9a88b16..27003a0 100644 --- a/samples/test_bnModExp.cpp +++ b/samples/test_bnModExp.cpp @@ -30,9 +30,9 @@ int main(int argc, const char** argv) { double ssl_avg_time = 0.0; double qat_avg_time = 0.0; -// clock_t start = CLOCKS_PER_SEC; -// clock_t ssl_elapsed = CLOCKS_PER_SEC; -// clock_t qat_elapsed = CLOCKS_PER_SEC; + // clock_t start = CLOCKS_PER_SEC; + // clock_t ssl_elapsed = CLOCKS_PER_SEC; + // clock_t qat_elapsed = CLOCKS_PER_SEC; HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; @@ -51,36 +51,36 @@ int main(int argc, const char** argv) { char* bn_str = BN_bn2hex(bn_mod); #ifdef _DESTINY_DEBUG_VERBOSE - printf("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, + printf("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); #endif - OPENSSL_free(bn_str); - - // Generate exponent in [0..bn_mod] + OPENSSL_free(bn_str); + + // Generate exponent in [0..bn_mod] BIGNUM* bn_exponent = BN_new(); if (!BN_rand_range(bn_exponent, bn_mod)) { BN_free(bn_mod); continue; } - // Generate base number + // Generate base number BIGNUM* bn_base = generateTestBNData(bit_length); // Perform OpenSSL ModExp Op BIGNUM* ssl_res = BN_new(); auto start = high_resolution_clock::now(); - //start = clock(); + // start = clock(); BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); auto stop = high_resolution_clock::now(); - auto ssl_duration = duration_cast(stop-start); - //ssl_elapsed = clock() - start; + auto ssl_duration = duration_cast(stop - start); + // ssl_elapsed = clock() - start; int len_ = (bit_length + 7) >> 3; - // Start QAT timer (including data conversion overhead) -// start = clock(); + // Start QAT timer (including data conversion overhead) + // start = clock(); start = high_resolution_clock::now(); - unsigned char* bn_base_data_ = + unsigned char* bn_base_data_ = (unsigned char*)calloc(len_, sizeof(unsigned char)); if (NULL == bn_base_data_) exit(1); BN_bn2binpad(bn_base, bn_base_data_, len_); @@ -96,10 +96,10 @@ int main(int argc, const char** argv) { (unsigned char*)calloc(len_, sizeof(unsigned char)); if (NULL == bn_remainder_data_) exit(1); stop = high_resolution_clock::now(); - auto cvt_duration = duration_cast(stop-start); -// clock_t cvt_elapsed = clock() - start; + auto cvt_duration = duration_cast(stop - start); + // clock_t cvt_elapsed = clock() - start; - // Simulate input number in BigNumber representation + // Simulate input number in BigNumber representation BigNumber big_num_base((Ipp32u)0); BigNumber big_num_mod((Ipp32u)0); BigNumber big_num_exponent((Ipp32u)0); @@ -113,109 +113,106 @@ int main(int argc, const char** argv) { printf("Failed at binToBigNumber()\n"); exit(1); } - status = binToBigNumber(big_num_exponent, bn_exponent_data_, bit_length); + status = + binToBigNumber(big_num_exponent, bn_exponent_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { printf("Failed at binToBigNumber()\n"); exit(1); } - // Reset numbers to 0 - memset(bn_base_data_,0,len_); - memset(bn_mod_data_,0,len_); - memset(bn_exponent_data_,0,len_); + // Reset numbers to 0 + memset(bn_base_data_, 0, len_); + memset(bn_mod_data_, 0, len_); + memset(bn_exponent_data_, 0, len_); // Make sure variables are reset - if (memcmp(bn_base_data_, bn_mod_data_, len_) || - memcmp(bn_base_data_, bn_exponent_data_, len_)) { - PRINT_ERR("Pointers are not reset to zero!"); - exit(1); - } + if (memcmp(bn_base_data_, bn_mod_data_, len_) || + memcmp(bn_base_data_, bn_exponent_data_, len_)) { + PRINT_ERR("Pointers are not reset to zero!"); + exit(1); + } - //start = clock(); + // start = clock(); start = high_resolution_clock::now(); - status = bigNumberToBin(bn_base_data_, bit_length, big_num_base); + status = bigNumberToBin(bn_base_data_, bit_length, big_num_base); if (HE_QAT_STATUS_SUCCESS != status) { printf("bn_base_data_: failed at bignumbertobin()\n"); exit(1); } - status = bigNumberToBin(bn_mod_data_, bit_length, big_num_mod); + status = bigNumberToBin(bn_mod_data_, bit_length, big_num_mod); if (HE_QAT_STATUS_SUCCESS != status) { printf("bn_base_data_: failed at bignumbertobin()\n"); exit(1); } - status = bigNumberToBin(bn_exponent_data_, bit_length, big_num_exponent); + status = + bigNumberToBin(bn_exponent_data_, bit_length, big_num_exponent); if (HE_QAT_STATUS_SUCCESS != status) { printf("bn_base_data_: failed at bignumbertobin()\n"); exit(1); } - //cvt_elapsed += (clock() - start); - cvt_duration += duration_cast(high_resolution_clock::now()-start); + // cvt_elapsed += (clock() - start); + cvt_duration += + duration_cast(high_resolution_clock::now() - start); - // Perform BigNumber modular exponentiation on QAT - //start = clock(); + // Perform BigNumber modular exponentiation on QAT + // start = clock(); start = high_resolution_clock::now(); - for (unsigned int b = 0; b < BATCH_SIZE; b++) - status = HE_QAT_bnModExp(bn_remainder_data_, bn_base_data_, - bn_exponent_data_, bn_mod_data_, bit_length); - getBnModExpRequest(BATCH_SIZE); + for (unsigned int b = 0; b < BATCH_SIZE; b++) + status = + HE_QAT_bnModExp(bn_remainder_data_, bn_base_data_, + bn_exponent_data_, bn_mod_data_, bit_length); + getBnModExpRequest(BATCH_SIZE); stop = high_resolution_clock::now(); - auto qat_duration = duration_cast(stop-start); + auto qat_duration = duration_cast(stop - start); - ssl_avg_time = (mod * ssl_avg_time + - ((double)(ssl_duration.count()))) / + ssl_avg_time = + (mod * ssl_avg_time + ((double)(ssl_duration.count()))) / (mod + 1); + qat_avg_time = (mod * qat_avg_time + + ((double)(qat_duration.count())) / BATCH_SIZE) / (mod + 1); - qat_avg_time = - (mod * qat_avg_time + - ((double) (qat_duration.count()))/ BATCH_SIZE) / - (mod + 1); - avg_speed_up = - (mod * avg_speed_up + - (ssl_duration.count()/(double)(qat_duration.count()/BATCH_SIZE)))/(mod + 1); - //qat_elapsed = clock() - start; - - //printf("BigNumber data conversion overhead: %.1lfus.\n", + avg_speed_up = (mod * avg_speed_up + + (ssl_duration.count() / + (double)(qat_duration.count() / BATCH_SIZE))) / + (mod + 1); + // qat_elapsed = clock() - start; + + // printf("BigNumber data conversion overhead: %.1lfus.\n", // (cvt_elapsed / (CLOCKS_PER_SEC / 1000000.0))); - //printf("BigNumber modular exponentiation on QAT: %.1lfus.\n", + // printf("BigNumber modular exponentiation on QAT: %.1lfus.\n", // (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); - //qat_elapsed += cvt_elapsed; - printf("Request #%u\t",mod+1); - printf("Overhead: %.1luus", - cvt_duration.count()); - printf("\tOpenSSL: %.1lfus", - ssl_avg_time); - printf("\tQAT: %.1lfus", - qat_avg_time); - printf("\tSpeed-up: %.1lfx", - avg_speed_up); - //qat_elapsed += cvt_elapsed; - - - - BIGNUM* qat_res = BN_new(); + // qat_elapsed += cvt_elapsed; + printf("Request #%u\t", mod + 1); + printf("Overhead: %.1luus", cvt_duration.count()); + printf("\tOpenSSL: %.1lfus", ssl_avg_time); + printf("\tQAT: %.1lfus", qat_avg_time); + printf("\tSpeed-up: %.1lfx", avg_speed_up); + // qat_elapsed += cvt_elapsed; + + BIGNUM* qat_res = BN_new(); BN_bin2bn(bn_remainder_data_, len_, qat_res); if (HE_QAT_STATUS_SUCCESS != status) { PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); - } + } #ifdef _DESTINY_DEBUG_VERBOSE else { PRINT_DBG("\nQAT bnModExpOp finished\n"); } #endif - //start = clock(); + // start = clock(); BigNumber big_num((Ipp32u)0); - status = binToBigNumber(big_num, bn_remainder_data_, bit_length); + status = binToBigNumber(big_num, bn_remainder_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { printf("bn_remainder_data_: Failed at bigNumberToBin()\n"); exit(1); } - //qat_elapsed += (clock() - start); - //printf("BigNumber ModExp total time: %.1lfus.\n", + // qat_elapsed += (clock() - start); + // printf("BigNumber ModExp total time: %.1lfus.\n", // (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); #ifdef _DESTINY_DEBUG_VERBOSE - bn_str = BN_bn2hex(qat_res); + bn_str = BN_bn2hex(qat_res); printf("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, BN_num_bytes(qat_res), BN_num_bits(qat_res)); #endif @@ -227,9 +224,10 @@ int main(int argc, const char** argv) { big_num.num2hex(str); printf("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, bit_len); - printf("---------------------################-----------------------\n"); + printf( + "---------------------################-----------------------\n"); #endif - + if (BN_cmp(qat_res, ssl_res) != 0) printf("\t** FAIL **\n"); else @@ -240,14 +238,13 @@ int main(int argc, const char** argv) { BN_free(bn_exponent); BN_free(qat_res); BN_free(ssl_res); - -// OPENSSL_free(bn_str); + + // OPENSSL_free(bn_str); free(bn_mod_data_); free(bn_base_data_); free(bn_exponent_data_); free(bn_remainder_data_); - } // Tear down OpenSSL context diff --git a/samples/test_bnModExpPerformOp.c b/samples/test_bnModExpPerformOp.c index cb41d51..2d06e5a 100644 --- a/samples/test_bnModExpPerformOp.c +++ b/samples/test_bnModExpPerformOp.c @@ -9,7 +9,7 @@ #include #include -int gDebugParam = 1; // Active in Debug mode +int gDebugParam = 1; // Active in Debug mode const unsigned int BATCH_SIZE = 1; int main(int argc, const char** argv) { From baa76470c7788f6325f6cd99b18a3d911c468d9c Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Wed, 30 Mar 2022 18:07:21 -0700 Subject: [PATCH 153/364] Fixed uint32 and BigNumber confusion in unittest - CtMultiplyPt and CtMultiplyPtArray cases (#71) --- test/test_ops.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/test/test_ops.cpp b/test/test_ops.cpp index c7a830a..025f3b4 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -58,18 +58,18 @@ void CtPlusPtArray(std::vector& res, void CtMultiplyPt(std::vector& res, const std::vector& ct1, - const std::vector& pt2, const ipcl::keyPair key) { + const std::vector& pt2, + const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { ipcl::EncryptedNumber a(key.pub_key, ct1[i]); - ipcl::EncryptedNumber b(key.pub_key, pt2[i]); - ipcl::EncryptedNumber sum = a * b; + ipcl::EncryptedNumber sum = a * pt2[i]; res[i] = sum.getBN(); } } void CtMultiplyPtArray(std::vector& res, const std::vector& ct1, - const std::vector& pt2, + const std::vector& pt2, const ipcl::keyPair key) { ipcl::EncryptedNumber a(key.pub_key, ct1); ipcl::EncryptedNumber b(key.pub_key, pt2); @@ -258,7 +258,7 @@ TEST(OperationTest, CtMultiplyPtTest) { std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -267,11 +267,12 @@ TEST(OperationTest, CtMultiplyPtTest) { pt1[i] = dist(rng); pt2[i] = dist(rng); ptbn1[i] = pt1[i]; + ptbn2[i] = pt2[i]; } key.pub_key->encrypt(ct1, ptbn1); - CtMultiplyPt(res, ct1, pt2, key); + CtMultiplyPt(res, ct1, ptbn2, key); key.priv_key->decrypt(dt, res); @@ -296,21 +297,21 @@ TEST(OperationTest, CtMultiplyZeroPtTest) { std::vector ct1(8), ct2(8); std::vector dt(8), res(8); - std::vector pt1(8), pt2(8); - std::vector ptbn1(8); + std::vector pt1(8), pt2(8, 0); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < 8; i++) { pt1[i] = dist(rng); - pt2[i] = 0; ptbn1[i] = pt1[i]; + ptbn2[i] = pt2[i]; } key.pub_key->encrypt(ct1, ptbn1); - CtMultiplyPt(res, ct1, pt2, key); + CtMultiplyPt(res, ct1, ptbn2, key); key.priv_key->decrypt(dt, res); @@ -350,7 +351,7 @@ TEST(OperationTest, CtMultiplyPtArrayTest) { key.pub_key->encrypt(ct1, ptbn1); - CtMultiplyPtArray(res, ct1, pt2, key); + CtMultiplyPtArray(res, ct1, ptbn2, key); key.priv_key->decrypt(dt, res); From a76971763f982c9264de6929827121eb60521b66 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 31 Mar 2022 18:04:22 -0700 Subject: [PATCH 154/364] Update README.md with more complete description and instructions. --- README.md | 164 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 130 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index ccf3d26..a7c3854 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Intel Homomorphic Encryption (HE) Acceleration Library for Quick Assist Technology (QAT) -Intel Homomorphic Encryption Acceleration Library for QAT (HEQAT Lib) is an open-source library which provides accelerated performance for homomorphic encryption (HE) math functions involving multi-precision numbers and modular arithmetic. This library is written in C99. +Intel Homomorphic Encryption Acceleration Library for QAT (HE QAT Lib) is an open-source library which provides accelerated performance for homomorphic encryption (HE) math functions involving multi-precision numbers and modular arithmetic. This library is written in C99. ## Contents - [Intel Homomorphic Encryption Acceleration Library for QAT](#intel-homomorphic-encryption-library-for-qat) @@ -10,7 +10,7 @@ Intel Homomorphic Encryption Acceleration Library for QAT (HEQAT Lib) is an open - [Dependencies](#dependencies) - [Instructions](#instructions) - [Testing and Benchmarking](#testing-and-benchmarking) -- [Standardization](#standardization) + - [Contributors](#contributors) ## Introduction @@ -18,64 +18,160 @@ Intel Homomorphic Encryption Acceleration Library for QAT (HEQAT Lib) is an open This library is underconstruction and currently only offers acceleration of modular exponentiation of multi-precision numbers, i.e. large numbers whose precision range from 1024 to 8192 bits. Current stage of implementation supports modular exponentiation of big numbers encoded with OpenSSL's BIGNUM data type and IPP Crypto's BigNumber class. More details about the modes of operation and characteristics of the execution flow are described below: - Synchronous: It means that calls will be made to send modular exponentiation work requests to be offloaded to the accelerator and processed in the order they are issued. + + - Asynchronous: It means that multiple concurrent modular exponentiation work requests can be offloaded to the accelerator and processed not necessarily in the order they are issued from the host side. - Blocking: It means that the next buffered work request waits for completion of the processing of the most recent request offloaded to the accelerator, when processing must be currently in progress. - - Batch Support: The internal buffer is set accommodate 16 request at a time so that the maximum batch size is 16. Therefore, only up to 16 requests can be exercised asynchronously from the application side, be it from a single `for loop` or static code block. Finally, in order to collect the requests, a call to the `get` function that waits for completion of the requests must be done. + - Batch Support: The internal buffer is set accommodate 256 requests at a time so that the maximum batch size is 256. Therefore, only up to 256 requests can be exercised asynchronously from the application side, be it from a single `for loop` or static code block. Finally, in order to collect the requests, a call to the `getBnModExpRequest()` function must be performed to wait for completion of all submitted asynchronous requests. - - Single-Threaded: It is currently safer to use single-threaded, although multiple threading is partially supported (try it at your own risk). Multi-threading can only be supported so long as the internal buffer can fill all the requests submitted by multiple threads, otherwise it will hang (this feature will become reliable in later versions). + - Single-Threaded: It is currently desinged (and safer) to use it with a single-threaded applications, although multithreading is partially supported (try it at your own risk). Multithreading support is limited to work under restrictive conditions, namely, the total number of incoming requests at any point in time from multiple threads does not exceed the size of the internal buffer from which work requests are taken to be offloaded to QAT devices. Effective multithreading support will relax this condition by relying on a separate buffer that admits outstanding work requests. + - - Single instance: The library is configure to use only 1 single QAT endpoint at any time at the creation of the QAT runtime context. + - Multiple Instances/Devices: The library accesses all logical instances from all visible and configured QAT endpoints at the creation of the QAT runtime context. Therefore, if 8 QAT endpoints are available, it will attempt to use them all, including all the total number of logical instances configured per process. -## Building the Library +>> _**Note**_: Current implementation does not verify if the instance/endpoint has the capabilities needed by the library. For example, the library needs access to the _asym_ capabilities like `CyLnModExp`, therefore it the configuration file of an endpoint happens to be configured not offer it, the application will exit with an error at some point during execution. + +## Building the HE QAT Library + +### Requirements +The hardware requirement to use the library is the following: + - Intel Sapphire Rapids + - Intel C62XX acceleration card + +As for the operating systems, the library has been tested and confirmed to work on Ubuntu 20.04. + +### Dependencies + +Required dependencies include: ``` -export ICP_ROOT=$HOME/QAT -cmake -S . -B build -DHE_QAT_MISC=OFF -cmake --build build -cmake --install build +cmake >=3.15.1 +git +pthread +gcc >= 9.1 +QAT20.L.0.8.0-00071.tar.gz (qatlib and QAT drivers) +ipp-crypto ``` -`HE_QAT_MISC` enables IPP Crypto. If you want to enable that, follow the build instructions below: +### Instructions + +Before attempting to build the library, please check if the platform has the QAT hardware. ``` -git clone https://github.com/intel/ipp-crypto.git -cd ipp-crypto -CC=gcc CXX=g++ cmake CMakeLists.txt -B_build -DARCH=intel64 -DMERGED_BLD:BOOL=on -DCMAKE_INSTALL_PREFIX=/opt/ipp-crypto -DOPENSSL_INCLUDE_DIR=/opt/openssl/include -DOPENSSL_LIBRARIES=/opt/openssl/lib -DOPENSSL_ROOT_DIR=/opt/openssl -DCMAKE_ASM_NASM_COMPILER=/opt/nasm-2.15/bin/nasm -cmake --build _build -j -sudo cmake --install _build +$ sudo lspci -d 8086:4940 +6b:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) +70:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) +75:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) +7a:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) +e8:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) +ed:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) +f2:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) +f7:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) ``` -### Running Examples +In the example above, the platform is a dual-socket Sapphire Rapids (SPR) and it shows 8 QAT endpoints, 4 on each socket. + +#### Installing QAT Software Stack ``` -./build/examples/test_context -``` +$ cd $HOME +$ mkdir QAT +$ mv QAT20.L.0.8.0-00071.tar.gz QAT/ +$ cd QAT +$ tar zxvf QAT20.L.0.8.0-00071.tar.gz +$ ./configure +$ sudo make -j +$ sudo make install +``` + +> _**Note**_: Please contact QAT team listed at [https://01.org/intel-quickassist-technology](https://01.org/intel-quickassist-technology) to obtain the latest `QAT20.L.0.8.0-00071.tar.gz` package. + +Verify the QAT installation by checking the QAT service status: + + +``` +sudo service qat_service status +``` + +If all checks out, following the instructions below to build the HE QAT library. + +#### Building the Library + +Without `BigNumber` support: + +``` +$ git clone https://github.com/intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.project-destiny.git +$ git checkout development +$ export ICP_ROOT=$HOME/QAT +$ cmake -S . -B build -DHE_QAT_MISC=OFF +$ cmake --build build +$ cmake --install build +``` + +The cmake configuration variable `HE_QAT_MISC=ON` enables `BigNumber` resources and samples, requiring IPP Crypto installation as a dependency. If usage of the utility functions that support `BigNumber` data type is needed, follow the building instructions below to install IPP Crypto and then rebuild the library with the cmake flag `HE_QAT_MISC=ON`: ``` -./build/examples/test_bnModExpPerformOp +$ git clone https://github.com/intel/ipp-crypto.git +$ cd ipp-crypto +$ CC=gcc CXX=g++ cmake CMakeLists.txt -B_build -DARCH=intel64 -DMERGED_BLD:BOOL=ON -DCMAKE_INSTALL_PREFIX=/opt/ipp-crypto -DOPENSSL_INCLUDE_DIR=/opt/openssl/include -DOPENSSL_LIBRARIES=/opt/openssl/lib -DOPENSSL_ROOT_DIR=/opt/openssl -DCMAKE_ASM_NASM_COMPILER=/opt/nasm-2.15/bin/nasm +$ cmake --build _build -j +$ sudo cmake --install _build +``` + +#### Configure QAT endpoints + +Before trying to run any application or example that uses the HE QAT Lib, the QAT endpoints must be configured. Examples of configurations can be found in the directory `config`. The configuration that we found to serve us with the best performance is located at `config/1inst1dev`. + +``` +$ sudo cp config/1inst1dev/4xxx_dev*.conf /etc/ +$ sudo service qat_service restart +``` + +#### Configuration Options + +In addition to the standard CMake configuration options, Intel HE Acceleration Library for QAT supports several cmake options to configure the build. For convenience, they are listed below: + + + +| HE_QAT_MISC | ON / OFF (default OFF) | Set to OFF, enable benchmark suite via Google benchmark | --> + + + + +#### Running Samples + +Test showing creation and teardown of the QAT runtime environment: + +``` +./build/samples/test_context ``` +Test showing functional correctness and performance: + ``` -./build/examples/test_bnConversion +./build/samples/test_bnModExpPerformOp ``` -### Requirements -The hardware requirement to use the library is the following: - - Intel Sapphire Rapids - - Intel C62XX acceleration card +If built with `HE_QAT_MISC=ON`, then the following samples below are also available to try. -As for the operating systems, the library has been tested and confirmed to work on Ubuntu 20.04. +Test showing data conversion between `BigNumber` and `CpaFlatBuffer` formats: -### Dependencies +``` +./build/samples/test_bnConversion +``` + +Test showing functional correctness and performance using `BigNumber` data types: -Required dependencies include: ``` -cmake >=3.15.1 -git -pthread -gcc >= 9.1 -qatlib -ippcrypto +./build/samples/test_bnModExp ``` +## Testing and Benchmarking + +TODO + +# Contributors + +Fillipe D. M. de Souza (Lead) + From d0c5a3910b70af686f9f44b3ae45b2f227e6403c Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 31 Mar 2022 19:15:29 -0700 Subject: [PATCH 155/364] Update README.md with more installation instructions. --- README.md | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a7c3854..abfc796 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ This library is underconstruction and currently only offers acceleration of modu ### Requirements The hardware requirement to use the library is the following: - Intel Sapphire Rapids - - Intel C62XX acceleration card + As for the operating systems, the library has been tested and confirmed to work on Ubuntu 20.04. @@ -48,7 +48,11 @@ Required dependencies include: ``` cmake >=3.15.1 git +yasm +libboost >= 1.14 +libudev >= 1.47 pthread +OpenSSL >=1.1.0 gcc >= 9.1 QAT20.L.0.8.0-00071.tar.gz (qatlib and QAT drivers) ipp-crypto @@ -72,6 +76,35 @@ f7:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) In the example above, the platform is a dual-socket Sapphire Rapids (SPR) and it shows 8 QAT endpoints, 4 on each socket. +#### Installing Dependencies + +``` +sudo apt install yasm zlib1g +sudo apt update -y +sudo apt install -y libsystemd-dev +sudo apt install -y pciutils (tested with version=3.6.4) +sudo apt install -y libudev-dev +sudo apt install -y libreadline-dev +sudo apt install -y libxml2-dev +sudo apt install -y libboost-dev +sudo apt install -y elfutils libelf-dev +sudo apt install -y libnl-3-dev +sudo apt install -y linux-headers-$(uname -r) +sudo apt install -y build-essential +sudo apt install -y libboost-regex-dev +``` + +#### Installing OpenSSL + +``` +$ git clone https://github.com/openssl/openssl.git +$ cd openssl/ +$ git checkout OpenSSL_1_1_1-stable +$ ./Configure --prefix=/opt/openssl +$ make +$ sudo make install +``` + #### Installing QAT Software Stack ``` @@ -85,7 +118,13 @@ $ sudo make -j $ sudo make install ``` -> _**Note**_: Please contact QAT team listed at [https://01.org/intel-quickassist-technology](https://01.org/intel-quickassist-technology) to obtain the latest `QAT20.L.0.8.0-00071.tar.gz` package. +Add `$USER` to the `qat` group. Must logout and log back in to take effect. + +``` +$ sudo usermod -aG qat $USER +``` + +> _**Note**_: Please contact the QAT team listed at [https://01.org/intel-quickassist-technology](https://01.org/intel-quickassist-technology) to obtain the latest `QAT20.L.0.8.0-00071.tar.gz` package. Verify the QAT installation by checking the QAT service status: From 9f8e2881ffc3dc0ce353ef3cfb192d8cfaaf7cb3 Mon Sep 17 00:00:00 2001 From: fdiasmor Date: Tue, 5 Apr 2022 17:18:19 -0700 Subject: [PATCH 156/364] QAT enablement and integration (#74) * Rename file names and class names(remove paillier_ prefix) (#54) * Rename file names(remove paillier_ prefix) * Rename class names(remove the Paillier prefix) * Renamed key_gen to keygen Co-authored-by: Sejun Kim * Refactoring applied (#55) * Initial QAT integration work with debug traces. * Return output/results from HE_QAT_bnModExp. * Fix correctness bug (partial fix: 8 out of 10/perf degradation). * Change to latest updated he_qat tag. * [QAT] Fix data conversion for errors exposed by CtMultiplyZeroPtTest and CtMultiplyPtArrayTest. * Update heqat.cmake to pull from latest development branch. * Remove debug traces. * Enable single input QAT ModExp interface. * Fix data conversion in BigNumber::toBin. * Add single input interface for QAT ModExp and usage of BigNumber::toBin(). * Pre-commit fix. * Pre-commit and clang-format fixes. * Clean out timing code. * Updating instructions to compile with QAT support. * Update README.md * Minor updates - Switched to git ssh for heqat repo - Automatically disables IPCL_ENABLE_OMP if IPCL_ENABLE_QAT Co-authored-by: Pengfei Zhao Co-authored-by: Sejun Kim --- CMakeLists.txt | 19 ++- README.md | 12 ++ benchmark/CMakeLists.txt | 5 + benchmark/bench_cryptography.cpp | 78 ++++------- benchmark/bench_ops.cpp | 176 ++++++++++-------------- benchmark/main.cpp | 12 ++ cmake/heqat/heqat.cmake | 48 +++++++ cmake/heqat/icp/CMakeLists.txt | 33 +++++ ipcl/CMakeLists.txt | 5 +- ipcl/bignum.cpp | 37 ++++- ipcl/include/ipcl/bignum.h | 14 +- ipcl/mod_exp.cpp | 201 ++++++++++++++++++++++++++- test/CMakeLists.txt | 5 + test/main.cpp | 18 ++- test/test_cryptography.cpp | 60 ++++---- test/test_ops.cpp | 226 +++++++++++++++---------------- 16 files changed, 637 insertions(+), 312 deletions(-) create mode 100644 cmake/heqat/heqat.cmake create mode 100644 cmake/heqat/icp/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 7918c0c..59c7573 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,8 +36,10 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_INSTALL_MESSAGE LAZY) set(CMAKE_INSTALL_RPATH "\$ORIGIN") -set(CMAKE_C_FLAGS "-O2") -set(CMAKE_CXX_FLAGS "-O2 -fpermissive") +#set(CMAKE_C_FLAGS "-O2 -pthread") +#set(CMAKE_CXX_FLAGS "-O2 -fpermissive -pthread") +set(CMAKE_C_FLAGS "-pthread") +set(CMAKE_CXX_FLAGS "-fpermissive -pthread") if(NOT CMAKE_INSTALL_PREFIX) set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}) @@ -50,14 +52,22 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) #--------------------------------------------------- option(IPCL_TEST "Enable testing" ON) option(IPCL_BENCHMARK "Enable benchmark" ON) +option(IPCL_ENABLE_QAT "Enable QAT" OFF) option(IPCL_ENABLE_OMP "Enable OpenMP testing/benchmarking" ON) option(IPCL_DOCS "Enable document building" OFF) option(IPCL_SHARED "Build shared library" ON) +if(IPCL_ENABLE_QAT) + add_compile_definitions(IPCL_USE_QAT) + message(STATUS "QAT enabled - IPCL_ENABLE_OMP set to OFF") + set(IPCL_ENABLE_OMP OFF) +endif() + if(IPCL_ENABLE_OMP) add_compile_definitions(IPCL_USE_OMP) endif() + if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(IPCL_DEBUG ON) else() @@ -73,6 +83,7 @@ message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") message(STATUS "IPCL_TEST: ${IPCL_TEST}") message(STATUS "IPCL_BENCHMARK: ${IPCL_BENCHMARK}") message(STATUS "IPCL_ENABLE_OMP: ${IPCL_ENABLE_OMP}") +message(STATUS "IPCL_ENABLE_QAT: ${IPCL_ENABLE_QAT}") message(STATUS "IPCL_DOCS: ${IPCL_DOCS}") message(STATUS "IPCL_SHARED: ${IPCL_SHARED}") @@ -106,6 +117,10 @@ include(ipcl-util) include(cmake/ippcrypto.cmake) +if(IPCL_ENABLE_QAT) + include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/heqat/heqat.cmake) +endif() + if(IPCL_TEST) include(cmake/gtest.cmake) endif() diff --git a/README.md b/README.md index ca17e85..3b5059b 100644 --- a/README.md +++ b/README.md @@ -81,10 +81,22 @@ It is possible to pass additional options to enable more features. The following |-------------------------|-----------|---------|-------------------------------------| |`IPCL_TEST` | ON/OFF | ON | unit-test | |`IPCL_BENCHMARK` | ON/OFF | ON | benchmark | +|`IPCL_ENABLE_QAT` | ON/OFF | OFF | enables QAT functionalities | |`IPCL_ENABLE_OMP` | ON/OFF | ON | enables OpenMP functionalities | |`IPCL_DOCS` | ON/OFF | OFF | build doxygen documentation | |`IPCL_SHARED` | ON/OFF | ON | build shared library | +## Compiling for QAT + +Install QAT software stack following the [instructions from the HE QAT Lib](https://github.com/intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.project-destiny/tree/development#installing-qat-software-stack). The current QAT support is not multithreading safe; therefore, `IPCL_ENABLE_OMP` must be set to `OFF`. + +```bash +export IPCL_DIR=$(pwd) +export ICP_ROOT=$HOME/QAT +cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DIPCL_ENABLE_QAT=ON -DIPCL_ENABLE_OMP=OFF +cmake --build build -j +``` + ## Testing and Benchmarking To run a set of unit tests via [Googletest](https://github.com/google/googletest), configure and build library with `-DIPCL_TEST=ON` (see [Instructions](#instructions)). Then, run diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index ae35824..a0d5ae3 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -20,3 +20,8 @@ if(IPCL_ENABLE_OMP) find_package(OpenMP REQUIRED) target_link_libraries(bench_ipcl PRIVATE OpenMP::OpenMP_CXX) endif() + +# enable QAT benchmarks +if(IPCL_ENABLE_QAT) + target_link_libraries(bench_ipcl PRIVATE libhe_qat) +endif() diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index b9ffb9d..1397867 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -22,13 +22,11 @@ static void BM_Encrypt(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize, - std::vector(8)); - std::vector> ct(dsize, - std::vector(8)); + std::vector> pt(dsize, std::vector(8)); + std::vector> ct(dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - pt[i][0] = ipcl::BigNumber((unsigned int)i); + pt[i][0] = BigNumber((unsigned int)i); } for (auto _ : state) { @@ -42,14 +40,12 @@ static void BM_Encrypt_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize / 8, - std::vector(8)); - std::vector> ct(dsize / 8, - std::vector(8)); + std::vector> pt(dsize / 8, std::vector(8)); + std::vector> ct(dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) - pt[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + pt[i][j] = BigNumber((unsigned int)(i * 8 + j)); } for (auto _ : state) { @@ -66,15 +62,12 @@ static void BM_Decrypt(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize, - std::vector(8)); - std::vector> ct(dsize, - std::vector(8)); - std::vector> de_ct( - dsize, std::vector(8)); + std::vector> pt(dsize, std::vector(8)); + std::vector> ct(dsize, std::vector(8)); + std::vector> de_ct(dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - pt[i][0] = ipcl::BigNumber((unsigned int)i); + pt[i][0] = BigNumber((unsigned int)i); } for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -92,16 +85,14 @@ static void BM_Decrypt_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize / 8, - std::vector(8)); - std::vector> ct(dsize / 8, - std::vector(8)); - std::vector> de_ct( - dsize / 8, std::vector(8)); + std::vector> pt(dsize / 8, std::vector(8)); + std::vector> ct(dsize / 8, std::vector(8)); + std::vector> de_ct(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) - pt[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + pt[i][j] = BigNumber((unsigned int)(i * 8 + j)); } for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -122,13 +113,11 @@ static void BM_Encrypt_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize, - std::vector(8)); - std::vector> ct(dsize, - std::vector(8)); + std::vector> pt(dsize, std::vector(8)); + std::vector> ct(dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - pt[i][0] = ipcl::BigNumber((unsigned int)i); + pt[i][0] = BigNumber((unsigned int)i); } for (auto _ : state) { @@ -145,14 +134,12 @@ static void BM_Encrypt_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize / 8, - std::vector(8)); - std::vector> ct(dsize / 8, - std::vector(8)); + std::vector> pt(dsize / 8, std::vector(8)); + std::vector> ct(dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) - pt[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + pt[i][j] = BigNumber((unsigned int)(i * 8 + j)); } for (auto _ : state) { @@ -170,14 +157,11 @@ static void BM_Decrypt_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize, - std::vector(8)); - std::vector> ct(dsize, - std::vector(8)); - std::vector> de_ct( - dsize, std::vector(8)); + std::vector> pt(dsize, std::vector(8)); + std::vector> ct(dsize, std::vector(8)); + std::vector> de_ct(dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - pt[i][0] = ipcl::BigNumber((unsigned int)i); + pt[i][0] = BigNumber((unsigned int)i); } for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -199,16 +183,14 @@ static void BM_Decrypt_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize / 8, - std::vector(8)); - std::vector> ct(dsize / 8, - std::vector(8)); - std::vector> de_ct( - dsize / 8, std::vector(8)); + std::vector> pt(dsize / 8, std::vector(8)); + std::vector> ct(dsize / 8, std::vector(8)); + std::vector> de_ct(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) - pt[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + pt[i][j] = BigNumber((unsigned int)(i * 8 + j)); } for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index 5282223..a020678 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -16,20 +16,16 @@ static void BM_Add_CTCT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, - std::vector(8)); - std::vector> b(dsize, - std::vector(8)); - std::vector> ct_a( - dsize, std::vector(8)); - std::vector> ct_b( - dsize, std::vector(8)); + std::vector> a(dsize, std::vector(8)); + std::vector> b(dsize, std::vector(8)); + std::vector> ct_a(dsize, std::vector(8)); + std::vector> ct_b(dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)i); + a[i][0] = BigNumber((unsigned int)i); key.pub_key->encrypt(ct_a[i], a[i]); - b[i][0] = ipcl::BigNumber((unsigned int)i); + b[i][0] = BigNumber((unsigned int)i); key.pub_key->encrypt(ct_b[i], b[i]); } @@ -48,19 +44,17 @@ static void BM_Add_CTCT_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize / 8, - std::vector(8)); - std::vector> b(dsize / 8, - std::vector(8)); - std::vector> ct_a( - dsize / 8, std::vector(8)); - std::vector> ct_b( - dsize / 8, std::vector(8)); + std::vector> a(dsize / 8, std::vector(8)); + std::vector> b(dsize / 8, std::vector(8)); + std::vector> ct_a(dsize / 8, + std::vector(8)); + std::vector> ct_b(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = BigNumber((unsigned int)(i * 8 + j)); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -85,16 +79,13 @@ static void BM_Add_CTPT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, - std::vector(8)); - std::vector> b(dsize, - std::vector(8)); - std::vector> ct_a( - dsize, std::vector(8)); + std::vector> a(dsize, std::vector(8)); + std::vector> b(dsize, std::vector(8)); + std::vector> ct_a(dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)i); - b[i][0] = ipcl::BigNumber((unsigned int)i); + a[i][0] = BigNumber((unsigned int)i); + b[i][0] = BigNumber((unsigned int)i); key.pub_key->encrypt(ct_a[i], a[i]); } @@ -112,17 +103,15 @@ static void BM_Add_CTPT_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize / 8, - std::vector(8)); - std::vector> b(dsize / 8, - std::vector(8)); - std::vector> ct_a( - dsize / 8, std::vector(8)); + std::vector> a(dsize / 8, std::vector(8)); + std::vector> b(dsize / 8, std::vector(8)); + std::vector> ct_a(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = BigNumber((unsigned int)(i * 8 + j)); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -145,16 +134,13 @@ static void BM_Mul_CTPT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, - std::vector(8)); - std::vector> b(dsize, - std::vector(8)); - std::vector> ct_a( - dsize, std::vector(8)); + std::vector> a(dsize, std::vector(8)); + std::vector> b(dsize, std::vector(8)); + std::vector> ct_a(dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)i); - b[i][0] = ipcl::BigNumber((unsigned int)i); + a[i][0] = BigNumber((unsigned int)i); + b[i][0] = BigNumber((unsigned int)i); key.pub_key->encrypt(ct_a[i], a[i]); } @@ -173,17 +159,15 @@ static void BM_Mul_CTPT_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize / 8, - std::vector(8)); - std::vector> b(dsize / 8, - std::vector(8)); - std::vector> ct_a( - dsize / 8, std::vector(8)); + std::vector> a(dsize / 8, std::vector(8)); + std::vector> b(dsize / 8, std::vector(8)); + std::vector> ct_a(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = BigNumber((unsigned int)(i * 8 + j)); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -208,20 +192,16 @@ static void BM_Add_CTCT_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, - std::vector(8)); - std::vector> b(dsize, - std::vector(8)); - std::vector> ct_a( - dsize, std::vector(8)); - std::vector> ct_b( - dsize, std::vector(8)); + std::vector> a(dsize, std::vector(8)); + std::vector> b(dsize, std::vector(8)); + std::vector> ct_a(dsize, std::vector(8)); + std::vector> ct_b(dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)i); + a[i][0] = BigNumber((unsigned int)i); key.pub_key->encrypt(ct_a[i], a[i]); - b[i][0] = ipcl::BigNumber((unsigned int)i); + b[i][0] = BigNumber((unsigned int)i); key.pub_key->encrypt(ct_b[i], b[i]); } @@ -244,19 +224,17 @@ static void BM_Add_CTCT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize / 8, - std::vector(8)); - std::vector> b(dsize / 8, - std::vector(8)); - std::vector> ct_a( - dsize / 8, std::vector(8)); - std::vector> ct_b( - dsize / 8, std::vector(8)); + std::vector> a(dsize / 8, std::vector(8)); + std::vector> b(dsize / 8, std::vector(8)); + std::vector> ct_a(dsize / 8, + std::vector(8)); + std::vector> ct_b(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = BigNumber((unsigned int)(i * 8 + j)); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -282,16 +260,13 @@ static void BM_Add_CTPT_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, - std::vector(8)); - std::vector> b(dsize, - std::vector(8)); - std::vector> ct_a( - dsize, std::vector(8)); + std::vector> a(dsize, std::vector(8)); + std::vector> b(dsize, std::vector(8)); + std::vector> ct_a(dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)i); - b[i][0] = ipcl::BigNumber((unsigned int)i); + a[i][0] = BigNumber((unsigned int)i); + b[i][0] = BigNumber((unsigned int)i); key.pub_key->encrypt(ct_a[i], a[i]); } @@ -313,17 +288,15 @@ static void BM_Add_CTPT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize / 8, - std::vector(8)); - std::vector> b(dsize / 8, - std::vector(8)); - std::vector> ct_a( - dsize / 8, std::vector(8)); + std::vector> a(dsize / 8, std::vector(8)); + std::vector> b(dsize / 8, std::vector(8)); + std::vector> ct_a(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = BigNumber((unsigned int)(i * 8 + j)); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -347,16 +320,13 @@ static void BM_Mul_CTPT_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, - std::vector(8)); - std::vector> b(dsize, - std::vector(8)); - std::vector> ct_a( - dsize, std::vector(8)); + std::vector> a(dsize, std::vector(8)); + std::vector> b(dsize, std::vector(8)); + std::vector> ct_a(dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)i); - b[i][0] = ipcl::BigNumber((unsigned int)i); + a[i][0] = BigNumber((unsigned int)i); + b[i][0] = BigNumber((unsigned int)i); key.pub_key->encrypt(ct_a[i], a[i]); } @@ -379,17 +349,15 @@ static void BM_Mul_CTPT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize / 8, - std::vector(8)); - std::vector> b(dsize / 8, - std::vector(8)); - std::vector> ct_a( - dsize / 8, std::vector(8)); + std::vector> a(dsize / 8, std::vector(8)); + std::vector> b(dsize / 8, std::vector(8)); + std::vector> ct_a(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j)); + a[i][j] = BigNumber((unsigned int)(i * 8 + j)); + b[i][j] = BigNumber((unsigned int)(i * 8 + j)); } key.pub_key->encrypt(ct_a[i], a[i]); diff --git a/benchmark/main.cpp b/benchmark/main.cpp index da89895..6c55a8a 100644 --- a/benchmark/main.cpp +++ b/benchmark/main.cpp @@ -1,11 +1,23 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 +#ifdef IPCL_USE_QAT +#include "he_qat_context.h" +#endif // IPCL_USE_QAT + #include int main(int argc, char** argv) { +#ifdef IPCL_USE_QAT + acquire_qat_devices(); +#endif // IPCL_USE_QAT + benchmark::Initialize(&argc, argv); benchmark::RunSpecifiedBenchmarks(); +#ifdef IPCL_USE_QAT + release_qat_devices(); +#endif + return 0; } diff --git a/cmake/heqat/heqat.cmake b/cmake/heqat/heqat.cmake new file mode 100644 index 0000000..53a2654 --- /dev/null +++ b/cmake/heqat/heqat.cmake @@ -0,0 +1,48 @@ +# Copyright (C) 2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +include(ExternalProject) +MESSAGE(STATUS "Configuring HE QAT") +set(HEQAT_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_he_qat) +set(HEQAT_GIT_REPO_URL git@github.com:intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.project-destiny.git) +set(HEQAT_GIT_LABEL development) +set(HEQAT_SRC_DIR ${HEQAT_PREFIX}/src/ext_he_qat/) + +set(HEQAT_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS}") + +ExternalProject_Add( + ext_he_qat + GIT_REPOSITORY ${HEQAT_GIT_REPO_URL} + GIT_TAG ${HEQAT_GIT_LABEL} + PREFIX ${HEQAT_PREFIX} + INSTALL_DIR ${HEQAT_PREFIX} + CMAKE_ARGS ${HEQAT_CXX_FLAGS} + -DCMAKE_INSTALL_PREFIX=${HEQAT_PREFIX} + -DHE_QAT_MISC=OFF + -DIPPCP_PREFIX_PATH=${IPPCRYPTO_PREFIX}/lib/cmake + #-DARCH=${HEQAT_ARCH} + #-DCMAKE_ASM_NASM_COMPILER=nasm + #-DCMAKE_BUILD_TYPE=Release + UPDATE_COMMAND "" +) + +add_dependencies(ext_he_qat libippcrypto) + +set(HEQAT_INC_DIR ${HEQAT_PREFIX}/include) #${HEQAT_SRC_DIR}/install/include) + +# Bring up CPA variables +include(${CMAKE_CURRENT_LIST_DIR}/icp/CMakeLists.txt) +list(APPEND HEQAT_INC_DIR ${ICP_INC_DIR}) + +add_library(libhe_qat INTERFACE) +add_dependencies(libhe_qat ext_he_qat) + +ExternalProject_Get_Property(ext_he_qat SOURCE_DIR BINARY_DIR) + +target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libcpa_sample_utils.a) # ${HEQAT_PREFIX}/lib/libhe_qat_misc.a) +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat_debug.so) +else() + target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat.so) +endif() +target_include_directories(libhe_qat SYSTEM INTERFACE ${HEQAT_INC_DIR}) diff --git a/cmake/heqat/icp/CMakeLists.txt b/cmake/heqat/icp/CMakeLists.txt new file mode 100644 index 0000000..ee0617a --- /dev/null +++ b/cmake/heqat/icp/CMakeLists.txt @@ -0,0 +1,33 @@ + +if(DEFINED ENV{ICP_ROOT}) + message(STATUS "Environment variable ICP_ROOT is defined as $ENV{ICP_ROOT}.") +else() + message(FATAL_ERROR "Environment variable ICP_ROOT must be defined. Try export ICP_ROOT=") +endif() + +set(ICP_ROOT $ENV{ICP_ROOT}) +set(ICP_BUILDOUTPUT_PATH ${ICP_ROOT}/build) +set(ICP_BUILDSYSTEM_PATH ${ICP_ROOT}/quickassist/build_system) +set(ICP_API_DIR ${ICP_ROOT}/quickassist) +set(ICP_LAC_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer) +set(ICP_OSAL_DIR ${ICP_ROOT}/quickassist/utilities/oasl) +set(ICP_ADF_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/qat_direct) +set(CMN_ROOT ${ICP_ROOT}/quickassist/utilities/libusdm_drv) + +#list(APPEND COMMON_INC_DIR ${ICP_API_DIR}/include +# ${ICP_LAC_DIR}/include +# ${ICP_ADF_DIR}/include +# ${CMN_ROOT} +#) + +set(ICP_INC_DIR ${ICP_API_DIR}/include + ${ICP_LAC_DIR}/include + ${ICP_ADF_DIR}/include + ${CMN_ROOT} + ${ICP_API_DIR}/include/dc + ${ICP_API_DIR}/include/lac) + +#Macros for the test case +add_definitions(-DDO_CRYPTO) +add_definitions(-DUSER_SPACE) +add_compile_options(-fPIC) diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index a4b1ff5..c24312e 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -24,7 +24,6 @@ target_include_directories(ipcl PUBLIC $ ) - target_include_directories(ipcl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PUBLIC $ @@ -54,6 +53,10 @@ else() target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) endif() +if(IPCL_ENABLE_QAT) + target_link_libraries(ipcl PRIVATE libhe_qat) +endif() + # check whether cpu support avx512 flag set(CPU_AVX512_FLAG "avx512ifma") execute_process(COMMAND lscpu COMMAND grep ${CPU_AVX512_FLAG} OUTPUT_VARIABLE CPU_ENABLE_AVX512) diff --git a/ipcl/bignum.cpp b/ipcl/bignum.cpp index b5adab3..e5eea58 100644 --- a/ipcl/bignum.cpp +++ b/ipcl/bignum.cpp @@ -25,7 +25,7 @@ // ////////////////////////////////////////////////////////////////////// -namespace ipcl { +// namespace ipcl { BigNumber::~BigNumber() { delete[](Ipp8u*) m_pBN; } @@ -138,7 +138,7 @@ BigNumber& BigNumber::operator=(const BigNumber& bn) { Ipp32u* bnData; ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); - delete (Ipp8u*)m_pBN; + delete[](Ipp8u*) m_pBN; create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); } return *this; @@ -509,4 +509,35 @@ void BigNumber::num2char(std::vector& dest) const { dest.assign(bnData, bnData + len); } -} // namespace ipcl + +bool BigNumber::fromBin(BigNumber& bn, const unsigned char* data, int len) { + if (len <= 0) return false; + + // Create BigNumber containg input data passed as argument + bn = BigNumber(reinterpret_cast(data), (len / 4)); + Ipp32u* ref_bn_data_ = NULL; + ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); + + // Convert it to little endian format + unsigned char* data_ = reinterpret_cast(ref_bn_data_); + for (int i = 0; i < len; i++) data_[i] = data[len - 1 - i]; + + return true; +} + +bool BigNumber::toBin(unsigned char* data, int len, const BigNumber& bn) { + if (len <= 0) return false; + + // Extract raw vector of data in little endian format + int bitSize = 0; + Ipp32u* ref_bn_data_ = NULL; + ippsRef_BN(NULL, &bitSize, &ref_bn_data_, BN(bn)); + + // Revert it to big endian format + int bitSizeLen = BITSIZE_WORD(bitSize) * 4; + unsigned char* data_ = reinterpret_cast(ref_bn_data_); + for (int i = 0; i < bitSizeLen; i++) data[len - 1 - i] = data_[i]; + + return true; +} +//} // namespace ipcl diff --git a/ipcl/include/ipcl/bignum.h b/ipcl/include/ipcl/bignum.h index fe62dc1..dd42d28 100644 --- a/ipcl/include/ipcl/bignum.h +++ b/ipcl/include/ipcl/bignum.h @@ -14,15 +14,17 @@ * limitations under the License. *******************************************************************************/ -#ifndef _BIGNUM_H_ -#define _BIGNUM_H_ +//#ifndef _BIGNUM_H_ +//#define _BIGNUM_H_ +#if !defined _BIGNUMBER_H_ +#define _BIGNUMBER_H_ #include #include #include -namespace ipcl { +// namespace ipcl { class BigNumber { public: @@ -122,6 +124,10 @@ class BigNumber { friend std::ostream& operator<<(std::ostream& os, const BigNumber& a); void num2char(std::vector& dest) const; + // Support QAT data format + static bool fromBin(BigNumber& bn, const unsigned char* data, int len); + static bool toBin(unsigned char* data, int len, const BigNumber& bn); + protected: bool create(const Ipp32u* pData, int length, IppsBigNumSGN sgn = IppsBigNumPOS); @@ -131,5 +137,5 @@ class BigNumber { constexpr int BITSIZE_WORD(int n) { return (((n) + 31) >> 5); } constexpr int BITSIZE_DWORD(int n) { return (((n) + 63) >> 6); } -} // namespace ipcl +//} // namespace ipcl #endif // _BIGNUM_H_ diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index ea1c41c..958987d 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -4,13 +4,200 @@ #include "ipcl/mod_exp.hpp" #include +#include #include #include "ipcl/util.hpp" +#ifdef IPCL_USE_QAT +#include "he_qat_bn_ops.h" +#include "he_qat_types.h" +#endif + namespace ipcl { +#ifdef IPCL_USE_QAT + +// Multiple input QAT ModExp interface to offload computation to QAT +static std::vector heQatBnModExp( + const std::vector& base, const std::vector& exponent, + const std::vector& modulus) { + static unsigned int counter = 0; + int nbits = modulus.front().BitSize(); + int length = BITSIZE_WORD(nbits) * 4; + nbits = 8 * length; + + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + // TODO(fdiasmor): Try replace calloc by alloca to see impact on performance. + unsigned char* bn_base_data_[IPCL_CRYPTO_MB_SIZE]; + unsigned char* bn_exponent_data_[IPCL_CRYPTO_MB_SIZE]; + unsigned char* bn_modulus_data_[IPCL_CRYPTO_MB_SIZE]; + unsigned char* bn_remainder_data_[IPCL_CRYPTO_MB_SIZE]; + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + bn_base_data_[i] = reinterpret_cast( + malloc(length * sizeof(unsigned char))); + bn_exponent_data_[i] = reinterpret_cast( + malloc(length * sizeof(unsigned char))); + bn_modulus_data_[i] = reinterpret_cast( + malloc(length * sizeof(unsigned char))); + bn_remainder_data_[i] = reinterpret_cast( + malloc(length * sizeof(unsigned char))); + + ERROR_CHECK( + bn_base_data_[i] != nullptr && bn_exponent_data_[i] != nullptr && + bn_modulus_data_[i] != nullptr && bn_remainder_data_[i] != nullptr, + "qatMultiBuffExp: alloc memory for error"); + + memset(bn_base_data_[i], 0, length); + memset(bn_exponent_data_[i], 0, length); + memset(bn_modulus_data_[i], 0, length); + memset(bn_remainder_data_[i], 0, length); + } + + // TODO(fdiasmor): Define and use IPCL_QAT_BATCH_SIZE instead of + // IPCL_CRYPTO_MB_SIZE. + for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + bool ret = BigNumber::toBin(bn_base_data_[i], length, base[i]); + if (!ret) { + printf("bn_base_data_: failed at bigNumberToBin()\n"); + exit(1); + } + ret = BigNumber::toBin(bn_exponent_data_[i], length, exponent[i]); + if (!ret) { + printf("bn_exponent_data_: failed at bigNumberToBin()\n"); + exit(1); + } + ret = BigNumber::toBin(bn_modulus_data_[i], length, modulus[i]); + if (!ret) { + printf("bn_modulus_data_: failed at bigNumberToBin()\n"); + exit(1); + } + + unsigned char* bn_base_ = + reinterpret_cast(bn_base_data_[i]); + unsigned char* bn_exponent_ = + reinterpret_cast(bn_exponent_data_[i]); + unsigned char* bn_modulus_ = + reinterpret_cast(bn_modulus_data_[i]); + unsigned char* bn_remainder_ = + reinterpret_cast(bn_remainder_data_[i]); + + status = HE_QAT_bnModExp(bn_remainder_, bn_base_, bn_exponent_, bn_modulus_, + nbits); + if (HE_QAT_STATUS_SUCCESS != status) { + PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); + } + } + getBnModExpRequest(IPCL_CRYPTO_MB_SIZE); + + std::vector remainder(IPCL_CRYPTO_MB_SIZE, 0); + // Collect results and pack them into BigNumber + for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + unsigned char* bn_remainder_ = bn_remainder_data_[i]; + bool ret = BigNumber::fromBin(remainder[i], bn_remainder_, length); + if (!ret) { + printf("bn_remainder_data_: failed at bignumbertobin()\n"); + exit(1); + } + } + + for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + free(bn_base_data_[i]); + bn_base_data_[i] = NULL; + free(bn_exponent_data_[i]); + bn_exponent_data_[i] = NULL; + free(bn_modulus_data_[i]); + bn_modulus_data_[i] = NULL; + } + + for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + free(bn_remainder_data_[i]); + bn_remainder_data_[i] = NULL; + } + + return remainder; +} + +// Single input QAT ModExp interface to offload computation to QAT +static BigNumber heQatBnModExp(const BigNumber& base, const BigNumber& exponent, + const BigNumber& modulus) { + static unsigned int counter = 0; + int nbits = modulus.BitSize(); + int length = BITSIZE_WORD(nbits) * 4; + nbits = 8 * length; + + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + // TODO(fdiasmor): Try replace calloc by alloca to see impact on performance. + unsigned char* bn_base_data_ = NULL; + unsigned char* bn_exponent_data_ = NULL; + unsigned char* bn_modulus_data_ = NULL; + unsigned char* bn_remainder_data_ = NULL; + + bn_base_data_ = + reinterpret_cast(malloc(length * sizeof(unsigned char))); + bn_exponent_data_ = + reinterpret_cast(malloc(length * sizeof(unsigned char))); + bn_modulus_data_ = + reinterpret_cast(malloc(length * sizeof(unsigned char))); + bn_remainder_data_ = + reinterpret_cast(malloc(length * sizeof(unsigned char))); + + ERROR_CHECK(bn_base_data_ != nullptr && bn_exponent_data_ != nullptr && + bn_modulus_data_ != nullptr && bn_remainder_data_ != nullptr, + "qatMultiBuffExp: alloc memory for error"); + + memset(bn_base_data_, 0, length); + memset(bn_exponent_data_, 0, length); + memset(bn_modulus_data_, 0, length); + memset(bn_remainder_data_, 0, length); + + bool ret = BigNumber::toBin(bn_base_data_, length, base); + if (!ret) { + printf("bn_base_data_: failed at bignumbertobin()\n"); + exit(1); + } + ret = BigNumber::toBin(bn_exponent_data_, length, exponent); + if (!ret) { + printf("bn_exponent_data_: failed at bignumbertobin()\n"); + exit(1); + } + ret = BigNumber::toBin(bn_modulus_data_, length, modulus); + if (!ret) { + printf("bn_modulus_data_: failed at bignumbertobin()\n"); + exit(1); + } + + status = HE_QAT_bnModExp(bn_remainder_data_, bn_base_data_, bn_exponent_data_, + bn_modulus_data_, nbits); + if (HE_QAT_STATUS_SUCCESS != status) { + PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); + } + getBnModExpRequest(1); + + // Collect result and pack it into BigNumber + BigNumber remainder; + ret = BigNumber::fromBin(remainder, bn_remainder_data_, length); + if (!ret) { + printf("bn_remainder_data_: failed at bignumbertobin()\n"); + exit(1); + } + + free(bn_base_data_); + bn_base_data_ = NULL; + free(bn_exponent_data_); + bn_exponent_data_ = NULL; + free(bn_modulus_data_); + bn_modulus_data_ = NULL; + free(bn_remainder_data_); + bn_remainder_data_ = NULL; + + return remainder; +} +#endif // IPCL_USE_QAT + static std::vector ippMBModExp(const std::vector& base, const std::vector& pow, const std::vector& m) { @@ -152,23 +339,33 @@ static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, std::vector ippModExp(const std::vector& base, const std::vector& pow, const std::vector& m) { +#ifdef IPCL_USE_QAT + std::vector remainder(IPCL_CRYPTO_MB_SIZE); + remainder = heQatBnModExp(base, pow, m); + return remainder; +#else #ifdef IPCL_CRYPTO_MB_MOD_EXP return ippMBModExp(base, pow, m); #else std::vector res(IPCL_CRYPTO_MB_SIZE); #ifdef IPCL_USE_OMP #pragma omp parallel for -#endif +#endif // IPCL_USE_OMP for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { res[i] = ippSBModExp(base[i], pow[i], m[i]); } return res; -#endif +#endif // else +#endif // IPCL_USE_QAT } BigNumber ippModExp(const BigNumber& base, const BigNumber& pow, const BigNumber& m) { +#ifdef IPCL_USE_QAT + return heQatBnModExp(base, pow, m); +#else return ippSBModExp(base, pow, m); +#endif // IPCL_USE_QAT } } // namespace ipcl diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bb24a5f..1cd5c4c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -20,3 +20,8 @@ if(IPCL_ENABLE_OMP) find_package(OpenMP REQUIRED) target_link_libraries(unittest_ipcl PRIVATE OpenMP::OpenMP_CXX) endif() + +# enable QAT unittests +if(IPCL_ENABLE_QAT) + target_link_libraries(unittest_ipcl PRIVATE libhe_qat) +endif() diff --git a/test/main.cpp b/test/main.cpp index 0ec6f12..29d68fd 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -1,13 +1,29 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 +#ifdef IPCL_USE_QAT +#include "he_qat_context.h" +#endif // IPCL_USE_QAT + #include #include int main(int argc, char** argv) { +#ifdef IPCL_USE_QAT + // Initialize QAT context + acquire_qat_devices(); +#endif // IPCL_USE_QAT + // Use system clock for seed srand(time(nullptr)); ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); + int status = RUN_ALL_TESTS(); + +#ifdef IPCL_USE_QAT + // Destroy QAT context + release_qat_devices(); +#endif + + return status; } diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index 931b0ac..c88eaba 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -17,11 +17,11 @@ TEST(CryptoTest, CryptoTest) { ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector ct(8); - std::vector dt(8); + std::vector ct(8); + std::vector dt(8); std::vector pt(8); - std::vector ptbn(8); + std::vector ptbn(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -45,9 +45,8 @@ TEST(CryptoTest, CryptoTest) { } #ifdef IPCL_USE_OMP -void Encryption(int num_threads, - std::vector>& v_ct, - const std::vector>& v_ptbn, +void Encryption(int num_threads, std::vector>& v_ct, + const std::vector>& v_ptbn, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { @@ -55,9 +54,8 @@ void Encryption(int num_threads, } } -void Decryption(int num_threads, - std::vector>& v_dt, - const std::vector>& v_ct, +void Decryption(int num_threads, std::vector>& v_dt, + const std::vector>& v_ct, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { @@ -71,14 +69,14 @@ TEST(CryptoTest, CryptoTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector> v_ct( - num_threads, std::vector(8)); - std::vector> v_dt( - num_threads, std::vector(8)); + std::vector> v_ct(num_threads, + std::vector(8)); + std::vector> v_dt(num_threads, + std::vector(8)); std::vector> v_pt(num_threads, std::vector(8)); - std::vector> v_ptbn( - num_threads, std::vector(8)); + std::vector> v_ptbn(num_threads, + std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); @@ -110,18 +108,18 @@ TEST(CryptoTest, CryptoTest_OMP) { #endif // IPCL_USE_OMP TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { - ipcl::BigNumber p = + BigNumber p = "0xff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c" "8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b4" "0a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff76" "4dd8b091f11a0943a2dd2b983b0df02f4c4d00b413"; - ipcl::BigNumber q = + BigNumber q = "0xdacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d" "9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de70" "72a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49b" "aa0f610bad100cdf47cc86e5034e2a0b2179e04ec7"; - ipcl::BigNumber n = p * q; + BigNumber n = p * q; int n_length = n.BitSize(); ipcl::PublicKey* public_key = new ipcl::PublicKey(n, n_length); @@ -129,12 +127,12 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { ipcl::keyPair key = {public_key, private_key}; - std::vector ptbn(8); - std::vector ct(8); - std::vector dt(8); - std::vector ir(8); + std::vector ptbn(8); + std::vector ct(8); + std::vector dt(8); + std::vector ir(8); - ipcl::BigNumber c1 = + BigNumber c1 = "0x1fb7f08a42deb47876e4cbdc3f0b172c033563a696ad7a7c76fa5971b793fa488dcdd6" "bd65c7c5440d67d847cb89ccca468b2c96763fff5a5ece8330251112d65e59b7da94cfe9" "309f441ccc8f59c67dec75113d37b1ee929c8d4ce6b5e561a30a91104b0526de892e4eff" @@ -151,7 +149,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "b98ccb676367b7b3b269c670cd0210edf70ad9cb337f766af75fe06d18b3f7f7c2eae656" "5ff2815c2c09b1a1f5"; - ipcl::BigNumber c2 = + BigNumber c2 = "0x61803645f2798c06f2c08fc254eee612c55542051c8777d6ce69ede9c84a179afb2081" "167494dee727488ae5e9b56d98f4fcf132514616859fc854fbd3acf6aecd97324ac3f2af" "fa9f44864a9afc505754aa3b564b4617e887d6aa1f88095bccf6b47f458566f9d85e80fc" @@ -168,7 +166,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "d6f1d6864f1fd3e2e3937e00d391ad330b443aec85528571740ed5538188c32caab27c7b" "f437df2bb97cb90e02"; - ipcl::BigNumber c1c2 = + BigNumber c1c2 = "0x309f6e614d875e3bb0a77eedeb8895e7c6f297f161f576aef4f8b72bb5b81ef78b831a" "af134b09fe8697159cfd678c49920cb790e36580c5201a96848d7242fceb025808dd26b5" "0ff573ffca3f65e51b3b9fe85c7e44f5c8df0a9e524f64a5acc5c62cba7475978eb55e08" @@ -185,9 +183,9 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "a6d47f9af6e68e18960fa5916cc48994334354d6303312b8e96602766bec337a8a92c596" "b21b6038828a6c9744"; - ipcl::BigNumber m1m2 = "0x616263646566676869606a6b6c6d6e6f"; + BigNumber m1m2 = "0x616263646566676869606a6b6c6d6e6f"; - ipcl::BigNumber r0 = + BigNumber r0 = "0x57fb19590c31dc7c034b2a889cf4037ce3db799909c1eb0adb6199d8e96791daca9018" "891f34309daff32dced4af7d793d16734d055e28023acab7295956bfbfdf62bf0ccb2ed3" "1d5d176ca8b404e93007565fb6b72c33a512b4dc4f719231d62e27e34c3733929af32247" @@ -196,7 +194,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "27991c44a43750c24ed0825718ad14cfb9c6b40b78ff3d25f71741f2def1c9d420d4b0fa" "1e0a02e7851b5ec6a81133a368b80d1500b0f28fc653d2e6ff4366236dbf80ae3b4beae3" "5e04579f2c"; - ipcl::BigNumber r1 = + BigNumber r1 = "0x6ee8ed76227672a7bcaa1e7f152c2ea39f2fa225f0713f58210c59b2270b110e38b650" "69aaedbeffc713c021336cc12f65227cc0357ca531c07c706e7224c2c11c3145bc0a05b1" "64f426ec03350820f9f416377e8720ddb577843cae929178bfe5772e2cc1e9b94e8fce81" @@ -220,10 +218,10 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { ipcl::EncryptedNumber a(key.pub_key, ct[0]); ipcl::EncryptedNumber b(key.pub_key, ct[1]); ipcl::EncryptedNumber sum = a + b; - ipcl::BigNumber res = sum.getBN(); + BigNumber res = sum.getBN(); - std::vector ct12(8); - std::vector dt12(8); + std::vector ct12(8); + std::vector dt12(8); for (int i = 0; i < 8; i++) { ct12[i] = res; } diff --git a/test/test_ops.cpp b/test/test_ops.cpp index c7a830a..8d1d63a 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -14,10 +14,8 @@ #include "ipcl/keygen.hpp" #include "ipcl/ops.hpp" -void CtPlusCt(std::vector& res, - const std::vector& ct1, - const std::vector& ct2, - const ipcl::keyPair key) { +void CtPlusCt(std::vector& res, const std::vector& ct1, + const std::vector& ct2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { ipcl::EncryptedNumber a(key.pub_key, ct1[i]); ipcl::EncryptedNumber b(key.pub_key, ct2[i]); @@ -26,38 +24,36 @@ void CtPlusCt(std::vector& res, } } -void CtPlusCtArray(std::vector& res, - const std::vector& ct1, - const std::vector& ct2, - const ipcl::keyPair key) { +void CtPlusCtArray(std::vector& res, + const std::vector& ct1, + const std::vector& ct2, const ipcl::keyPair key) { ipcl::EncryptedNumber a(key.pub_key, ct1); ipcl::EncryptedNumber b(key.pub_key, ct2); ipcl::EncryptedNumber sum = a + b; res = sum.getArrayBN(); } -void CtPlusPt(std::vector& res, - const std::vector& ct1, +void CtPlusPt(std::vector& res, const std::vector& ct1, const std::vector& pt2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { ipcl::EncryptedNumber a(key.pub_key, ct1[i]); - ipcl::BigNumber b = pt2[i]; + BigNumber b = pt2[i]; ipcl::EncryptedNumber sum = a + b; res[i] = sum.getBN(); } } -void CtPlusPtArray(std::vector& res, - const std::vector& ct1, - const std::vector& ptbn2, +void CtPlusPtArray(std::vector& res, + const std::vector& ct1, + const std::vector& ptbn2, const ipcl::keyPair key) { ipcl::EncryptedNumber a(key.pub_key, ct1); ipcl::EncryptedNumber sum = a + ptbn2; res = sum.getArrayBN(); } -void CtMultiplyPt(std::vector& res, - const std::vector& ct1, +void CtMultiplyPt(std::vector& res, + const std::vector& ct1, const std::vector& pt2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { ipcl::EncryptedNumber a(key.pub_key, ct1[i]); @@ -67,8 +63,8 @@ void CtMultiplyPt(std::vector& res, } } -void CtMultiplyPtArray(std::vector& res, - const std::vector& ct1, +void CtMultiplyPtArray(std::vector& res, + const std::vector& ct1, const std::vector& pt2, const ipcl::keyPair key) { ipcl::EncryptedNumber a(key.pub_key, ct1); @@ -77,13 +73,12 @@ void CtMultiplyPtArray(std::vector& res, res = sum.getArrayBN(); } -void AddSub(std::vector& res, - const std::vector& ct1, - const std::vector& ct2, const ipcl::keyPair key) { +void AddSub(std::vector& res, const std::vector& ct1, + const std::vector& ct2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { ipcl::EncryptedNumber a(key.pub_key, ct1[i]); ipcl::EncryptedNumber b(key.pub_key, ct2[i]); - ipcl::BigNumber m1(2); + BigNumber m1(2); a = a + b * m1; ipcl::EncryptedNumber sum = a + b; res[i] = sum.getBN(); @@ -93,11 +88,11 @@ void AddSub(std::vector& res, TEST(OperationTest, CtPlusCtTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -134,11 +129,11 @@ TEST(OperationTest, CtPlusCtTest) { TEST(OperationTest, CtPlusCtArrayTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -175,11 +170,11 @@ TEST(OperationTest, CtPlusCtArrayTest) { TEST(OperationTest, CtPlusPtTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8); + std::vector ptbn1(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -214,11 +209,11 @@ TEST(OperationTest, CtPlusPtTest) { TEST(OperationTest, CtPlusPtArrayTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -254,11 +249,11 @@ TEST(OperationTest, CtPlusPtArrayTest) { TEST(OperationTest, CtMultiplyPtTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8); + std::vector ptbn1(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -293,11 +288,11 @@ TEST(OperationTest, CtMultiplyPtTest) { TEST(OperationTest, CtMultiplyZeroPtTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8); + std::vector ptbn1(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -332,11 +327,11 @@ TEST(OperationTest, CtMultiplyZeroPtTest) { TEST(OperationTest, CtMultiplyPtArrayTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8); - std::vector dt(8), res(8); + std::vector ct1(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -372,11 +367,11 @@ TEST(OperationTest, CtMultiplyPtArrayTest) { TEST(OperationTest, AddSubTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -410,10 +405,9 @@ TEST(OperationTest, AddSubTest) { } #ifdef IPCL_USE_OMP -void CtPlusCt_OMP(int num_threads, - std::vector>& v_sum, - const std::vector>& v_ct1, - const std::vector>& v_ct2, +void CtPlusCt_OMP(int num_threads, std::vector>& v_sum, + const std::vector>& v_ct1, + const std::vector>& v_ct2, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { @@ -426,15 +420,14 @@ void CtPlusCt_OMP(int num_threads, } } -void CtPlusPt_OMP(int num_threads, - std::vector>& v_sum, - const std::vector>& v_ct1, +void CtPlusPt_OMP(int num_threads, std::vector>& v_sum, + const std::vector>& v_ct1, const std::vector>& v_pt2, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { - ipcl::BigNumber b = v_pt2[i][j]; + BigNumber b = v_pt2[i][j]; ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); ipcl::EncryptedNumber sum = a + b; v_sum[i][j] = sum.getBN(); @@ -443,14 +436,14 @@ void CtPlusPt_OMP(int num_threads, } void CtPlusPtArray_OMP(int num_threads, - std::vector>& v_sum, - const std::vector>& v_ct1, + std::vector>& v_sum, + const std::vector>& v_ct1, const std::vector>& v_pt2, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { ipcl::EncryptedNumber a(key.pub_key, v_ct1[i]); - std::vector b(8); + std::vector b(8); for (int j = 0; j < 8; j++) { b[j] = v_pt2[i][j]; } @@ -460,25 +453,26 @@ void CtPlusPtArray_OMP(int num_threads, } void CtMultiplyPt_OMP(int num_threads, - std::vector>& v_product, - const std::vector>& v_ct1, + std::vector>& v_product, + const std::vector>& v_ct1, const std::vector>& v_pt2, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); - ipcl::BigNumber b = v_pt2[i][j]; + BigNumber b = v_pt2[i][j]; ipcl::EncryptedNumber product = a * b; v_product[i][j] = product.getBN(); } } } -void CtMultiplyPtArray_OMP( - int num_threads, std::vector>& v_product, - const std::vector>& v_ct1, - const std::vector>& v_pt2, const ipcl::keyPair key) { +void CtMultiplyPtArray_OMP(int num_threads, + std::vector>& v_product, + const std::vector>& v_ct1, + const std::vector>& v_pt2, + const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { ipcl::EncryptedNumber a(key.pub_key, v_ct1[i]); @@ -493,22 +487,22 @@ TEST(OperationTest, CtPlusCtTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector> v_ct1( - num_threads, std::vector(8)); - std::vector> v_ct2( - num_threads, std::vector(8)); - std::vector> v_dt( - num_threads, std::vector(8)); - std::vector> v_sum( - num_threads, std::vector(8)); + std::vector> v_ct1(num_threads, + std::vector(8)); + std::vector> v_ct2(num_threads, + std::vector(8)); + std::vector> v_dt(num_threads, + std::vector(8)); + std::vector> v_sum(num_threads, + std::vector(8)); std::vector> v_pt1(num_threads, std::vector(8)); std::vector> v_pt2(num_threads, std::vector(8)); - std::vector> v_ptbn1( - num_threads, std::vector(8)); - std::vector> v_ptbn2( - num_threads, std::vector(8)); + std::vector> v_ptbn1(num_threads, + std::vector(8)); + std::vector> v_ptbn2(num_threads, + std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -559,20 +553,20 @@ TEST(OperationTest, CtPlusPtTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector> v_ct1( - num_threads, std::vector(8)); - std::vector> v_dt( - num_threads, std::vector(8)); - std::vector> v_sum( - num_threads, std::vector(8)); + std::vector> v_ct1(num_threads, + std::vector(8)); + std::vector> v_dt(num_threads, + std::vector(8)); + std::vector> v_sum(num_threads, + std::vector(8)); std::vector> v_pt1(num_threads, std::vector(8)); std::vector> v_pt2(num_threads, std::vector(8)); - std::vector> v_ptbn1( - num_threads, std::vector(8)); - std::vector> v_ptbn2( - num_threads, std::vector(8)); + std::vector> v_ptbn1(num_threads, + std::vector(8)); + std::vector> v_ptbn2(num_threads, + std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -622,20 +616,20 @@ TEST(OperationTest, CtPlusPtArrayTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector> v_ct1( - num_threads, std::vector(8)); - std::vector> v_dt( - num_threads, std::vector(8)); - std::vector> v_sum( - num_threads, std::vector(8)); + std::vector> v_ct1(num_threads, + std::vector(8)); + std::vector> v_dt(num_threads, + std::vector(8)); + std::vector> v_sum(num_threads, + std::vector(8)); std::vector> v_pt1(num_threads, std::vector(8)); std::vector> v_pt2(num_threads, std::vector(8)); - std::vector> v_ptbn1( - num_threads, std::vector(8)); - std::vector> v_ptbn2( - num_threads, std::vector(8)); + std::vector> v_ptbn1(num_threads, + std::vector(8)); + std::vector> v_ptbn2(num_threads, + std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -685,20 +679,20 @@ TEST(OperationTest, CtMultiplyPtTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector> v_ct1( - num_threads, std::vector(8)); - std::vector> v_dt( - num_threads, std::vector(8)); - std::vector> v_product( - num_threads, std::vector(8)); + std::vector> v_ct1(num_threads, + std::vector(8)); + std::vector> v_dt(num_threads, + std::vector(8)); + std::vector> v_product(num_threads, + std::vector(8)); std::vector> v_pt1(num_threads, std::vector(8)); std::vector> v_pt2(num_threads, std::vector(8)); - std::vector> v_ptbn1( - num_threads, std::vector(8)); - std::vector> v_ptbn2( - num_threads, std::vector(8)); + std::vector> v_ptbn1(num_threads, + std::vector(8)); + std::vector> v_ptbn2(num_threads, + std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); @@ -748,20 +742,20 @@ TEST(OperationTest, CtMultiplyPtArrayTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector> v_ct1( - num_threads, std::vector(8)); - std::vector> v_dt( - num_threads, std::vector(8)); - std::vector> v_product( - num_threads, std::vector(8)); + std::vector> v_ct1(num_threads, + std::vector(8)); + std::vector> v_dt(num_threads, + std::vector(8)); + std::vector> v_product(num_threads, + std::vector(8)); std::vector> v_pt1(num_threads, std::vector(8)); std::vector> v_pt2(num_threads, std::vector(8)); - std::vector> v_ptbn1( - num_threads, std::vector(8)); - std::vector> v_ptbn2( - num_threads, std::vector(8)); + std::vector> v_ptbn1(num_threads, + std::vector(8)); + std::vector> v_ptbn2(num_threads, + std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); From a0ecd9b0d8f402fd6d8ec1140ffdbf50300589ad Mon Sep 17 00:00:00 2001 From: fdiasmor Date: Tue, 5 Apr 2022 18:05:56 -0700 Subject: [PATCH 157/364] QAT Modular Exponentiation Integration (#73) * update qat branch (#59) * Rename file names and class names(remove paillier_ prefix) (#54) * Rename file names(remove paillier_ prefix) * Rename class names(remove the Paillier prefix) * Renamed key_gen to keygen Co-authored-by: Sejun Kim (cherry picked from commit 338146f2322115812b1a6adc42f31e387084cd1e) * Refactoring applied (#55) (cherry picked from commit 0aac79eafd41affb71a18f99189a98014d81e84f) Co-authored-by: Sejun Kim * Initial QAT integration work with debug traces. * Return output/results from HE_QAT_bnModExp. * Fix correctness bug (partial fix: 8 out of 10/perf degradation). * Change to latest updated he_qat tag. * [QAT] Fix data conversion for errors exposed by CtMultiplyZeroPtTest and CtMultiplyPtArrayTest. * Update heqat.cmake to pull from latest development branch. * Remove debug traces. * Enable single input QAT ModExp interface. * Fix data conversion in BigNumber::toBin. * Add single input interface for QAT ModExp and usage of BigNumber::toBin(). * Pre-commit fix. * Pre-commit and clang-format fixes. * Clean out timing code. * Updating instructions to compile with QAT support. * Update README.md * Minor updates - Switched to git ssh for heqat repo - Automatically disables IPCL_ENABLE_OMP if IPCL_ENABLE_QAT Co-authored-by: Pengfei Zhao Co-authored-by: Sejun Kim --- CMakeLists.txt | 20 ++- README.md | 12 ++ benchmark/CMakeLists.txt | 5 + benchmark/bench_cryptography.cpp | 78 ++++------- benchmark/bench_ops.cpp | 200 +++++++++++++------------- benchmark/main.cpp | 12 ++ cmake/heqat/heqat.cmake | 48 +++++++ cmake/heqat/icp/CMakeLists.txt | 33 +++++ ipcl/CMakeLists.txt | 5 +- ipcl/bignum.cpp | 36 ++++- ipcl/include/ipcl/bignum.h | 14 +- ipcl/mod_exp.cpp | 199 +++++++++++++++++++++++++- test/CMakeLists.txt | 5 + test/main.cpp | 18 ++- test/test_cryptography.cpp | 60 ++++---- test/test_ops.cpp | 231 +++++++++++++++---------------- 16 files changed, 662 insertions(+), 314 deletions(-) create mode 100644 cmake/heqat/heqat.cmake create mode 100644 cmake/heqat/icp/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 8fef7f0..6778db6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,8 +36,10 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_INSTALL_MESSAGE LAZY) set(CMAKE_INSTALL_RPATH "\$ORIGIN") -set(CMAKE_C_FLAGS "-O2") -set(CMAKE_CXX_FLAGS "-O2 -fpermissive") +#set(CMAKE_C_FLAGS "-O2 -pthread") +#set(CMAKE_CXX_FLAGS "-O2 -fpermissive -pthread") +set(CMAKE_C_FLAGS "-pthread") +set(CMAKE_CXX_FLAGS "-fpermissive -pthread") if(NOT CMAKE_INSTALL_PREFIX) set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}) @@ -50,14 +52,23 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) #--------------------------------------------------- option(IPCL_TEST "Enable testing" ON) option(IPCL_BENCHMARK "Enable benchmark" ON) +option(IPCL_ENABLE_QAT "Enable QAT" OFF) option(IPCL_ENABLE_OMP "Enable OpenMP testing/benchmarking" ON) option(IPCL_DOCS "Enable document building" OFF) option(IPCL_SHARED "Build shared library" ON) option(IPCL_DEBUG_DISABLE_AVX512IFMA "(Debugging) Disable usage of AVX512IFMA instructions" OFF) + +if(IPCL_ENABLE_QAT) + add_compile_definitions(IPCL_USE_QAT) + message(STATUS "QAT enabled - IPCL_ENABLE_OMP set to OFF") + set(IPCL_ENABLE_OMP OFF) +endif() + if(IPCL_ENABLE_OMP) add_compile_definitions(IPCL_USE_OMP) endif() + if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(IPCL_DEBUG ON) else() @@ -73,6 +84,7 @@ message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") message(STATUS "IPCL_TEST: ${IPCL_TEST}") message(STATUS "IPCL_BENCHMARK: ${IPCL_BENCHMARK}") message(STATUS "IPCL_ENABLE_OMP: ${IPCL_ENABLE_OMP}") +message(STATUS "IPCL_ENABLE_QAT: ${IPCL_ENABLE_QAT}") message(STATUS "IPCL_DOCS: ${IPCL_DOCS}") message(STATUS "IPCL_SHARED: ${IPCL_SHARED}") @@ -120,6 +132,10 @@ include(ipcl-util) include(cmake/ippcrypto.cmake) +if(IPCL_ENABLE_QAT) + include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/heqat/heqat.cmake) +endif() + if(IPCL_TEST) include(cmake/gtest.cmake) endif() diff --git a/README.md b/README.md index ca17e85..3b5059b 100644 --- a/README.md +++ b/README.md @@ -81,10 +81,22 @@ It is possible to pass additional options to enable more features. The following |-------------------------|-----------|---------|-------------------------------------| |`IPCL_TEST` | ON/OFF | ON | unit-test | |`IPCL_BENCHMARK` | ON/OFF | ON | benchmark | +|`IPCL_ENABLE_QAT` | ON/OFF | OFF | enables QAT functionalities | |`IPCL_ENABLE_OMP` | ON/OFF | ON | enables OpenMP functionalities | |`IPCL_DOCS` | ON/OFF | OFF | build doxygen documentation | |`IPCL_SHARED` | ON/OFF | ON | build shared library | +## Compiling for QAT + +Install QAT software stack following the [instructions from the HE QAT Lib](https://github.com/intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.project-destiny/tree/development#installing-qat-software-stack). The current QAT support is not multithreading safe; therefore, `IPCL_ENABLE_OMP` must be set to `OFF`. + +```bash +export IPCL_DIR=$(pwd) +export ICP_ROOT=$HOME/QAT +cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DIPCL_ENABLE_QAT=ON -DIPCL_ENABLE_OMP=OFF +cmake --build build -j +``` + ## Testing and Benchmarking To run a set of unit tests via [Googletest](https://github.com/google/googletest), configure and build library with `-DIPCL_TEST=ON` (see [Instructions](#instructions)). Then, run diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index dc122fe..2cc21fa 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -20,3 +20,8 @@ if(IPCL_ENABLE_OMP) find_package(OpenMP REQUIRED) target_link_libraries(bench_ipcl PRIVATE OpenMP::OpenMP_CXX) endif() + +# enable QAT benchmarks +if(IPCL_ENABLE_QAT) + target_link_libraries(bench_ipcl PRIVATE libhe_qat) +endif() diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index 74b4bca..4fe2066 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -22,13 +22,11 @@ static void BM_Encrypt(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize, - std::vector(8)); - std::vector> ct(dsize, - std::vector(8)); + std::vector> pt(dsize, std::vector(8)); + std::vector> ct(dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) - pt[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); + pt[i][0] = BigNumber((unsigned int)(i * 1024) + 999); for (auto _ : state) { for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -41,13 +39,11 @@ static void BM_Encrypt_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize / 8, - std::vector(8)); - std::vector> ct(dsize / 8, - std::vector(8)); + std::vector> pt(dsize / 8, std::vector(8)); + std::vector> ct(dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize; ++i) - pt[i / 8][i & 7] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); + pt[i / 8][i & 7] = BigNumber((unsigned int)(i * 1024) + 999); for (auto _ : state) { for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -63,15 +59,12 @@ static void BM_Decrypt(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize, - std::vector(8)); - std::vector> ct(dsize, - std::vector(8)); - std::vector> de_ct( - dsize, std::vector(8)); + std::vector> pt(dsize, std::vector(8)); + std::vector> ct(dsize, std::vector(8)); + std::vector> de_ct(dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) - pt[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); + pt[i][0] = BigNumber((unsigned int)(i * 1024) + 999); for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -88,15 +81,13 @@ static void BM_Decrypt_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize / 8, - std::vector(8)); - std::vector> ct(dsize / 8, - std::vector(8)); - std::vector> de_ct( - dsize / 8, std::vector(8)); + std::vector> pt(dsize / 8, std::vector(8)); + std::vector> ct(dsize / 8, std::vector(8)); + std::vector> de_ct(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize; ++i) - pt[i / 8][i & 7] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); + pt[i / 8][i & 7] = BigNumber((unsigned int)(i * 1024) + 999); for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -116,13 +107,11 @@ static void BM_Encrypt_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize, - std::vector(8)); - std::vector> ct(dsize, - std::vector(8)); + std::vector> pt(dsize, std::vector(8)); + std::vector> ct(dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) - pt[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); + pt[i][0] = BigNumber((unsigned int)(i * 1024) + 999); for (auto _ : state) { #pragma omp parallel for @@ -138,13 +127,11 @@ static void BM_Encrypt_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize / 8, - std::vector(8)); - std::vector> ct(dsize / 8, - std::vector(8)); + std::vector> pt(dsize / 8, std::vector(8)); + std::vector> ct(dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize; ++i) - pt[i / 8][i & 7] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); + pt[i / 8][i & 7] = BigNumber((unsigned int)(i * 1024) + 999); for (auto _ : state) { #pragma omp parallel for @@ -161,15 +148,12 @@ static void BM_Decrypt_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize, - std::vector(8)); - std::vector> ct(dsize, - std::vector(8)); - std::vector> de_ct( - dsize, std::vector(8)); + std::vector> pt(dsize, std::vector(8)); + std::vector> ct(dsize, std::vector(8)); + std::vector> de_ct(dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) - pt[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); + pt[i][0] = BigNumber((unsigned int)(i * 1024) + 999); for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -190,15 +174,13 @@ static void BM_Decrypt_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize / 8, - std::vector(8)); - std::vector> ct(dsize / 8, - std::vector(8)); - std::vector> de_ct( - dsize / 8, std::vector(8)); + std::vector> pt(dsize / 8, std::vector(8)); + std::vector> ct(dsize / 8, std::vector(8)); + std::vector> de_ct(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize; ++i) - pt[i / 8][i & 7] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); + pt[i / 8][i & 7] = BigNumber((unsigned int)(i * 1024) + 999); for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index 369e3ae..0effcf2 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -16,20 +16,18 @@ static void BM_Add_CTCT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a( - dsize, std::vector(8, 65535)); - std::vector> b( - dsize, std::vector(8, 65535)); - std::vector> ct_a( - dsize, std::vector(8)); - std::vector> ct_b( - dsize, std::vector(8)); + std::vector> a(dsize, + std::vector(8, 65535)); + std::vector> b(dsize, + std::vector(8, 65535)); + std::vector> ct_a(dsize, std::vector(8)); + std::vector> ct_b(dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); + a[i][0] = BigNumber((unsigned int)(i * 1024) + 999); key.pub_key->encrypt(ct_a[i], a[i]); - b[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); + b[i][0] = BigNumber((unsigned int)(i * 1024) + 999); key.pub_key->encrypt(ct_b[i], b[i]); } @@ -48,19 +46,19 @@ static void BM_Add_CTCT_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a( - dsize / 8, std::vector(8, 65535)); - std::vector> b( - dsize / 8, std::vector(8, 65535)); - std::vector> ct_a( - dsize / 8, std::vector(8)); - std::vector> ct_b( - dsize / 8, std::vector(8)); + std::vector> a(dsize / 8, + std::vector(8, 65535)); + std::vector> b(dsize / 8, + std::vector(8, 65535)); + std::vector> ct_a(dsize / 8, + std::vector(8)); + std::vector> ct_b(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + a[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + b[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -85,16 +83,15 @@ static void BM_Add_CTPT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a( - dsize, std::vector(8, 65535)); - std::vector> b( - dsize, std::vector(8, 65535)); - std::vector> ct_a( - dsize, std::vector(8)); + std::vector> a(dsize, + std::vector(8, 65535)); + std::vector> b(dsize, + std::vector(8, 65535)); + std::vector> ct_a(dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); - b[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); + a[i][0] = BigNumber((unsigned int)(i * 1024) + 999); + b[i][0] = BigNumber((unsigned int)i * 1024 + 999); key.pub_key->encrypt(ct_a[i], a[i]); } @@ -112,17 +109,17 @@ static void BM_Add_CTPT_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a( - dsize / 8, std::vector(8, 65535)); - std::vector> b( - dsize / 8, std::vector(8, 65535)); - std::vector> ct_a( - dsize / 8, std::vector(8)); + std::vector> a(dsize / 8, + std::vector(8, 65535)); + std::vector> b(dsize / 8, + std::vector(8, 65535)); + std::vector> ct_a(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + a[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + b[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -145,16 +142,15 @@ static void BM_Mul_CTPT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a( - dsize, std::vector(8, 65535)); - std::vector> b( - dsize, std::vector(8, 65535)); - std::vector> ct_a( - dsize, std::vector(8)); + std::vector> a(dsize, + std::vector(8, 65535)); + std::vector> b(dsize, + std::vector(8, 65535)); + std::vector> ct_a(dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); - b[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); + a[i][0] = BigNumber((unsigned int)i * 1024 + 999); + b[i][0] = BigNumber((unsigned int)i * 1024 + 999); key.pub_key->encrypt(ct_a[i], a[i]); } @@ -173,17 +169,17 @@ static void BM_Mul_CTPT_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a( - dsize / 8, std::vector(8, 65535)); - std::vector> b( - dsize / 8, std::vector(8, 65535)); - std::vector> ct_a( - dsize / 8, std::vector(8)); + std::vector> a(dsize / 8, + std::vector(8, 65535)); + std::vector> b(dsize / 8, + std::vector(8, 65535)); + std::vector> ct_a(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + a[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + b[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -208,20 +204,18 @@ static void BM_Add_CTCT_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a( - dsize, std::vector(8, 65535)); - std::vector> b( - dsize, std::vector(8, 65535)); - std::vector> ct_a( - dsize, std::vector(8)); - std::vector> ct_b( - dsize, std::vector(8)); + std::vector> a(dsize, + std::vector(8, 65535)); + std::vector> b(dsize, + std::vector(8, 65535)); + std::vector> ct_a(dsize, std::vector(8)); + std::vector> ct_b(dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); + a[i][0] = BigNumber((unsigned int)i * 1024 + 999); key.pub_key->encrypt(ct_a[i], a[i]); - b[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); + b[i][0] = BigNumber((unsigned int)i * 1024 + 999); key.pub_key->encrypt(ct_b[i], b[i]); } @@ -244,19 +238,19 @@ static void BM_Add_CTCT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a( - dsize / 8, std::vector(8, 65535)); - std::vector> b( - dsize / 8, std::vector(8, 65535)); - std::vector> ct_a( - dsize / 8, std::vector(8)); - std::vector> ct_b( - dsize / 8, std::vector(8)); + std::vector> a(dsize / 8, + std::vector(8, 65535)); + std::vector> b(dsize / 8, + std::vector(8, 65535)); + std::vector> ct_a(dsize / 8, + std::vector(8)); + std::vector> ct_b(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + a[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + b[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -282,16 +276,15 @@ static void BM_Add_CTPT_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a( - dsize, std::vector(8, 65535)); - std::vector> b( - dsize, std::vector(8, 65535)); - std::vector> ct_a( - dsize, std::vector(8)); + std::vector> a(dsize, + std::vector(8, 65535)); + std::vector> b(dsize, + std::vector(8, 65535)); + std::vector> ct_a(dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); - b[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); + a[i][0] = BigNumber((unsigned int)i * 1024 + 999); + b[i][0] = BigNumber((unsigned int)i * 1024 + 999); key.pub_key->encrypt(ct_a[i], a[i]); } @@ -313,17 +306,17 @@ static void BM_Add_CTPT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a( - dsize / 8, std::vector(8, 65535)); - std::vector> b( - dsize / 8, std::vector(8, 65535)); - std::vector> ct_a( - dsize / 8, std::vector(8)); + std::vector> a(dsize / 8, + std::vector(8, 65535)); + std::vector> b(dsize / 8, + std::vector(8, 65535)); + std::vector> ct_a(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + a[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + b[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -347,16 +340,15 @@ static void BM_Mul_CTPT_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a( - dsize, std::vector(8, 65535)); - std::vector> b( - dsize, std::vector(8, 65535)); - std::vector> ct_a( - dsize, std::vector(8)); + std::vector> a(dsize, + std::vector(8, 65535)); + std::vector> b(dsize, + std::vector(8, 65535)); + std::vector> ct_a(dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); - b[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); + a[i][0] = BigNumber((unsigned int)i * 1024 + 999); + b[i][0] = BigNumber((unsigned int)i * 1024 + 999); key.pub_key->encrypt(ct_a[i], a[i]); } @@ -379,17 +371,17 @@ static void BM_Mul_CTPT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a( - dsize / 8, std::vector(8, 65535)); - std::vector> b( - dsize / 8, std::vector(8, 65535)); - std::vector> ct_a( - dsize / 8, std::vector(8)); + std::vector> a(dsize / 8, + std::vector(8, 65535)); + std::vector> b(dsize / 8, + std::vector(8, 65535)); + std::vector> ct_a(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + a[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + b[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); } key.pub_key->encrypt(ct_a[i], a[i]); diff --git a/benchmark/main.cpp b/benchmark/main.cpp index da89895..63ecedd 100644 --- a/benchmark/main.cpp +++ b/benchmark/main.cpp @@ -1,11 +1,23 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 +#ifdef IPCL_USE_QAT +#include +#endif // IPCL_USE_QAT + #include int main(int argc, char** argv) { +#ifdef IPCL_USE_QAT + acquire_qat_devices(); +#endif // IPCL_USE_QAT + benchmark::Initialize(&argc, argv); benchmark::RunSpecifiedBenchmarks(); +#ifdef IPCL_USE_QAT + release_qat_devices(); +#endif + return 0; } diff --git a/cmake/heqat/heqat.cmake b/cmake/heqat/heqat.cmake new file mode 100644 index 0000000..53a2654 --- /dev/null +++ b/cmake/heqat/heqat.cmake @@ -0,0 +1,48 @@ +# Copyright (C) 2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +include(ExternalProject) +MESSAGE(STATUS "Configuring HE QAT") +set(HEQAT_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_he_qat) +set(HEQAT_GIT_REPO_URL git@github.com:intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.project-destiny.git) +set(HEQAT_GIT_LABEL development) +set(HEQAT_SRC_DIR ${HEQAT_PREFIX}/src/ext_he_qat/) + +set(HEQAT_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS}") + +ExternalProject_Add( + ext_he_qat + GIT_REPOSITORY ${HEQAT_GIT_REPO_URL} + GIT_TAG ${HEQAT_GIT_LABEL} + PREFIX ${HEQAT_PREFIX} + INSTALL_DIR ${HEQAT_PREFIX} + CMAKE_ARGS ${HEQAT_CXX_FLAGS} + -DCMAKE_INSTALL_PREFIX=${HEQAT_PREFIX} + -DHE_QAT_MISC=OFF + -DIPPCP_PREFIX_PATH=${IPPCRYPTO_PREFIX}/lib/cmake + #-DARCH=${HEQAT_ARCH} + #-DCMAKE_ASM_NASM_COMPILER=nasm + #-DCMAKE_BUILD_TYPE=Release + UPDATE_COMMAND "" +) + +add_dependencies(ext_he_qat libippcrypto) + +set(HEQAT_INC_DIR ${HEQAT_PREFIX}/include) #${HEQAT_SRC_DIR}/install/include) + +# Bring up CPA variables +include(${CMAKE_CURRENT_LIST_DIR}/icp/CMakeLists.txt) +list(APPEND HEQAT_INC_DIR ${ICP_INC_DIR}) + +add_library(libhe_qat INTERFACE) +add_dependencies(libhe_qat ext_he_qat) + +ExternalProject_Get_Property(ext_he_qat SOURCE_DIR BINARY_DIR) + +target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libcpa_sample_utils.a) # ${HEQAT_PREFIX}/lib/libhe_qat_misc.a) +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat_debug.so) +else() + target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat.so) +endif() +target_include_directories(libhe_qat SYSTEM INTERFACE ${HEQAT_INC_DIR}) diff --git a/cmake/heqat/icp/CMakeLists.txt b/cmake/heqat/icp/CMakeLists.txt new file mode 100644 index 0000000..ee0617a --- /dev/null +++ b/cmake/heqat/icp/CMakeLists.txt @@ -0,0 +1,33 @@ + +if(DEFINED ENV{ICP_ROOT}) + message(STATUS "Environment variable ICP_ROOT is defined as $ENV{ICP_ROOT}.") +else() + message(FATAL_ERROR "Environment variable ICP_ROOT must be defined. Try export ICP_ROOT=") +endif() + +set(ICP_ROOT $ENV{ICP_ROOT}) +set(ICP_BUILDOUTPUT_PATH ${ICP_ROOT}/build) +set(ICP_BUILDSYSTEM_PATH ${ICP_ROOT}/quickassist/build_system) +set(ICP_API_DIR ${ICP_ROOT}/quickassist) +set(ICP_LAC_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer) +set(ICP_OSAL_DIR ${ICP_ROOT}/quickassist/utilities/oasl) +set(ICP_ADF_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/qat_direct) +set(CMN_ROOT ${ICP_ROOT}/quickassist/utilities/libusdm_drv) + +#list(APPEND COMMON_INC_DIR ${ICP_API_DIR}/include +# ${ICP_LAC_DIR}/include +# ${ICP_ADF_DIR}/include +# ${CMN_ROOT} +#) + +set(ICP_INC_DIR ${ICP_API_DIR}/include + ${ICP_LAC_DIR}/include + ${ICP_ADF_DIR}/include + ${CMN_ROOT} + ${ICP_API_DIR}/include/dc + ${ICP_API_DIR}/include/lac) + +#Macros for the test case +add_definitions(-DDO_CRYPTO) +add_definitions(-DUSER_SPACE) +add_compile_options(-fPIC) diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 6bf7a0c..385db16 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -24,7 +24,6 @@ target_include_directories(ipcl PUBLIC $ ) - target_include_directories(ipcl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PUBLIC $ @@ -54,6 +53,10 @@ else() target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) endif() +if(IPCL_ENABLE_QAT) + target_link_libraries(ipcl PRIVATE libhe_qat) +endif() + set_target_properties(ipcl PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(ipcl PROPERTIES VERSION ${IPCL_VERSION}) if(IPCL_DEBUG) diff --git a/ipcl/bignum.cpp b/ipcl/bignum.cpp index b5adab3..d49708a 100644 --- a/ipcl/bignum.cpp +++ b/ipcl/bignum.cpp @@ -25,7 +25,7 @@ // ////////////////////////////////////////////////////////////////////// -namespace ipcl { +// namespace ipcl { BigNumber::~BigNumber() { delete[](Ipp8u*) m_pBN; } @@ -138,7 +138,7 @@ BigNumber& BigNumber::operator=(const BigNumber& bn) { Ipp32u* bnData; ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); - delete (Ipp8u*)m_pBN; + delete[](Ipp8u*) m_pBN; create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); } return *this; @@ -509,4 +509,34 @@ void BigNumber::num2char(std::vector& dest) const { dest.assign(bnData, bnData + len); } -} // namespace ipcl +bool BigNumber::fromBin(BigNumber& bn, const unsigned char* data, int len) { + if (len <= 0) return false; + + // Create BigNumber containg input data passed as argument + bn = BigNumber(reinterpret_cast(data), (len / 4)); + Ipp32u* ref_bn_data_ = NULL; + ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); + + // Convert it to little endian format + unsigned char* data_ = reinterpret_cast(ref_bn_data_); + for (int i = 0; i < len; i++) data_[i] = data[len - 1 - i]; + + return true; +} + +bool BigNumber::toBin(unsigned char* data, int len, const BigNumber& bn) { + if (len <= 0) return false; + + // Extract raw vector of data in little endian format + int bitSize = 0; + Ipp32u* ref_bn_data_ = NULL; + ippsRef_BN(NULL, &bitSize, &ref_bn_data_, BN(bn)); + + // Revert it to big endian format + int bitSizeLen = BITSIZE_WORD(bitSize) * 4; + unsigned char* data_ = reinterpret_cast(ref_bn_data_); + for (int i = 0; i < bitSizeLen; i++) data[len - 1 - i] = data_[i]; + + return true; +} +//} // namespace ipcl diff --git a/ipcl/include/ipcl/bignum.h b/ipcl/include/ipcl/bignum.h index fe62dc1..dd42d28 100644 --- a/ipcl/include/ipcl/bignum.h +++ b/ipcl/include/ipcl/bignum.h @@ -14,15 +14,17 @@ * limitations under the License. *******************************************************************************/ -#ifndef _BIGNUM_H_ -#define _BIGNUM_H_ +//#ifndef _BIGNUM_H_ +//#define _BIGNUM_H_ +#if !defined _BIGNUMBER_H_ +#define _BIGNUMBER_H_ #include #include #include -namespace ipcl { +// namespace ipcl { class BigNumber { public: @@ -122,6 +124,10 @@ class BigNumber { friend std::ostream& operator<<(std::ostream& os, const BigNumber& a); void num2char(std::vector& dest) const; + // Support QAT data format + static bool fromBin(BigNumber& bn, const unsigned char* data, int len); + static bool toBin(unsigned char* data, int len, const BigNumber& bn); + protected: bool create(const Ipp32u* pData, int length, IppsBigNumSGN sgn = IppsBigNumPOS); @@ -131,5 +137,5 @@ class BigNumber { constexpr int BITSIZE_WORD(int n) { return (((n) + 31) >> 5); } constexpr int BITSIZE_DWORD(int n) { return (((n) + 63) >> 6); } -} // namespace ipcl +//} // namespace ipcl #endif // _BIGNUM_H_ diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index b578b60..bc7613e 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -4,13 +4,200 @@ #include "ipcl/mod_exp.hpp" #include +#include #include #include "ipcl/util.hpp" +#ifdef IPCL_USE_QAT +#include +#include +#endif + namespace ipcl { +#ifdef IPCL_USE_QAT + +// Multiple input QAT ModExp interface to offload computation to QAT +static std::vector heQatBnModExp( + const std::vector& base, const std::vector& exponent, + const std::vector& modulus) { + static unsigned int counter = 0; + int nbits = modulus.front().BitSize(); + int length = BITSIZE_WORD(nbits) * 4; + nbits = 8 * length; + + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + // TODO(fdiasmor): Try replace calloc by alloca to see impact on performance. + unsigned char* bn_base_data_[IPCL_CRYPTO_MB_SIZE]; + unsigned char* bn_exponent_data_[IPCL_CRYPTO_MB_SIZE]; + unsigned char* bn_modulus_data_[IPCL_CRYPTO_MB_SIZE]; + unsigned char* bn_remainder_data_[IPCL_CRYPTO_MB_SIZE]; + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + bn_base_data_[i] = reinterpret_cast( + malloc(length * sizeof(unsigned char))); + bn_exponent_data_[i] = reinterpret_cast( + malloc(length * sizeof(unsigned char))); + bn_modulus_data_[i] = reinterpret_cast( + malloc(length * sizeof(unsigned char))); + bn_remainder_data_[i] = reinterpret_cast( + malloc(length * sizeof(unsigned char))); + + ERROR_CHECK( + bn_base_data_[i] != nullptr && bn_exponent_data_[i] != nullptr && + bn_modulus_data_[i] != nullptr && bn_remainder_data_[i] != nullptr, + "qatMultiBuffExp: alloc memory for error"); + + memset(bn_base_data_[i], 0, length); + memset(bn_exponent_data_[i], 0, length); + memset(bn_modulus_data_[i], 0, length); + memset(bn_remainder_data_[i], 0, length); + } + + // TODO(fdiasmor): Define and use IPCL_QAT_BATCH_SIZE instead of + // IPCL_CRYPTO_MB_SIZE. + for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + bool ret = BigNumber::toBin(bn_base_data_[i], length, base[i]); + if (!ret) { + printf("bn_base_data_: failed at bigNumberToBin()\n"); + exit(1); + } + ret = BigNumber::toBin(bn_exponent_data_[i], length, exponent[i]); + if (!ret) { + printf("bn_exponent_data_: failed at bigNumberToBin()\n"); + exit(1); + } + ret = BigNumber::toBin(bn_modulus_data_[i], length, modulus[i]); + if (!ret) { + printf("bn_modulus_data_: failed at bigNumberToBin()\n"); + exit(1); + } + + unsigned char* bn_base_ = + reinterpret_cast(bn_base_data_[i]); + unsigned char* bn_exponent_ = + reinterpret_cast(bn_exponent_data_[i]); + unsigned char* bn_modulus_ = + reinterpret_cast(bn_modulus_data_[i]); + unsigned char* bn_remainder_ = + reinterpret_cast(bn_remainder_data_[i]); + + status = HE_QAT_bnModExp(bn_remainder_, bn_base_, bn_exponent_, bn_modulus_, + nbits); + if (HE_QAT_STATUS_SUCCESS != status) { + PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); + } + } + getBnModExpRequest(IPCL_CRYPTO_MB_SIZE); + + std::vector remainder(IPCL_CRYPTO_MB_SIZE, 0); + // Collect results and pack them into BigNumber + for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + unsigned char* bn_remainder_ = bn_remainder_data_[i]; + bool ret = BigNumber::fromBin(remainder[i], bn_remainder_, length); + if (!ret) { + printf("bn_remainder_data_: failed at bignumbertobin()\n"); + exit(1); + } + } + + for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + free(bn_base_data_[i]); + bn_base_data_[i] = NULL; + free(bn_exponent_data_[i]); + bn_exponent_data_[i] = NULL; + free(bn_modulus_data_[i]); + bn_modulus_data_[i] = NULL; + } + + for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + free(bn_remainder_data_[i]); + bn_remainder_data_[i] = NULL; + } + + return remainder; +} + +// Single input QAT ModExp interface to offload computation to QAT +static BigNumber heQatBnModExp(const BigNumber& base, const BigNumber& exponent, + const BigNumber& modulus) { + static unsigned int counter = 0; + int nbits = modulus.BitSize(); + int length = BITSIZE_WORD(nbits) * 4; + nbits = 8 * length; + + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + // TODO(fdiasmor): Try replace calloc by alloca to see impact on performance. + unsigned char* bn_base_data_ = NULL; + unsigned char* bn_exponent_data_ = NULL; + unsigned char* bn_modulus_data_ = NULL; + unsigned char* bn_remainder_data_ = NULL; + + bn_base_data_ = + reinterpret_cast(malloc(length * sizeof(unsigned char))); + bn_exponent_data_ = + reinterpret_cast(malloc(length * sizeof(unsigned char))); + bn_modulus_data_ = + reinterpret_cast(malloc(length * sizeof(unsigned char))); + bn_remainder_data_ = + reinterpret_cast(malloc(length * sizeof(unsigned char))); + + ERROR_CHECK(bn_base_data_ != nullptr && bn_exponent_data_ != nullptr && + bn_modulus_data_ != nullptr && bn_remainder_data_ != nullptr, + "qatMultiBuffExp: alloc memory for error"); + + memset(bn_base_data_, 0, length); + memset(bn_exponent_data_, 0, length); + memset(bn_modulus_data_, 0, length); + memset(bn_remainder_data_, 0, length); + + bool ret = BigNumber::toBin(bn_base_data_, length, base); + if (!ret) { + printf("bn_base_data_: failed at bignumbertobin()\n"); + exit(1); + } + ret = BigNumber::toBin(bn_exponent_data_, length, exponent); + if (!ret) { + printf("bn_exponent_data_: failed at bignumbertobin()\n"); + exit(1); + } + ret = BigNumber::toBin(bn_modulus_data_, length, modulus); + if (!ret) { + printf("bn_modulus_data_: failed at bignumbertobin()\n"); + exit(1); + } + + status = HE_QAT_bnModExp(bn_remainder_data_, bn_base_data_, bn_exponent_data_, + bn_modulus_data_, nbits); + if (HE_QAT_STATUS_SUCCESS != status) { + PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); + } + getBnModExpRequest(1); + + // Collect result and pack it into BigNumber + BigNumber remainder; + ret = BigNumber::fromBin(remainder, bn_remainder_data_, length); + if (!ret) { + printf("bn_remainder_data_: failed at bignumbertobin()\n"); + exit(1); + } + + free(bn_base_data_); + bn_base_data_ = NULL; + free(bn_exponent_data_); + bn_exponent_data_ = NULL; + free(bn_modulus_data_); + bn_modulus_data_ = NULL; + free(bn_remainder_data_); + bn_remainder_data_ = NULL; + + return remainder; +} +#endif // IPCL_USE_QAT + static std::vector ippMBModExp(const std::vector& base, const std::vector& pow, const std::vector& m) { @@ -152,6 +339,11 @@ static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, std::vector ippModExp(const std::vector& base, const std::vector& pow, const std::vector& m) { +#ifdef IPCL_USE_QAT + std::vector remainder(IPCL_CRYPTO_MB_SIZE); + remainder = heQatBnModExp(base, pow, m); + return remainder; +#else #ifdef IPCL_CRYPTO_MB_MOD_EXP return ippMBModExp(base, pow, m); #else @@ -159,12 +351,17 @@ std::vector ippModExp(const std::vector& base, for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) res[i] = ippSBModExp(base[i], pow[i], m[i]); return res; -#endif +#endif // else +#endif // IPCL_USE_QAT } BigNumber ippModExp(const BigNumber& base, const BigNumber& pow, const BigNumber& m) { +#ifdef IPCL_USE_QAT + return heQatBnModExp(base, pow, m); +#else return ippSBModExp(base, pow, m); +#endif // IPCL_USE_QAT } } // namespace ipcl diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bca944a..1be4b73 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -20,3 +20,8 @@ if(IPCL_ENABLE_OMP) find_package(OpenMP REQUIRED) target_link_libraries(unittest_ipcl PRIVATE OpenMP::OpenMP_CXX) endif() + +# enable QAT unittests +if(IPCL_ENABLE_QAT) + target_link_libraries(unittest_ipcl PRIVATE libhe_qat) +endif() diff --git a/test/main.cpp b/test/main.cpp index 0ec6f12..a27eecf 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -1,13 +1,29 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 +#ifdef IPCL_USE_QAT +#include +#endif // IPCL_USE_QAT + #include #include int main(int argc, char** argv) { +#ifdef IPCL_USE_QAT + // Initialize QAT context + acquire_qat_devices(); +#endif // IPCL_USE_QAT + // Use system clock for seed srand(time(nullptr)); ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); + int status = RUN_ALL_TESTS(); + +#ifdef IPCL_USE_QAT + // Destroy QAT context + release_qat_devices(); +#endif + + return status; } diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index 931b0ac..c88eaba 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -17,11 +17,11 @@ TEST(CryptoTest, CryptoTest) { ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector ct(8); - std::vector dt(8); + std::vector ct(8); + std::vector dt(8); std::vector pt(8); - std::vector ptbn(8); + std::vector ptbn(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -45,9 +45,8 @@ TEST(CryptoTest, CryptoTest) { } #ifdef IPCL_USE_OMP -void Encryption(int num_threads, - std::vector>& v_ct, - const std::vector>& v_ptbn, +void Encryption(int num_threads, std::vector>& v_ct, + const std::vector>& v_ptbn, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { @@ -55,9 +54,8 @@ void Encryption(int num_threads, } } -void Decryption(int num_threads, - std::vector>& v_dt, - const std::vector>& v_ct, +void Decryption(int num_threads, std::vector>& v_dt, + const std::vector>& v_ct, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { @@ -71,14 +69,14 @@ TEST(CryptoTest, CryptoTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector> v_ct( - num_threads, std::vector(8)); - std::vector> v_dt( - num_threads, std::vector(8)); + std::vector> v_ct(num_threads, + std::vector(8)); + std::vector> v_dt(num_threads, + std::vector(8)); std::vector> v_pt(num_threads, std::vector(8)); - std::vector> v_ptbn( - num_threads, std::vector(8)); + std::vector> v_ptbn(num_threads, + std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); @@ -110,18 +108,18 @@ TEST(CryptoTest, CryptoTest_OMP) { #endif // IPCL_USE_OMP TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { - ipcl::BigNumber p = + BigNumber p = "0xff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c" "8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b4" "0a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff76" "4dd8b091f11a0943a2dd2b983b0df02f4c4d00b413"; - ipcl::BigNumber q = + BigNumber q = "0xdacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d" "9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de70" "72a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49b" "aa0f610bad100cdf47cc86e5034e2a0b2179e04ec7"; - ipcl::BigNumber n = p * q; + BigNumber n = p * q; int n_length = n.BitSize(); ipcl::PublicKey* public_key = new ipcl::PublicKey(n, n_length); @@ -129,12 +127,12 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { ipcl::keyPair key = {public_key, private_key}; - std::vector ptbn(8); - std::vector ct(8); - std::vector dt(8); - std::vector ir(8); + std::vector ptbn(8); + std::vector ct(8); + std::vector dt(8); + std::vector ir(8); - ipcl::BigNumber c1 = + BigNumber c1 = "0x1fb7f08a42deb47876e4cbdc3f0b172c033563a696ad7a7c76fa5971b793fa488dcdd6" "bd65c7c5440d67d847cb89ccca468b2c96763fff5a5ece8330251112d65e59b7da94cfe9" "309f441ccc8f59c67dec75113d37b1ee929c8d4ce6b5e561a30a91104b0526de892e4eff" @@ -151,7 +149,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "b98ccb676367b7b3b269c670cd0210edf70ad9cb337f766af75fe06d18b3f7f7c2eae656" "5ff2815c2c09b1a1f5"; - ipcl::BigNumber c2 = + BigNumber c2 = "0x61803645f2798c06f2c08fc254eee612c55542051c8777d6ce69ede9c84a179afb2081" "167494dee727488ae5e9b56d98f4fcf132514616859fc854fbd3acf6aecd97324ac3f2af" "fa9f44864a9afc505754aa3b564b4617e887d6aa1f88095bccf6b47f458566f9d85e80fc" @@ -168,7 +166,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "d6f1d6864f1fd3e2e3937e00d391ad330b443aec85528571740ed5538188c32caab27c7b" "f437df2bb97cb90e02"; - ipcl::BigNumber c1c2 = + BigNumber c1c2 = "0x309f6e614d875e3bb0a77eedeb8895e7c6f297f161f576aef4f8b72bb5b81ef78b831a" "af134b09fe8697159cfd678c49920cb790e36580c5201a96848d7242fceb025808dd26b5" "0ff573ffca3f65e51b3b9fe85c7e44f5c8df0a9e524f64a5acc5c62cba7475978eb55e08" @@ -185,9 +183,9 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "a6d47f9af6e68e18960fa5916cc48994334354d6303312b8e96602766bec337a8a92c596" "b21b6038828a6c9744"; - ipcl::BigNumber m1m2 = "0x616263646566676869606a6b6c6d6e6f"; + BigNumber m1m2 = "0x616263646566676869606a6b6c6d6e6f"; - ipcl::BigNumber r0 = + BigNumber r0 = "0x57fb19590c31dc7c034b2a889cf4037ce3db799909c1eb0adb6199d8e96791daca9018" "891f34309daff32dced4af7d793d16734d055e28023acab7295956bfbfdf62bf0ccb2ed3" "1d5d176ca8b404e93007565fb6b72c33a512b4dc4f719231d62e27e34c3733929af32247" @@ -196,7 +194,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "27991c44a43750c24ed0825718ad14cfb9c6b40b78ff3d25f71741f2def1c9d420d4b0fa" "1e0a02e7851b5ec6a81133a368b80d1500b0f28fc653d2e6ff4366236dbf80ae3b4beae3" "5e04579f2c"; - ipcl::BigNumber r1 = + BigNumber r1 = "0x6ee8ed76227672a7bcaa1e7f152c2ea39f2fa225f0713f58210c59b2270b110e38b650" "69aaedbeffc713c021336cc12f65227cc0357ca531c07c706e7224c2c11c3145bc0a05b1" "64f426ec03350820f9f416377e8720ddb577843cae929178bfe5772e2cc1e9b94e8fce81" @@ -220,10 +218,10 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { ipcl::EncryptedNumber a(key.pub_key, ct[0]); ipcl::EncryptedNumber b(key.pub_key, ct[1]); ipcl::EncryptedNumber sum = a + b; - ipcl::BigNumber res = sum.getBN(); + BigNumber res = sum.getBN(); - std::vector ct12(8); - std::vector dt12(8); + std::vector ct12(8); + std::vector dt12(8); for (int i = 0; i < 8; i++) { ct12[i] = res; } diff --git a/test/test_ops.cpp b/test/test_ops.cpp index 025f3b4..e9ea896 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -14,10 +14,8 @@ #include "ipcl/keygen.hpp" #include "ipcl/ops.hpp" -void CtPlusCt(std::vector& res, - const std::vector& ct1, - const std::vector& ct2, - const ipcl::keyPair key) { +void CtPlusCt(std::vector& res, const std::vector& ct1, + const std::vector& ct2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { ipcl::EncryptedNumber a(key.pub_key, ct1[i]); ipcl::EncryptedNumber b(key.pub_key, ct2[i]); @@ -26,40 +24,37 @@ void CtPlusCt(std::vector& res, } } -void CtPlusCtArray(std::vector& res, - const std::vector& ct1, - const std::vector& ct2, - const ipcl::keyPair key) { +void CtPlusCtArray(std::vector& res, + const std::vector& ct1, + const std::vector& ct2, const ipcl::keyPair key) { ipcl::EncryptedNumber a(key.pub_key, ct1); ipcl::EncryptedNumber b(key.pub_key, ct2); ipcl::EncryptedNumber sum = a + b; res = sum.getArrayBN(); } -void CtPlusPt(std::vector& res, - const std::vector& ct1, +void CtPlusPt(std::vector& res, const std::vector& ct1, const std::vector& pt2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { ipcl::EncryptedNumber a(key.pub_key, ct1[i]); - ipcl::BigNumber b = pt2[i]; + BigNumber b = pt2[i]; ipcl::EncryptedNumber sum = a + b; res[i] = sum.getBN(); } } -void CtPlusPtArray(std::vector& res, - const std::vector& ct1, - const std::vector& ptbn2, +void CtPlusPtArray(std::vector& res, + const std::vector& ct1, + const std::vector& ptbn2, const ipcl::keyPair key) { ipcl::EncryptedNumber a(key.pub_key, ct1); ipcl::EncryptedNumber sum = a + ptbn2; res = sum.getArrayBN(); } -void CtMultiplyPt(std::vector& res, - const std::vector& ct1, - const std::vector& pt2, - const ipcl::keyPair key) { +void CtMultiplyPt(std::vector& res, + const std::vector& ct1, + const std::vector& pt2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { ipcl::EncryptedNumber a(key.pub_key, ct1[i]); ipcl::EncryptedNumber sum = a * pt2[i]; @@ -67,9 +62,9 @@ void CtMultiplyPt(std::vector& res, } } -void CtMultiplyPtArray(std::vector& res, - const std::vector& ct1, - const std::vector& pt2, +void CtMultiplyPtArray(std::vector& res, + const std::vector& ct1, + const std::vector& pt2, const ipcl::keyPair key) { ipcl::EncryptedNumber a(key.pub_key, ct1); ipcl::EncryptedNumber b(key.pub_key, pt2); @@ -77,13 +72,12 @@ void CtMultiplyPtArray(std::vector& res, res = sum.getArrayBN(); } -void AddSub(std::vector& res, - const std::vector& ct1, - const std::vector& ct2, const ipcl::keyPair key) { +void AddSub(std::vector& res, const std::vector& ct1, + const std::vector& ct2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { ipcl::EncryptedNumber a(key.pub_key, ct1[i]); ipcl::EncryptedNumber b(key.pub_key, ct2[i]); - ipcl::BigNumber m1(2); + BigNumber m1(2); a = a + b * m1; ipcl::EncryptedNumber sum = a + b; res[i] = sum.getBN(); @@ -93,11 +87,11 @@ void AddSub(std::vector& res, TEST(OperationTest, CtPlusCtTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -134,11 +128,11 @@ TEST(OperationTest, CtPlusCtTest) { TEST(OperationTest, CtPlusCtArrayTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -175,11 +169,11 @@ TEST(OperationTest, CtPlusCtArrayTest) { TEST(OperationTest, CtPlusPtTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8); + std::vector ptbn1(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -214,11 +208,11 @@ TEST(OperationTest, CtPlusPtTest) { TEST(OperationTest, CtPlusPtArrayTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -254,11 +248,11 @@ TEST(OperationTest, CtPlusPtArrayTest) { TEST(OperationTest, CtMultiplyPtTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -294,11 +288,11 @@ TEST(OperationTest, CtMultiplyPtTest) { TEST(OperationTest, CtMultiplyZeroPtTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8, 0); - std::vector ptbn1(8), ptbn2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -333,11 +327,11 @@ TEST(OperationTest, CtMultiplyZeroPtTest) { TEST(OperationTest, CtMultiplyPtArrayTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8); - std::vector dt(8), res(8); + std::vector ct1(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -373,11 +367,11 @@ TEST(OperationTest, CtMultiplyPtArrayTest) { TEST(OperationTest, AddSubTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -411,10 +405,9 @@ TEST(OperationTest, AddSubTest) { } #ifdef IPCL_USE_OMP -void CtPlusCt_OMP(int num_threads, - std::vector>& v_sum, - const std::vector>& v_ct1, - const std::vector>& v_ct2, +void CtPlusCt_OMP(int num_threads, std::vector>& v_sum, + const std::vector>& v_ct1, + const std::vector>& v_ct2, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { @@ -427,15 +420,14 @@ void CtPlusCt_OMP(int num_threads, } } -void CtPlusPt_OMP(int num_threads, - std::vector>& v_sum, - const std::vector>& v_ct1, +void CtPlusPt_OMP(int num_threads, std::vector>& v_sum, + const std::vector>& v_ct1, const std::vector>& v_pt2, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { - ipcl::BigNumber b = v_pt2[i][j]; + BigNumber b = v_pt2[i][j]; ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); ipcl::EncryptedNumber sum = a + b; v_sum[i][j] = sum.getBN(); @@ -444,14 +436,14 @@ void CtPlusPt_OMP(int num_threads, } void CtPlusPtArray_OMP(int num_threads, - std::vector>& v_sum, - const std::vector>& v_ct1, + std::vector>& v_sum, + const std::vector>& v_ct1, const std::vector>& v_pt2, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { ipcl::EncryptedNumber a(key.pub_key, v_ct1[i]); - std::vector b(8); + std::vector b(8); for (int j = 0; j < 8; j++) { b[j] = v_pt2[i][j]; } @@ -461,25 +453,26 @@ void CtPlusPtArray_OMP(int num_threads, } void CtMultiplyPt_OMP(int num_threads, - std::vector>& v_product, - const std::vector>& v_ct1, + std::vector>& v_product, + const std::vector>& v_ct1, const std::vector>& v_pt2, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); - ipcl::BigNumber b = v_pt2[i][j]; + BigNumber b = v_pt2[i][j]; ipcl::EncryptedNumber product = a * b; v_product[i][j] = product.getBN(); } } } -void CtMultiplyPtArray_OMP( - int num_threads, std::vector>& v_product, - const std::vector>& v_ct1, - const std::vector>& v_pt2, const ipcl::keyPair key) { +void CtMultiplyPtArray_OMP(int num_threads, + std::vector>& v_product, + const std::vector>& v_ct1, + const std::vector>& v_pt2, + const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { ipcl::EncryptedNumber a(key.pub_key, v_ct1[i]); @@ -494,22 +487,22 @@ TEST(OperationTest, CtPlusCtTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector> v_ct1( - num_threads, std::vector(8)); - std::vector> v_ct2( - num_threads, std::vector(8)); - std::vector> v_dt( - num_threads, std::vector(8)); - std::vector> v_sum( - num_threads, std::vector(8)); + std::vector> v_ct1(num_threads, + std::vector(8)); + std::vector> v_ct2(num_threads, + std::vector(8)); + std::vector> v_dt(num_threads, + std::vector(8)); + std::vector> v_sum(num_threads, + std::vector(8)); std::vector> v_pt1(num_threads, std::vector(8)); std::vector> v_pt2(num_threads, std::vector(8)); - std::vector> v_ptbn1( - num_threads, std::vector(8)); - std::vector> v_ptbn2( - num_threads, std::vector(8)); + std::vector> v_ptbn1(num_threads, + std::vector(8)); + std::vector> v_ptbn2(num_threads, + std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -560,20 +553,20 @@ TEST(OperationTest, CtPlusPtTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector> v_ct1( - num_threads, std::vector(8)); - std::vector> v_dt( - num_threads, std::vector(8)); - std::vector> v_sum( - num_threads, std::vector(8)); + std::vector> v_ct1(num_threads, + std::vector(8)); + std::vector> v_dt(num_threads, + std::vector(8)); + std::vector> v_sum(num_threads, + std::vector(8)); std::vector> v_pt1(num_threads, std::vector(8)); std::vector> v_pt2(num_threads, std::vector(8)); - std::vector> v_ptbn1( - num_threads, std::vector(8)); - std::vector> v_ptbn2( - num_threads, std::vector(8)); + std::vector> v_ptbn1(num_threads, + std::vector(8)); + std::vector> v_ptbn2(num_threads, + std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -623,20 +616,20 @@ TEST(OperationTest, CtPlusPtArrayTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector> v_ct1( - num_threads, std::vector(8)); - std::vector> v_dt( - num_threads, std::vector(8)); - std::vector> v_sum( - num_threads, std::vector(8)); + std::vector> v_ct1(num_threads, + std::vector(8)); + std::vector> v_dt(num_threads, + std::vector(8)); + std::vector> v_sum(num_threads, + std::vector(8)); std::vector> v_pt1(num_threads, std::vector(8)); std::vector> v_pt2(num_threads, std::vector(8)); - std::vector> v_ptbn1( - num_threads, std::vector(8)); - std::vector> v_ptbn2( - num_threads, std::vector(8)); + std::vector> v_ptbn1(num_threads, + std::vector(8)); + std::vector> v_ptbn2(num_threads, + std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -686,20 +679,20 @@ TEST(OperationTest, CtMultiplyPtTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector> v_ct1( - num_threads, std::vector(8)); - std::vector> v_dt( - num_threads, std::vector(8)); - std::vector> v_product( - num_threads, std::vector(8)); + std::vector> v_ct1(num_threads, + std::vector(8)); + std::vector> v_dt(num_threads, + std::vector(8)); + std::vector> v_product(num_threads, + std::vector(8)); std::vector> v_pt1(num_threads, std::vector(8)); std::vector> v_pt2(num_threads, std::vector(8)); - std::vector> v_ptbn1( - num_threads, std::vector(8)); - std::vector> v_ptbn2( - num_threads, std::vector(8)); + std::vector> v_ptbn1(num_threads, + std::vector(8)); + std::vector> v_ptbn2(num_threads, + std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); @@ -749,20 +742,20 @@ TEST(OperationTest, CtMultiplyPtArrayTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector> v_ct1( - num_threads, std::vector(8)); - std::vector> v_dt( - num_threads, std::vector(8)); - std::vector> v_product( - num_threads, std::vector(8)); + std::vector> v_ct1(num_threads, + std::vector(8)); + std::vector> v_dt(num_threads, + std::vector(8)); + std::vector> v_product(num_threads, + std::vector(8)); std::vector> v_pt1(num_threads, std::vector(8)); std::vector> v_pt2(num_threads, std::vector(8)); - std::vector> v_ptbn1( - num_threads, std::vector(8)); - std::vector> v_ptbn2( - num_threads, std::vector(8)); + std::vector> v_ptbn1(num_threads, + std::vector(8)); + std::vector> v_ptbn2(num_threads, + std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); From 03259615ab861547185c0ee48da8a7028ce8e91a Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Wed, 6 Apr 2022 16:56:11 -0700 Subject: [PATCH 158/364] Revert "QAT Modular Exponentiation Integration (#73)" (#76) This reverts commit a0ecd9b0d8f402fd6d8ec1140ffdbf50300589ad. - keep QAT clean of development for now --- CMakeLists.txt | 20 +-- README.md | 12 -- benchmark/CMakeLists.txt | 5 - benchmark/bench_cryptography.cpp | 78 +++++++---- benchmark/bench_ops.cpp | 200 +++++++++++++------------- benchmark/main.cpp | 12 -- cmake/heqat/heqat.cmake | 48 ------- cmake/heqat/icp/CMakeLists.txt | 33 ----- ipcl/CMakeLists.txt | 5 +- ipcl/bignum.cpp | 36 +---- ipcl/include/ipcl/bignum.h | 14 +- ipcl/mod_exp.cpp | 199 +------------------------- test/CMakeLists.txt | 5 - test/main.cpp | 18 +-- test/test_cryptography.cpp | 60 ++++---- test/test_ops.cpp | 231 ++++++++++++++++--------------- 16 files changed, 314 insertions(+), 662 deletions(-) delete mode 100644 cmake/heqat/heqat.cmake delete mode 100644 cmake/heqat/icp/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 6778db6..8fef7f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,10 +36,8 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_INSTALL_MESSAGE LAZY) set(CMAKE_INSTALL_RPATH "\$ORIGIN") -#set(CMAKE_C_FLAGS "-O2 -pthread") -#set(CMAKE_CXX_FLAGS "-O2 -fpermissive -pthread") -set(CMAKE_C_FLAGS "-pthread") -set(CMAKE_CXX_FLAGS "-fpermissive -pthread") +set(CMAKE_C_FLAGS "-O2") +set(CMAKE_CXX_FLAGS "-O2 -fpermissive") if(NOT CMAKE_INSTALL_PREFIX) set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}) @@ -52,23 +50,14 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) #--------------------------------------------------- option(IPCL_TEST "Enable testing" ON) option(IPCL_BENCHMARK "Enable benchmark" ON) -option(IPCL_ENABLE_QAT "Enable QAT" OFF) option(IPCL_ENABLE_OMP "Enable OpenMP testing/benchmarking" ON) option(IPCL_DOCS "Enable document building" OFF) option(IPCL_SHARED "Build shared library" ON) option(IPCL_DEBUG_DISABLE_AVX512IFMA "(Debugging) Disable usage of AVX512IFMA instructions" OFF) - -if(IPCL_ENABLE_QAT) - add_compile_definitions(IPCL_USE_QAT) - message(STATUS "QAT enabled - IPCL_ENABLE_OMP set to OFF") - set(IPCL_ENABLE_OMP OFF) -endif() - if(IPCL_ENABLE_OMP) add_compile_definitions(IPCL_USE_OMP) endif() - if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(IPCL_DEBUG ON) else() @@ -84,7 +73,6 @@ message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") message(STATUS "IPCL_TEST: ${IPCL_TEST}") message(STATUS "IPCL_BENCHMARK: ${IPCL_BENCHMARK}") message(STATUS "IPCL_ENABLE_OMP: ${IPCL_ENABLE_OMP}") -message(STATUS "IPCL_ENABLE_QAT: ${IPCL_ENABLE_QAT}") message(STATUS "IPCL_DOCS: ${IPCL_DOCS}") message(STATUS "IPCL_SHARED: ${IPCL_SHARED}") @@ -132,10 +120,6 @@ include(ipcl-util) include(cmake/ippcrypto.cmake) -if(IPCL_ENABLE_QAT) - include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/heqat/heqat.cmake) -endif() - if(IPCL_TEST) include(cmake/gtest.cmake) endif() diff --git a/README.md b/README.md index 3b5059b..ca17e85 100644 --- a/README.md +++ b/README.md @@ -81,22 +81,10 @@ It is possible to pass additional options to enable more features. The following |-------------------------|-----------|---------|-------------------------------------| |`IPCL_TEST` | ON/OFF | ON | unit-test | |`IPCL_BENCHMARK` | ON/OFF | ON | benchmark | -|`IPCL_ENABLE_QAT` | ON/OFF | OFF | enables QAT functionalities | |`IPCL_ENABLE_OMP` | ON/OFF | ON | enables OpenMP functionalities | |`IPCL_DOCS` | ON/OFF | OFF | build doxygen documentation | |`IPCL_SHARED` | ON/OFF | ON | build shared library | -## Compiling for QAT - -Install QAT software stack following the [instructions from the HE QAT Lib](https://github.com/intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.project-destiny/tree/development#installing-qat-software-stack). The current QAT support is not multithreading safe; therefore, `IPCL_ENABLE_OMP` must be set to `OFF`. - -```bash -export IPCL_DIR=$(pwd) -export ICP_ROOT=$HOME/QAT -cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DIPCL_ENABLE_QAT=ON -DIPCL_ENABLE_OMP=OFF -cmake --build build -j -``` - ## Testing and Benchmarking To run a set of unit tests via [Googletest](https://github.com/google/googletest), configure and build library with `-DIPCL_TEST=ON` (see [Instructions](#instructions)). Then, run diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 2cc21fa..dc122fe 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -20,8 +20,3 @@ if(IPCL_ENABLE_OMP) find_package(OpenMP REQUIRED) target_link_libraries(bench_ipcl PRIVATE OpenMP::OpenMP_CXX) endif() - -# enable QAT benchmarks -if(IPCL_ENABLE_QAT) - target_link_libraries(bench_ipcl PRIVATE libhe_qat) -endif() diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index 4fe2066..74b4bca 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -22,11 +22,13 @@ static void BM_Encrypt(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize, std::vector(8)); - std::vector> ct(dsize, std::vector(8)); + std::vector> pt(dsize, + std::vector(8)); + std::vector> ct(dsize, + std::vector(8)); for (size_t i = 0; i < dsize; ++i) - pt[i][0] = BigNumber((unsigned int)(i * 1024) + 999); + pt[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); for (auto _ : state) { for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -39,11 +41,13 @@ static void BM_Encrypt_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize / 8, std::vector(8)); - std::vector> ct(dsize / 8, std::vector(8)); + std::vector> pt(dsize / 8, + std::vector(8)); + std::vector> ct(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize; ++i) - pt[i / 8][i & 7] = BigNumber((unsigned int)(i * 1024) + 999); + pt[i / 8][i & 7] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); for (auto _ : state) { for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -59,12 +63,15 @@ static void BM_Decrypt(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize, std::vector(8)); - std::vector> ct(dsize, std::vector(8)); - std::vector> de_ct(dsize, std::vector(8)); + std::vector> pt(dsize, + std::vector(8)); + std::vector> ct(dsize, + std::vector(8)); + std::vector> de_ct( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) - pt[i][0] = BigNumber((unsigned int)(i * 1024) + 999); + pt[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -81,13 +88,15 @@ static void BM_Decrypt_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize / 8, std::vector(8)); - std::vector> ct(dsize / 8, std::vector(8)); - std::vector> de_ct(dsize / 8, - std::vector(8)); + std::vector> pt(dsize / 8, + std::vector(8)); + std::vector> ct(dsize / 8, + std::vector(8)); + std::vector> de_ct( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize; ++i) - pt[i / 8][i & 7] = BigNumber((unsigned int)(i * 1024) + 999); + pt[i / 8][i & 7] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -107,11 +116,13 @@ static void BM_Encrypt_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize, std::vector(8)); - std::vector> ct(dsize, std::vector(8)); + std::vector> pt(dsize, + std::vector(8)); + std::vector> ct(dsize, + std::vector(8)); for (size_t i = 0; i < dsize; ++i) - pt[i][0] = BigNumber((unsigned int)(i * 1024) + 999); + pt[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); for (auto _ : state) { #pragma omp parallel for @@ -127,11 +138,13 @@ static void BM_Encrypt_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize / 8, std::vector(8)); - std::vector> ct(dsize / 8, std::vector(8)); + std::vector> pt(dsize / 8, + std::vector(8)); + std::vector> ct(dsize / 8, + std::vector(8)); for (size_t i = 0; i < dsize; ++i) - pt[i / 8][i & 7] = BigNumber((unsigned int)(i * 1024) + 999); + pt[i / 8][i & 7] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); for (auto _ : state) { #pragma omp parallel for @@ -148,12 +161,15 @@ static void BM_Decrypt_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize, std::vector(8)); - std::vector> ct(dsize, std::vector(8)); - std::vector> de_ct(dsize, std::vector(8)); + std::vector> pt(dsize, + std::vector(8)); + std::vector> ct(dsize, + std::vector(8)); + std::vector> de_ct( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) - pt[i][0] = BigNumber((unsigned int)(i * 1024) + 999); + pt[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); @@ -174,13 +190,15 @@ static void BM_Decrypt_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize / 8, std::vector(8)); - std::vector> ct(dsize / 8, std::vector(8)); - std::vector> de_ct(dsize / 8, - std::vector(8)); + std::vector> pt(dsize / 8, + std::vector(8)); + std::vector> ct(dsize / 8, + std::vector(8)); + std::vector> de_ct( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize; ++i) - pt[i / 8][i & 7] = BigNumber((unsigned int)(i * 1024) + 999); + pt[i / 8][i & 7] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index 0effcf2..369e3ae 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -16,18 +16,20 @@ static void BM_Add_CTCT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, - std::vector(8, 65535)); - std::vector> b(dsize, - std::vector(8, 65535)); - std::vector> ct_a(dsize, std::vector(8)); - std::vector> ct_b(dsize, std::vector(8)); + std::vector> a( + dsize, std::vector(8, 65535)); + std::vector> b( + dsize, std::vector(8, 65535)); + std::vector> ct_a( + dsize, std::vector(8)); + std::vector> ct_b( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = BigNumber((unsigned int)(i * 1024) + 999); + a[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); key.pub_key->encrypt(ct_a[i], a[i]); - b[i][0] = BigNumber((unsigned int)(i * 1024) + 999); + b[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); key.pub_key->encrypt(ct_b[i], b[i]); } @@ -46,19 +48,19 @@ static void BM_Add_CTCT_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize / 8, - std::vector(8, 65535)); - std::vector> b(dsize / 8, - std::vector(8, 65535)); - std::vector> ct_a(dsize / 8, - std::vector(8)); - std::vector> ct_b(dsize / 8, - std::vector(8)); + std::vector> a( + dsize / 8, std::vector(8, 65535)); + std::vector> b( + dsize / 8, std::vector(8, 65535)); + std::vector> ct_a( + dsize / 8, std::vector(8)); + std::vector> ct_b( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - b[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -83,15 +85,16 @@ static void BM_Add_CTPT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, - std::vector(8, 65535)); - std::vector> b(dsize, - std::vector(8, 65535)); - std::vector> ct_a(dsize, std::vector(8)); + std::vector> a( + dsize, std::vector(8, 65535)); + std::vector> b( + dsize, std::vector(8, 65535)); + std::vector> ct_a( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = BigNumber((unsigned int)(i * 1024) + 999); - b[i][0] = BigNumber((unsigned int)i * 1024 + 999); + a[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); + b[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); key.pub_key->encrypt(ct_a[i], a[i]); } @@ -109,17 +112,17 @@ static void BM_Add_CTPT_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize / 8, - std::vector(8, 65535)); - std::vector> b(dsize / 8, - std::vector(8, 65535)); - std::vector> ct_a(dsize / 8, - std::vector(8)); + std::vector> a( + dsize / 8, std::vector(8, 65535)); + std::vector> b( + dsize / 8, std::vector(8, 65535)); + std::vector> ct_a( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - b[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -142,15 +145,16 @@ static void BM_Mul_CTPT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, - std::vector(8, 65535)); - std::vector> b(dsize, - std::vector(8, 65535)); - std::vector> ct_a(dsize, std::vector(8)); + std::vector> a( + dsize, std::vector(8, 65535)); + std::vector> b( + dsize, std::vector(8, 65535)); + std::vector> ct_a( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = BigNumber((unsigned int)i * 1024 + 999); - b[i][0] = BigNumber((unsigned int)i * 1024 + 999); + a[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); + b[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); key.pub_key->encrypt(ct_a[i], a[i]); } @@ -169,17 +173,17 @@ static void BM_Mul_CTPT_buff8(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize / 8, - std::vector(8, 65535)); - std::vector> b(dsize / 8, - std::vector(8, 65535)); - std::vector> ct_a(dsize / 8, - std::vector(8)); + std::vector> a( + dsize / 8, std::vector(8, 65535)); + std::vector> b( + dsize / 8, std::vector(8, 65535)); + std::vector> ct_a( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - b[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -204,18 +208,20 @@ static void BM_Add_CTCT_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, - std::vector(8, 65535)); - std::vector> b(dsize, - std::vector(8, 65535)); - std::vector> ct_a(dsize, std::vector(8)); - std::vector> ct_b(dsize, std::vector(8)); + std::vector> a( + dsize, std::vector(8, 65535)); + std::vector> b( + dsize, std::vector(8, 65535)); + std::vector> ct_a( + dsize, std::vector(8)); + std::vector> ct_b( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = BigNumber((unsigned int)i * 1024 + 999); + a[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); key.pub_key->encrypt(ct_a[i], a[i]); - b[i][0] = BigNumber((unsigned int)i * 1024 + 999); + b[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); key.pub_key->encrypt(ct_b[i], b[i]); } @@ -238,19 +244,19 @@ static void BM_Add_CTCT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize / 8, - std::vector(8, 65535)); - std::vector> b(dsize / 8, - std::vector(8, 65535)); - std::vector> ct_a(dsize / 8, - std::vector(8)); - std::vector> ct_b(dsize / 8, - std::vector(8)); + std::vector> a( + dsize / 8, std::vector(8, 65535)); + std::vector> b( + dsize / 8, std::vector(8, 65535)); + std::vector> ct_a( + dsize / 8, std::vector(8)); + std::vector> ct_b( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - b[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -276,15 +282,16 @@ static void BM_Add_CTPT_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, - std::vector(8, 65535)); - std::vector> b(dsize, - std::vector(8, 65535)); - std::vector> ct_a(dsize, std::vector(8)); + std::vector> a( + dsize, std::vector(8, 65535)); + std::vector> b( + dsize, std::vector(8, 65535)); + std::vector> ct_a( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = BigNumber((unsigned int)i * 1024 + 999); - b[i][0] = BigNumber((unsigned int)i * 1024 + 999); + a[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); + b[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); key.pub_key->encrypt(ct_a[i], a[i]); } @@ -306,17 +313,17 @@ static void BM_Add_CTPT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize / 8, - std::vector(8, 65535)); - std::vector> b(dsize / 8, - std::vector(8, 65535)); - std::vector> ct_a(dsize / 8, - std::vector(8)); + std::vector> a( + dsize / 8, std::vector(8, 65535)); + std::vector> b( + dsize / 8, std::vector(8, 65535)); + std::vector> ct_a( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - b[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); } key.pub_key->encrypt(ct_a[i], a[i]); @@ -340,15 +347,16 @@ static void BM_Mul_CTPT_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, - std::vector(8, 65535)); - std::vector> b(dsize, - std::vector(8, 65535)); - std::vector> ct_a(dsize, std::vector(8)); + std::vector> a( + dsize, std::vector(8, 65535)); + std::vector> b( + dsize, std::vector(8, 65535)); + std::vector> ct_a( + dsize, std::vector(8)); for (size_t i = 0; i < dsize; ++i) { - a[i][0] = BigNumber((unsigned int)i * 1024 + 999); - b[i][0] = BigNumber((unsigned int)i * 1024 + 999); + a[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); + b[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); key.pub_key->encrypt(ct_a[i], a[i]); } @@ -371,17 +379,17 @@ static void BM_Mul_CTPT_buff8_OMP(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize / 8, - std::vector(8, 65535)); - std::vector> b(dsize / 8, - std::vector(8, 65535)); - std::vector> ct_a(dsize / 8, - std::vector(8)); + std::vector> a( + dsize / 8, std::vector(8, 65535)); + std::vector> b( + dsize / 8, std::vector(8, 65535)); + std::vector> ct_a( + dsize / 8, std::vector(8)); for (size_t i = 0; i < dsize / 8; ++i) { for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - b[i][j] = BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); + b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); } key.pub_key->encrypt(ct_a[i], a[i]); diff --git a/benchmark/main.cpp b/benchmark/main.cpp index 63ecedd..da89895 100644 --- a/benchmark/main.cpp +++ b/benchmark/main.cpp @@ -1,23 +1,11 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#ifdef IPCL_USE_QAT -#include -#endif // IPCL_USE_QAT - #include int main(int argc, char** argv) { -#ifdef IPCL_USE_QAT - acquire_qat_devices(); -#endif // IPCL_USE_QAT - benchmark::Initialize(&argc, argv); benchmark::RunSpecifiedBenchmarks(); -#ifdef IPCL_USE_QAT - release_qat_devices(); -#endif - return 0; } diff --git a/cmake/heqat/heqat.cmake b/cmake/heqat/heqat.cmake deleted file mode 100644 index 53a2654..0000000 --- a/cmake/heqat/heqat.cmake +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright (C) 2021 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -include(ExternalProject) -MESSAGE(STATUS "Configuring HE QAT") -set(HEQAT_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_he_qat) -set(HEQAT_GIT_REPO_URL git@github.com:intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.project-destiny.git) -set(HEQAT_GIT_LABEL development) -set(HEQAT_SRC_DIR ${HEQAT_PREFIX}/src/ext_he_qat/) - -set(HEQAT_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS}") - -ExternalProject_Add( - ext_he_qat - GIT_REPOSITORY ${HEQAT_GIT_REPO_URL} - GIT_TAG ${HEQAT_GIT_LABEL} - PREFIX ${HEQAT_PREFIX} - INSTALL_DIR ${HEQAT_PREFIX} - CMAKE_ARGS ${HEQAT_CXX_FLAGS} - -DCMAKE_INSTALL_PREFIX=${HEQAT_PREFIX} - -DHE_QAT_MISC=OFF - -DIPPCP_PREFIX_PATH=${IPPCRYPTO_PREFIX}/lib/cmake - #-DARCH=${HEQAT_ARCH} - #-DCMAKE_ASM_NASM_COMPILER=nasm - #-DCMAKE_BUILD_TYPE=Release - UPDATE_COMMAND "" -) - -add_dependencies(ext_he_qat libippcrypto) - -set(HEQAT_INC_DIR ${HEQAT_PREFIX}/include) #${HEQAT_SRC_DIR}/install/include) - -# Bring up CPA variables -include(${CMAKE_CURRENT_LIST_DIR}/icp/CMakeLists.txt) -list(APPEND HEQAT_INC_DIR ${ICP_INC_DIR}) - -add_library(libhe_qat INTERFACE) -add_dependencies(libhe_qat ext_he_qat) - -ExternalProject_Get_Property(ext_he_qat SOURCE_DIR BINARY_DIR) - -target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libcpa_sample_utils.a) # ${HEQAT_PREFIX}/lib/libhe_qat_misc.a) -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat_debug.so) -else() - target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat.so) -endif() -target_include_directories(libhe_qat SYSTEM INTERFACE ${HEQAT_INC_DIR}) diff --git a/cmake/heqat/icp/CMakeLists.txt b/cmake/heqat/icp/CMakeLists.txt deleted file mode 100644 index ee0617a..0000000 --- a/cmake/heqat/icp/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ - -if(DEFINED ENV{ICP_ROOT}) - message(STATUS "Environment variable ICP_ROOT is defined as $ENV{ICP_ROOT}.") -else() - message(FATAL_ERROR "Environment variable ICP_ROOT must be defined. Try export ICP_ROOT=") -endif() - -set(ICP_ROOT $ENV{ICP_ROOT}) -set(ICP_BUILDOUTPUT_PATH ${ICP_ROOT}/build) -set(ICP_BUILDSYSTEM_PATH ${ICP_ROOT}/quickassist/build_system) -set(ICP_API_DIR ${ICP_ROOT}/quickassist) -set(ICP_LAC_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer) -set(ICP_OSAL_DIR ${ICP_ROOT}/quickassist/utilities/oasl) -set(ICP_ADF_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/qat_direct) -set(CMN_ROOT ${ICP_ROOT}/quickassist/utilities/libusdm_drv) - -#list(APPEND COMMON_INC_DIR ${ICP_API_DIR}/include -# ${ICP_LAC_DIR}/include -# ${ICP_ADF_DIR}/include -# ${CMN_ROOT} -#) - -set(ICP_INC_DIR ${ICP_API_DIR}/include - ${ICP_LAC_DIR}/include - ${ICP_ADF_DIR}/include - ${CMN_ROOT} - ${ICP_API_DIR}/include/dc - ${ICP_API_DIR}/include/lac) - -#Macros for the test case -add_definitions(-DDO_CRYPTO) -add_definitions(-DUSER_SPACE) -add_compile_options(-fPIC) diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 385db16..6bf7a0c 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -24,6 +24,7 @@ target_include_directories(ipcl PUBLIC $ ) + target_include_directories(ipcl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PUBLIC $ @@ -53,10 +54,6 @@ else() target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) endif() -if(IPCL_ENABLE_QAT) - target_link_libraries(ipcl PRIVATE libhe_qat) -endif() - set_target_properties(ipcl PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(ipcl PROPERTIES VERSION ${IPCL_VERSION}) if(IPCL_DEBUG) diff --git a/ipcl/bignum.cpp b/ipcl/bignum.cpp index d49708a..b5adab3 100644 --- a/ipcl/bignum.cpp +++ b/ipcl/bignum.cpp @@ -25,7 +25,7 @@ // ////////////////////////////////////////////////////////////////////// -// namespace ipcl { +namespace ipcl { BigNumber::~BigNumber() { delete[](Ipp8u*) m_pBN; } @@ -138,7 +138,7 @@ BigNumber& BigNumber::operator=(const BigNumber& bn) { Ipp32u* bnData; ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); - delete[](Ipp8u*) m_pBN; + delete (Ipp8u*)m_pBN; create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); } return *this; @@ -509,34 +509,4 @@ void BigNumber::num2char(std::vector& dest) const { dest.assign(bnData, bnData + len); } -bool BigNumber::fromBin(BigNumber& bn, const unsigned char* data, int len) { - if (len <= 0) return false; - - // Create BigNumber containg input data passed as argument - bn = BigNumber(reinterpret_cast(data), (len / 4)); - Ipp32u* ref_bn_data_ = NULL; - ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); - - // Convert it to little endian format - unsigned char* data_ = reinterpret_cast(ref_bn_data_); - for (int i = 0; i < len; i++) data_[i] = data[len - 1 - i]; - - return true; -} - -bool BigNumber::toBin(unsigned char* data, int len, const BigNumber& bn) { - if (len <= 0) return false; - - // Extract raw vector of data in little endian format - int bitSize = 0; - Ipp32u* ref_bn_data_ = NULL; - ippsRef_BN(NULL, &bitSize, &ref_bn_data_, BN(bn)); - - // Revert it to big endian format - int bitSizeLen = BITSIZE_WORD(bitSize) * 4; - unsigned char* data_ = reinterpret_cast(ref_bn_data_); - for (int i = 0; i < bitSizeLen; i++) data[len - 1 - i] = data_[i]; - - return true; -} -//} // namespace ipcl +} // namespace ipcl diff --git a/ipcl/include/ipcl/bignum.h b/ipcl/include/ipcl/bignum.h index dd42d28..fe62dc1 100644 --- a/ipcl/include/ipcl/bignum.h +++ b/ipcl/include/ipcl/bignum.h @@ -14,17 +14,15 @@ * limitations under the License. *******************************************************************************/ -//#ifndef _BIGNUM_H_ -//#define _BIGNUM_H_ -#if !defined _BIGNUMBER_H_ -#define _BIGNUMBER_H_ +#ifndef _BIGNUM_H_ +#define _BIGNUM_H_ #include #include #include -// namespace ipcl { +namespace ipcl { class BigNumber { public: @@ -124,10 +122,6 @@ class BigNumber { friend std::ostream& operator<<(std::ostream& os, const BigNumber& a); void num2char(std::vector& dest) const; - // Support QAT data format - static bool fromBin(BigNumber& bn, const unsigned char* data, int len); - static bool toBin(unsigned char* data, int len, const BigNumber& bn); - protected: bool create(const Ipp32u* pData, int length, IppsBigNumSGN sgn = IppsBigNumPOS); @@ -137,5 +131,5 @@ class BigNumber { constexpr int BITSIZE_WORD(int n) { return (((n) + 31) >> 5); } constexpr int BITSIZE_DWORD(int n) { return (((n) + 63) >> 6); } -//} // namespace ipcl +} // namespace ipcl #endif // _BIGNUM_H_ diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index bc7613e..b578b60 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -4,200 +4,13 @@ #include "ipcl/mod_exp.hpp" #include -#include #include #include "ipcl/util.hpp" -#ifdef IPCL_USE_QAT -#include -#include -#endif - namespace ipcl { -#ifdef IPCL_USE_QAT - -// Multiple input QAT ModExp interface to offload computation to QAT -static std::vector heQatBnModExp( - const std::vector& base, const std::vector& exponent, - const std::vector& modulus) { - static unsigned int counter = 0; - int nbits = modulus.front().BitSize(); - int length = BITSIZE_WORD(nbits) * 4; - nbits = 8 * length; - - HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; - - // TODO(fdiasmor): Try replace calloc by alloca to see impact on performance. - unsigned char* bn_base_data_[IPCL_CRYPTO_MB_SIZE]; - unsigned char* bn_exponent_data_[IPCL_CRYPTO_MB_SIZE]; - unsigned char* bn_modulus_data_[IPCL_CRYPTO_MB_SIZE]; - unsigned char* bn_remainder_data_[IPCL_CRYPTO_MB_SIZE]; - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - bn_base_data_[i] = reinterpret_cast( - malloc(length * sizeof(unsigned char))); - bn_exponent_data_[i] = reinterpret_cast( - malloc(length * sizeof(unsigned char))); - bn_modulus_data_[i] = reinterpret_cast( - malloc(length * sizeof(unsigned char))); - bn_remainder_data_[i] = reinterpret_cast( - malloc(length * sizeof(unsigned char))); - - ERROR_CHECK( - bn_base_data_[i] != nullptr && bn_exponent_data_[i] != nullptr && - bn_modulus_data_[i] != nullptr && bn_remainder_data_[i] != nullptr, - "qatMultiBuffExp: alloc memory for error"); - - memset(bn_base_data_[i], 0, length); - memset(bn_exponent_data_[i], 0, length); - memset(bn_modulus_data_[i], 0, length); - memset(bn_remainder_data_[i], 0, length); - } - - // TODO(fdiasmor): Define and use IPCL_QAT_BATCH_SIZE instead of - // IPCL_CRYPTO_MB_SIZE. - for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - bool ret = BigNumber::toBin(bn_base_data_[i], length, base[i]); - if (!ret) { - printf("bn_base_data_: failed at bigNumberToBin()\n"); - exit(1); - } - ret = BigNumber::toBin(bn_exponent_data_[i], length, exponent[i]); - if (!ret) { - printf("bn_exponent_data_: failed at bigNumberToBin()\n"); - exit(1); - } - ret = BigNumber::toBin(bn_modulus_data_[i], length, modulus[i]); - if (!ret) { - printf("bn_modulus_data_: failed at bigNumberToBin()\n"); - exit(1); - } - - unsigned char* bn_base_ = - reinterpret_cast(bn_base_data_[i]); - unsigned char* bn_exponent_ = - reinterpret_cast(bn_exponent_data_[i]); - unsigned char* bn_modulus_ = - reinterpret_cast(bn_modulus_data_[i]); - unsigned char* bn_remainder_ = - reinterpret_cast(bn_remainder_data_[i]); - - status = HE_QAT_bnModExp(bn_remainder_, bn_base_, bn_exponent_, bn_modulus_, - nbits); - if (HE_QAT_STATUS_SUCCESS != status) { - PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); - } - } - getBnModExpRequest(IPCL_CRYPTO_MB_SIZE); - - std::vector remainder(IPCL_CRYPTO_MB_SIZE, 0); - // Collect results and pack them into BigNumber - for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - unsigned char* bn_remainder_ = bn_remainder_data_[i]; - bool ret = BigNumber::fromBin(remainder[i], bn_remainder_, length); - if (!ret) { - printf("bn_remainder_data_: failed at bignumbertobin()\n"); - exit(1); - } - } - - for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - free(bn_base_data_[i]); - bn_base_data_[i] = NULL; - free(bn_exponent_data_[i]); - bn_exponent_data_[i] = NULL; - free(bn_modulus_data_[i]); - bn_modulus_data_[i] = NULL; - } - - for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - free(bn_remainder_data_[i]); - bn_remainder_data_[i] = NULL; - } - - return remainder; -} - -// Single input QAT ModExp interface to offload computation to QAT -static BigNumber heQatBnModExp(const BigNumber& base, const BigNumber& exponent, - const BigNumber& modulus) { - static unsigned int counter = 0; - int nbits = modulus.BitSize(); - int length = BITSIZE_WORD(nbits) * 4; - nbits = 8 * length; - - HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; - - // TODO(fdiasmor): Try replace calloc by alloca to see impact on performance. - unsigned char* bn_base_data_ = NULL; - unsigned char* bn_exponent_data_ = NULL; - unsigned char* bn_modulus_data_ = NULL; - unsigned char* bn_remainder_data_ = NULL; - - bn_base_data_ = - reinterpret_cast(malloc(length * sizeof(unsigned char))); - bn_exponent_data_ = - reinterpret_cast(malloc(length * sizeof(unsigned char))); - bn_modulus_data_ = - reinterpret_cast(malloc(length * sizeof(unsigned char))); - bn_remainder_data_ = - reinterpret_cast(malloc(length * sizeof(unsigned char))); - - ERROR_CHECK(bn_base_data_ != nullptr && bn_exponent_data_ != nullptr && - bn_modulus_data_ != nullptr && bn_remainder_data_ != nullptr, - "qatMultiBuffExp: alloc memory for error"); - - memset(bn_base_data_, 0, length); - memset(bn_exponent_data_, 0, length); - memset(bn_modulus_data_, 0, length); - memset(bn_remainder_data_, 0, length); - - bool ret = BigNumber::toBin(bn_base_data_, length, base); - if (!ret) { - printf("bn_base_data_: failed at bignumbertobin()\n"); - exit(1); - } - ret = BigNumber::toBin(bn_exponent_data_, length, exponent); - if (!ret) { - printf("bn_exponent_data_: failed at bignumbertobin()\n"); - exit(1); - } - ret = BigNumber::toBin(bn_modulus_data_, length, modulus); - if (!ret) { - printf("bn_modulus_data_: failed at bignumbertobin()\n"); - exit(1); - } - - status = HE_QAT_bnModExp(bn_remainder_data_, bn_base_data_, bn_exponent_data_, - bn_modulus_data_, nbits); - if (HE_QAT_STATUS_SUCCESS != status) { - PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); - } - getBnModExpRequest(1); - - // Collect result and pack it into BigNumber - BigNumber remainder; - ret = BigNumber::fromBin(remainder, bn_remainder_data_, length); - if (!ret) { - printf("bn_remainder_data_: failed at bignumbertobin()\n"); - exit(1); - } - - free(bn_base_data_); - bn_base_data_ = NULL; - free(bn_exponent_data_); - bn_exponent_data_ = NULL; - free(bn_modulus_data_); - bn_modulus_data_ = NULL; - free(bn_remainder_data_); - bn_remainder_data_ = NULL; - - return remainder; -} -#endif // IPCL_USE_QAT - static std::vector ippMBModExp(const std::vector& base, const std::vector& pow, const std::vector& m) { @@ -339,11 +152,6 @@ static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, std::vector ippModExp(const std::vector& base, const std::vector& pow, const std::vector& m) { -#ifdef IPCL_USE_QAT - std::vector remainder(IPCL_CRYPTO_MB_SIZE); - remainder = heQatBnModExp(base, pow, m); - return remainder; -#else #ifdef IPCL_CRYPTO_MB_MOD_EXP return ippMBModExp(base, pow, m); #else @@ -351,17 +159,12 @@ std::vector ippModExp(const std::vector& base, for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) res[i] = ippSBModExp(base[i], pow[i], m[i]); return res; -#endif // else -#endif // IPCL_USE_QAT +#endif } BigNumber ippModExp(const BigNumber& base, const BigNumber& pow, const BigNumber& m) { -#ifdef IPCL_USE_QAT - return heQatBnModExp(base, pow, m); -#else return ippSBModExp(base, pow, m); -#endif // IPCL_USE_QAT } } // namespace ipcl diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 1be4b73..bca944a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -20,8 +20,3 @@ if(IPCL_ENABLE_OMP) find_package(OpenMP REQUIRED) target_link_libraries(unittest_ipcl PRIVATE OpenMP::OpenMP_CXX) endif() - -# enable QAT unittests -if(IPCL_ENABLE_QAT) - target_link_libraries(unittest_ipcl PRIVATE libhe_qat) -endif() diff --git a/test/main.cpp b/test/main.cpp index a27eecf..0ec6f12 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -1,29 +1,13 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#ifdef IPCL_USE_QAT -#include -#endif // IPCL_USE_QAT - #include #include int main(int argc, char** argv) { -#ifdef IPCL_USE_QAT - // Initialize QAT context - acquire_qat_devices(); -#endif // IPCL_USE_QAT - // Use system clock for seed srand(time(nullptr)); ::testing::InitGoogleTest(&argc, argv); - int status = RUN_ALL_TESTS(); - -#ifdef IPCL_USE_QAT - // Destroy QAT context - release_qat_devices(); -#endif - - return status; + return RUN_ALL_TESTS(); } diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index c88eaba..931b0ac 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -17,11 +17,11 @@ TEST(CryptoTest, CryptoTest) { ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector ct(8); - std::vector dt(8); + std::vector ct(8); + std::vector dt(8); std::vector pt(8); - std::vector ptbn(8); + std::vector ptbn(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -45,8 +45,9 @@ TEST(CryptoTest, CryptoTest) { } #ifdef IPCL_USE_OMP -void Encryption(int num_threads, std::vector>& v_ct, - const std::vector>& v_ptbn, +void Encryption(int num_threads, + std::vector>& v_ct, + const std::vector>& v_ptbn, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { @@ -54,8 +55,9 @@ void Encryption(int num_threads, std::vector>& v_ct, } } -void Decryption(int num_threads, std::vector>& v_dt, - const std::vector>& v_ct, +void Decryption(int num_threads, + std::vector>& v_dt, + const std::vector>& v_ct, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { @@ -69,14 +71,14 @@ TEST(CryptoTest, CryptoTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector> v_ct(num_threads, - std::vector(8)); - std::vector> v_dt(num_threads, - std::vector(8)); + std::vector> v_ct( + num_threads, std::vector(8)); + std::vector> v_dt( + num_threads, std::vector(8)); std::vector> v_pt(num_threads, std::vector(8)); - std::vector> v_ptbn(num_threads, - std::vector(8)); + std::vector> v_ptbn( + num_threads, std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); @@ -108,18 +110,18 @@ TEST(CryptoTest, CryptoTest_OMP) { #endif // IPCL_USE_OMP TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { - BigNumber p = + ipcl::BigNumber p = "0xff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c" "8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b4" "0a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff76" "4dd8b091f11a0943a2dd2b983b0df02f4c4d00b413"; - BigNumber q = + ipcl::BigNumber q = "0xdacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d" "9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de70" "72a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49b" "aa0f610bad100cdf47cc86e5034e2a0b2179e04ec7"; - BigNumber n = p * q; + ipcl::BigNumber n = p * q; int n_length = n.BitSize(); ipcl::PublicKey* public_key = new ipcl::PublicKey(n, n_length); @@ -127,12 +129,12 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { ipcl::keyPair key = {public_key, private_key}; - std::vector ptbn(8); - std::vector ct(8); - std::vector dt(8); - std::vector ir(8); + std::vector ptbn(8); + std::vector ct(8); + std::vector dt(8); + std::vector ir(8); - BigNumber c1 = + ipcl::BigNumber c1 = "0x1fb7f08a42deb47876e4cbdc3f0b172c033563a696ad7a7c76fa5971b793fa488dcdd6" "bd65c7c5440d67d847cb89ccca468b2c96763fff5a5ece8330251112d65e59b7da94cfe9" "309f441ccc8f59c67dec75113d37b1ee929c8d4ce6b5e561a30a91104b0526de892e4eff" @@ -149,7 +151,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "b98ccb676367b7b3b269c670cd0210edf70ad9cb337f766af75fe06d18b3f7f7c2eae656" "5ff2815c2c09b1a1f5"; - BigNumber c2 = + ipcl::BigNumber c2 = "0x61803645f2798c06f2c08fc254eee612c55542051c8777d6ce69ede9c84a179afb2081" "167494dee727488ae5e9b56d98f4fcf132514616859fc854fbd3acf6aecd97324ac3f2af" "fa9f44864a9afc505754aa3b564b4617e887d6aa1f88095bccf6b47f458566f9d85e80fc" @@ -166,7 +168,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "d6f1d6864f1fd3e2e3937e00d391ad330b443aec85528571740ed5538188c32caab27c7b" "f437df2bb97cb90e02"; - BigNumber c1c2 = + ipcl::BigNumber c1c2 = "0x309f6e614d875e3bb0a77eedeb8895e7c6f297f161f576aef4f8b72bb5b81ef78b831a" "af134b09fe8697159cfd678c49920cb790e36580c5201a96848d7242fceb025808dd26b5" "0ff573ffca3f65e51b3b9fe85c7e44f5c8df0a9e524f64a5acc5c62cba7475978eb55e08" @@ -183,9 +185,9 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "a6d47f9af6e68e18960fa5916cc48994334354d6303312b8e96602766bec337a8a92c596" "b21b6038828a6c9744"; - BigNumber m1m2 = "0x616263646566676869606a6b6c6d6e6f"; + ipcl::BigNumber m1m2 = "0x616263646566676869606a6b6c6d6e6f"; - BigNumber r0 = + ipcl::BigNumber r0 = "0x57fb19590c31dc7c034b2a889cf4037ce3db799909c1eb0adb6199d8e96791daca9018" "891f34309daff32dced4af7d793d16734d055e28023acab7295956bfbfdf62bf0ccb2ed3" "1d5d176ca8b404e93007565fb6b72c33a512b4dc4f719231d62e27e34c3733929af32247" @@ -194,7 +196,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "27991c44a43750c24ed0825718ad14cfb9c6b40b78ff3d25f71741f2def1c9d420d4b0fa" "1e0a02e7851b5ec6a81133a368b80d1500b0f28fc653d2e6ff4366236dbf80ae3b4beae3" "5e04579f2c"; - BigNumber r1 = + ipcl::BigNumber r1 = "0x6ee8ed76227672a7bcaa1e7f152c2ea39f2fa225f0713f58210c59b2270b110e38b650" "69aaedbeffc713c021336cc12f65227cc0357ca531c07c706e7224c2c11c3145bc0a05b1" "64f426ec03350820f9f416377e8720ddb577843cae929178bfe5772e2cc1e9b94e8fce81" @@ -218,10 +220,10 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { ipcl::EncryptedNumber a(key.pub_key, ct[0]); ipcl::EncryptedNumber b(key.pub_key, ct[1]); ipcl::EncryptedNumber sum = a + b; - BigNumber res = sum.getBN(); + ipcl::BigNumber res = sum.getBN(); - std::vector ct12(8); - std::vector dt12(8); + std::vector ct12(8); + std::vector dt12(8); for (int i = 0; i < 8; i++) { ct12[i] = res; } diff --git a/test/test_ops.cpp b/test/test_ops.cpp index e9ea896..025f3b4 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -14,8 +14,10 @@ #include "ipcl/keygen.hpp" #include "ipcl/ops.hpp" -void CtPlusCt(std::vector& res, const std::vector& ct1, - const std::vector& ct2, const ipcl::keyPair key) { +void CtPlusCt(std::vector& res, + const std::vector& ct1, + const std::vector& ct2, + const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { ipcl::EncryptedNumber a(key.pub_key, ct1[i]); ipcl::EncryptedNumber b(key.pub_key, ct2[i]); @@ -24,37 +26,40 @@ void CtPlusCt(std::vector& res, const std::vector& ct1, } } -void CtPlusCtArray(std::vector& res, - const std::vector& ct1, - const std::vector& ct2, const ipcl::keyPair key) { +void CtPlusCtArray(std::vector& res, + const std::vector& ct1, + const std::vector& ct2, + const ipcl::keyPair key) { ipcl::EncryptedNumber a(key.pub_key, ct1); ipcl::EncryptedNumber b(key.pub_key, ct2); ipcl::EncryptedNumber sum = a + b; res = sum.getArrayBN(); } -void CtPlusPt(std::vector& res, const std::vector& ct1, +void CtPlusPt(std::vector& res, + const std::vector& ct1, const std::vector& pt2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { ipcl::EncryptedNumber a(key.pub_key, ct1[i]); - BigNumber b = pt2[i]; + ipcl::BigNumber b = pt2[i]; ipcl::EncryptedNumber sum = a + b; res[i] = sum.getBN(); } } -void CtPlusPtArray(std::vector& res, - const std::vector& ct1, - const std::vector& ptbn2, +void CtPlusPtArray(std::vector& res, + const std::vector& ct1, + const std::vector& ptbn2, const ipcl::keyPair key) { ipcl::EncryptedNumber a(key.pub_key, ct1); ipcl::EncryptedNumber sum = a + ptbn2; res = sum.getArrayBN(); } -void CtMultiplyPt(std::vector& res, - const std::vector& ct1, - const std::vector& pt2, const ipcl::keyPair key) { +void CtMultiplyPt(std::vector& res, + const std::vector& ct1, + const std::vector& pt2, + const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { ipcl::EncryptedNumber a(key.pub_key, ct1[i]); ipcl::EncryptedNumber sum = a * pt2[i]; @@ -62,9 +67,9 @@ void CtMultiplyPt(std::vector& res, } } -void CtMultiplyPtArray(std::vector& res, - const std::vector& ct1, - const std::vector& pt2, +void CtMultiplyPtArray(std::vector& res, + const std::vector& ct1, + const std::vector& pt2, const ipcl::keyPair key) { ipcl::EncryptedNumber a(key.pub_key, ct1); ipcl::EncryptedNumber b(key.pub_key, pt2); @@ -72,12 +77,13 @@ void CtMultiplyPtArray(std::vector& res, res = sum.getArrayBN(); } -void AddSub(std::vector& res, const std::vector& ct1, - const std::vector& ct2, const ipcl::keyPair key) { +void AddSub(std::vector& res, + const std::vector& ct1, + const std::vector& ct2, const ipcl::keyPair key) { for (int i = 0; i < 8; i++) { ipcl::EncryptedNumber a(key.pub_key, ct1[i]); ipcl::EncryptedNumber b(key.pub_key, ct2[i]); - BigNumber m1(2); + ipcl::BigNumber m1(2); a = a + b * m1; ipcl::EncryptedNumber sum = a + b; res[i] = sum.getBN(); @@ -87,11 +93,11 @@ void AddSub(std::vector& res, const std::vector& ct1, TEST(OperationTest, CtPlusCtTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -128,11 +134,11 @@ TEST(OperationTest, CtPlusCtTest) { TEST(OperationTest, CtPlusCtArrayTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -169,11 +175,11 @@ TEST(OperationTest, CtPlusCtArrayTest) { TEST(OperationTest, CtPlusPtTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8); + std::vector ptbn1(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -208,11 +214,11 @@ TEST(OperationTest, CtPlusPtTest) { TEST(OperationTest, CtPlusPtArrayTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -248,11 +254,11 @@ TEST(OperationTest, CtPlusPtArrayTest) { TEST(OperationTest, CtMultiplyPtTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -288,11 +294,11 @@ TEST(OperationTest, CtMultiplyPtTest) { TEST(OperationTest, CtMultiplyZeroPtTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8, 0); - std::vector ptbn1(8), ptbn2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -327,11 +333,11 @@ TEST(OperationTest, CtMultiplyZeroPtTest) { TEST(OperationTest, CtMultiplyPtArrayTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8); - std::vector dt(8), res(8); + std::vector ct1(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -367,11 +373,11 @@ TEST(OperationTest, CtMultiplyPtArrayTest) { TEST(OperationTest, AddSubTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector ct1(8), ct2(8); + std::vector dt(8), res(8); std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); + std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -405,9 +411,10 @@ TEST(OperationTest, AddSubTest) { } #ifdef IPCL_USE_OMP -void CtPlusCt_OMP(int num_threads, std::vector>& v_sum, - const std::vector>& v_ct1, - const std::vector>& v_ct2, +void CtPlusCt_OMP(int num_threads, + std::vector>& v_sum, + const std::vector>& v_ct1, + const std::vector>& v_ct2, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { @@ -420,14 +427,15 @@ void CtPlusCt_OMP(int num_threads, std::vector>& v_sum, } } -void CtPlusPt_OMP(int num_threads, std::vector>& v_sum, - const std::vector>& v_ct1, +void CtPlusPt_OMP(int num_threads, + std::vector>& v_sum, + const std::vector>& v_ct1, const std::vector>& v_pt2, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { - BigNumber b = v_pt2[i][j]; + ipcl::BigNumber b = v_pt2[i][j]; ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); ipcl::EncryptedNumber sum = a + b; v_sum[i][j] = sum.getBN(); @@ -436,14 +444,14 @@ void CtPlusPt_OMP(int num_threads, std::vector>& v_sum, } void CtPlusPtArray_OMP(int num_threads, - std::vector>& v_sum, - const std::vector>& v_ct1, + std::vector>& v_sum, + const std::vector>& v_ct1, const std::vector>& v_pt2, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { ipcl::EncryptedNumber a(key.pub_key, v_ct1[i]); - std::vector b(8); + std::vector b(8); for (int j = 0; j < 8; j++) { b[j] = v_pt2[i][j]; } @@ -453,26 +461,25 @@ void CtPlusPtArray_OMP(int num_threads, } void CtMultiplyPt_OMP(int num_threads, - std::vector>& v_product, - const std::vector>& v_ct1, + std::vector>& v_product, + const std::vector>& v_ct1, const std::vector>& v_pt2, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { for (int j = 0; j < 8; j++) { ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); - BigNumber b = v_pt2[i][j]; + ipcl::BigNumber b = v_pt2[i][j]; ipcl::EncryptedNumber product = a * b; v_product[i][j] = product.getBN(); } } } -void CtMultiplyPtArray_OMP(int num_threads, - std::vector>& v_product, - const std::vector>& v_ct1, - const std::vector>& v_pt2, - const ipcl::keyPair key) { +void CtMultiplyPtArray_OMP( + int num_threads, std::vector>& v_product, + const std::vector>& v_ct1, + const std::vector>& v_pt2, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { ipcl::EncryptedNumber a(key.pub_key, v_ct1[i]); @@ -487,22 +494,22 @@ TEST(OperationTest, CtPlusCtTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector> v_ct1(num_threads, - std::vector(8)); - std::vector> v_ct2(num_threads, - std::vector(8)); - std::vector> v_dt(num_threads, - std::vector(8)); - std::vector> v_sum(num_threads, - std::vector(8)); + std::vector> v_ct1( + num_threads, std::vector(8)); + std::vector> v_ct2( + num_threads, std::vector(8)); + std::vector> v_dt( + num_threads, std::vector(8)); + std::vector> v_sum( + num_threads, std::vector(8)); std::vector> v_pt1(num_threads, std::vector(8)); std::vector> v_pt2(num_threads, std::vector(8)); - std::vector> v_ptbn1(num_threads, - std::vector(8)); - std::vector> v_ptbn2(num_threads, - std::vector(8)); + std::vector> v_ptbn1( + num_threads, std::vector(8)); + std::vector> v_ptbn2( + num_threads, std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -553,20 +560,20 @@ TEST(OperationTest, CtPlusPtTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector> v_ct1(num_threads, - std::vector(8)); - std::vector> v_dt(num_threads, - std::vector(8)); - std::vector> v_sum(num_threads, - std::vector(8)); + std::vector> v_ct1( + num_threads, std::vector(8)); + std::vector> v_dt( + num_threads, std::vector(8)); + std::vector> v_sum( + num_threads, std::vector(8)); std::vector> v_pt1(num_threads, std::vector(8)); std::vector> v_pt2(num_threads, std::vector(8)); - std::vector> v_ptbn1(num_threads, - std::vector(8)); - std::vector> v_ptbn2(num_threads, - std::vector(8)); + std::vector> v_ptbn1( + num_threads, std::vector(8)); + std::vector> v_ptbn2( + num_threads, std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -616,20 +623,20 @@ TEST(OperationTest, CtPlusPtArrayTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector> v_ct1(num_threads, - std::vector(8)); - std::vector> v_dt(num_threads, - std::vector(8)); - std::vector> v_sum(num_threads, - std::vector(8)); + std::vector> v_ct1( + num_threads, std::vector(8)); + std::vector> v_dt( + num_threads, std::vector(8)); + std::vector> v_sum( + num_threads, std::vector(8)); std::vector> v_pt1(num_threads, std::vector(8)); std::vector> v_pt2(num_threads, std::vector(8)); - std::vector> v_ptbn1(num_threads, - std::vector(8)); - std::vector> v_ptbn2(num_threads, - std::vector(8)); + std::vector> v_ptbn1( + num_threads, std::vector(8)); + std::vector> v_ptbn2( + num_threads, std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); @@ -679,20 +686,20 @@ TEST(OperationTest, CtMultiplyPtTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector> v_ct1(num_threads, - std::vector(8)); - std::vector> v_dt(num_threads, - std::vector(8)); - std::vector> v_product(num_threads, - std::vector(8)); + std::vector> v_ct1( + num_threads, std::vector(8)); + std::vector> v_dt( + num_threads, std::vector(8)); + std::vector> v_product( + num_threads, std::vector(8)); std::vector> v_pt1(num_threads, std::vector(8)); std::vector> v_pt2(num_threads, std::vector(8)); - std::vector> v_ptbn1(num_threads, - std::vector(8)); - std::vector> v_ptbn2(num_threads, - std::vector(8)); + std::vector> v_ptbn1( + num_threads, std::vector(8)); + std::vector> v_ptbn2( + num_threads, std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); @@ -742,20 +749,20 @@ TEST(OperationTest, CtMultiplyPtArrayTest_OMP) { size_t num_threads = omp_get_max_threads(); - std::vector> v_ct1(num_threads, - std::vector(8)); - std::vector> v_dt(num_threads, - std::vector(8)); - std::vector> v_product(num_threads, - std::vector(8)); + std::vector> v_ct1( + num_threads, std::vector(8)); + std::vector> v_dt( + num_threads, std::vector(8)); + std::vector> v_product( + num_threads, std::vector(8)); std::vector> v_pt1(num_threads, std::vector(8)); std::vector> v_pt2(num_threads, std::vector(8)); - std::vector> v_ptbn1(num_threads, - std::vector(8)); - std::vector> v_ptbn2(num_threads, - std::vector(8)); + std::vector> v_ptbn1( + num_threads, std::vector(8)); + std::vector> v_ptbn2( + num_threads, std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); From 81cdff7bf82d2cfc69660f3f94fcd37abb33c722 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 7 Apr 2022 15:15:25 -0700 Subject: [PATCH 159/364] Add support to admit 1024 simultaneous requests in batch mode. --- he_qat/include/he_qat_types.h | 2 +- samples/test_bnModExp.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/he_qat/include/he_qat_types.h b/he_qat/include/he_qat_types.h index d2b9dfa..88d107e 100644 --- a/he_qat/include/he_qat_types.h +++ b/he_qat/include/he_qat_types.h @@ -13,7 +13,7 @@ extern "C" { #include -#define HE_QAT_BUFFER_SIZE 256 +#define HE_QAT_BUFFER_SIZE 1024 // Type definitions typedef enum { HE_QAT_SYNC = 1, HE_QAT_ASYNC = 2 } HE_QAT_EXEC_MODE; diff --git a/samples/test_bnModExp.cpp b/samples/test_bnModExp.cpp index 27003a0..4ef256a 100644 --- a/samples/test_bnModExp.cpp +++ b/samples/test_bnModExp.cpp @@ -18,7 +18,7 @@ int gDebugParam = 1; #endif -const unsigned int BATCH_SIZE = 48; +const unsigned int BATCH_SIZE = 1024; using namespace std::chrono; From ed96cbc88119798ffdfc858cf61f43247f20241e Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 8 Apr 2022 23:55:13 -0700 Subject: [PATCH 160/364] Incomplete draft. --- he_qat/he_qat_bn_ops.c | 212 ++++++++++++++++++++++++++++++++- he_qat/he_qat_context.c | 44 +++++-- he_qat/include/he_qat_bn_ops.h | 6 + he_qat/include/he_qat_types.h | 25 +++- 4 files changed, 269 insertions(+), 18 deletions(-) diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index 90f3257..7067585 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -26,6 +26,7 @@ double time_taken = 0.0; // Global buffer for the runtime environment HE_QAT_RequestBuffer he_qat_buffer; +HE_QAT_RequestBufferList outstanding_buffer; /// @brief /// @function @@ -98,12 +99,118 @@ static void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { #endif } +static void submit_request_list(HE_QAT_RequestBuffer* _buffer, + const HE_QAT_TaskRequestList* _requests) { +#ifdef HE_QAT_DEBUG + printf("Lock write request\n"); +#endif + if (0 == _requests->count) return; + + pthread_mutex_lock(&_buffer->mutex); + +#ifdef HE_QAT_DEBUG + printf("Wait lock write request. [buffer size: %d]\n", _buffer->count); +#endif + + while (_buffer->count >= HE_QAT_BUFFER_SIZE || + (HE_QAT_BUFFER_SIZE - _buffer->count + 1) < _requests->count) + pthread_cond_wait(&_buffer->any_free_slot, &_buffer->mutex); + + assert(_buffer->count < HE_QAT_BUFFER_SIZE); + assert(_requests->count <= (HE_QAT_BUFFER_SIZE - _buffer->count + 1)); + + for (unsigned int i = 0; i < _requests->count; i++) { + _buffer->data[_buffer->next_free_slot++] = _requests->request[i]; + _buffer->next_free_slot %= HE_QAT_BUFFER_SIZE; + } + _buffer->count += _requests->count; + + pthread_cond_signal(&_buffer->any_more_data); + pthread_mutex_unlock(&_buffer->mutex); +#ifdef HE_QAT_DEBUG + printf("Unlocked write request. [buffer size: %d]\n", _buffer->count); +#endif +} + +static void* get_buffer(HE_QAT_RequestBufferList* _list, unsigned int index) { + if (0 == index) return _list->data; + unsigned int j = 0; + void* curr = _list->next; + while (curr) { + if (index == ++j) break; + curr = _list->next; + } + return curr; +} + +static void* add_buffer(HE_QAT_RequestBufferList* _list) { return NULL; } + +static void del_buffer() { return; } + +/// @brief +/// @function +/// Thread-safe producer implementation for the shared outstanding request +/// buffer that stores request from multiple threads. +/// Stores requests in a buffer that will be sent to the HE QAT buffer. +static void push_request(HE_QAT_RequestBufferList* _outstanding_buffer, + void* args, unsigned int num_requests = 1) { +#ifdef HE_QAT_DEBUG + printf("Lock write outstanding requests\n"); +#endif + pthread_mutex_lock(&_outstanding_buffer->mutex); + +#ifdef HE_QAT_DEBUG + printf("Wait lock write request. [outstanding buffer size: %d]\n", + _outstanding_buffer->count); +#endif + // if (NULL == args) pthread_mutex_unlock(&_outstanding_buffer->mutex); + unsigned int list_size = _outstanding_buffer->size; + unsigned int buffer_size = list_size * HE_QAT_BUFFER_SIZE; + // TODO(fdiasmor): Dynamically expand the outstanding buffer + // while (buffer_size < num_requests && + // buffer_size < HE_QAT_LIST_SIZE * HE_QAT_BUFFER_SIZE) { + // _outstanding_buffer->data[list_size] = + //malloc(sizeof(HE_QAT_TaskRequest)*HE_QAT_BUFFER_SIZE); if + //(_outstanding_buffer) + // buffer_size = ++list_size * HE_QAT_BUFFER_SIZE; + // } + // Create more space, if required, to a certain extent + // For now, it assumes maximum number of requests per thread and per call is + // equal to HE_QAT_BUFFER_SIZE and maximum number of threads is + // HE_QAT_BUFFER_COUNT + while (_outstanding_buffer->count >= buffer_size || + (buffer_size - _outstanding_buffer->count + 1 < num_requests)) + pthread_cond_wait(&_outstanding_buffer->any_free_slot, + &_outstanding_buffer->mutex); + + assert(_outstanding_buffer->count < buffer_size); + assert(buffer_size - _outstanding_buffer->count + 1 >= num_requests); + + HE_QAT_TaskRequestList* requests = (HE_QAT_TaskRequestList*)args; + for (unsigned int i = 0; i < requests->count; i++) { + unsigned int index = _outstanding_buffer->next_free_slot / buffer_size; + unsigned int slot = _outstanding_buffer->next_free_slot % buffer_size; + _outstanding_buffer->data[index][slot] = requests->request[i]; + _outstanding_buffer->next_free_slot++; + _outstanding_buffer->next_free_slot %= buffer_size; + _outstanding_buffer->count++; + } + + pthread_cond_signal(&_outstanding_buffer->any_more_data); + pthread_mutex_unlock(&_outstanding_buffer->mutex); +#ifdef HE_QAT_DEBUG + printf("Unlocked write request. [outstanding buffer count: %d]\n", + _outstanding_buffer->count); +#endif +} + /// @brief /// @function /// Thread-safe consumer implementation for the shared request buffer. /// Read requests from a buffer to finally offload the work to QAT devices. static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) { void* item = NULL; + pthread_mutex_lock(&_buffer->mutex); // Wait while buffer is empty while (_buffer->count <= 0) @@ -125,6 +232,109 @@ static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) { return (HE_QAT_TaskRequest*)(item); } +/// @brief +/// @function +/// Thread-safe consumer implementation for the shared request buffer. +/// Read requests from a buffer to finally offload the work to QAT devices. +static void read_request_list(HE_QAT_TaskRequestList* _requests, + HE_QAT_RequestBuffer* _buffer) { + if (NULL == _requests) return; + + pthread_mutex_lock(&_buffer->mutex); + // Wait while buffer is empty + while (_buffer->count <= 0) + pthread_cond_wait(&_buffer->any_more_data, &_buffer->mutex); + + assert(_buffer->count > 0); + // assert(_buffer->count <= HE_QAT_BUFFER_SIZE); + + for (unsigned int i = 0; i < _buffer->count; i++) { + _requests->request[i] = _buffer->data[_buffer->next_data_slot++]; + _buffer->next_data_slot %= HE_QAT_BUFFER_SIZE; + } + _requests->count = _buffer->count; + _buffer->count = 0; + + pthread_cond_signal(&_buffer->any_free_slot); + pthread_mutex_unlock(&_buffer->mutex); + + return; +} + +/// @brief +/// @function +/// Thread-safe consumer implementation for the shared request buffer. +/// Read requests from a buffer to finally offload the work to QAT devices. +static void pull_request(HE_QAT_TaskRequestList* _requests, + HE_QAT_RequestBufferList* _outstanding_buffer, + unsigned int max_num_requests = 1) { + if (NULL == _requests) return; + + pthread_mutex_lock(&_outstanding_buffer->mutex); + + unsigned int list_size = _outstanding_buffer->size; + unsigned int buffer_size = list_size * HE_QAT_BUFFER_SIZE; + + // Wait while buffer is empty + while (_outstanding_buffer->count <= 0) + pthread_cond_wait(&_outstanding_buffer->any_more_data, + &_outstanding_buffer->mutex); + + assert(_outstanding_buffer->count > 0); + + unsigned int num_requests = (_outstanding_buffer->count <= max_num_requests) + ? _outstanding_buffer->count + : max_num_requests; + + assert(num_requests <= HE_QAT_BUFFER_SIZE); + + //_requests->count = 0; + for (unsigned int i = 0; i < num_requests; i++) { + unsigned int index = _outstanding_buffer->next_data_slot / buffer_size; + unsigned int slot = _outstanding_buffer->next_data_slot % buffer_size; + + _requests->request[i] = _outstanding_buffer->data[index][slot]; + //_requests->count++; + + _outstanding_buffer->next_data_slot++; + _outstanding_buffer->next_data_slot %= buffer_size; + //_outstanding_buffer->count--; + } + _requests->count = num_requests; + _outstanding_buffer->count -= num_requests; + + pthread_cond_signal(&_outstanding_buffer->any_free_slot); + pthread_mutex_unlock(&_outstanding_buffer->mutex); + + return; +} + +static void* schedule_requests(void* state) { + if (NULL == state) { + printf("Failed at buffer_manager: argument is NULL.\n"); + pthread_exit(NULL); + } + + int* active = (int*)state; + + HE_QAT_TaskRequestList outstanding_requests; + for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { + outstanding_requests->request[i] = NULL; + } + outstading_requests->count = 0; + + // this thread should receive signal from context to exit + while (active) { + // collect a set of requests from the outstanding buffer + pull_request(&outstanding_requests, &outstanding_buffer, + HE_QAT_BUFFER_SIZE); + // submit them to the HE QAT buffer for offloading + submit_request(&he_qat_buffer, &outstanding_requests); + } + + pthread_exit(NULL); +} + /// @brief /// @function start_inst_polling /// @param[in] HE_QAT_InstConfig Parameter values to start and poll instances. @@ -132,7 +342,7 @@ static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) { static void* start_inst_polling(void* _inst_config) { if (NULL == _inst_config) { printf( - "Failed at start_inst_polling: argument is NULL."); //,__FUNC__); + "Failed at start_inst_polling: argument is NULL.\n"); //,__FUNC__); pthread_exit(NULL); } diff --git a/he_qat/he_qat_context.c b/he_qat/he_qat_context.c index ab04e67..d91758a 100644 --- a/he_qat/he_qat_context.c +++ b/he_qat/he_qat_context.c @@ -26,16 +26,21 @@ #define NUM_ACTIVE_INSTANCES 8 +volatile int context_state = 0; + // Global variable declarations // HE_QAT_Inst he_qat_instances[HE_QAT_MAX_NUM_INST]; // pthread_attr_t he_qat_inst_attr[HE_QAT_MAX_NUM_INST]; // HE_QAT_InstConfig he_qat_inst_config[HE_QAT_MAX_NUM_INST]; // HE_QAT_RequestBuffer he_qat_buffer; +pthread_t buffer_manager; HE_QAT_Inst he_qat_instances[NUM_ACTIVE_INSTANCES]; pthread_attr_t he_qat_inst_attr[NUM_ACTIVE_INSTANCES]; HE_QAT_InstConfig he_qat_inst_config[NUM_ACTIVE_INSTANCES]; extern HE_QAT_RequestBuffer he_qat_buffer; +extern HE_QAT_RequestBufferList outstanding_buffer; +extern void* schedule_requests(void* state); extern void* start_perform_op(void* _inst_config); extern void stop_perform_op(void* _inst_config, unsigned num_inst); @@ -183,6 +188,29 @@ HE_QAT_STATUS acquire_qat_devices() { printf("Detached processing threads.\n"); #endif + // Set context state to active + context_state = 1; + + // Launch buffer manager thread to schedule incoming requests + if (0 != pthread_create(&buffer_manager, NULL, schedule_requests, + (void*)&context_state)) { + context_state = 0; + release_qat_devices(); + printf( + "Failed to complete QAT initialization while creating buffer " + "manager thread.\n"); + return HE_QAT_STATUS_FAIL; + } + + if (0 != pthread_detach(buffer_manager)) { + context_state = 0; + release_qat_devices(); + printf( + "Failed to complete QAT initialization while launching buffer " + "manager thread.\n"); + return HE_QAT_STATUS_FAIL; + } + return HE_QAT_STATUS_SUCCESS; } @@ -192,24 +220,16 @@ HE_QAT_STATUS acquire_qat_devices() { HE_QAT_STATUS release_qat_devices() { CpaStatus status = CPA_STATUS_FAIL; - // signal all qat instance to stop polling - // stop_inst_polling(); - // - // // Release QAT instances handles - // for (int i = 0; i < HE_QAT_MAX_NUM_INST; i++) { - // status = cpaCyStopInstance(he_qat_inst_config[i].inst_handle); - // if (CPA_STATUS_SUCCESS != status) { - // printf("Failed to stop QAT instance #%d\n",i); - // return HE_QAT_STATUS_FAIL; - // } - // } + if (0 == context_state) return HE_QAT_STATUS_SUCCESS; stop_perform_op(he_qat_inst_config, NUM_ACTIVE_INSTANCES); #ifdef _DESTINY_DEBUG_VERBOSE printf("Stopped polling and processing threads.\n"); #endif - // Deallocate memory of QAT InstConfig + // Deactivate context (this will cause the buffer manager thread to be + // terminated) + context_state = 0; // Stop QAT SSL service icp_sal_userStop(); diff --git a/he_qat/include/he_qat_bn_ops.h b/he_qat/include/he_qat_bn_ops.h index 7ad679c..a6a7c46 100644 --- a/he_qat/include/he_qat_bn_ops.h +++ b/he_qat/include/he_qat_bn_ops.h @@ -47,6 +47,12 @@ typedef struct { #endif } HE_QAT_TaskRequest; +// One for each consumer +typedef struct { + HE_QAT_TaskRequest* request[HE_QAT_BUFFER_SIZE]; + unsigned int count; +} HE_QAT_TaskRequestList; + /// @brief /// @function /// Perform big number modular exponentiation for input data in diff --git a/he_qat/include/he_qat_types.h b/he_qat/include/he_qat_types.h index 88d107e..7322e44 100644 --- a/he_qat/include/he_qat_types.h +++ b/he_qat/include/he_qat_types.h @@ -14,6 +14,7 @@ extern "C" { #include #define HE_QAT_BUFFER_SIZE 1024 +#define HE_QAT_BUFFER_COUNT 8 // Type definitions typedef enum { HE_QAT_SYNC = 1, HE_QAT_ASYNC = 2 } HE_QAT_EXEC_MODE; @@ -31,15 +32,29 @@ typedef pthread_t HE_QAT_Inst; typedef struct { void* data[HE_QAT_BUFFER_SIZE]; // - int count; // occupied track number of buffer enties - int next_free_slot; // nextin index of the next free slot to accommodate a - // request - int next_data_slot; // nextout index of next request to be processed - pthread_mutex_t mutex; // + unsigned int count; // occupied track number of buffer enties + unsigned int + next_free_slot; // nextin index of the next free slot for a request + unsigned int + next_data_slot; // nextout index of next request to be processed + pthread_mutex_t mutex; // pthread_cond_t any_more_data; // more pthread_cond_t any_free_slot; // less } HE_QAT_RequestBuffer; +typedef struct { + void* data[HE_QAT_BUFFER_COUNT][HE_QAT_BUFFER_SIZE]; // + unsigned int count; + unsigned int size; + unsigned int + next_free_slot; // nextin index of the next free slot for a request + unsigned int + next_data_slot; // nextout index of next request to be processed + pthread_mutex_t mutex; // + pthread_cond_t any_more_data; // more + pthread_cond_t any_free_slot; // less +} HE_QAT_RequestBufferList; + typedef struct { int inst_id; CpaInstanceHandle inst_handle; From 595da30acbfe10458b204a83b1ccbcad94919a7e Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 18 Apr 2022 18:07:27 -0700 Subject: [PATCH 161/364] Add type to represent outstanding buffers. --- he_qat/include/he_qat_types.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/he_qat/include/he_qat_types.h b/he_qat/include/he_qat_types.h index 7322e44..01fd012 100644 --- a/he_qat/include/he_qat_types.h +++ b/he_qat/include/he_qat_types.h @@ -32,7 +32,7 @@ typedef pthread_t HE_QAT_Inst; typedef struct { void* data[HE_QAT_BUFFER_SIZE]; // - unsigned int count; // occupied track number of buffer enties + volatile unsigned int count; // occupied track number of buffer enties unsigned int next_free_slot; // nextin index of the next free slot for a request unsigned int @@ -55,6 +55,20 @@ typedef struct { pthread_cond_t any_free_slot; // less } HE_QAT_RequestBufferList; +typedef struct { + HE_QAT_RequestBuffer buffer[HE_QAT_BUFFER_COUNT]; // + unsigned int busy_count; + unsigned int + next_free_buffer; // nextin index of the next free slot for a request + int free_buffer[HE_QAT_BUFFER_COUNT]; + unsigned int + next_ready_buffer; // nextout index of next request to be processed + int ready_buffer[HE_QAT_BUFFER_COUNT]; + pthread_mutex_t mutex; // + pthread_cond_t any_ready_buffer; // more + pthread_cond_t any_free_buffer; // less +} HE_QAT_OutstandingBuffer; + typedef struct { int inst_id; CpaInstanceHandle inst_handle; From ead16e2696299a00a0b3cfb750d43af706d30995 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 18 Apr 2022 18:09:18 -0700 Subject: [PATCH 162/364] Initialize outstanding buffers. --- he_qat/he_qat_context.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/he_qat/he_qat_context.c b/he_qat/he_qat_context.c index d91758a..5b0d372 100644 --- a/he_qat/he_qat_context.c +++ b/he_qat/he_qat_context.c @@ -29,10 +29,6 @@ volatile int context_state = 0; // Global variable declarations -// HE_QAT_Inst he_qat_instances[HE_QAT_MAX_NUM_INST]; -// pthread_attr_t he_qat_inst_attr[HE_QAT_MAX_NUM_INST]; -// HE_QAT_InstConfig he_qat_inst_config[HE_QAT_MAX_NUM_INST]; -// HE_QAT_RequestBuffer he_qat_buffer; pthread_t buffer_manager; HE_QAT_Inst he_qat_instances[NUM_ACTIVE_INSTANCES]; pthread_attr_t he_qat_inst_attr[NUM_ACTIVE_INSTANCES]; @@ -40,6 +36,7 @@ HE_QAT_InstConfig he_qat_inst_config[NUM_ACTIVE_INSTANCES]; extern HE_QAT_RequestBuffer he_qat_buffer; extern HE_QAT_RequestBufferList outstanding_buffer; +extern HE_QAT_OutstandingBuffer outstanding; extern void* schedule_requests(void* state); extern void* start_perform_op(void* _inst_config); extern void stop_perform_op(void* _inst_config, unsigned num_inst); @@ -146,6 +143,27 @@ HE_QAT_STATUS acquire_qat_devices() { he_qat_buffer.data[i] = NULL; } + // Initialize QAT outstanding buffers + outstanding.busy_count = 0; + outstanding.next_free_buffer = 0; + outstanding.next_ready_buffer = 0; + for (int i = 0; i < HE_QAT_BUFFER_COUNT; i++) { + outstanding.free_buffer[i] = 1; + outstanding.ready_buffer[i] = 0; + outstanding.buffer[i].count = 0; + outstanding.buffer[i].next_free_slot = 0; + outstanding.buffer[i].next_data_slot = 0; + for (int j = 0; j < HE_QAT_BUFFER_SIZE; j++) { + outstanding.buffer[i].data[j] = NULL; + } + pthread_mutex_init(&outstanding.buffer[i].mutex, NULL); + pthread_cond_init(&outstanding.buffer[i].any_more_data, NULL); + pthread_cond_init(&outstanding.buffer[i].any_free_data, NULL); + } + pthread_mutex_init(&outstanding.mutex, NULL); + pthread_cond_init(&outstanding.any_free_buffer, NULL); + pthread_cond_init(&outstanding.any_ready_buffer, NULL); + // Creating QAT instances (consumer threads) to process op requests pthread_attr_t attr; cpu_set_t cpus; @@ -194,7 +212,6 @@ HE_QAT_STATUS acquire_qat_devices() { // Launch buffer manager thread to schedule incoming requests if (0 != pthread_create(&buffer_manager, NULL, schedule_requests, (void*)&context_state)) { - context_state = 0; release_qat_devices(); printf( "Failed to complete QAT initialization while creating buffer " @@ -203,7 +220,6 @@ HE_QAT_STATUS acquire_qat_devices() { } if (0 != pthread_detach(buffer_manager)) { - context_state = 0; release_qat_devices(); printf( "Failed to complete QAT initialization while launching buffer " From 82809478f2163107fd2dae40e8a6812d7e2e40e1 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 18 Apr 2022 18:10:46 -0700 Subject: [PATCH 163/364] Complete multi-threading support with distributed outstanding buffers. + Add acquire buffer interface. + Add release buffer interface. + Add bnModExp multi-threaded interface. + Add function to complete the request pulling mechanism from outstanding buffers. + Use the new outstanding buffer type. --- he_qat/he_qat_bn_ops.c | 322 ++++++++++++++++++++++++++++++--- he_qat/include/he_qat_bn_ops.h | 12 ++ 2 files changed, 311 insertions(+), 23 deletions(-) diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index 7067585..7a429d4 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -27,6 +27,7 @@ double time_taken = 0.0; // Global buffer for the runtime environment HE_QAT_RequestBuffer he_qat_buffer; HE_QAT_RequestBufferList outstanding_buffer; +HE_QAT_OutstandingBuffer outstanding; /// @brief /// @function @@ -112,6 +113,7 @@ static void submit_request_list(HE_QAT_RequestBuffer* _buffer, printf("Wait lock write request. [buffer size: %d]\n", _buffer->count); #endif + // Wait until buffer can accomodate the number of input requests while (_buffer->count >= HE_QAT_BUFFER_SIZE || (HE_QAT_BUFFER_SIZE - _buffer->count + 1) < _requests->count) pthread_cond_wait(&_buffer->any_free_slot, &_buffer->mutex); @@ -132,26 +134,12 @@ static void submit_request_list(HE_QAT_RequestBuffer* _buffer, #endif } -static void* get_buffer(HE_QAT_RequestBufferList* _list, unsigned int index) { - if (0 == index) return _list->data; - unsigned int j = 0; - void* curr = _list->next; - while (curr) { - if (index == ++j) break; - curr = _list->next; - } - return curr; -} - -static void* add_buffer(HE_QAT_RequestBufferList* _list) { return NULL; } - -static void del_buffer() { return; } - /// @brief /// @function /// Thread-safe producer implementation for the shared outstanding request /// buffer that stores request from multiple threads. /// Stores requests in a buffer that will be sent to the HE QAT buffer. +/// @unused static void push_request(HE_QAT_RequestBufferList* _outstanding_buffer, void* args, unsigned int num_requests = 1) { #ifdef HE_QAT_DEBUG @@ -208,6 +196,7 @@ static void push_request(HE_QAT_RequestBufferList* _outstanding_buffer, /// @function /// Thread-safe consumer implementation for the shared request buffer. /// Read requests from a buffer to finally offload the work to QAT devices. +/// Supported in single-threaded or multi-threaded mode. static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) { void* item = NULL; @@ -220,9 +209,6 @@ static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) { item = _buffer->data[_buffer->next_data_slot++]; - // TODO(fdiasmor): for multithreading mode - // Make copy of request so that the buffer can be reused - _buffer->next_data_slot %= HE_QAT_BUFFER_SIZE; _buffer->count--; @@ -236,6 +222,7 @@ static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) { /// @function /// Thread-safe consumer implementation for the shared request buffer. /// Read requests from a buffer to finally offload the work to QAT devices. +/// @future: Meant for multi-threaded mode. static void read_request_list(HE_QAT_TaskRequestList* _requests, HE_QAT_RequestBuffer* _buffer) { if (NULL == _requests) return; @@ -265,8 +252,10 @@ static void read_request_list(HE_QAT_TaskRequestList* _requests, /// @function /// Thread-safe consumer implementation for the shared request buffer. /// Read requests from a buffer to finally offload the work to QAT devices. +/// @deprecated static void pull_request(HE_QAT_TaskRequestList* _requests, - HE_QAT_RequestBufferList* _outstanding_buffer, + //HE_QAT_OutstandingBuffer *_outstanding_buffer, + HE_QAT_RequestBufferList* _outstanding_buffer, unsigned int max_num_requests = 1) { if (NULL == _requests) return; @@ -309,6 +298,115 @@ static void pull_request(HE_QAT_TaskRequestList* _requests, return; } +static void pull_outstanding_requests(HE_QAT_TaskRequestList* _requests, + HE_QAT_OutstandingBuffer *_outstanding_buffer, + unsigned int max_num_requests = 1) { + + if (NULL == _requests) return; + _requests->count = 0; + + // for now, only one thread can change next_ready_buffer + // so no need for sync tools + + // Select an outstanding buffer to pull requests and add them into the processing queue (internal buffer) + pthread_mutex_lock(&_outstanding_buffer->mutex); + // Wait until next outstanding buffer becomes available for use + while (outstanding.busy_count <= 0) + pthread_cond_wait(&_outstanding_buffer->any_ready_buffer, &_outstanding_buffer->mutex); + + int any_ready = 0; + unsigned int index =_outstanding_buffer->next_ready_buffer; // no fairness + for (unsigned int i = 0; i < HE_QAT_BUFFER_COUNT; i++) { + index = i; // ensure fairness + if (_outstanding_buffer->ready_buffer[index] + && _outstanding_buffer->buffer[index].count) { //sync with mutex at interface + any_ready = 1; + break; + } + //index = (index + 1) % HE_QAT_BUFFER_COUNT; + } + // Ensures it gets picked once only + pthread_mutex_unlock(&_outstanding_buffer->mutex); + + if (!any_ready) return; + + // Extract outstanding requests from outstanding buffer + // (this is the only function that reads from outstanding buffer, from a single thread) + pthread_mutex_lock(&_outstanding_buffer->buffer[index].mutex); + // This conditional waiting may not be required + // Wait while buffer is empty + while (_outstanding_buffer->buffer[index].count <= 0) { + pthread_cond_wait(&_outstanding_buffer->buffer[index].any_more_data, + &_outstanding_buffer->buffer[index].mutex); + } + assert(_outstanding_buffer->buffer[index].count > 0); + // + + unsigned int num_requests = (_outstanding_buffer->buffer[index].count < max_num_requests) + ? _outstanding_buffer->buffer[index].count : max_num_requests; + + assert(num_requests <= HE_QAT_BUFFER_SIZE); + + for (unsigned int i = 0; i < num_requests; i++) { + _requests->request[i] = _outstanding_buffer->buffer[index] + .data[_outstanding_buffer->buffer[index].next_data_slot]; + _outstanding_buffer->buffer[index].count--; + _outstanding_buffer->buffer[index].next_data_slot++; + _outstanding_buffer->buffer[index].next_data_slot %= HE_QAT_BUFFER_SIZE; + } + _requests->count = num_requests; + + pthread_cond_signal(&_outstanding_buffer->buffer[index].any_free_slot); + pthread_mutex_unlock(&_outstanding_buffer->buffer[index].mutex); + + // --------------------------------------------------------------------------- + // Notify there is an outstanding buffer in ready for the processing queue +// pthread_mutex_lock(&_outstanding_buffer->mutex); +// +// _outstanding_buffer->ready_count--; +// _outstanding_buffer->ready_buffer[index] = 0; +// +// pthread_cond_signal(&_outstanding_buffer->any_free_buffer); +// pthread_mutex_unlock(&_outstanding_buffer->mutex); + + return; +} + +// Frontend for multithreading support +HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int *_buffer_id) { + if (NULL == _buffer_id) return HE_QAT_STATUS_INVALID_PARAM; + + pthread_mutex_lock(&outstanding.mutex); + // Wait until next outstanding buffer becomes available for use + while (outstanding.busy_count >= HE_QAT_BUFFER_COUNT) + pthread_cond_wait(&outstanding.any_free_buffer, &outstanding.mutex); + + assert(outstanding.busy_count < HE_QAT_BUFFER_COUNT); + + // find next available + unsigned int next_free_buffer = outstanding.next_free_buffer; + for (unsigned int i = 0; i < HE_QAT_BUFFER_COUNT; i++) { + if (outstanding.free_buffer[next_free_buffer]) { + outstanding.free_buffer[next_free_buffer] = 0; + *_buffer_id = next_free_buffer; + break; + } + next_free_buffer = (next_free_buffer + 1) % HE_QAT_BUFFER_COUNT; + } + + outstanding.next_free_buffer = (*_buffer_id + 1) % HE_QAT_BUFFER_COUNT; + outstanding.next_ready_buffer = *_buffer_id; + outstanding.ready_buffer[*_buffer_id] = 1; + outstanding.busy_count++; + // busy meaning: + // taken by a thread, enqueued requests, in processing, waiting results + + pthread_cond_signal(&outstanding.any_ready_buffer); + pthread_mutex_unlock(&outstanding.mutex); + + return HE_QAT_STATUS_SUCCESS; +} + static void* schedule_requests(void* state) { if (NULL == state) { printf("Failed at buffer_manager: argument is NULL.\n"); @@ -324,12 +422,12 @@ static void* schedule_requests(void* state) { outstading_requests->count = 0; // this thread should receive signal from context to exit - while (active) { + while (*active) { // collect a set of requests from the outstanding buffer - pull_request(&outstanding_requests, &outstanding_buffer, - HE_QAT_BUFFER_SIZE); + //pull_request(&outstanding_requests, &outstanding_buffer, HE_QAT_BUFFER_SIZE); + pull_outstanding_requests(&outstanding_requests, &outstanding, HE_QAT_BUFFER_SIZE); // submit them to the HE QAT buffer for offloading - submit_request(&he_qat_buffer, &outstanding_requests); + submit_request_list(&he_qat_buffer, &outstanding_requests); } pthread_exit(NULL); @@ -660,6 +758,81 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, return HE_QAT_STATUS_SUCCESS; } +// Assume allocate_bnModExp_buffer(&_buffer_id) to be called first +// to secure and allocate an outstanding buffer for the target thread. +// Multithread support for release_bnModExp_buffer(_buffer_id, batch_size) +void release_bnModExp_buffer(int _buffer_id, unsigned int _batch_size) { + unsigned int j = 0; + +#ifdef HE_QAT_PERF + gettimeofday(&start_time, NULL); +#endif + do { + // Buffer read may be safe for single-threaded blocking calls only. + // Note: Not tested on multithreaded environment. + HE_QAT_TaskRequest* task = + (HE_QAT_TaskRequest*) outstanding.buffer[_buffer_id].data[j]; + + //if (NULL == task) + // continue; + + // Block and synchronize: Wait for the most recently offloaded request + // to complete processing + pthread_mutex_lock( + &task->mutex); // mutex only needed for the conditional variable + while (HE_QAT_STATUS_READY != task->request_status) + pthread_cond_wait(&task->ready, &task->mutex); + +#ifdef HE_QAT_PERF + time_taken = (task->end.tv_sec - task->start.tv_sec) * 1e6; + time_taken = + (time_taken + (task->end.tv_usec - task->start.tv_usec)); //*1e-6; + printf("%u time: %.1lfus\n", j, time_taken); +#endif + + // Free up QAT temporary memory + CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; + if (op_data) { + PHYS_CONTIG_FREE(op_data->base.pData); + PHYS_CONTIG_FREE(op_data->exponent.pData); + PHYS_CONTIG_FREE(op_data->modulus.pData); + } + free(task->op_data); + task->op_data = NULL; + if (task->op_result.pData) { + PHYS_CONTIG_FREE(task->op_result.pData); + } + + // Move forward to wait for the next request that will be offloaded + pthread_mutex_unlock(&task->mutex); + + // Fix segmentation fault? + free(outstanding.buffer[_buffer_id].data[j]); + outstanding.buffer[_buffer_id].data[j] = NULL; + } while (++j < batch_size); + +#ifdef HE_QAT_PERF + gettimeofday(&end_time, NULL); + time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; + time_taken = + (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; + printf("Batch Wall Time: %.1lfus\n", time_taken); +#endif + + // Release outstanding buffer for usage by another thread + pthread_mutex_lock(&outstanding.mutex); + + outstanding.next_free_buffer = _buffer_id; + outstanding.ready_buffer[_buffer_id] = 0; + outstanding.free_buffer[_buffer_id] = 1; + outstanding.busy_count--; + + pthread_cond_signal(&outstanding.any_free_buffer); + pthread_mutex_unlock(&outstanding.mutex); + + return; +} + // Maybe it will be useful to pass the number of requests to retrieve // Pass post-processing function as argument to bring output to expected type void getBnModExpRequest(unsigned int batch_size) { @@ -872,3 +1045,106 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, return HE_QAT_STATUS_SUCCESS; } + +HE_QAT_STATUS HE_QAT_bnModExp_MT(int _buffer_id, unsigned char* r, unsigned char* b, + unsigned char* e, unsigned char* m, int nbits) { +#ifdef HE_QAT_DEBUG + static unsigned long long req_count = 0; + // printf("Wait lock write request. [buffer size: %d]\n",_buffer->count); +#endif + // Unpack data and copy to QAT friendly memory space + int len = nbits / 8; + + if (NULL == r) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == b) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == e) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == m) return HE_QAT_STATUS_INVALID_PARAM; + + Cpa8U* pBase = NULL; + Cpa8U* pModulus = NULL; + Cpa8U* pExponent = NULL; + + // TODO(fdiasmor): Try it with 8-byte alignment. + CpaStatus status = CPA_STATUS_FAIL; + // status = PHYS_CONTIG_ALLOC(&pBase, len); + status = PHYS_CONTIG_ALLOC_ALIGNED(&pBase, len, 8); + if (CPA_STATUS_SUCCESS == status && NULL != pBase) { + memcpy(pBase, b, len); + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + // status = PHYS_CONTIG_ALLOC(&pExponent, len); + status = PHYS_CONTIG_ALLOC_ALIGNED(&pExponent, len, 8); + if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { + memcpy(pExponent, e, len); + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + // status = PHYS_CONTIG_ALLOC(&pModulus, len); + status = PHYS_CONTIG_ALLOC_ALIGNED(&pModulus, len, 8); + if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { + memcpy(pModulus, m, len); + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + // HE_QAT_TaskRequest request = + // HE_QAT_PACK_MODEXP_REQUEST(pBase, pExponent, pModulus, r) + // Pack it as a QAT Task Request + HE_QAT_TaskRequest* request = + (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); + if (NULL == request) { + printf( + "HE_QAT_TaskRequest memory allocation failed in " + "bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + + CpaCyLnModExpOpData* op_data = + (CpaCyLnModExpOpData*)calloc(1, sizeof(CpaCyLnModExpOpData)); + if (NULL == op_data) { + printf("Cpa memory allocation failed in bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + op_data->base.pData = pBase; + op_data->base.dataLenInBytes = len; + op_data->exponent.pData = pExponent; + op_data->exponent.dataLenInBytes = len; + op_data->modulus.pData = pModulus; + op_data->modulus.dataLenInBytes = len; + request->op_data = (void*)op_data; + + // status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); + status = PHYS_CONTIG_ALLOC_ALIGNED(&request->op_result.pData, len, 8); + if (CPA_STATUS_SUCCESS == status && NULL != request->op_result.pData) { + request->op_result.dataLenInBytes = len; + } else { + printf( + "CpaFlatBuffer.pData memory allocation failed in " + "bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + + request->op_type = HE_QAT_OP_MODEXP; + request->callback_func = (void*)HE_QAT_bnModExpCallback; + request->op_status = status; + request->op_output = (void*)r; + + // Ensure calls are synchronized at exit (blocking) + pthread_mutex_init(&request->mutex, NULL); + pthread_cond_init(&request->ready, NULL); + +#ifdef HE_QAT_DEBUG + printf("BN ModExp interface call for request #%llu\n", ++req_count); +#endif + + // Submit request using producer function + submit_request(&outstanding.buffer[_buffer_id], (void*)request); + + return HE_QAT_STATUS_SUCCESS; +} diff --git a/he_qat/include/he_qat_bn_ops.h b/he_qat/include/he_qat_bn_ops.h index a6a7c46..e3869eb 100644 --- a/he_qat/include/he_qat_bn_ops.h +++ b/he_qat/include/he_qat_bn_ops.h @@ -110,6 +110,18 @@ void getBnModExpRequest(unsigned int num_requests); HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, unsigned char* e, unsigned char* m, int nbits); + +/* ***** Multi-threading supported interface ******* */ + + +HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int *_buffer_id); + +HE_QAT_STATUS HE_QAT_bnModExp_MT(int _buffer_id, + unsigned char* r, unsigned char* b, + unsigned char* e, unsigned char* m, int nbits); + +void release_bnModExp_buffer(int _buffer_id, unsigned int _batch_size); + #ifdef __cplusplus } // extern "C" { #endif From 720fc798b5f363f6a81a18b57bd3f3b2484b72da Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 19 Apr 2022 15:08:25 -0700 Subject: [PATCH 164/364] Code format changes. --- he_qat/he_qat_bn_ops.c | 108 ++++++++++++++++++--------------- he_qat/he_qat_context.c | 10 +-- he_qat/include/he_qat_bn_ops.h | 10 ++- he_qat/include/he_qat_types.h | 8 +-- 4 files changed, 72 insertions(+), 64 deletions(-) diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index 7a429d4..700596e 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -158,7 +158,7 @@ static void push_request(HE_QAT_RequestBufferList* _outstanding_buffer, // while (buffer_size < num_requests && // buffer_size < HE_QAT_LIST_SIZE * HE_QAT_BUFFER_SIZE) { // _outstanding_buffer->data[list_size] = - //malloc(sizeof(HE_QAT_TaskRequest)*HE_QAT_BUFFER_SIZE); if + // malloc(sizeof(HE_QAT_TaskRequest)*HE_QAT_BUFFER_SIZE); if //(_outstanding_buffer) // buffer_size = ++list_size * HE_QAT_BUFFER_SIZE; // } @@ -254,8 +254,8 @@ static void read_request_list(HE_QAT_TaskRequestList* _requests, /// Read requests from a buffer to finally offload the work to QAT devices. /// @deprecated static void pull_request(HE_QAT_TaskRequestList* _requests, - //HE_QAT_OutstandingBuffer *_outstanding_buffer, - HE_QAT_RequestBufferList* _outstanding_buffer, + // HE_QAT_OutstandingBuffer *_outstanding_buffer, + HE_QAT_RequestBufferList* _outstanding_buffer, unsigned int max_num_requests = 1) { if (NULL == _requests) return; @@ -298,40 +298,44 @@ static void pull_request(HE_QAT_TaskRequestList* _requests, return; } -static void pull_outstanding_requests(HE_QAT_TaskRequestList* _requests, - HE_QAT_OutstandingBuffer *_outstanding_buffer, - unsigned int max_num_requests = 1) { - +static void pull_outstanding_requests( + HE_QAT_TaskRequestList* _requests, + HE_QAT_OutstandingBuffer* _outstanding_buffer, + unsigned int max_num_requests = 1) { if (NULL == _requests) return; _requests->count = 0; // for now, only one thread can change next_ready_buffer // so no need for sync tools - // Select an outstanding buffer to pull requests and add them into the processing queue (internal buffer) + // Select an outstanding buffer to pull requests and add them into the + // processing queue (internal buffer) pthread_mutex_lock(&_outstanding_buffer->mutex); // Wait until next outstanding buffer becomes available for use while (outstanding.busy_count <= 0) - pthread_cond_wait(&_outstanding_buffer->any_ready_buffer, &_outstanding_buffer->mutex); - + pthread_cond_wait(&_outstanding_buffer->any_ready_buffer, + &_outstanding_buffer->mutex); + int any_ready = 0; - unsigned int index =_outstanding_buffer->next_ready_buffer; // no fairness + unsigned int index = _outstanding_buffer->next_ready_buffer; // no fairness for (unsigned int i = 0; i < HE_QAT_BUFFER_COUNT; i++) { - index = i; // ensure fairness - if (_outstanding_buffer->ready_buffer[index] - && _outstanding_buffer->buffer[index].count) { //sync with mutex at interface + index = i; // ensure fairness + if (_outstanding_buffer->ready_buffer[index] && + _outstanding_buffer->buffer[index] + .count) { // sync with mutex at interface any_ready = 1; - break; - } - //index = (index + 1) % HE_QAT_BUFFER_COUNT; + break; + } + // index = (index + 1) % HE_QAT_BUFFER_COUNT; } // Ensures it gets picked once only pthread_mutex_unlock(&_outstanding_buffer->mutex); if (!any_ready) return; - // Extract outstanding requests from outstanding buffer - // (this is the only function that reads from outstanding buffer, from a single thread) + // Extract outstanding requests from outstanding buffer + // (this is the only function that reads from outstanding buffer, from a + // single thread) pthread_mutex_lock(&_outstanding_buffer->buffer[index].mutex); // This conditional waiting may not be required // Wait while buffer is empty @@ -340,16 +344,19 @@ static void pull_outstanding_requests(HE_QAT_TaskRequestList* _requests, &_outstanding_buffer->buffer[index].mutex); } assert(_outstanding_buffer->buffer[index].count > 0); - // + // - unsigned int num_requests = (_outstanding_buffer->buffer[index].count < max_num_requests) - ? _outstanding_buffer->buffer[index].count : max_num_requests; + unsigned int num_requests = + (_outstanding_buffer->buffer[index].count < max_num_requests) + ? _outstanding_buffer->buffer[index].count + : max_num_requests; assert(num_requests <= HE_QAT_BUFFER_SIZE); for (unsigned int i = 0; i < num_requests; i++) { - _requests->request[i] = _outstanding_buffer->buffer[index] - .data[_outstanding_buffer->buffer[index].next_data_slot]; + _requests->request[i] = + _outstanding_buffer->buffer[index] + .data[_outstanding_buffer->buffer[index].next_data_slot]; _outstanding_buffer->buffer[index].count--; _outstanding_buffer->buffer[index].next_data_slot++; _outstanding_buffer->buffer[index].next_data_slot %= HE_QAT_BUFFER_SIZE; @@ -361,19 +368,19 @@ static void pull_outstanding_requests(HE_QAT_TaskRequestList* _requests, // --------------------------------------------------------------------------- // Notify there is an outstanding buffer in ready for the processing queue -// pthread_mutex_lock(&_outstanding_buffer->mutex); -// -// _outstanding_buffer->ready_count--; -// _outstanding_buffer->ready_buffer[index] = 0; -// -// pthread_cond_signal(&_outstanding_buffer->any_free_buffer); -// pthread_mutex_unlock(&_outstanding_buffer->mutex); - + // pthread_mutex_lock(&_outstanding_buffer->mutex); + // + // _outstanding_buffer->ready_count--; + // _outstanding_buffer->ready_buffer[index] = 0; + // + // pthread_cond_signal(&_outstanding_buffer->any_free_buffer); + // pthread_mutex_unlock(&_outstanding_buffer->mutex); + return; } // Frontend for multithreading support -HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int *_buffer_id) { +HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id) { if (NULL == _buffer_id) return HE_QAT_STATUS_INVALID_PARAM; pthread_mutex_lock(&outstanding.mutex); @@ -382,23 +389,23 @@ HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int *_buffer_id) { pthread_cond_wait(&outstanding.any_free_buffer, &outstanding.mutex); assert(outstanding.busy_count < HE_QAT_BUFFER_COUNT); - + // find next available unsigned int next_free_buffer = outstanding.next_free_buffer; for (unsigned int i = 0; i < HE_QAT_BUFFER_COUNT; i++) { if (outstanding.free_buffer[next_free_buffer]) { - outstanding.free_buffer[next_free_buffer] = 0; - *_buffer_id = next_free_buffer; - break; - } - next_free_buffer = (next_free_buffer + 1) % HE_QAT_BUFFER_COUNT; + outstanding.free_buffer[next_free_buffer] = 0; + *_buffer_id = next_free_buffer; + break; + } + next_free_buffer = (next_free_buffer + 1) % HE_QAT_BUFFER_COUNT; } outstanding.next_free_buffer = (*_buffer_id + 1) % HE_QAT_BUFFER_COUNT; outstanding.next_ready_buffer = *_buffer_id; outstanding.ready_buffer[*_buffer_id] = 1; outstanding.busy_count++; - // busy meaning: + // busy meaning: // taken by a thread, enqueued requests, in processing, waiting results pthread_cond_signal(&outstanding.any_ready_buffer); @@ -424,8 +431,10 @@ static void* schedule_requests(void* state) { // this thread should receive signal from context to exit while (*active) { // collect a set of requests from the outstanding buffer - //pull_request(&outstanding_requests, &outstanding_buffer, HE_QAT_BUFFER_SIZE); - pull_outstanding_requests(&outstanding_requests, &outstanding, HE_QAT_BUFFER_SIZE); + // pull_request(&outstanding_requests, &outstanding_buffer, + // HE_QAT_BUFFER_SIZE); + pull_outstanding_requests(&outstanding_requests, &outstanding, + HE_QAT_BUFFER_SIZE); // submit them to the HE QAT buffer for offloading submit_request_list(&he_qat_buffer, &outstanding_requests); } @@ -758,12 +767,12 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, return HE_QAT_STATUS_SUCCESS; } -// Assume allocate_bnModExp_buffer(&_buffer_id) to be called first +// Assume allocate_bnModExp_buffer(&_buffer_id) to be called first // to secure and allocate an outstanding buffer for the target thread. // Multithread support for release_bnModExp_buffer(_buffer_id, batch_size) void release_bnModExp_buffer(int _buffer_id, unsigned int _batch_size) { unsigned int j = 0; - + #ifdef HE_QAT_PERF gettimeofday(&start_time, NULL); #endif @@ -771,9 +780,9 @@ void release_bnModExp_buffer(int _buffer_id, unsigned int _batch_size) { // Buffer read may be safe for single-threaded blocking calls only. // Note: Not tested on multithreaded environment. HE_QAT_TaskRequest* task = - (HE_QAT_TaskRequest*) outstanding.buffer[_buffer_id].data[j]; + (HE_QAT_TaskRequest*)outstanding.buffer[_buffer_id].data[j]; - //if (NULL == task) + // if (NULL == task) // continue; // Block and synchronize: Wait for the most recently offloaded request @@ -808,7 +817,7 @@ void release_bnModExp_buffer(int _buffer_id, unsigned int _batch_size) { // Fix segmentation fault? free(outstanding.buffer[_buffer_id].data[j]); - outstanding.buffer[_buffer_id].data[j] = NULL; + outstanding.buffer[_buffer_id].data[j] = NULL; } while (++j < batch_size); #ifdef HE_QAT_PERF @@ -1046,8 +1055,9 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, return HE_QAT_STATUS_SUCCESS; } -HE_QAT_STATUS HE_QAT_bnModExp_MT(int _buffer_id, unsigned char* r, unsigned char* b, - unsigned char* e, unsigned char* m, int nbits) { +HE_QAT_STATUS HE_QAT_bnModExp_MT(int _buffer_id, unsigned char* r, + unsigned char* b, unsigned char* e, + unsigned char* m, int nbits) { #ifdef HE_QAT_DEBUG static unsigned long long req_count = 0; // printf("Wait lock write request. [buffer size: %d]\n",_buffer->count); diff --git a/he_qat/he_qat_context.c b/he_qat/he_qat_context.c index 5b0d372..f3a3748 100644 --- a/he_qat/he_qat_context.c +++ b/he_qat/he_qat_context.c @@ -149,13 +149,13 @@ HE_QAT_STATUS acquire_qat_devices() { outstanding.next_ready_buffer = 0; for (int i = 0; i < HE_QAT_BUFFER_COUNT; i++) { outstanding.free_buffer[i] = 1; - outstanding.ready_buffer[i] = 0; - outstanding.buffer[i].count = 0; - outstanding.buffer[i].next_free_slot = 0; - outstanding.buffer[i].next_data_slot = 0; + outstanding.ready_buffer[i] = 0; + outstanding.buffer[i].count = 0; + outstanding.buffer[i].next_free_slot = 0; + outstanding.buffer[i].next_data_slot = 0; for (int j = 0; j < HE_QAT_BUFFER_SIZE; j++) { outstanding.buffer[i].data[j] = NULL; - } + } pthread_mutex_init(&outstanding.buffer[i].mutex, NULL); pthread_cond_init(&outstanding.buffer[i].any_more_data, NULL); pthread_cond_init(&outstanding.buffer[i].any_free_data, NULL); diff --git a/he_qat/include/he_qat_bn_ops.h b/he_qat/include/he_qat_bn_ops.h index e3869eb..48db5ac 100644 --- a/he_qat/include/he_qat_bn_ops.h +++ b/he_qat/include/he_qat_bn_ops.h @@ -110,15 +110,13 @@ void getBnModExpRequest(unsigned int num_requests); HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, unsigned char* e, unsigned char* m, int nbits); - /* ***** Multi-threading supported interface ******* */ +HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id); -HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int *_buffer_id); - -HE_QAT_STATUS HE_QAT_bnModExp_MT(int _buffer_id, - unsigned char* r, unsigned char* b, - unsigned char* e, unsigned char* m, int nbits); +HE_QAT_STATUS HE_QAT_bnModExp_MT(int _buffer_id, unsigned char* r, + unsigned char* b, unsigned char* e, + unsigned char* m, int nbits); void release_bnModExp_buffer(int _buffer_id, unsigned int _batch_size); diff --git a/he_qat/include/he_qat_types.h b/he_qat/include/he_qat_types.h index 01fd012..b9f6921 100644 --- a/he_qat/include/he_qat_types.h +++ b/he_qat/include/he_qat_types.h @@ -32,7 +32,7 @@ typedef pthread_t HE_QAT_Inst; typedef struct { void* data[HE_QAT_BUFFER_SIZE]; // - volatile unsigned int count; // occupied track number of buffer enties + volatile unsigned int count; // occupied track number of buffer enties unsigned int next_free_slot; // nextin index of the next free slot for a request unsigned int @@ -62,11 +62,11 @@ typedef struct { next_free_buffer; // nextin index of the next free slot for a request int free_buffer[HE_QAT_BUFFER_COUNT]; unsigned int - next_ready_buffer; // nextout index of next request to be processed + next_ready_buffer; // nextout index of next request to be processed int ready_buffer[HE_QAT_BUFFER_COUNT]; - pthread_mutex_t mutex; // + pthread_mutex_t mutex; // pthread_cond_t any_ready_buffer; // more - pthread_cond_t any_free_buffer; // less + pthread_cond_t any_free_buffer; // less } HE_QAT_OutstandingBuffer; typedef struct { From d1e9ba32016aa69ed04ac0831c7212a8a17ba204 Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Mon, 25 Apr 2022 23:10:20 +0800 Subject: [PATCH 165/364] improve encrypt decrypt (#75) *Major updates: - Add BaseText PlainText CipherText classes - Rewrite encrypt/decrypt function with PlainText/CipherText - Rewrite all unit tests with PlainText/CipherText - Rewrite all benchmarks with PlainText/CipherText - Remove old EncryptedNumber class and ops.hpp/cpp file - Add support for encryption and decryption of arbitrary length vectors - Add support for CT+CT CT+PT CT*PT of arbitrary length vector - Add support for CT+scalar(CT/PT) and CT*scalar(PT) - Enable OpenMP in ippModExp * Minor updates and Bug fixes: - Fix decryptRAW incorrect result issue when OMP is enabled - Fix zero padding error when using ippMBModExp - Extend all unit test and benchmark to support arbitrary length BigNumber vector - Updated encrypt function, removed encryptMB/SB and replaced with raw_encrypt - Removed ipcl:: namespace from BigNumber (easier work with QAT data exchange) - Fixed non avx512ifma modexp error Co-authored-by: Sejun Kim --- benchmark/bench_cryptography.cpp | 192 +------- benchmark/bench_ops.cpp | 404 ++------------- ipcl/CMakeLists.txt | 4 +- ipcl/base_text.cpp | 76 +++ ipcl/bignum.cpp | 4 - ipcl/ciphertext.cpp | 148 ++++++ ipcl/include/ipcl/base_text.hpp | 83 ++++ ipcl/include/ipcl/bignum.h | 3 - ipcl/include/ipcl/ciphertext.hpp | 67 +++ ipcl/include/ipcl/ops.hpp | 132 ----- ipcl/include/ipcl/plaintext.hpp | 75 +++ ipcl/include/ipcl/pri_key.hpp | 18 +- ipcl/include/ipcl/pub_key.hpp | 30 +- ipcl/mod_exp.cpp | 125 ++++- ipcl/ops.cpp | 157 ------ ipcl/plaintext.cpp | 46 ++ ipcl/pri_key.cpp | 67 ++- ipcl/pub_key.cpp | 70 ++- test/test_cryptography.cpp | 240 +++++---- test/test_ops.cpp | 819 +++++++++++++++---------------- 20 files changed, 1257 insertions(+), 1503 deletions(-) create mode 100644 ipcl/base_text.cpp create mode 100644 ipcl/ciphertext.cpp create mode 100644 ipcl/include/ipcl/base_text.hpp create mode 100644 ipcl/include/ipcl/ciphertext.hpp delete mode 100644 ipcl/include/ipcl/ops.hpp create mode 100644 ipcl/include/ipcl/plaintext.hpp delete mode 100644 ipcl/ops.cpp create mode 100644 ipcl/plaintext.cpp diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index 74b4bca..2817fa8 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -3,6 +3,7 @@ #include +#include #include #ifdef IPCL_USE_OMP #include @@ -10,6 +11,8 @@ #include "ipcl/keygen.hpp" +constexpr int SELF_DEF_NUM_VALUES = 20; + static void BM_KeyGen(benchmark::State& state) { int64_t n_length = state.range(0); for (auto _ : state) { @@ -22,195 +25,32 @@ static void BM_Encrypt(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize, - std::vector(8)); - std::vector> ct(dsize, - std::vector(8)); - - for (size_t i = 0; i < dsize; ++i) - pt[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); - - for (auto _ : state) { - for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); - } -} - -BENCHMARK(BM_Encrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); - -static void BM_Encrypt_buff8(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); + std::vector exp_value_v(dsize); - std::vector> pt(dsize / 8, - std::vector(8)); - std::vector> ct(dsize / 8, - std::vector(8)); + for (size_t i = 0; i < dsize; i++) + exp_value_v[i] = (unsigned int)(i * 1024) + 999; - for (size_t i = 0; i < dsize; ++i) - pt[i / 8][i & 7] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); + ipcl::PlainText pt(exp_value_v); + ipcl::CipherText ct; - for (auto _ : state) { - for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); - } + for (auto _ : state) ct = key.pub_key->encrypt(pt); } -BENCHMARK(BM_Encrypt_buff8) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); +BENCHMARK(BM_Encrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); static void BM_Decrypt(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize, - std::vector(8)); - std::vector> ct(dsize, - std::vector(8)); - std::vector> de_ct( - dsize, std::vector(8)); + std::vector exp_value_v(dsize); - for (size_t i = 0; i < dsize; ++i) - pt[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); + for (size_t i = 0; i < dsize; i++) + exp_value_v[i] = (unsigned int)(i * 1024) + 999; - for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); + ipcl::PlainText pt(exp_value_v), dt; + ipcl::CipherText ct = key.pub_key->encrypt(pt); - for (auto _ : state) { - for (size_t i = 0; i < dsize; ++i) { - key.priv_key->decrypt(de_ct[i], ct[i]); - } - } + for (auto _ : state) dt = key.priv_key->decrypt(ct); } BENCHMARK(BM_Decrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); - -static void BM_Decrypt_buff8(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> pt(dsize / 8, - std::vector(8)); - std::vector> ct(dsize / 8, - std::vector(8)); - std::vector> de_ct( - dsize / 8, std::vector(8)); - - for (size_t i = 0; i < dsize; ++i) - pt[i / 8][i & 7] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); - - for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); - - for (auto _ : state) { - for (size_t i = 0; i < dsize / 8; ++i) - key.priv_key->decrypt(de_ct[i], ct[i]); - } -} - -BENCHMARK(BM_Decrypt_buff8) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - -#ifdef IPCL_USE_OMP -static void BM_Encrypt_OMP(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> pt(dsize, - std::vector(8)); - std::vector> ct(dsize, - std::vector(8)); - - for (size_t i = 0; i < dsize; ++i) - pt[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); - - for (auto _ : state) { -#pragma omp parallel for - for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); - } -} -BENCHMARK(BM_Encrypt_OMP) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - -static void BM_Encrypt_buff8_OMP(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> pt(dsize / 8, - std::vector(8)); - std::vector> ct(dsize / 8, - std::vector(8)); - - for (size_t i = 0; i < dsize; ++i) - pt[i / 8][i & 7] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); - - for (auto _ : state) { -#pragma omp parallel for - for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); - } -} - -BENCHMARK(BM_Encrypt_buff8_OMP) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - -static void BM_Decrypt_OMP(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> pt(dsize, - std::vector(8)); - std::vector> ct(dsize, - std::vector(8)); - std::vector> de_ct( - dsize, std::vector(8)); - - for (size_t i = 0; i < dsize; ++i) - pt[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); - - for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); - - for (auto _ : state) { -#pragma omp parallel for - for (size_t i = 0; i < dsize; ++i) { - key.priv_key->decrypt(de_ct[i], ct[i]); - } - } -} - -BENCHMARK(BM_Decrypt_OMP) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - -static void BM_Decrypt_buff8_OMP(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> pt(dsize / 8, - std::vector(8)); - std::vector> ct(dsize / 8, - std::vector(8)); - std::vector> de_ct( - dsize / 8, std::vector(8)); - - for (size_t i = 0; i < dsize; ++i) - pt[i / 8][i & 7] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); - - for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); - - for (auto _ : state) { -#pragma omp parallel for - for (size_t i = 0; i < dsize / 8; ++i) - key.priv_key->decrypt(de_ct[i], ct[i]); - } -} - -BENCHMARK(BM_Decrypt_buff8_OMP) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); -#endif // IPCL_USE_OMP diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index 369e3ae..62e1a93 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -9,404 +9,74 @@ #endif // IPCL_USE_OMP #include +#include "ipcl/ciphertext.hpp" #include "ipcl/keygen.hpp" -#include "ipcl/ops.hpp" +#include "ipcl/plaintext.hpp" + +constexpr int SELF_DEF_NUM_VALUES = 20; static void BM_Add_CTCT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a( - dsize, std::vector(8, 65535)); - std::vector> b( - dsize, std::vector(8, 65535)); - std::vector> ct_a( - dsize, std::vector(8)); - std::vector> ct_b( - dsize, std::vector(8)); - - for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); - key.pub_key->encrypt(ct_a[i], a[i]); + std::vector exp_value1_v(dsize, 65535), exp_value2_v(dsize, 65535); - b[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); - key.pub_key->encrypt(ct_b[i], b[i]); + ipcl::PlainText pt1, pt2; + for (int i = 0; i < dsize; i++) { + exp_value1_v[i] += (unsigned int)(i * 1024); + exp_value2_v[i] += (unsigned int)(i * 1024); } + pt1 = ipcl::PlainText(exp_value1_v); + pt2 = ipcl::PlainText(exp_value2_v); - for (auto _ : state) { - for (size_t i = 0; i < dsize; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber pen_b(key.pub_key, ct_b[i]); - ipcl::EncryptedNumber sum = pen_a + pen_b; - } - } + ipcl::CipherText ct1 = key.pub_key->encrypt(pt1); + ipcl::CipherText ct2 = key.pub_key->encrypt(pt2); + ipcl::CipherText sum; + for (auto _ : state) sum = ct1 + ct2; } BENCHMARK(BM_Add_CTCT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); -static void BM_Add_CTCT_buff8(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> a( - dsize / 8, std::vector(8, 65535)); - std::vector> b( - dsize / 8, std::vector(8, 65535)); - std::vector> ct_a( - dsize / 8, std::vector(8)); - std::vector> ct_b( - dsize / 8, std::vector(8)); - - for (size_t i = 0; i < dsize / 8; ++i) { - for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - } - - key.pub_key->encrypt(ct_a[i], a[i]); - key.pub_key->encrypt(ct_b[i], b[i]); - } - - for (auto _ : state) { - for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber pen_b(key.pub_key, ct_b[i]); - ipcl::EncryptedNumber sum = pen_a + pen_b; - } - } -} - -BENCHMARK(BM_Add_CTCT_buff8) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - static void BM_Add_CTPT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a( - dsize, std::vector(8, 65535)); - std::vector> b( - dsize, std::vector(8, 65535)); - std::vector> ct_a( - dsize, std::vector(8)); + std::vector exp_value1_v(dsize, 65535), exp_value2_v(dsize, 65535); - for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)(i * 1024) + 999); - b[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); - key.pub_key->encrypt(ct_a[i], a[i]); + ipcl::PlainText pt1, pt2; + for (int i = 0; i < dsize; i++) { + exp_value1_v[i] += (unsigned int)(i * 1024); + exp_value2_v[i] += (unsigned int)(i * 1024); } + pt1 = ipcl::PlainText(exp_value1_v); + pt2 = ipcl::PlainText(exp_value2_v); - for (auto _ : state) { - for (size_t i = 0; i < dsize; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber sum = pen_a + b[i]; - } - } -} - -BENCHMARK(BM_Add_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); - -static void BM_Add_CTPT_buff8(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); + ipcl::CipherText ct1 = key.pub_key->encrypt(pt1); + ipcl::CipherText sum; - std::vector> a( - dsize / 8, std::vector(8, 65535)); - std::vector> b( - dsize / 8, std::vector(8, 65535)); - std::vector> ct_a( - dsize / 8, std::vector(8)); - - for (size_t i = 0; i < dsize / 8; ++i) { - for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - } - - key.pub_key->encrypt(ct_a[i], a[i]); - } - - for (auto _ : state) { - for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber sum = pen_a + b[i]; - } - } + for (auto _ : state) sum = ct1 + pt2; } -BENCHMARK(BM_Add_CTPT_buff8) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); +BENCHMARK(BM_Add_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); static void BM_Mul_CTPT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a( - dsize, std::vector(8, 65535)); - std::vector> b( - dsize, std::vector(8, 65535)); - std::vector> ct_a( - dsize, std::vector(8)); - - for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); - b[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); - key.pub_key->encrypt(ct_a[i], a[i]); - } - - for (auto _ : state) { - for (size_t i = 0; i < dsize; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber pen_b(key.pub_key, b[i]); - ipcl::EncryptedNumber sum = pen_a * pen_b; - } - } -} - -BENCHMARK(BM_Mul_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); - -static void BM_Mul_CTPT_buff8(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> a( - dsize / 8, std::vector(8, 65535)); - std::vector> b( - dsize / 8, std::vector(8, 65535)); - std::vector> ct_a( - dsize / 8, std::vector(8)); - - for (size_t i = 0; i < dsize / 8; ++i) { - for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - } - - key.pub_key->encrypt(ct_a[i], a[i]); - } - - for (auto _ : state) { - for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber pen_b(key.pub_key, b[i]); - ipcl::EncryptedNumber sum = pen_a * pen_b; - } - } -} - -BENCHMARK(BM_Mul_CTPT_buff8) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - -#ifdef IPCL_USE_OMP -static void BM_Add_CTCT_OMP(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> a( - dsize, std::vector(8, 65535)); - std::vector> b( - dsize, std::vector(8, 65535)); - std::vector> ct_a( - dsize, std::vector(8)); - std::vector> ct_b( - dsize, std::vector(8)); - - for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); - key.pub_key->encrypt(ct_a[i], a[i]); - - b[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); - key.pub_key->encrypt(ct_b[i], b[i]); - } - - for (auto _ : state) { -#pragma omp parallel for - for (size_t i = 0; i < dsize; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber pen_b(key.pub_key, ct_b[i]); - ipcl::EncryptedNumber sum = pen_a + pen_b; - } - } -} - -BENCHMARK(BM_Add_CTCT_OMP) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - -static void BM_Add_CTCT_buff8_OMP(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> a( - dsize / 8, std::vector(8, 65535)); - std::vector> b( - dsize / 8, std::vector(8, 65535)); - std::vector> ct_a( - dsize / 8, std::vector(8)); - std::vector> ct_b( - dsize / 8, std::vector(8)); - - for (size_t i = 0; i < dsize / 8; ++i) { - for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - } + std::vector exp_value1_v(dsize, 65535), exp_value2_v(dsize, 65535); - key.pub_key->encrypt(ct_a[i], a[i]); - key.pub_key->encrypt(ct_b[i], b[i]); + ipcl::PlainText pt1, pt2; + for (int i = 0; i < dsize; i++) { + exp_value1_v[i] += (unsigned int)(i * 1024); + exp_value2_v[i] += (unsigned int)(i * 1024); } + pt1 = ipcl::PlainText(exp_value1_v); + pt2 = ipcl::PlainText(exp_value2_v); - for (auto _ : state) { -#pragma omp parallel for - for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber pen_b(key.pub_key, ct_b[i]); - ipcl::EncryptedNumber sum = pen_a + pen_b; - } - } -} + ipcl::CipherText ct1 = key.pub_key->encrypt(pt1); + ipcl::CipherText product; -BENCHMARK(BM_Add_CTCT_buff8_OMP) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - -static void BM_Add_CTPT_OMP(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> a( - dsize, std::vector(8, 65535)); - std::vector> b( - dsize, std::vector(8, 65535)); - std::vector> ct_a( - dsize, std::vector(8)); - - for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); - b[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); - key.pub_key->encrypt(ct_a[i], a[i]); - } - - for (auto _ : state) { -#pragma omp parallel for - for (size_t i = 0; i < dsize; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber sum = pen_a + b[i]; - } - } + for (auto _ : state) product = ct1 * pt2; } -BENCHMARK(BM_Add_CTPT_OMP) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - -static void BM_Add_CTPT_buff8_OMP(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> a( - dsize / 8, std::vector(8, 65535)); - std::vector> b( - dsize / 8, std::vector(8, 65535)); - std::vector> ct_a( - dsize / 8, std::vector(8)); - - for (size_t i = 0; i < dsize / 8; ++i) { - for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - } - - key.pub_key->encrypt(ct_a[i], a[i]); - } - - for (auto _ : state) { -#pragma omp parallel for - for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber sum = pen_a + b[i]; - } - } -} - -BENCHMARK(BM_Add_CTPT_buff8_OMP) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - -static void BM_Mul_CTPT_OMP(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> a( - dsize, std::vector(8, 65535)); - std::vector> b( - dsize, std::vector(8, 65535)); - std::vector> ct_a( - dsize, std::vector(8)); - - for (size_t i = 0; i < dsize; ++i) { - a[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); - b[i][0] = ipcl::BigNumber((unsigned int)i * 1024 + 999); - key.pub_key->encrypt(ct_a[i], a[i]); - } - - for (auto _ : state) { -#pragma omp parallel for - for (size_t i = 0; i < dsize; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber pen_b(key.pub_key, b[i]); - ipcl::EncryptedNumber sum = pen_a * pen_b; - } - } -} - -BENCHMARK(BM_Mul_CTPT_OMP) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - -static void BM_Mul_CTPT_buff8_OMP(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> a( - dsize / 8, std::vector(8, 65535)); - std::vector> b( - dsize / 8, std::vector(8, 65535)); - std::vector> ct_a( - dsize / 8, std::vector(8)); - - for (size_t i = 0; i < dsize / 8; ++i) { - for (size_t j = 0; j < 8; ++j) { - a[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - b[i][j] = ipcl::BigNumber((unsigned int)(i * 8 + j) * 1024 + 999); - } - - key.pub_key->encrypt(ct_a[i], a[i]); - } - - for (auto _ : state) { -#pragma omp parallel for - for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber pen_b(key.pub_key, b[i]); - ipcl::EncryptedNumber sum = pen_a * pen_b; - } - } -} - -BENCHMARK(BM_Mul_CTPT_buff8_OMP) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); -#endif // IPCL_USE_OMP +BENCHMARK(BM_Mul_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 6bf7a0c..c35d682 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -3,10 +3,12 @@ set(IPCL_SRCS pri_key.cpp pub_key.cpp - ops.cpp keygen.cpp bignum.cpp mod_exp.cpp + base_text.cpp + plaintext.cpp + ciphertext.cpp ) diff --git a/ipcl/base_text.cpp b/ipcl/base_text.cpp new file mode 100644 index 0000000..e4e43c5 --- /dev/null +++ b/ipcl/base_text.cpp @@ -0,0 +1,76 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/base_text.hpp" + +#include "ipcl/util.hpp" + +namespace ipcl { + +BaseText::BaseText(const uint32_t& n) : m_texts{BigNumber(n)}, m_size(1) {} + +BaseText::BaseText(const std::vector& n_v) { + for (auto& n : n_v) { + m_texts.push_back(BigNumber(n)); + } + m_size = m_texts.size(); +} + +BaseText::BaseText(const BigNumber& bn) : m_texts{bn}, m_size(1) {} + +BaseText::BaseText(const std::vector& bn_v) + : m_texts(bn_v), m_size(m_texts.size()) {} + +BaseText::BaseText(const BaseText& bt) { + this->m_texts = bt.getTexts(); + this->m_size = bt.getSize(); +} + +BaseText& BaseText::operator=(const BaseText& other) { + if (this == &other) return *this; + + this->m_texts = other.m_texts; + this->m_size = other.m_size; + return *this; +} + +BigNumber BaseText::getElement(const std::size_t& idx) const { + ERROR_CHECK(idx <= m_size, "BaseText: getElement index is out of range"); + + return m_texts[idx]; +} + +std::vector BaseText::getElementVec(const std::size_t& idx) const { + ERROR_CHECK(idx <= m_size, "BaseText: getElementVec index is out of range"); + + std::vector v; + m_texts[idx].num2vec(v); + + return v; +} + +std::string BaseText::getElementHex(const std::size_t& idx) const { + ERROR_CHECK(idx <= m_size, "BaseText: getElementHex index is out of range"); + std::string s; + m_texts[idx].num2hex(s); + + return s; +} + +std::vector BaseText::getChunk(const std::size_t& start, + const std::size_t& size) const { + ERROR_CHECK((start >= 0) && ((start + size) <= m_size), + "BaseText: getChunk parameter is incorrect"); + + auto it_start = m_texts.begin() + start; + auto it_end = it_start + size; + auto v = std::vector(it_start, it_end); + + return v; +} + +std::vector BaseText::getTexts() const { return m_texts; } + +std::size_t BaseText::getSize() const { return m_size; } + +} // namespace ipcl diff --git a/ipcl/bignum.cpp b/ipcl/bignum.cpp index b5adab3..7a685db 100644 --- a/ipcl/bignum.cpp +++ b/ipcl/bignum.cpp @@ -25,8 +25,6 @@ // ////////////////////////////////////////////////////////////////////// -namespace ipcl { - BigNumber::~BigNumber() { delete[](Ipp8u*) m_pBN; } bool BigNumber::create(const Ipp32u* pData, int length, IppsBigNumSGN sgn) { @@ -508,5 +506,3 @@ void BigNumber::num2char(std::vector& dest) const { int len = (bnBitLen + 7) >> 3; dest.assign(bnData, bnData + len); } - -} // namespace ipcl diff --git a/ipcl/ciphertext.cpp b/ipcl/ciphertext.cpp new file mode 100644 index 0000000..9532d9e --- /dev/null +++ b/ipcl/ciphertext.cpp @@ -0,0 +1,148 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/ciphertext.hpp" + +#include + +#ifdef IPCL_CRYPTO_OMP +#include +#endif + +#include "ipcl/mod_exp.hpp" + +namespace ipcl { +CipherText::CipherText(const PublicKey* pub_key, const uint32_t& n) + : BaseText(n), m_pubkey(pub_key) {} + +CipherText::CipherText(const PublicKey* pub_key, + const std::vector& n_v) + : BaseText(n_v), m_pubkey(pub_key) {} + +CipherText::CipherText(const PublicKey* pub_key, const BigNumber& bn) + : BaseText(bn), m_pubkey(pub_key) {} + +CipherText::CipherText(const PublicKey* pub_key, + const std::vector& bn_v) + : BaseText(bn_v), m_pubkey(pub_key) {} + +CipherText::CipherText(const CipherText& ct) : BaseText(ct) { + this->m_pubkey = ct.m_pubkey; +} + +CipherText& CipherText::operator=(const CipherText& other) { + BaseText::operator=(other); + this->m_pubkey = other.m_pubkey; + + return *this; +} + +// CT+CT +CipherText CipherText::operator+(const CipherText& other) const { + std::size_t b_size = other.getSize(); + ERROR_CHECK(this->m_size == b_size || b_size == 1, + "CT + CT error: Size mismatch!"); + ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), + "CT + CT error: 2 different public keys detected!"); + + const auto& a = *this; + const auto& b = other; + + if (m_size == 1) { + BigNumber sum = a.raw_add(a.m_texts.front(), b.getTexts().front()); + return CipherText(m_pubkey, sum); + } else { + std::vector sum(m_size); + + if (b_size == 1) { + // add vector by scalar +#ifdef IPCL_USE_OMP +#pragma omp parallel for +#endif // IPCL_USE_OMP + for (std::size_t i = 0; i < m_size; i++) + sum[i] = a.raw_add(a.m_texts[i], b.m_texts[0]); + } else { + // add vector by vector +#ifdef IPCL_USE_OMP +#pragma omp parallel for +#endif // IPCL_USE_OMP + for (std::size_t i = 0; i < m_size; i++) + sum[i] = a.raw_add(a.m_texts[i], b.m_texts[i]); + } + return CipherText(m_pubkey, sum); + } +} + +// CT + PT +CipherText CipherText::operator+(const PlainText& other) const { + // convert PT to CT + CipherText b = this->m_pubkey->encrypt(other, false); + // calculate CT + CT + return this->operator+(b); +} + +// CT * PT +CipherText CipherText::operator*(const PlainText& other) const { + std::size_t b_size = other.getSize(); + ERROR_CHECK(this->m_size == b_size || b_size == 1, + "CT * PT error: Size mismatch!"); + + const auto& a = *this; + const auto& b = other; + + if (m_size == 1) { + BigNumber product = a.raw_mul(a.m_texts.front(), b.getTexts().front()); + return CipherText(m_pubkey, product); + } else { + std::vector product; + if (b_size == 1) { + // multiply vector by scalar + std::vector b_v(a.m_size, b.getElement(0)); + product = a.raw_mul(a.m_texts, b_v); + } else { + // multiply vector by vector + product = a.raw_mul(a.m_texts, b.getTexts()); + } + return CipherText(m_pubkey, product); + } +} + +PublicKey CipherText::getPubKey() const { return *m_pubkey; } + +CipherText CipherText::rotate(int shift) const { + ERROR_CHECK(m_size != 1, "rotate: Cannot rotate single CipherText"); + ERROR_CHECK(shift >= -8 && shift <= 8, + "rotate: Cannot shift more than 8 or -8"); + + if (shift == 0 || shift == 8 || shift == -8) + return CipherText(m_pubkey, m_texts); + + if (shift > 0) + shift = 8 - shift; + else + shift = -shift; + + std::vector new_bn = getTexts(); + std::rotate(std::begin(new_bn), std::begin(new_bn) + shift, std::end(new_bn)); + return CipherText(m_pubkey, new_bn); +} + +BigNumber CipherText::raw_add(const BigNumber& a, const BigNumber& b) const { + // Hold a copy of nsquare for multi-threaded + const BigNumber& sq = m_pubkey->getNSQ(); + return a * b % sq; +} + +BigNumber CipherText::raw_mul(const BigNumber& a, const BigNumber& b) const { + const BigNumber& sq = m_pubkey->getNSQ(); + return ipcl::ippModExp(a, b, sq); +} + +std::vector CipherText::raw_mul( + const std::vector& a, const std::vector& b) const { + std::size_t v_size = a.size(); + std::vector sq(v_size, m_pubkey->getNSQ()); + return ipcl::ippModExp(a, b, sq); +} + +} // namespace ipcl diff --git a/ipcl/include/ipcl/base_text.hpp b/ipcl/include/ipcl/base_text.hpp new file mode 100644 index 0000000..0f9e10e --- /dev/null +++ b/ipcl/include/ipcl/base_text.hpp @@ -0,0 +1,83 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IPCL_INCLUDE_IPCL_BASE_TEXT_HPP_ +#define IPCL_INCLUDE_IPCL_BASE_TEXT_HPP_ + +#include +#include + +#include "ipcl/bignum.h" + +namespace ipcl { + +class BaseText { + public: + BaseText() = default; + ~BaseText() = default; + + /** + * BaseText constructors + */ + explicit BaseText(const uint32_t& n); + explicit BaseText(const std::vector& n_v); + explicit BaseText(const BigNumber& bn); + explicit BaseText(const std::vector& bn_v); + + /** + * BaseText copy constructor + */ + BaseText(const BaseText& bt); + + /** + * BaseText assignment constructor + */ + BaseText& operator=(const BaseText& other); + + /** + * Gets the specified BigNumber element in m_text + * @param[in] idx Element index + * return Element in m_text of type BigNumber + */ + BigNumber getElement(const std::size_t& idx) const; + + /** + * Gets the specified BigNumber vector form + * @param[in] idx Element index + * @return Element vector form + */ + std::vector getElementVec(const std::size_t& idx) const; + + /** + * Gets the specified BigNumber hex string form + * @param[in] idx Element index + * @return Element hex string form + */ + std::string getElementHex(const std::size_t& idx) const; + + /** + * Gets a chunk of BigNumber element in m_text + * @param[in] start Start position + * @param[in] size The number of element + * return A chunk of BigNumber element + */ + std::vector getChunk(const std::size_t& start, + const std::size_t& size) const; + + /** + * Gets the BigNumber container + */ + std::vector getTexts() const; + + /** + * Gets the size of the BigNumber container + */ + std::size_t getSize() const; + + protected: + std::vector m_texts; ///< Container used to store BigNumber + std::size_t m_size; ///< Container size +}; + +} // namespace ipcl +#endif // IPCL_INCLUDE_IPCL_BASE_TEXT_HPP_ diff --git a/ipcl/include/ipcl/bignum.h b/ipcl/include/ipcl/bignum.h index fe62dc1..b97c0c2 100644 --- a/ipcl/include/ipcl/bignum.h +++ b/ipcl/include/ipcl/bignum.h @@ -22,8 +22,6 @@ #include #include -namespace ipcl { - class BigNumber { public: BigNumber(Ipp32u value = 0); @@ -131,5 +129,4 @@ class BigNumber { constexpr int BITSIZE_WORD(int n) { return (((n) + 31) >> 5); } constexpr int BITSIZE_DWORD(int n) { return (((n) + 63) >> 6); } -} // namespace ipcl #endif // _BIGNUM_H_ diff --git a/ipcl/include/ipcl/ciphertext.hpp b/ipcl/include/ipcl/ciphertext.hpp new file mode 100644 index 0000000..bd6d701 --- /dev/null +++ b/ipcl/include/ipcl/ciphertext.hpp @@ -0,0 +1,67 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IPCL_INCLUDE_IPCL_CIPHERTEXT_HPP_ +#define IPCL_INCLUDE_IPCL_CIPHERTEXT_HPP_ + +#include + +#include "ipcl/plaintext.hpp" +#include "ipcl/pub_key.hpp" +#include "ipcl/util.hpp" + +namespace ipcl { + +class CipherText : public BaseText { + public: + CipherText() = default; + ~CipherText() = default; + + /** + * CipherText constructors + */ + CipherText(const PublicKey* pub_key, const uint32_t& n); + CipherText(const PublicKey* pub_key, const std::vector& n_v); + CipherText(const PublicKey* pub_key, const BigNumber& bn); + CipherText(const PublicKey* pub_key, const std::vector& bn_vec); + + /** + * CipherText copy constructor + */ + CipherText(const CipherText& ct); + /** + * CipherText assignment constructor + */ + CipherText& operator=(const CipherText& other); + + // CT+CT + CipherText operator+(const CipherText& other) const; + // CT+PT + CipherText operator+(const PlainText& other) const; + // CT*PT + CipherText operator*(const PlainText& other) const; + + /** + * Get public key + */ + PublicKey getPubKey() const; + + /** + * Rotate CipherText + * @param[in] shift rotate length + */ + CipherText rotate(int shift) const; + + const void* addr = static_cast(this); + + private: + BigNumber raw_add(const BigNumber& a, const BigNumber& b) const; + BigNumber raw_mul(const BigNumber& a, const BigNumber& b) const; + std::vector raw_mul(const std::vector& a, + const std::vector& b) const; + + const PublicKey* m_pubkey; ///< Public key used to encrypt big number +}; + +} // namespace ipcl +#endif // IPCL_INCLUDE_IPCL_CIPHERTEXT_HPP_ diff --git a/ipcl/include/ipcl/ops.hpp b/ipcl/include/ipcl/ops.hpp deleted file mode 100644 index 6aab2f8..0000000 --- a/ipcl/include/ipcl/ops.hpp +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#ifndef IPCL_INCLUDE_IPCL_OPS_HPP_ -#define IPCL_INCLUDE_IPCL_OPS_HPP_ - -#include - -#include "ipcl/pub_key.hpp" -#include "ipcl/util.hpp" - -namespace ipcl { - -class EncryptedNumber { - public: - /** - * EncryptedNumber constructor - * @param[in] pub_key paillier public key - * @param[in] bn ciphertext encrypted by paillier public key - */ - EncryptedNumber(const PublicKey* pub_key, const BigNumber& bn); - - /** - * EncryptedNumber constructor - * @param[in] pub_key paillier public key - * @param[in] bn array of ciphertexts encrypted by paillier public key - * @param[in] length size of array(default value is IPCL_CRYPTO_MB_SIZE) - */ - EncryptedNumber(const PublicKey* pub_key, const std::vector& bn, - size_t length = IPCL_CRYPTO_MB_SIZE); - - /** - * EncryptedNumber constructor - * @param[in] pub_key paillier public key - * @param[in] scalar array of integer scalars - * @param[in] length size of array(default value is IPCL_CRYPTO_MB_SIZE) - */ - EncryptedNumber(const PublicKey* pub_key, const std::vector& scalar, - size_t length = IPCL_CRYPTO_MB_SIZE); - - /** - * Arithmetic addition operator - * @param[in] bn augend - */ - EncryptedNumber operator+(const EncryptedNumber& bn) const; - - /** - * Arithmetic addition operator - * @param[in] other augend - */ - EncryptedNumber operator+(const BigNumber& other) const; - - /** - * Arithmetic addition operator - * @param[in] other array of augend - */ - EncryptedNumber operator+(const std::vector& other) const; - - /** - * Arithmetic multiply operator - * @param[in] bn multiplicand - */ - EncryptedNumber operator*(const EncryptedNumber& bn) const; - - /** - * Arithmetic multiply operator - * @param[in] other multiplicand - */ - EncryptedNumber operator*(const BigNumber& other) const; - - /** - * Apply obfuscator for ciphertext, obfuscated needed only when the ciphertext - * is exposed - */ - void apply_obfuscator(); - - /** - * Return ciphertext - * @param[in] idx index of ciphertext stored in EncryptedNumber - * (default = 0) - */ - BigNumber getBN(size_t idx = 0) const { - ERROR_CHECK(m_available != 1 || idx <= 0, - "getBN: EncryptedNumber only has 1 BigNumber"); - - return m_bn[idx]; - } - - /** - * Get public key - */ - PublicKey getPK() const { return *m_pubkey; } - - /** - * Rotate EncryptedNumber - * @param[in] shift rotate length - */ - EncryptedNumber rotate(int shift) const; - - /** - * Return entire ciphertext array - * @param[out] bn output array - */ - std::vector getArrayBN() const { return m_bn; } - - /** - * Check if element in EncryptedNumber is single - */ - bool isSingle() const { return m_available == 1; } - - /** - * Get size of array in EncryptedNumber - */ - size_t getLength() const { return m_length; } - - const void* addr = static_cast(this); - - private: - bool b_isObfuscator; - int m_available; - const PublicKey* m_pubkey; - size_t m_length; - std::vector m_bn; - - BigNumber raw_add(const BigNumber& a, const BigNumber& b) const; - BigNumber raw_mul(const BigNumber& a, const BigNumber& b) const; - std::vector raw_mul(const std::vector& a, - const std::vector& b) const; -}; - -} // namespace ipcl -#endif // IPCL_INCLUDE_IPCL_OPS_HPP_ diff --git a/ipcl/include/ipcl/plaintext.hpp b/ipcl/include/ipcl/plaintext.hpp new file mode 100644 index 0000000..8b34e7d --- /dev/null +++ b/ipcl/include/ipcl/plaintext.hpp @@ -0,0 +1,75 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IPCL_INCLUDE_IPCL_PLAINTEXT_HPP_ +#define IPCL_INCLUDE_IPCL_PLAINTEXT_HPP_ + +#include + +#include "ipcl/base_text.hpp" + +namespace ipcl { +/** + * This structure encapsulates types uint32_t, + * uint32_t vector, BigNumber and BigNumber vector. + */ +class PlainText : public BaseText { + public: + PlainText() = default; + ~PlainText() = default; + + /** + * PlainText constructor + * @param[in] n Reference to a uint32_t integer + */ + explicit PlainText(const uint32_t& n); + + /** + * PlainText constructor + * @param[in] n_v Reference to a uint32_t vector + */ + explicit PlainText(const std::vector& n_v); + + /** + * PlainText constructor + * @param[in] bn Reference to a BigNumber + */ + explicit PlainText(const BigNumber& bn); + + /** + * PlainText constructor + * @param[in] bn_v Reference to a BigNumber vector + */ + explicit PlainText(const std::vector& bn_v); + + /** + * PlainText copy constructor + */ + PlainText(const PlainText& pt); + + /** + * PlainText assignment constructor + */ + PlainText& operator=(const PlainText& other); + + /** + * User define implicit type conversion + * Convert 1st element to uint32_t vector. + */ + operator std::vector(); + + /** + * User define implicit type conversion + * Convert 1st element to type BigNumber. + */ + operator BigNumber(); + + /** + * User define implicit type conversion + * Convert all element to type BigNumber. + */ + operator std::vector(); +}; + +} // namespace ipcl +#endif // IPCL_INCLUDE_IPCL_PLAINTEXT_HPP_ diff --git a/ipcl/include/ipcl/pri_key.hpp b/ipcl/include/ipcl/pri_key.hpp index b3466eb..d351d03 100644 --- a/ipcl/include/ipcl/pri_key.hpp +++ b/ipcl/include/ipcl/pri_key.hpp @@ -6,7 +6,8 @@ #include -#include "ipcl/ops.hpp" +#include "ipcl/ciphertext.hpp" +#include "ipcl/plaintext.hpp" namespace ipcl { @@ -29,19 +30,10 @@ class PrivateKey { /** * Decrypt ciphertext - * @param[out] plaintext output of the decryption - * @param[in] ciphertext ciphertext to be decrypted + * @param[in] ciphertext CipherText to be decrypted + * @return plaintext of type PlainText */ - void decrypt(std::vector& plaintext, - const std::vector& ciphertext) const; - - /** - * Decrypt ciphertext - * @param[out] plaintext output of the decryption - * @param[in] ciphertext EncryptedNumber to be decrypted - */ - void decrypt(std::vector& plaintext, - const EncryptedNumber ciphertext) const; + PlainText decrypt(const CipherText& ciphertext) const; const void* addr = static_cast(this); diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp index b3e757e..9f9c9b5 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -7,9 +7,12 @@ #include #include "ipcl/bignum.h" +#include "ipcl/plaintext.hpp" namespace ipcl { +class CipherText; + class PublicKey { public: /** @@ -37,20 +40,11 @@ class PublicKey { /** * Encrypt plaintext - * @param[out] ciphertext output of the encryption - * @param[in] value array of plaintext to be encrypted + * @param[in] plaintext of type PlainText * @param[in] make_secure apply obfuscator(default value is true) + * @return ciphertext of type CipherText */ - void encrypt(std::vector& ciphertext, - const std::vector& value, - bool make_secure = true) const; - - /** - * Encrypt plaintext - * @param[out] ciphertext output of the encryption - * @param[in] value plaintext to be encrypted - */ - void encrypt(BigNumber& ciphertext, const BigNumber& value) const; + CipherText encrypt(const PlainText& plaintext, bool make_secure = true) const; /** * Get N of public key in paillier scheme @@ -113,14 +107,14 @@ class PublicKey { std::vector randIpp32u(int size) const; /** - * Raw encrypt function - * @param[out] ciphertext array output of the encryption - * @param[in] plaintext plaintext array to be encrypted + * Big number vector multi buffer encryption + * @param[in] pt plaintext of BigNumber vector type * @param[in] make_secure apply obfuscator(default value is true) + * @return ciphertext of BigNumber vector type */ - void raw_encrypt(std::vector& ciphertext, - const std::vector& plaintext, - bool make_secure = true) const; + std::vector raw_encrypt(const std::vector& pt, + bool make_secure = true) const; + /** * Get random value * @param[in] length bit length diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index b578b60..be9535b 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -5,7 +5,13 @@ #include +#include #include +#include + +#ifdef IPCL_CRYPTO_OMP +#include +#endif #include "ipcl/util.hpp" @@ -30,6 +36,9 @@ static std::vector ippMBModExp(const std::vector& base, std::vector p_array(IPCL_CRYPTO_MB_SIZE); int length = dwords * sizeof(int64u); +#ifdef IPCL_USE_OMP +#pragma omp parallel for +#endif // IPCL_USE_OMP for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { out_x[i] = reinterpret_cast(alloca(length)); b_array[i] = reinterpret_cast(alloca(length)); @@ -53,27 +62,32 @@ static std::vector ippMBModExp(const std::vector& base, std::vector pow_b(IPCL_CRYPTO_MB_SIZE); std::vector pow_p(IPCL_CRYPTO_MB_SIZE); std::vector pow_nsquare(IPCL_CRYPTO_MB_SIZE); - int nsqBitLen; - int expBitLen = 0; + std::vector b_size_v(IPCL_CRYPTO_MB_SIZE); + std::vector p_size_v(IPCL_CRYPTO_MB_SIZE); + std::vector n_size_v(IPCL_CRYPTO_MB_SIZE); - for (int i = 0, bBitLen, pBitLen; i < IPCL_CRYPTO_MB_SIZE; i++) { - ippsRef_BN(nullptr, &bBitLen, reinterpret_cast(&pow_b[i]), +#ifdef IPCL_USE_OMP +#pragma omp parallel for +#endif // IPCL_USE_OMP + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + ippsRef_BN(nullptr, &b_size_v[i], reinterpret_cast(&pow_b[i]), base[i]); - ippsRef_BN(nullptr, &pBitLen, reinterpret_cast(&pow_p[i]), + ippsRef_BN(nullptr, &p_size_v[i], reinterpret_cast(&pow_p[i]), pow[i]); - ippsRef_BN(nullptr, &nsqBitLen, &pow_nsquare[i], m[i]); - - memcpy(b_array[i], pow_b[i], BITSIZE_WORD(bBitLen) * 4); - memcpy(p_array[i], pow_p[i], BITSIZE_WORD(pBitLen) * 4); + ippsRef_BN(nullptr, &n_size_v[i], &pow_nsquare[i], m[i]); - if (expBitLen < pBitLen) expBitLen = pBitLen; + memcpy(b_array[i], pow_b[i], BITSIZE_WORD(b_size_v[i]) * 4); + memcpy(p_array[i], pow_p[i], BITSIZE_WORD(p_size_v[i]) * 4); } - /* - *Note: If actual sizes of exp are different, set the exp_bits parameter equal - *to maximum size of the actual module in bit size and extend all the modules - *with zero bits - */ + // Find the biggest size of module and exp + int nsqBitLen = *std::max_element(n_size_v.begin(), n_size_v.end()); + int expBitLen = *std::max_element(p_size_v.begin(), p_size_v.end()); + + // If actual sizes of modules are different, + // set the mod_bits parameter equal to maximum size of the actual module in + // bit size and extend all the modules with zero bits to the mod_bits value. + // The same is applicable for the exp_bits parameter and actual exponents. st = mbx_exp_mb8(out_x.data(), b_array.data(), p_array.data(), expBitLen, reinterpret_cast(pow_nsquare.data()), nsqBitLen, reinterpret_cast(buffer.data()), bufferLen); @@ -89,6 +103,9 @@ static std::vector ippMBModExp(const std::vector& base, BigNumber bn_c(m.front()); std::vector res(IPCL_CRYPTO_MB_SIZE, 0); +#ifdef IPCL_USE_OMP +#pragma omp parallel for +#endif // IPCL_USE_OMP for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { bn_c.Set(reinterpret_cast(out_x[i]), BITSIZE_WORD(nsqBitLen), IppsBigNumPOS); @@ -152,14 +169,82 @@ static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, std::vector ippModExp(const std::vector& base, const std::vector& pow, const std::vector& m) { + std::size_t v_size = base.size(); + std::vector res(v_size); + #ifdef IPCL_CRYPTO_MB_MOD_EXP - return ippMBModExp(base, pow, m); + + // If there is only 1 big number, we don't need to use MBModExp + if (v_size == 1) { + res[0] = ippSBModExp(base[0], pow[0], m[0]); + return res; + } + + std::size_t offset = 0; + std::size_t num_chunk = v_size / IPCL_CRYPTO_MB_SIZE; + std::size_t remainder = v_size % IPCL_CRYPTO_MB_SIZE; + +#ifdef IPCL_USE_OMP +#pragma omp parallel for +#endif // IPCL_USE_OMP + for (std::size_t i = 0; i < num_chunk; i++) { + offset = i * IPCL_CRYPTO_MB_SIZE; + auto base_start = base.begin() + offset; + auto base_end = base_start + IPCL_CRYPTO_MB_SIZE; + + auto pow_start = pow.begin() + offset; + auto pow_end = pow_start + IPCL_CRYPTO_MB_SIZE; + + auto m_start = m.begin() + offset; + auto m_end = m_start + IPCL_CRYPTO_MB_SIZE; + + auto base_chunk = std::vector(base_start, base_end); + auto pow_chunk = std::vector(pow_start, pow_end); + auto m_chunk = std::vector(m_start, m_end); + + auto tmp = ippMBModExp(base_chunk, pow_chunk, m_chunk); + std::copy(tmp.begin(), tmp.end(), res.begin() + offset); + } + + offset = num_chunk * IPCL_CRYPTO_MB_SIZE; + // If only 1 big number left, we don't need to make padding + if (remainder == 1) + res[offset] = ippSBModExp(base[offset], pow[offset], m[offset]); + + // If the 1 < remainder < IPCL_CRYPTO_MB_SIZE, we need to make padding + if (remainder > 1) { + auto base_start = base.begin() + offset; + auto base_end = base_start + remainder; + + auto pow_start = pow.begin() + offset; + auto pow_end = pow_start + remainder; + + auto m_start = m.begin() + offset; + auto m_end = m_start + remainder; + + std::vector base_chunk(IPCL_CRYPTO_MB_SIZE, 0); + std::vector pow_chunk(IPCL_CRYPTO_MB_SIZE, 0); + std::vector m_chunk(IPCL_CRYPTO_MB_SIZE, 0); + + std::copy(base_start, base_end, base_chunk.begin()); + std::copy(pow_start, pow_end, pow_chunk.begin()); + std::copy(m_start, m_end, m_chunk.begin()); + + auto tmp = ippMBModExp(base_chunk, pow_chunk, m_chunk); + std::copy(tmp.begin(), tmp.begin() + remainder, res.begin() + offset); + } + + return res; + #else - std::vector res(IPCL_CRYPTO_MB_SIZE); - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) - res[i] = ippSBModExp(base[i], pow[i], m[i]); + +#ifdef IPCL_USE_OMP +#pragma omp parallel for +#endif // IPCL_USE_OMP + for (int i = 0; i < v_size; i++) res[i] = ippSBModExp(base[i], pow[i], m[i]); return res; -#endif + +#endif // IPCL_CRYPTO_MB_MOD_EXP } BigNumber ippModExp(const BigNumber& base, const BigNumber& pow, diff --git a/ipcl/ops.cpp b/ipcl/ops.cpp deleted file mode 100644 index 2deaf5d..0000000 --- a/ipcl/ops.cpp +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include "ipcl/ops.hpp" - -#include - -#include "ipcl/mod_exp.hpp" - -namespace ipcl { -// constructors -// -EncryptedNumber::EncryptedNumber(const PublicKey* pub_key, const BigNumber& bn) - : b_isObfuscator(false), - m_available(1), - m_pubkey(pub_key), - m_length(1), - m_bn{bn} {} - -EncryptedNumber::EncryptedNumber(const PublicKey* pub_key, - const std::vector& bn, - size_t length) - : b_isObfuscator(false), - m_pubkey(pub_key), - m_available(IPCL_CRYPTO_MB_SIZE), - m_length(length), - m_bn{bn[0], bn[1], bn[2], bn[3], bn[4], bn[5], bn[6], bn[7]} {} - -EncryptedNumber::EncryptedNumber(const PublicKey* pub_key, - const std::vector& scalar, - size_t length) - : b_isObfuscator(false), - m_pubkey(pub_key), - m_available(IPCL_CRYPTO_MB_SIZE), - m_length(length), - m_bn{scalar[0], scalar[1], scalar[2], scalar[3], - scalar[4], scalar[5], scalar[6], scalar[7]} {} - -// CT+CT -EncryptedNumber EncryptedNumber::operator+(const EncryptedNumber& other) const { - ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), - "operator+: two different public keys detected!!"); - - const auto& a = *this; - const auto& b = other; - - if (m_available == 1) { - BigNumber sum = a.raw_add(a.m_bn.front(), b.m_bn.front()); - return EncryptedNumber(m_pubkey, sum); - } - std::vector sum(IPCL_CRYPTO_MB_SIZE); - for (int i = 0; i < m_available; i++) - sum[i] = a.raw_add(a.m_bn[i], b.m_bn[i]); - return EncryptedNumber(m_pubkey, sum); -} - -// CT+PT -EncryptedNumber EncryptedNumber::operator+(const BigNumber& other) const { - const auto& a = *this; - BigNumber b; - a.m_pubkey->encrypt(b, other); - - BigNumber sum = a.raw_add(a.m_bn.front(), b); - return EncryptedNumber(m_pubkey, sum); -} - -// multi encrypted CT+PT -EncryptedNumber EncryptedNumber::operator+( - const std::vector& other) const { - VEC_SIZE_CHECK(other); - - const auto& a = *this; - - std::vector b(IPCL_CRYPTO_MB_SIZE); - std::vector sum(IPCL_CRYPTO_MB_SIZE); - a.m_pubkey->encrypt(b, other, false); - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) - sum[i] = a.raw_add(a.m_bn[i], b[i]); - return EncryptedNumber(m_pubkey, sum); -} - -// CT*PT EncryptedNumber store a plaintext integer, not an encrypted -// integer -EncryptedNumber EncryptedNumber::operator*(const EncryptedNumber& other) const { - ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), - "operator*: two different public keys detected!!"); - - const auto& a = *this; - const auto& b = other; - - if (m_available == 1) { - BigNumber product = a.raw_mul(a.m_bn.front(), b.m_bn.front()); - return EncryptedNumber(m_pubkey, product); - } - - std::vector&& product = a.raw_mul(a.m_bn, b.m_bn); - return EncryptedNumber(m_pubkey, product); -} - -// CT*PT -EncryptedNumber EncryptedNumber::operator*(const BigNumber& other) const { - const auto& a = *this; - - BigNumber b = other; - BigNumber product = a.raw_mul(a.m_bn.front(), b); - return EncryptedNumber(m_pubkey, product); -} - -BigNumber EncryptedNumber::raw_add(const BigNumber& a, - const BigNumber& b) const { - // Hold a copy of nsquare for multi-threaded - const BigNumber& sq = m_pubkey->getNSQ(); - return a * b % sq; -} - -std::vector EncryptedNumber::raw_mul( - const std::vector& a, const std::vector& b) const { - std::vector sq(IPCL_CRYPTO_MB_SIZE, m_pubkey->getNSQ()); - return ipcl::ippModExp(a, b, sq); -} - -BigNumber EncryptedNumber::raw_mul(const BigNumber& a, - const BigNumber& b) const { - const BigNumber& sq = m_pubkey->getNSQ(); - return ipcl::ippModExp(a, b, sq); -} - -EncryptedNumber EncryptedNumber::rotate(int shift) const { - ERROR_CHECK(m_available != 1, "rotate: Cannot rotate single EncryptedNumber"); - ERROR_CHECK(shift >= -8 && shift <= 8, - "rotate: Cannot shift more than 8 or -8"); - - if (shift == 0 || shift == 8 || shift == -8) - return EncryptedNumber(m_pubkey, m_bn); - - if (shift > 0) - shift = 8 - shift; - else - shift = -shift; - - std::vector new_bn = getArrayBN(); - - std::rotate(std::begin(new_bn), std::begin(new_bn) + shift, std::end(new_bn)); - return EncryptedNumber(m_pubkey, new_bn); -} - -void EncryptedNumber::apply_obfuscator() { - b_isObfuscator = true; - std::vector obfuscator(IPCL_CRYPTO_MB_SIZE); - m_pubkey->applyObfuscator(obfuscator); - - BigNumber sq = m_pubkey->getNSQ(); - for (int i = 0; i < m_available; i++) - m_bn[i] = sq.ModMul(m_bn[i], obfuscator[i]); -} - -} // namespace ipcl diff --git a/ipcl/plaintext.cpp b/ipcl/plaintext.cpp new file mode 100644 index 0000000..a4feccf --- /dev/null +++ b/ipcl/plaintext.cpp @@ -0,0 +1,46 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/plaintext.hpp" + +#include "ipcl/util.hpp" + +namespace ipcl { + +PlainText::PlainText(const uint32_t& n) : BaseText(n) {} + +PlainText::PlainText(const std::vector& n_v) : BaseText(n_v) {} + +PlainText::PlainText(const BigNumber& bn) : BaseText(bn) {} + +PlainText::PlainText(const std::vector& bn_v) : BaseText(bn_v) {} + +PlainText::PlainText(const PlainText& pt) : BaseText(pt) {} + +PlainText& PlainText::operator=(const PlainText& other) { + BaseText::operator=(other); + + return *this; +} + +PlainText::operator std::vector() { + ERROR_CHECK(m_size > 0, + "PlainText: type conversion to uint32_t vector error"); + std::vector v; + m_texts[0].num2vec(v); + + return v; +} + +PlainText::operator BigNumber() { + ERROR_CHECK(m_size > 0, "PlainText: type conversion to BigNumber error"); + return m_texts[0]; +} + +PlainText::operator std::vector() { + ERROR_CHECK(m_size > 0, + "PlainText: type conversion to BigNumber vector error"); + return m_texts; +} + +} // namespace ipcl diff --git a/ipcl/pri_key.cpp b/ipcl/pri_key.cpp index 083c708..f938217 100644 --- a/ipcl/pri_key.cpp +++ b/ipcl/pri_key.cpp @@ -53,54 +53,49 @@ PrivateKey::PrivateKey(const PublicKey* public_key, const BigNumber& p, ERROR_CHECK(p != q, "PrivateKey ctor: p and q are same"); } -void PrivateKey::decryptRAW(std::vector& plaintext, - const std::vector& ciphertext) const { - std::vector pow_lambda(IPCL_CRYPTO_MB_SIZE, m_lambda); - std::vector modulo(IPCL_CRYPTO_MB_SIZE, m_nsquare); - std::vector res = ipcl::ippModExp(ciphertext, pow_lambda, modulo); - - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - BigNumber m = (res[i] - 1) / m_n; - m *= m_x; - plaintext[i] = m % m_n; - } -} +PlainText PrivateKey::decrypt(const CipherText& ct) const { + ERROR_CHECK(ct.getPubKey().getN() == m_pubkey->getN(), + "decrypt: The value of N in public key mismatch."); -void PrivateKey::decrypt(std::vector& plaintext, - const std::vector& ciphertext) const { - VEC_SIZE_CHECK(plaintext); - VEC_SIZE_CHECK(ciphertext); + std::size_t ct_size = ct.getSize(); + std::vector pt_bn(ct_size); + std::vector ct_bn = ct.getTexts(); if (m_enable_crt) - decryptCRT(plaintext, ciphertext); + decryptCRT(pt_bn, ct_bn); else - decryptRAW(plaintext, ciphertext); + decryptRAW(pt_bn, ct_bn); + + return PlainText(pt_bn); } -void PrivateKey::decrypt(std::vector& plaintext, - const EncryptedNumber ciphertext) const { - VEC_SIZE_CHECK(plaintext); - // check key match - ERROR_CHECK(ciphertext.getPK().getN() == m_pubkey->getN(), - "decrypt: public key mismatch error."); +void PrivateKey::decryptRAW(std::vector& plaintext, + const std::vector& ciphertext) const { + std::size_t v_size = plaintext.size(); - const std::vector& res = ciphertext.getArrayBN(); - if (m_enable_crt) - decryptCRT(plaintext, res); - else - decryptRAW(plaintext, res); + std::vector pow_lambda(v_size, m_lambda); + std::vector modulo(v_size, m_nsquare); + std::vector res = ipcl::ippModExp(ciphertext, pow_lambda, modulo); + + BigNumber nn = m_n; + BigNumber xx = m_x; + for (int i = 0; i < v_size; i++) { + BigNumber m = (res[i] - 1) / nn; + m = m * xx; + plaintext[i] = m % nn; + } } // CRT to calculate base^exp mod n^2 void PrivateKey::decryptCRT(std::vector& plaintext, const std::vector& ciphertext) const { - std::vector basep(IPCL_CRYPTO_MB_SIZE), baseq(IPCL_CRYPTO_MB_SIZE); - std::vector pm1(IPCL_CRYPTO_MB_SIZE, m_pminusone), - qm1(IPCL_CRYPTO_MB_SIZE, m_qminusone); - std::vector psq(IPCL_CRYPTO_MB_SIZE, m_psquare), - qsq(IPCL_CRYPTO_MB_SIZE, m_qsquare); + std::size_t v_size = plaintext.size(); + + std::vector basep(v_size), baseq(v_size); + std::vector pm1(v_size, m_pminusone), qm1(v_size, m_qminusone); + std::vector psq(v_size, m_psquare), qsq(v_size, m_qsquare); - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + for (int i = 0; i < v_size; i++) { basep[i] = ciphertext[i] % psq[i]; baseq[i] = ciphertext[i] % qsq[i]; } @@ -109,7 +104,7 @@ void PrivateKey::decryptCRT(std::vector& plaintext, std::vector resp = ipcl::ippModExp(basep, pm1, psq); std::vector resq = ipcl::ippModExp(baseq, qm1, qsq); - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + for (int i = 0; i < v_size; i++) { BigNumber dp = computeLfun(resp[i], m_p) * m_hp % m_p; BigNumber dq = computeLfun(resq[i], m_q) * m_hq % m_q; plaintext[i] = computeCRT(dp, dq); diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index f3d347b..06c2b58 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -14,6 +14,7 @@ #include #endif +#include "ipcl/ciphertext.hpp" #include "ipcl/mod_exp.hpp" #include "ipcl/util.hpp" @@ -110,12 +111,11 @@ void PublicKey::enableDJN() { } void PublicKey::applyObfuscator(std::vector& obfuscator) const { - std::vector r(IPCL_CRYPTO_MB_SIZE); - std::vector pown(IPCL_CRYPTO_MB_SIZE, m_n); - std::vector base(IPCL_CRYPTO_MB_SIZE, m_hs); - std::vector sq(IPCL_CRYPTO_MB_SIZE, m_nsquare); - - VEC_SIZE_CHECK(obfuscator); + std::size_t obf_size = obfuscator.size(); + std::vector r(obf_size); + std::vector pown(obf_size, m_n); + std::vector base(obf_size, m_hs); + std::vector sq(obf_size, m_nsquare); if (m_enable_DJN) { for (auto& r_ : r) { @@ -123,7 +123,10 @@ void PublicKey::applyObfuscator(std::vector& obfuscator) const { } obfuscator = ipcl::ippModExp(base, r, sq); } else { - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { +#ifdef IPCL_USE_OMP +#pragma omp parallel for +#endif // IPCL_USE_OMP + for (int i = 0; i < obf_size; i++) { if (m_testv) { r[i] = m_r[i]; } else { @@ -138,49 +141,42 @@ void PublicKey::applyObfuscator(std::vector& obfuscator) const { } void PublicKey::setRandom(const std::vector& r) { - VEC_SIZE_CHECK(r); - std::copy(r.begin(), r.end(), std::back_inserter(m_r)); m_testv = true; } -void PublicKey::raw_encrypt(std::vector& ciphertext, - const std::vector& plaintext, - bool make_secure) const { - // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 +std::vector PublicKey::raw_encrypt(const std::vector& pt, + bool make_secure) const { + std::size_t pt_size = pt.size(); + + std::vector ct(pt_size); BigNumber sq = m_nsquare; - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - BigNumber bn(plaintext[i]); - ciphertext[i] = (m_n * bn + 1) % sq; + +#ifdef IPCL_USE_OMP +#pragma omp parallel for +#endif // IPCL_USE_OMP + for (std::size_t i = 0; i < pt_size; i++) { + ct[i] = (m_n * pt[i] + 1) % m_nsquare; } if (make_secure) { - std::vector obfuscator(IPCL_CRYPTO_MB_SIZE); + std::vector obfuscator(pt_size); applyObfuscator(obfuscator); - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) - ciphertext[i] = sq.ModMul(ciphertext[i], obfuscator[i]); +#ifdef IPCL_USE_OMP +#pragma omp parallel for +#endif // IPCL_USE_OMP + for (std::size_t i = 0; i < pt_size; i++) + ct[i] = sq.ModMul(ct[i], obfuscator[i]); } + return ct; } -void PublicKey::encrypt(std::vector& ciphertext, - const std::vector& value, - bool make_secure) const { - VEC_SIZE_CHECK(ciphertext); - VEC_SIZE_CHECK(value); +CipherText PublicKey::encrypt(const PlainText& pt, bool make_secure) const { + std::size_t pt_size = pt.getSize(); + std::vector ct_bn_v(pt_size); - raw_encrypt(ciphertext, value, make_secure); + ct_bn_v = raw_encrypt(pt.getTexts(), make_secure); + return CipherText(this, ct_bn_v); } - -// Used for CT+PT, where PT do not need to add obfuscator -void PublicKey::encrypt(BigNumber& ciphertext, const BigNumber& value) const { - // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 - ciphertext = (m_n * value + 1) % m_nsquare; - - /*----- Path to caculate (n+1)^plaintext mod n^2 ------------ - BigNumber bn(value); - ciphertext = ippMontExp(m_g, bn, m_nsquare); - ---------------------------------------------------------- */ -} - } // namespace ipcl diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index 931b0ac..d32f6ac 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -11,117 +11,58 @@ #endif // IPCL_USE_OMP #include "gtest/gtest.h" +#include "ipcl/ciphertext.hpp" #include "ipcl/keygen.hpp" -#include "ipcl/ops.hpp" +#include "ipcl/plaintext.hpp" -TEST(CryptoTest, CryptoTest) { - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector ct(8); - std::vector dt(8); - - std::vector pt(8); - std::vector ptbn(8); - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < 8; i++) { - pt[i] = dist(rng); - ptbn[i] = pt[i]; - } - - key.pub_key->encrypt(ct, ptbn); - key.priv_key->decrypt(dt, ct); - - for (int i = 0; i < 8; i++) { - std::vector v; - dt[i].num2vec(v); - EXPECT_EQ(v[0], pt[i]); - } - - delete key.pub_key; - delete key.priv_key; -} - -#ifdef IPCL_USE_OMP -void Encryption(int num_threads, - std::vector>& v_ct, - const std::vector>& v_ptbn, - const ipcl::keyPair key) { -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - key.pub_key->encrypt(v_ct[i], v_ptbn[i]); - } -} +constexpr int SELF_DEF_NUM_VALUES = 20; -void Decryption(int num_threads, - std::vector>& v_dt, - const std::vector>& v_ct, - const ipcl::keyPair key) { -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - key.priv_key->decrypt(v_dt[i], v_ct[i]); - } -} +TEST(CryptoTest, CryptoTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; -TEST(CryptoTest, CryptoTest_OMP) { - // use one keypair to do several encryption/decryption ipcl::keyPair key = ipcl::generateKeypair(2048, true); - size_t num_threads = omp_get_max_threads(); - - std::vector> v_ct( - num_threads, std::vector(8)); - std::vector> v_dt( - num_threads, std::vector(8)); - std::vector> v_pt(num_threads, - std::vector(8)); - std::vector> v_ptbn( - num_threads, std::vector(8)); + std::vector exp_value(num_values); + ipcl::PlainText pt; + ipcl::CipherText ct; + ipcl::PlainText dt; std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); - for (int i = 0; i < num_threads; i++) { - // for each threads, generated different rand testing value - for (int j = 0; j < 8; j++) { - v_pt[i][j] = dist(rng); - v_ptbn[i][j] = v_pt[i][j]; - } + for (int i = 0; i < num_values; i++) { + exp_value[i] = dist(rng); } - Encryption(num_threads, v_ct, v_ptbn, key); - Decryption(num_threads, v_dt, v_ct, key); + pt = ipcl::PlainText(exp_value); + ct = key.pub_key->encrypt(pt); + dt = key.priv_key->decrypt(ct); - // check output for all threads - for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < 8; j++) { - std::vector v; - v_dt[i][j].num2vec(v); - EXPECT_EQ(v[0], v_pt[i][j]); - } + for (int i = 0; i < num_values; i++) { + std::vector v = dt.getElementVec(i); + EXPECT_EQ(v[0], exp_value[i]); } delete key.pub_key; delete key.priv_key; } -#endif // IPCL_USE_OMP TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { - ipcl::BigNumber p = + const uint32_t num_values = SELF_DEF_NUM_VALUES; + + BigNumber p = "0xff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c" "8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b4" "0a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff76" "4dd8b091f11a0943a2dd2b983b0df02f4c4d00b413"; - ipcl::BigNumber q = + BigNumber q = "0xdacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d" "9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de70" "72a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49b" "aa0f610bad100cdf47cc86e5034e2a0b2179e04ec7"; - ipcl::BigNumber n = p * q; + BigNumber n = p * q; int n_length = n.BitSize(); ipcl::PublicKey* public_key = new ipcl::PublicKey(n, n_length); @@ -129,12 +70,10 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { ipcl::keyPair key = {public_key, private_key}; - std::vector ptbn(8); - std::vector ct(8); - std::vector dt(8); - std::vector ir(8); + std::vector pt_bn_v(num_values); + std::vector ir_bn_v(num_values); - ipcl::BigNumber c1 = + BigNumber c1 = "0x1fb7f08a42deb47876e4cbdc3f0b172c033563a696ad7a7c76fa5971b793fa488dcdd6" "bd65c7c5440d67d847cb89ccca468b2c96763fff5a5ece8330251112d65e59b7da94cfe9" "309f441ccc8f59c67dec75113d37b1ee929c8d4ce6b5e561a30a91104b0526de892e4eff" @@ -151,7 +90,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "b98ccb676367b7b3b269c670cd0210edf70ad9cb337f766af75fe06d18b3f7f7c2eae656" "5ff2815c2c09b1a1f5"; - ipcl::BigNumber c2 = + BigNumber c2 = "0x61803645f2798c06f2c08fc254eee612c55542051c8777d6ce69ede9c84a179afb2081" "167494dee727488ae5e9b56d98f4fcf132514616859fc854fbd3acf6aecd97324ac3f2af" "fa9f44864a9afc505754aa3b564b4617e887d6aa1f88095bccf6b47f458566f9d85e80fc" @@ -168,7 +107,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "d6f1d6864f1fd3e2e3937e00d391ad330b443aec85528571740ed5538188c32caab27c7b" "f437df2bb97cb90e02"; - ipcl::BigNumber c1c2 = + BigNumber c1c2 = "0x309f6e614d875e3bb0a77eedeb8895e7c6f297f161f576aef4f8b72bb5b81ef78b831a" "af134b09fe8697159cfd678c49920cb790e36580c5201a96848d7242fceb025808dd26b5" "0ff573ffca3f65e51b3b9fe85c7e44f5c8df0a9e524f64a5acc5c62cba7475978eb55e08" @@ -185,9 +124,9 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "a6d47f9af6e68e18960fa5916cc48994334354d6303312b8e96602766bec337a8a92c596" "b21b6038828a6c9744"; - ipcl::BigNumber m1m2 = "0x616263646566676869606a6b6c6d6e6f"; + BigNumber m1m2 = "0x616263646566676869606a6b6c6d6e6f"; - ipcl::BigNumber r0 = + BigNumber r0 = "0x57fb19590c31dc7c034b2a889cf4037ce3db799909c1eb0adb6199d8e96791daca9018" "891f34309daff32dced4af7d793d16734d055e28023acab7295956bfbfdf62bf0ccb2ed3" "1d5d176ca8b404e93007565fb6b72c33a512b4dc4f719231d62e27e34c3733929af32247" @@ -196,7 +135,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "27991c44a43750c24ed0825718ad14cfb9c6b40b78ff3d25f71741f2def1c9d420d4b0fa" "1e0a02e7851b5ec6a81133a368b80d1500b0f28fc653d2e6ff4366236dbf80ae3b4beae3" "5e04579f2c"; - ipcl::BigNumber r1 = + BigNumber r1 = "0x6ee8ed76227672a7bcaa1e7f152c2ea39f2fa225f0713f58210c59b2270b110e38b650" "69aaedbeffc713c021336cc12f65227cc0357ca531c07c706e7224c2c11c3145bc0a05b1" "64f426ec03350820f9f416377e8720ddb577843cae929178bfe5772e2cc1e9b94e8fce81" @@ -206,49 +145,108 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "4883680e42b5d8582344e3e07a01fbd6c46328dcfa03074d0bc02927f58466c2fa74ab60" "8177e3ec1b"; - for (int i = 0; i < 8; i++) { - ir[i] = r0; - ptbn[i] = "0x414243444546474849404a4b4c4d4e4f"; + for (int i = 0; i < num_values; i++) { + ir_bn_v[i] = r0; + pt_bn_v[i] = "0x414243444546474849404a4b4c4d4e4f"; } - ir[1] = r1; - ptbn[1] = "0x20202020202020202020202020202020"; + ir_bn_v[1] = r1; + pt_bn_v[1] = "0x20202020202020202020202020202020"; - key.pub_key->setRandom(ir); + ipcl::PlainText pt; + ipcl::CipherText ct; - key.pub_key->encrypt(ct, ptbn); + key.pub_key->setRandom(ir_bn_v); - ipcl::EncryptedNumber a(key.pub_key, ct[0]); - ipcl::EncryptedNumber b(key.pub_key, ct[1]); - ipcl::EncryptedNumber sum = a + b; - ipcl::BigNumber res = sum.getBN(); + pt = ipcl::PlainText(pt_bn_v); + ct = key.pub_key->encrypt(pt); - std::vector ct12(8); - std::vector dt12(8); - for (int i = 0; i < 8; i++) { - ct12[i] = res; + ipcl::PlainText dt; + dt = key.priv_key->decrypt(ct); + for (int i = 0; i < num_values; i++) { + EXPECT_EQ(dt.getElement(i), pt_bn_v[i]); } - key.priv_key->decrypt(dt, ct); - key.priv_key->decrypt(dt12, ct12); - std::string str1, str2; - c1.num2hex(str1); - ct[0].num2hex(str2); - EXPECT_EQ(str1, str2); + EXPECT_EQ(str1, ct.getElementHex(0)); + c2.num2hex(str2); + EXPECT_EQ(str2, ct.getElementHex(1)); + + ipcl::CipherText a(key.pub_key, ct.getElement(0)); + ipcl::CipherText b(key.pub_key, ct.getElement(1)); + ipcl::CipherText sum = a + b; + + std::string str3; + c1c2.num2hex(str3); + EXPECT_EQ(str3, sum.getElementHex(0)); + + std::string str4; + ipcl::PlainText dt_sum; + + dt_sum = key.priv_key->decrypt(sum); + m1m2.num2hex(str4); + EXPECT_EQ(str4, dt_sum.getElementHex(0)); + + delete key.pub_key; + delete key.priv_key; +} + +#ifdef IPCL_USE_OMP +void Encryption(int num_threads, std::vector& ct_v, + const std::vector& pt_v, + const ipcl::keyPair key) { +#pragma omp parallel for + for (int i = 0; i < num_threads; i++) { + ct_v[i] = key.pub_key->encrypt(pt_v[i]); + } +} + +void Decryption(int num_threads, std::vector& dt_v, + const std::vector& ct_v, + const ipcl::keyPair key) { +#pragma omp parallel for + for (int i = 0; i < num_threads; i++) { + dt_v[i] = key.priv_key->decrypt(ct_v[i]); + } +} - c2.num2hex(str1); - ct[1].num2hex(str2); - EXPECT_EQ(str1, str2); +TEST(CryptoTest, CryptoTest_OMP) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + // use one keypair to do several encryption/decryption + ipcl::keyPair key = ipcl::generateKeypair(2048, true); - c1c2.num2hex(str1); - res.num2hex(str2); - EXPECT_EQ(str1, str2); + size_t num_threads = omp_get_max_threads(); - m1m2.num2hex(str1); - dt12[0].num2hex(str2); - EXPECT_EQ(str1, str2); + std::vector> exp_value( + num_threads, std::vector(num_values)); + std::vector pt_v(num_threads); + std::vector ct_v(num_threads); + std::vector dt_v(num_threads); + + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < num_threads; i++) { + // for each threads, generated different rand testing value + for (int j = 0; j < num_values; j++) { + exp_value[i][j] = dist(rng); + } + pt_v[i] = ipcl::PlainText(exp_value[i]); + } + + Encryption(num_threads, ct_v, pt_v, key); + Decryption(num_threads, dt_v, ct_v, key); + + // check output for all threads + for (int i = 0; i < num_threads; i++) { + for (int j = 0; j < num_values; j++) { + std::vector v = dt_v[i].getElementVec(j); + EXPECT_EQ(v[0], exp_value[i][j]); + } + } delete key.pub_key; delete key.priv_key; } +#endif // IPCL_USE_OMP diff --git a/test/test_ops.cpp b/test/test_ops.cpp index 025f3b4..dc159f9 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -11,120 +11,121 @@ #endif // IPCL_USE_OMP #include "gtest/gtest.h" +#include "ipcl/ciphertext.hpp" #include "ipcl/keygen.hpp" -#include "ipcl/ops.hpp" - -void CtPlusCt(std::vector& res, - const std::vector& ct1, - const std::vector& ct2, - const ipcl::keyPair key) { - for (int i = 0; i < 8; i++) { - ipcl::EncryptedNumber a(key.pub_key, ct1[i]); - ipcl::EncryptedNumber b(key.pub_key, ct2[i]); - ipcl::EncryptedNumber sum = a + b; - res[i] = sum.getBN(); +#include "ipcl/plaintext.hpp" + +constexpr int SELF_DEF_NUM_VALUES = 20; + +void CtPlusCt(ipcl::CipherText& res, const ipcl::CipherText& ct1, + const ipcl::CipherText& ct2, const ipcl::keyPair key) { + int size = ct1.getSize(); + std::vector sum_bn_v(size); + + for (int i = 0; i < size; i++) { + ipcl::CipherText a(key.pub_key, ct1.getElement(i)); + ipcl::CipherText b(key.pub_key, ct2.getElement(i)); + ipcl::CipherText sum = a + b; + sum_bn_v[i] = sum.getElement(0); } + res = ipcl::CipherText(key.pub_key, sum_bn_v); } -void CtPlusCtArray(std::vector& res, - const std::vector& ct1, - const std::vector& ct2, - const ipcl::keyPair key) { - ipcl::EncryptedNumber a(key.pub_key, ct1); - ipcl::EncryptedNumber b(key.pub_key, ct2); - ipcl::EncryptedNumber sum = a + b; - res = sum.getArrayBN(); +void CtPlusCtArray(ipcl::CipherText& res, const ipcl::CipherText& ct1, + const ipcl::CipherText& ct2, const ipcl::keyPair key) { + res = ct1 + ct2; } -void CtPlusPt(std::vector& res, - const std::vector& ct1, - const std::vector& pt2, const ipcl::keyPair key) { - for (int i = 0; i < 8; i++) { - ipcl::EncryptedNumber a(key.pub_key, ct1[i]); - ipcl::BigNumber b = pt2[i]; - ipcl::EncryptedNumber sum = a + b; - res[i] = sum.getBN(); +void CtPlusPt(ipcl::CipherText& res, const ipcl::CipherText& ct1, + const ipcl::PlainText& pt2, const ipcl::keyPair key) { + int size = ct1.getSize(); + std::vector sum_bn_v(size); + + for (int i = 0; i < size; i++) { + ipcl::CipherText a(key.pub_key, ct1.getElement(i)); + ipcl::PlainText b(pt2.getElement(i)); + ipcl::CipherText sum = a + b; + sum_bn_v[i] = sum.getElement(0); } + res = ipcl::CipherText(key.pub_key, sum_bn_v); } -void CtPlusPtArray(std::vector& res, - const std::vector& ct1, - const std::vector& ptbn2, - const ipcl::keyPair key) { - ipcl::EncryptedNumber a(key.pub_key, ct1); - ipcl::EncryptedNumber sum = a + ptbn2; - res = sum.getArrayBN(); +void CtPlusPtArray(ipcl::CipherText& res, const ipcl::CipherText& ct1, + const ipcl::PlainText& pt2, const ipcl::keyPair key) { + res = ct1 + pt2; } -void CtMultiplyPt(std::vector& res, - const std::vector& ct1, - const std::vector& pt2, - const ipcl::keyPair key) { - for (int i = 0; i < 8; i++) { - ipcl::EncryptedNumber a(key.pub_key, ct1[i]); - ipcl::EncryptedNumber sum = a * pt2[i]; - res[i] = sum.getBN(); +void CtMultiplyPt(ipcl::CipherText& res, const ipcl::CipherText& ct1, + const ipcl::PlainText& pt2, const ipcl::keyPair key) { + int size = ct1.getSize(); + std::vector product_bn_v(size); + + for (int i = 0; i < size; i++) { + ipcl::CipherText a(key.pub_key, ct1.getElement(i)); + ipcl::PlainText b(pt2.getElement(i)); + ipcl::CipherText product = a * b; + product_bn_v[i] = product.getElement(0); } + res = ipcl::CipherText(key.pub_key, product_bn_v); } -void CtMultiplyPtArray(std::vector& res, - const std::vector& ct1, - const std::vector& pt2, - const ipcl::keyPair key) { - ipcl::EncryptedNumber a(key.pub_key, ct1); - ipcl::EncryptedNumber b(key.pub_key, pt2); - ipcl::EncryptedNumber sum = a * b; - res = sum.getArrayBN(); +void CtMultiplyPtArray(ipcl::CipherText& res, const ipcl::CipherText& ct1, + const ipcl::PlainText& pt2, const ipcl::keyPair key) { + res = ct1 * pt2; } -void AddSub(std::vector& res, - const std::vector& ct1, - const std::vector& ct2, const ipcl::keyPair key) { - for (int i = 0; i < 8; i++) { - ipcl::EncryptedNumber a(key.pub_key, ct1[i]); - ipcl::EncryptedNumber b(key.pub_key, ct2[i]); - ipcl::BigNumber m1(2); +void AddSub(ipcl::CipherText& res, const ipcl::CipherText& ct1, + const ipcl::CipherText& ct2, const ipcl::keyPair key) { + int size = ct1.getSize(); + std::vector sum_bn_v(size); + + for (int i = 0; i < size; i++) { + ipcl::CipherText a(key.pub_key, ct1.getElement(i)); + ipcl::CipherText b(key.pub_key, ct2.getElement(i)); + ipcl::PlainText m1(2); + a = a + b * m1; - ipcl::EncryptedNumber sum = a + b; - res[i] = sum.getBN(); + ipcl::CipherText sum = a + b; + sum_bn_v[i] = sum.getElement(0); } + res = ipcl::CipherText(key.pub_key, sum_bn_v); } TEST(OperationTest, CtPlusCtTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_sum; + ipcl::CipherText ct1, ct2, ct_sum; - std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; - ptbn2[i] = pt2[i]; + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); - key.pub_key->encrypt(ct1, ptbn1); - key.pub_key->encrypt(ct2, ptbn2); + ct1 = key.pub_key->encrypt(pt1); + ct2 = key.pub_key->encrypt(pt2); - CtPlusCt(res, ct1, ct2, key); + CtPlusCt(ct_sum, ct1, ct2, key); - key.priv_key->decrypt(dt, res); + dt_sum = key.priv_key->decrypt(ct_sum); - for (int i = 0; i < 8; i++) { - std::vector v; - dt[i].num2vec(v); + for (int i = 0; i < num_values; i++) { + std::vector v = dt_sum.getElementVec(i); + uint64_t sum = v[0]; + if (v.size() > 1) sum = ((uint64_t)v[1] << 32) | v[0]; - uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + uint64_t exp_sum = (uint64_t)exp_value1[i] + (uint64_t)exp_value2[i]; - EXPECT_EQ(v_dp, v_pp); + EXPECT_EQ(sum, exp_sum); } delete key.pub_key; @@ -132,40 +133,40 @@ TEST(OperationTest, CtPlusCtTest) { } TEST(OperationTest, CtPlusCtArrayTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_sum; + ipcl::CipherText ct1, ct2, ct_sum; - std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; - ptbn2[i] = pt2[i]; + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); - key.pub_key->encrypt(ct1, ptbn1); - key.pub_key->encrypt(ct2, ptbn2); + ct1 = key.pub_key->encrypt(pt1); + ct2 = key.pub_key->encrypt(pt2); - CtPlusCtArray(res, ct1, ct2, key); + CtPlusCtArray(ct_sum, ct1, ct2, key); - key.priv_key->decrypt(dt, res); + dt_sum = key.priv_key->decrypt(ct_sum); - for (int i = 0; i < 8; i++) { - std::vector v; - dt[i].num2vec(v); + for (int i = 0; i < num_values; i++) { + std::vector v = dt_sum.getElementVec(i); + uint64_t sum = v[0]; + if (v.size() > 1) sum = ((uint64_t)v[1] << 32) | v[0]; - uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + uint64_t exp_sum = (uint64_t)exp_value1[i] + (uint64_t)exp_value2[i]; - EXPECT_EQ(v_dp, v_pp); + EXPECT_EQ(sum, exp_sum); } delete key.pub_key; @@ -173,38 +174,39 @@ TEST(OperationTest, CtPlusCtArrayTest) { } TEST(OperationTest, CtPlusPtTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_sum; + ipcl::CipherText ct1, ct2, ct_sum; - std::vector pt1(8), pt2(8); - std::vector ptbn1(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); - key.pub_key->encrypt(ct1, ptbn1); + ct1 = key.pub_key->encrypt(pt1); - CtPlusPt(res, ct1, pt2, key); + CtPlusPt(ct_sum, ct1, pt2, key); - key.priv_key->decrypt(dt, res); + dt_sum = key.priv_key->decrypt(ct_sum); - for (int i = 0; i < 8; i++) { - std::vector v; - dt[i].num2vec(v); + for (int i = 0; i < num_values; i++) { + std::vector v = dt_sum.getElementVec(i); + uint64_t sum = v[0]; + if (v.size() > 1) sum = ((uint64_t)v[1] << 32) | v[0]; - uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + uint64_t exp_sum = (uint64_t)exp_value1[i] + (uint64_t)exp_value2[i]; - EXPECT_EQ(v_dp, v_pp); + EXPECT_EQ(sum, exp_sum); } delete key.pub_key; @@ -212,39 +214,39 @@ TEST(OperationTest, CtPlusPtTest) { } TEST(OperationTest, CtPlusPtArrayTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_sum; + ipcl::CipherText ct1, ct2, ct_sum; - std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; - ptbn2[i] = pt2[i]; + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); - key.pub_key->encrypt(ct1, ptbn1); + ct1 = key.pub_key->encrypt(pt1); - CtPlusPtArray(res, ct1, ptbn2, key); + CtPlusPtArray(ct_sum, ct1, pt2, key); - key.priv_key->decrypt(dt, res); + dt_sum = key.priv_key->decrypt(ct_sum); - for (int i = 0; i < 8; i++) { - std::vector v; - dt[i].num2vec(v); + for (int i = 0; i < num_values; i++) { + std::vector v = dt_sum.getElementVec(i); + uint64_t sum = v[0]; + if (v.size() > 1) sum = ((uint64_t)v[1] << 32) | v[0]; - uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + uint64_t exp_sum = (uint64_t)exp_value1[i] + (uint64_t)exp_value2[i]; - EXPECT_EQ(v_dp, v_pp); + EXPECT_EQ(sum, exp_sum); } delete key.pub_key; @@ -252,39 +254,39 @@ TEST(OperationTest, CtPlusPtArrayTest) { } TEST(OperationTest, CtMultiplyPtTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_product; + ipcl::CipherText ct1, ct2, ct_product; - std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; - ptbn2[i] = pt2[i]; + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); - key.pub_key->encrypt(ct1, ptbn1); + ct1 = key.pub_key->encrypt(pt1); - CtMultiplyPt(res, ct1, ptbn2, key); + CtMultiplyPt(ct_product, ct1, pt2, key); - key.priv_key->decrypt(dt, res); + dt_product = key.priv_key->decrypt(ct_product); - for (int i = 0; i < 8; i++) { - std::vector v; - dt[i].num2vec(v); + for (int i = 0; i < num_values; i++) { + std::vector v = dt_product.getElementVec(i); + uint64_t product = v[0]; + if (v.size() > 1) product = ((uint64_t)v[1] << 32) | v[0]; - uint64_t v_pp = (uint64_t)pt1[i] * (uint64_t)pt2[i]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + uint64_t exp_product = (uint64_t)exp_value1[i] * (uint64_t)exp_value2[i]; - EXPECT_EQ(v_dp, v_pp); + EXPECT_EQ(product, exp_product); } delete key.pub_key; @@ -292,38 +294,40 @@ TEST(OperationTest, CtMultiplyPtTest) { } TEST(OperationTest, CtMultiplyZeroPtTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_product; + ipcl::CipherText ct1, ct2, ct_product; - std::vector pt1(8), pt2(8, 0); - std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - ptbn1[i] = pt1[i]; - ptbn2[i] = pt2[i]; + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = 0; } - key.pub_key->encrypt(ct1, ptbn1); + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); - CtMultiplyPt(res, ct1, ptbn2, key); + ct1 = key.pub_key->encrypt(pt1); - key.priv_key->decrypt(dt, res); + CtMultiplyPt(ct_product, ct1, pt2, key); - for (int i = 0; i < 8; i++) { - std::vector v; - dt[i].num2vec(v); + dt_product = key.priv_key->decrypt(ct_product); - uint64_t v_pp = (uint64_t)pt1[i] * (uint64_t)pt2[i]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + for (int i = 0; i < num_values; i++) { + std::vector v = dt_product.getElementVec(i); + uint64_t product = v[0]; + if (v.size() > 1) product = ((uint64_t)v[1] << 32) | v[0]; - EXPECT_EQ(v_dp, v_pp); + uint64_t exp_product = (uint64_t)exp_value1[i] * (uint64_t)exp_value2[i]; + + EXPECT_EQ(product, exp_product); } delete key.pub_key; @@ -331,39 +335,39 @@ TEST(OperationTest, CtMultiplyZeroPtTest) { } TEST(OperationTest, CtMultiplyPtArrayTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8); - std::vector dt(8), res(8); + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_product; + ipcl::CipherText ct1, ct2, ct_product; - std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; - ptbn2[i] = pt2[i]; + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); - key.pub_key->encrypt(ct1, ptbn1); + ct1 = key.pub_key->encrypt(pt1); - CtMultiplyPtArray(res, ct1, ptbn2, key); + CtMultiplyPtArray(ct_product, ct1, pt2, key); - key.priv_key->decrypt(dt, res); + dt_product = key.priv_key->decrypt(ct_product); - for (int i = 0; i < 8; i++) { - std::vector v; - dt[i].num2vec(v); + for (int i = 0; i < num_values; i++) { + std::vector v = dt_product.getElementVec(i); + uint64_t product = v[0]; + if (v.size() > 1) product = ((uint64_t)v[1] << 32) | v[0]; - uint64_t v_pp = (uint64_t)pt1[i] * (uint64_t)pt2[i]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + uint64_t exp_product = (uint64_t)exp_value1[i] * (uint64_t)exp_value2[i]; - EXPECT_EQ(v_dp, v_pp); + EXPECT_EQ(product, exp_product); } delete key.pub_key; @@ -371,39 +375,40 @@ TEST(OperationTest, CtMultiplyPtArrayTest) { } TEST(OperationTest, AddSubTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_sum; + ipcl::CipherText ct1, ct2, ct_sum; - std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; - ptbn2[i] = pt2[i]; + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); - key.pub_key->encrypt(ct1, ptbn1); - key.pub_key->encrypt(ct2, ptbn2); + ct1 = key.pub_key->encrypt(pt1); + ct2 = key.pub_key->encrypt(pt2); - AddSub(res, ct1, ct2, key); - key.priv_key->decrypt(dt, res); + AddSub(ct_sum, ct1, ct2, key); - for (int i = 0; i < 8; i++) { - std::vector v; - dt[i].num2vec(v); + dt_sum = key.priv_key->decrypt(ct_sum); - uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i] * 3; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + for (int i = 0; i < num_values; i++) { + std::vector v = dt_sum.getElementVec(i); + uint64_t sum = v[0]; + if (v.size() > 1) sum = ((uint64_t)v[1] << 32) | v[0]; - EXPECT_EQ(v_dp, v_pp); + uint64_t exp_sum = (uint64_t)exp_value1[i] + (uint64_t)exp_value2[i] * 3; + + EXPECT_EQ(sum, exp_sum); } delete key.pub_key; @@ -411,143 +416,139 @@ TEST(OperationTest, AddSubTest) { } #ifdef IPCL_USE_OMP -void CtPlusCt_OMP(int num_threads, - std::vector>& v_sum, - const std::vector>& v_ct1, - const std::vector>& v_ct2, +void CtPlusCt_OMP(int num_threads, std::vector& res_v, + const std::vector& ct1_v, + const std::vector& ct2_v, const ipcl::keyPair key) { + std::vector> sum_bn_v(num_threads); + #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < 8; j++) { - ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); - ipcl::EncryptedNumber b(key.pub_key, v_ct2[i][j]); - ipcl::EncryptedNumber sum = a + b; - v_sum[i][j] = sum.getBN(); + int size = ct1_v[i].getSize(); + sum_bn_v[i] = std::vector(size); + for (int j = 0; j < size; j++) { + ipcl::CipherText a(key.pub_key, ct1_v[i].getElement(j)); + ipcl::CipherText b(key.pub_key, ct2_v[i].getElement(j)); + ipcl::CipherText sum = a + b; + sum_bn_v[i][j] = sum.getElement(0); } + res_v[i] = ipcl::CipherText(key.pub_key, sum_bn_v[i]); } } -void CtPlusPt_OMP(int num_threads, - std::vector>& v_sum, - const std::vector>& v_ct1, - const std::vector>& v_pt2, +void CtPlusPt_OMP(int num_threads, std::vector& res_v, + const std::vector& ct1_v, + const std::vector& pt2_v, const ipcl::keyPair key) { + std::vector> sum_bn_v(num_threads); + #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < 8; j++) { - ipcl::BigNumber b = v_pt2[i][j]; - ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); - ipcl::EncryptedNumber sum = a + b; - v_sum[i][j] = sum.getBN(); + int size = ct1_v[i].getSize(); + sum_bn_v[i] = std::vector(size); + for (int j = 0; j < size; j++) { + ipcl::CipherText a(key.pub_key, ct1_v[i].getElement(j)); + ipcl::PlainText b(pt2_v[i].getElement(j)); + ipcl::CipherText sum = a + b; + sum_bn_v[i][j] = sum.getElement(0); } + res_v[i] = ipcl::CipherText(key.pub_key, sum_bn_v[i]); } } -void CtPlusPtArray_OMP(int num_threads, - std::vector>& v_sum, - const std::vector>& v_ct1, - const std::vector>& v_pt2, +void CtPlusPtArray_OMP(int num_threads, std::vector& res_v, + const std::vector& ct1_v, + const std::vector& pt2_v, const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - ipcl::EncryptedNumber a(key.pub_key, v_ct1[i]); - std::vector b(8); - for (int j = 0; j < 8; j++) { - b[j] = v_pt2[i][j]; - } - ipcl::EncryptedNumber sum = a + b; - v_sum[i] = sum.getArrayBN(); + res_v[i] = ct1_v[i] + pt2_v[i]; } } -void CtMultiplyPt_OMP(int num_threads, - std::vector>& v_product, - const std::vector>& v_ct1, - const std::vector>& v_pt2, - const ipcl::keyPair key) { +void CtMultiplyPtArray_OMP(int num_threads, + std::vector& res_v, + const std::vector& ct1_v, + const std::vector& pt2_v, + const ipcl::keyPair key) { #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < 8; j++) { - ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); - ipcl::BigNumber b = v_pt2[i][j]; - ipcl::EncryptedNumber product = a * b; - v_product[i][j] = product.getBN(); - } + res_v[i] = ct1_v[i] * pt2_v[i]; } } -void CtMultiplyPtArray_OMP( - int num_threads, std::vector>& v_product, - const std::vector>& v_ct1, - const std::vector>& v_pt2, const ipcl::keyPair key) { +void CtMultiplyPt_OMP(int num_threads, std::vector& res_v, + const std::vector& ct1_v, + const std::vector& pt2_v, + const ipcl::keyPair key) { + std::vector> product_bn_v(num_threads); + #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - ipcl::EncryptedNumber a(key.pub_key, v_ct1[i]); - ipcl::EncryptedNumber b(key.pub_key, v_pt2[i]); - ipcl::EncryptedNumber product = a * b; - v_product[i] = product.getArrayBN(); + int size = ct1_v[i].getSize(); + product_bn_v[i] = std::vector(size); + for (int j = 0; j < size; j++) { + ipcl::CipherText a(key.pub_key, ct1_v[i].getElement(j)); + ipcl::PlainText b(pt2_v[i].getElement(j)); + ipcl::CipherText product = a * b; + product_bn_v[i][j] = product.getElement(0); + } + res_v[i] = ipcl::CipherText(key.pub_key, product_bn_v[i]); } } TEST(OperationTest, CtPlusCtTest_OMP) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + ipcl::keyPair key = ipcl::generateKeypair(2048); size_t num_threads = omp_get_max_threads(); - std::vector> v_ct1( - num_threads, std::vector(8)); - std::vector> v_ct2( - num_threads, std::vector(8)); - std::vector> v_dt( - num_threads, std::vector(8)); - std::vector> v_sum( - num_threads, std::vector(8)); - std::vector> v_pt1(num_threads, - std::vector(8)); - std::vector> v_pt2(num_threads, - std::vector(8)); - std::vector> v_ptbn1( - num_threads, std::vector(8)); - std::vector> v_ptbn2( - num_threads, std::vector(8)); + std::vector> exp_value1_vv( + num_threads, std::vector(num_values)), + exp_value2_vv(num_threads, std::vector(num_values)); + std::vector pt1_v(num_threads), pt2_v(num_threads), + dt_sum_v(num_threads); + std::vector ct1_v(num_threads), ct2_v(num_threads), + ct_sum_v(num_threads); + std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { // for each threads, generated different rand testing value - for (int j = 0; j < 8; j++) { - v_pt1[i][j] = dist(rng); - v_pt2[i][j] = dist(rng); - v_ptbn1[i][j] = v_pt1[i][j]; - v_ptbn2[i][j] = v_pt2[i][j]; + for (int j = 0; j < num_values; j++) { + exp_value1_vv[i][j] = dist(rng); + exp_value2_vv[i][j] = dist(rng); } + pt1_v[i] = ipcl::PlainText(exp_value1_vv[i]); + pt2_v[i] = ipcl::PlainText(exp_value2_vv[i]); } #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - key.pub_key->encrypt(v_ct1[i], v_ptbn1[i]); - key.pub_key->encrypt(v_ct2[i], v_ptbn2[i]); + ct1_v[i] = key.pub_key->encrypt(pt1_v[i]); + ct2_v[i] = key.pub_key->encrypt(pt2_v[i]); } - CtPlusCt_OMP(num_threads, v_sum, v_ct1, v_ct2, key); + CtPlusCt_OMP(num_threads, ct_sum_v, ct1_v, ct2_v, key); #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - key.priv_key->decrypt(v_dt[i], v_sum[i]); + dt_sum_v[i] = key.priv_key->decrypt(ct_sum_v[i]); } // check output for all threads for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < 8; j++) { - std::vector v; - v_dt[i][j].num2vec(v); - - uint64_t v_pp = (uint64_t)v_pt1[i][j] + (uint64_t)v_pt2[i][j]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; - - EXPECT_EQ(v_dp, v_pp); + for (int j = 0; j < num_values; j++) { + std::vector v = dt_sum_v[i].getElementVec(j); + uint64_t sum = v[0]; + if (v.size() > 1) sum = ((uint64_t)v[1] << 32) | v[0]; + uint64_t exp_sum = + (uint64_t)exp_value1_vv[i][j] + (uint64_t)exp_value2_vv[i][j]; + + EXPECT_EQ(sum, exp_sum); } } @@ -556,61 +557,56 @@ TEST(OperationTest, CtPlusCtTest_OMP) { } TEST(OperationTest, CtPlusPtTest_OMP) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + ipcl::keyPair key = ipcl::generateKeypair(2048); size_t num_threads = omp_get_max_threads(); - std::vector> v_ct1( - num_threads, std::vector(8)); - std::vector> v_dt( - num_threads, std::vector(8)); - std::vector> v_sum( - num_threads, std::vector(8)); - std::vector> v_pt1(num_threads, - std::vector(8)); - std::vector> v_pt2(num_threads, - std::vector(8)); - std::vector> v_ptbn1( - num_threads, std::vector(8)); - std::vector> v_ptbn2( - num_threads, std::vector(8)); + std::vector> exp_value1_vv( + num_threads, std::vector(num_values)), + exp_value2_vv(num_threads, std::vector(num_values)); + std::vector pt1_v(num_threads), pt2_v(num_threads), + dt_sum_v(num_threads); + std::vector ct1_v(num_threads), ct2_v(num_threads), + ct_sum_v(num_threads); + std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { // for each threads, generated different rand testing value - for (int j = 0; j < 8; j++) { - v_pt1[i][j] = dist(rng); - v_pt2[i][j] = dist(rng); - v_ptbn1[i][j] = v_pt1[i][j]; - v_ptbn2[i][j] = v_pt2[i][j]; + for (int j = 0; j < num_values; j++) { + exp_value1_vv[i][j] = dist(rng); + exp_value2_vv[i][j] = dist(rng); } + pt1_v[i] = ipcl::PlainText(exp_value1_vv[i]); + pt2_v[i] = ipcl::PlainText(exp_value2_vv[i]); } #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - key.pub_key->encrypt(v_ct1[i], v_ptbn1[i]); + ct1_v[i] = key.pub_key->encrypt(pt1_v[i]); } - CtPlusPt_OMP(num_threads, v_sum, v_ct1, v_pt2, key); + CtPlusPt_OMP(num_threads, ct_sum_v, ct1_v, pt2_v, key); #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - key.priv_key->decrypt(v_dt[i], v_sum[i]); + dt_sum_v[i] = key.priv_key->decrypt(ct_sum_v[i]); } // check output for all threads for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < 8; j++) { - std::vector v; - v_dt[i][j].num2vec(v); - - uint64_t v_pp = (uint64_t)v_pt1[i][j] + (uint64_t)v_pt2[i][j]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; - - EXPECT_EQ(v_dp, v_pp); + for (int j = 0; j < num_values; j++) { + std::vector v = dt_sum_v[i].getElementVec(j); + uint64_t sum = v[0]; + if (v.size() > 1) sum = ((uint64_t)v[1] << 32) | v[0]; + uint64_t exp_sum = + (uint64_t)exp_value1_vv[i][j] + (uint64_t)exp_value2_vv[i][j]; + + EXPECT_EQ(sum, exp_sum); } } @@ -619,61 +615,56 @@ TEST(OperationTest, CtPlusPtTest_OMP) { } TEST(OperationTest, CtPlusPtArrayTest_OMP) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + ipcl::keyPair key = ipcl::generateKeypair(2048); size_t num_threads = omp_get_max_threads(); - std::vector> v_ct1( - num_threads, std::vector(8)); - std::vector> v_dt( - num_threads, std::vector(8)); - std::vector> v_sum( - num_threads, std::vector(8)); - std::vector> v_pt1(num_threads, - std::vector(8)); - std::vector> v_pt2(num_threads, - std::vector(8)); - std::vector> v_ptbn1( - num_threads, std::vector(8)); - std::vector> v_ptbn2( - num_threads, std::vector(8)); + std::vector> exp_value1_vv( + num_threads, std::vector(num_values)), + exp_value2_vv(num_threads, std::vector(num_values)); + std::vector pt1_v(num_threads), pt2_v(num_threads), + dt_sum_v(num_threads); + std::vector ct1_v(num_threads), ct2_v(num_threads), + ct_sum_v(num_threads); + std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); for (int i = 0; i < num_threads; i++) { // for each threads, generated different rand testing value - for (int j = 0; j < 8; j++) { - v_pt1[i][j] = dist(rng); - v_pt2[i][j] = dist(rng); - v_ptbn1[i][j] = v_pt1[i][j]; - v_ptbn2[i][j] = v_pt2[i][j]; + for (int j = 0; j < num_values; j++) { + exp_value1_vv[i][j] = dist(rng); + exp_value2_vv[i][j] = dist(rng); } + pt1_v[i] = ipcl::PlainText(exp_value1_vv[i]); + pt2_v[i] = ipcl::PlainText(exp_value2_vv[i]); } #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - key.pub_key->encrypt(v_ct1[i], v_ptbn1[i]); + ct1_v[i] = key.pub_key->encrypt(pt1_v[i]); } - CtPlusPtArray_OMP(num_threads, v_sum, v_ct1, v_pt2, key); + CtPlusPtArray_OMP(num_threads, ct_sum_v, ct1_v, pt2_v, key); #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - key.priv_key->decrypt(v_dt[i], v_sum[i]); + dt_sum_v[i] = key.priv_key->decrypt(ct_sum_v[i]); } // check output for all threads for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < 8; j++) { - std::vector v; - v_dt[i][j].num2vec(v); - - uint64_t v_pp = (uint64_t)v_pt1[i][j] + (uint64_t)v_pt2[i][j]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; - - EXPECT_EQ(v_dp, v_pp); + for (int j = 0; j < num_values; j++) { + std::vector v = dt_sum_v[i].getElementVec(j); + uint64_t sum = v[0]; + if (v.size() > 1) sum = ((uint64_t)v[1] << 32) | v[0]; + uint64_t exp_sum = + (uint64_t)exp_value1_vv[i][j] + (uint64_t)exp_value2_vv[i][j]; + + EXPECT_EQ(sum, exp_sum); } } @@ -681,25 +672,20 @@ TEST(OperationTest, CtPlusPtArrayTest_OMP) { delete key.priv_key; } -TEST(OperationTest, CtMultiplyPtTest_OMP) { +TEST(OperationTest, CtMultiplyPtArrayTest_OMP) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + ipcl::keyPair key = ipcl::generateKeypair(2048); size_t num_threads = omp_get_max_threads(); - std::vector> v_ct1( - num_threads, std::vector(8)); - std::vector> v_dt( - num_threads, std::vector(8)); - std::vector> v_product( - num_threads, std::vector(8)); - std::vector> v_pt1(num_threads, - std::vector(8)); - std::vector> v_pt2(num_threads, - std::vector(8)); - std::vector> v_ptbn1( - num_threads, std::vector(8)); - std::vector> v_ptbn2( - num_threads, std::vector(8)); + std::vector> exp_value1_vv( + num_threads, std::vector(num_values)), + exp_value2_vv(num_threads, std::vector(num_values)); + std::vector pt1_v(num_threads), pt2_v(num_threads), + dt_product_v(num_threads); + std::vector ct1_v(num_threads), ct2_v(num_threads), + ct_product_v(num_threads); std::random_device dev; std::mt19937 rng(dev()); @@ -707,36 +693,36 @@ TEST(OperationTest, CtMultiplyPtTest_OMP) { for (int i = 0; i < num_threads; i++) { // for each threads, generated different rand testing value - for (int j = 0; j < 8; j++) { - v_pt1[i][j] = dist(rng); - v_pt2[i][j] = dist(rng); - v_ptbn1[i][j] = v_pt1[i][j]; - v_ptbn2[i][j] = v_pt2[i][j]; + for (int j = 0; j < num_values; j++) { + exp_value1_vv[i][j] = dist(rng); + exp_value2_vv[i][j] = dist(rng); } + pt1_v[i] = ipcl::PlainText(exp_value1_vv[i]); + pt2_v[i] = ipcl::PlainText(exp_value2_vv[i]); } #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - key.pub_key->encrypt(v_ct1[i], v_ptbn1[i]); + ct1_v[i] = key.pub_key->encrypt(pt1_v[i]); } - CtMultiplyPt_OMP(num_threads, v_product, v_ct1, v_pt2, key); + CtMultiplyPtArray_OMP(num_threads, ct_product_v, ct1_v, pt2_v, key); #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - key.priv_key->decrypt(v_dt[i], v_product[i]); + dt_product_v[i] = key.priv_key->decrypt(ct_product_v[i]); } // check output for all threads for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < 8; j++) { - std::vector v; - v_dt[i][j].num2vec(v); - - uint64_t v_pp = (uint64_t)v_pt1[i][j] * (uint64_t)v_pt2[i][j]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; - EXPECT_EQ(v_dp, v_pp); + for (int j = 0; j < num_values; j++) { + std::vector v = dt_product_v[i].getElementVec(j); + uint64_t product = v[0]; + if (v.size() > 1) product = ((uint64_t)v[1] << 32) | v[0]; + uint64_t exp_product = + (uint64_t)exp_value1_vv[i][j] * (uint64_t)exp_value2_vv[i][j]; + + EXPECT_EQ(product, exp_product); } } @@ -744,25 +730,20 @@ TEST(OperationTest, CtMultiplyPtTest_OMP) { delete key.priv_key; } -TEST(OperationTest, CtMultiplyPtArrayTest_OMP) { +TEST(OperationTest, CtMultiplyPtTest_OMP) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + ipcl::keyPair key = ipcl::generateKeypair(2048); size_t num_threads = omp_get_max_threads(); - std::vector> v_ct1( - num_threads, std::vector(8)); - std::vector> v_dt( - num_threads, std::vector(8)); - std::vector> v_product( - num_threads, std::vector(8)); - std::vector> v_pt1(num_threads, - std::vector(8)); - std::vector> v_pt2(num_threads, - std::vector(8)); - std::vector> v_ptbn1( - num_threads, std::vector(8)); - std::vector> v_ptbn2( - num_threads, std::vector(8)); + std::vector> exp_value1_vv( + num_threads, std::vector(num_values)), + exp_value2_vv(num_threads, std::vector(num_values)); + std::vector pt1_v(num_threads), pt2_v(num_threads), + dt_product_v(num_threads); + std::vector ct1_v(num_threads), ct2_v(num_threads), + ct_product_v(num_threads); std::random_device dev; std::mt19937 rng(dev()); @@ -770,39 +751,41 @@ TEST(OperationTest, CtMultiplyPtArrayTest_OMP) { for (int i = 0; i < num_threads; i++) { // for each threads, generated different rand testing value - for (int j = 0; j < 8; j++) { - v_pt1[i][j] = dist(rng); - v_pt2[i][j] = dist(rng); - v_ptbn1[i][j] = v_pt1[i][j]; - v_ptbn2[i][j] = v_pt2[i][j]; + for (int j = 0; j < num_values; j++) { + exp_value1_vv[i][j] = dist(rng); + exp_value2_vv[i][j] = dist(rng); } + pt1_v[i] = ipcl::PlainText(exp_value1_vv[i]); + pt2_v[i] = ipcl::PlainText(exp_value2_vv[i]); } +#pragma omp parallel for for (int i = 0; i < num_threads; i++) { - key.pub_key->encrypt(v_ct1[i], v_ptbn1[i]); + ct1_v[i] = key.pub_key->encrypt(pt1_v[i]); } - CtMultiplyPtArray_OMP(num_threads, v_product, v_ct1, v_pt2, key); + CtMultiplyPt_OMP(num_threads, ct_product_v, ct1_v, pt2_v, key); #pragma omp parallel for for (int i = 0; i < num_threads; i++) { - key.priv_key->decrypt(v_dt[i], v_product[i]); + dt_product_v[i] = key.priv_key->decrypt(ct_product_v[i]); } // check output for all threads for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < 8; j++) { - std::vector v; - v_dt[i][j].num2vec(v); - - uint64_t v_pp = (uint64_t)v_pt1[i][j] * (uint64_t)v_pt2[i][j]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; - EXPECT_EQ(v_dp, v_pp); + for (int j = 0; j < num_values; j++) { + std::vector v = dt_product_v[i].getElementVec(j); + uint64_t product = v[0]; + if (v.size() > 1) product = ((uint64_t)v[1] << 32) | v[0]; + uint64_t exp_product = + (uint64_t)exp_value1_vv[i][j] * (uint64_t)exp_value2_vv[i][j]; + + EXPECT_EQ(product, exp_product); } } delete key.pub_key; delete key.priv_key; } + #endif // IPCL_USE_OMP From 83c7f34ad5ea21d59f16cb4521e22004390150a1 Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Thu, 28 Apr 2022 01:44:03 +0800 Subject: [PATCH 166/364] Fix OpenMP bug and performance issues * Improve the performance of encryption/decryption and CT+CT/PT CT*PT * Remove OMP unittest, and clean unittest/benchmark --- benchmark/CMakeLists.txt | 6 - benchmark/bench_cryptography.cpp | 5 - benchmark/bench_ops.cpp | 7 +- ipcl/CMakeLists.txt | 5 + ipcl/ciphertext.cpp | 4 - ipcl/mod_exp.cpp | 50 ++-- ipcl/pri_key.cpp | 7 + ipcl/pub_key.cpp | 13 -- test/CMakeLists.txt | 6 - test/test_cryptography.cpp | 64 ------ test/test_ops.cpp | 379 ------------------------------- 11 files changed, 28 insertions(+), 518 deletions(-) diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index dc122fe..00662dc 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -14,9 +14,3 @@ target_include_directories(bench_ipcl PRIVATE target_link_libraries(bench_ipcl PRIVATE ipcl -pthread libgbenchmark ) - -# enable OpenMP benchmarks -if(IPCL_ENABLE_OMP) - find_package(OpenMP REQUIRED) - target_link_libraries(bench_ipcl PRIVATE OpenMP::OpenMP_CXX) -endif() diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index 2817fa8..2a96750 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -5,14 +5,9 @@ #include #include -#ifdef IPCL_USE_OMP -#include -#endif // IPCL_USE_OMP #include "ipcl/keygen.hpp" -constexpr int SELF_DEF_NUM_VALUES = 20; - static void BM_KeyGen(benchmark::State& state) { int64_t n_length = state.range(0); for (auto _ : state) { diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index 62e1a93..452d777 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -3,18 +3,13 @@ #include -#include -#ifdef IPCL_USE_OMP -#include -#endif // IPCL_USE_OMP #include +#include #include "ipcl/ciphertext.hpp" #include "ipcl/keygen.hpp" #include "ipcl/plaintext.hpp" -constexpr int SELF_DEF_NUM_VALUES = 20; - static void BM_Add_CTCT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index c35d682..c424388 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -47,6 +47,11 @@ install(DIRECTORY ${IPPCRYPTO_INC_DIR}/ target_link_libraries(ipcl PUBLIC OpenSSL::SSL OpenSSL::Crypto Threads::Threads) +if(IPCL_ENABLE_OMP) + find_package(OpenMP REQUIRED) + target_link_libraries(ipcl PRIVATE OpenMP::OpenMP_CXX) +endif() + if(IPCL_SHARED) target_link_libraries(ipcl PRIVATE libippcrypto) target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) diff --git a/ipcl/ciphertext.cpp b/ipcl/ciphertext.cpp index 9532d9e..27cdcdb 100644 --- a/ipcl/ciphertext.cpp +++ b/ipcl/ciphertext.cpp @@ -5,10 +5,6 @@ #include -#ifdef IPCL_CRYPTO_OMP -#include -#endif - #include "ipcl/mod_exp.hpp" namespace ipcl { diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index be9535b..950b388 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -9,10 +9,6 @@ #include #include -#ifdef IPCL_CRYPTO_OMP -#include -#endif - #include "ipcl/util.hpp" namespace ipcl { @@ -34,23 +30,16 @@ static std::vector ippMBModExp(const std::vector& base, std::vector out_x(IPCL_CRYPTO_MB_SIZE); std::vector b_array(IPCL_CRYPTO_MB_SIZE); std::vector p_array(IPCL_CRYPTO_MB_SIZE); - int length = dwords * sizeof(int64u); - -#ifdef IPCL_USE_OMP -#pragma omp parallel for -#endif // IPCL_USE_OMP - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - out_x[i] = reinterpret_cast(alloca(length)); - b_array[i] = reinterpret_cast(alloca(length)); - p_array[i] = reinterpret_cast(alloca(length)); - ERROR_CHECK( - out_x[i] != nullptr && b_array[i] != nullptr && p_array[i] != nullptr, - "ippMultiBuffExp: alloc memory for error"); + int mem_pool_size = IPCL_CRYPTO_MB_SIZE * dwords; + std::vector out_mem_pool(mem_pool_size); + std::vector base_mem_pool(mem_pool_size); + std::vector pow_mem_pool(mem_pool_size); - memset(out_x[i], 0, length); - memset(b_array[i], 0, length); - memset(p_array[i], 0, length); + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + out_x[i] = &out_mem_pool[i * dwords]; + b_array[i] = &base_mem_pool[i * dwords]; + p_array[i] = &pow_mem_pool[i * dwords]; } /* @@ -66,9 +55,6 @@ static std::vector ippMBModExp(const std::vector& base, std::vector p_size_v(IPCL_CRYPTO_MB_SIZE); std::vector n_size_v(IPCL_CRYPTO_MB_SIZE); -#ifdef IPCL_USE_OMP -#pragma omp parallel for -#endif // IPCL_USE_OMP for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { ippsRef_BN(nullptr, &b_size_v[i], reinterpret_cast(&pow_b[i]), base[i]); @@ -100,16 +86,11 @@ static std::vector ippMBModExp(const std::vector& base, } // It is important to hold a copy of nsquare for thread-safe purpose - BigNumber bn_c(m.front()); + std::vector res(IPCL_CRYPTO_MB_SIZE, m.front()); - std::vector res(IPCL_CRYPTO_MB_SIZE, 0); -#ifdef IPCL_USE_OMP -#pragma omp parallel for -#endif // IPCL_USE_OMP for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - bn_c.Set(reinterpret_cast(out_x[i]), BITSIZE_WORD(nsqBitLen), - IppsBigNumPOS); - res[i] = bn_c; + res[i].Set(reinterpret_cast(out_x[i]), BITSIZE_WORD(nsqBitLen), + IppsBigNumPOS); } return res; } @@ -188,14 +169,13 @@ std::vector ippModExp(const std::vector& base, #pragma omp parallel for #endif // IPCL_USE_OMP for (std::size_t i = 0; i < num_chunk; i++) { - offset = i * IPCL_CRYPTO_MB_SIZE; - auto base_start = base.begin() + offset; + auto base_start = base.begin() + i * IPCL_CRYPTO_MB_SIZE; auto base_end = base_start + IPCL_CRYPTO_MB_SIZE; - auto pow_start = pow.begin() + offset; + auto pow_start = pow.begin() + i * IPCL_CRYPTO_MB_SIZE; auto pow_end = pow_start + IPCL_CRYPTO_MB_SIZE; - auto m_start = m.begin() + offset; + auto m_start = m.begin() + i * IPCL_CRYPTO_MB_SIZE; auto m_end = m_start + IPCL_CRYPTO_MB_SIZE; auto base_chunk = std::vector(base_start, base_end); @@ -203,7 +183,7 @@ std::vector ippModExp(const std::vector& base, auto m_chunk = std::vector(m_start, m_end); auto tmp = ippMBModExp(base_chunk, pow_chunk, m_chunk); - std::copy(tmp.begin(), tmp.end(), res.begin() + offset); + std::copy(tmp.begin(), tmp.end(), res.begin() + i * IPCL_CRYPTO_MB_SIZE); } offset = num_chunk * IPCL_CRYPTO_MB_SIZE; diff --git a/ipcl/pri_key.cpp b/ipcl/pri_key.cpp index f938217..3d8c80c 100644 --- a/ipcl/pri_key.cpp +++ b/ipcl/pri_key.cpp @@ -79,6 +79,10 @@ void PrivateKey::decryptRAW(std::vector& plaintext, BigNumber nn = m_n; BigNumber xx = m_x; + +#ifdef IPCL_USE_OMP +#pragma omp parallel for +#endif // IPCL_USE_OMP for (int i = 0; i < v_size; i++) { BigNumber m = (res[i] - 1) / nn; m = m * xx; @@ -104,6 +108,9 @@ void PrivateKey::decryptCRT(std::vector& plaintext, std::vector resp = ipcl::ippModExp(basep, pm1, psq); std::vector resq = ipcl::ippModExp(baseq, qm1, qsq); +#ifdef IPCL_USE_OMP +#pragma omp parallel for +#endif // IPCL_USE_OMP for (int i = 0; i < v_size; i++) { BigNumber dp = computeLfun(resp[i], m_p) * m_hp % m_p; BigNumber dq = computeLfun(resq[i], m_q) * m_hq % m_q; diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index 06c2b58..5ebb419 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -10,10 +10,6 @@ #include #include -#ifdef IPCL_CRYPTO_OMP -#include -#endif - #include "ipcl/ciphertext.hpp" #include "ipcl/mod_exp.hpp" #include "ipcl/util.hpp" @@ -123,9 +119,6 @@ void PublicKey::applyObfuscator(std::vector& obfuscator) const { } obfuscator = ipcl::ippModExp(base, r, sq); } else { -#ifdef IPCL_USE_OMP -#pragma omp parallel for -#endif // IPCL_USE_OMP for (int i = 0; i < obf_size; i++) { if (m_testv) { r[i] = m_r[i]; @@ -152,9 +145,6 @@ std::vector PublicKey::raw_encrypt(const std::vector& pt, std::vector ct(pt_size); BigNumber sq = m_nsquare; -#ifdef IPCL_USE_OMP -#pragma omp parallel for -#endif // IPCL_USE_OMP for (std::size_t i = 0; i < pt_size; i++) { ct[i] = (m_n * pt[i] + 1) % m_nsquare; } @@ -163,9 +153,6 @@ std::vector PublicKey::raw_encrypt(const std::vector& pt, std::vector obfuscator(pt_size); applyObfuscator(obfuscator); -#ifdef IPCL_USE_OMP -#pragma omp parallel for -#endif // IPCL_USE_OMP for (std::size_t i = 0; i < pt_size; i++) ct[i] = sq.ModMul(ct[i], obfuscator[i]); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bca944a..fe6c6e9 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -14,9 +14,3 @@ target_include_directories(unittest_ipcl PRIVATE target_link_libraries(unittest_ipcl PRIVATE ipcl -pthread libgtest ) - -# enable OpenMP unittests -if(IPCL_ENABLE_OMP) - find_package(OpenMP REQUIRED) - target_link_libraries(unittest_ipcl PRIVATE OpenMP::OpenMP_CXX) -endif() diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index d32f6ac..eaaf3e3 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -6,10 +6,6 @@ #include #include -#ifdef IPCL_USE_OMP -#include -#endif // IPCL_USE_OMP - #include "gtest/gtest.h" #include "ipcl/ciphertext.hpp" #include "ipcl/keygen.hpp" @@ -190,63 +186,3 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { delete key.pub_key; delete key.priv_key; } - -#ifdef IPCL_USE_OMP -void Encryption(int num_threads, std::vector& ct_v, - const std::vector& pt_v, - const ipcl::keyPair key) { -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - ct_v[i] = key.pub_key->encrypt(pt_v[i]); - } -} - -void Decryption(int num_threads, std::vector& dt_v, - const std::vector& ct_v, - const ipcl::keyPair key) { -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - dt_v[i] = key.priv_key->decrypt(ct_v[i]); - } -} - -TEST(CryptoTest, CryptoTest_OMP) { - const uint32_t num_values = SELF_DEF_NUM_VALUES; - // use one keypair to do several encryption/decryption - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - size_t num_threads = omp_get_max_threads(); - - std::vector> exp_value( - num_threads, std::vector(num_values)); - std::vector pt_v(num_threads); - std::vector ct_v(num_threads); - std::vector dt_v(num_threads); - - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < num_threads; i++) { - // for each threads, generated different rand testing value - for (int j = 0; j < num_values; j++) { - exp_value[i][j] = dist(rng); - } - pt_v[i] = ipcl::PlainText(exp_value[i]); - } - - Encryption(num_threads, ct_v, pt_v, key); - Decryption(num_threads, dt_v, ct_v, key); - - // check output for all threads - for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < num_values; j++) { - std::vector v = dt_v[i].getElementVec(j); - EXPECT_EQ(v[0], exp_value[i][j]); - } - } - - delete key.pub_key; - delete key.priv_key; -} -#endif // IPCL_USE_OMP diff --git a/test/test_ops.cpp b/test/test_ops.cpp index dc159f9..6bb9c4e 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -6,10 +6,6 @@ #include #include -#ifdef IPCL_USE_OMP -#include -#endif // IPCL_USE_OMP - #include "gtest/gtest.h" #include "ipcl/ciphertext.hpp" #include "ipcl/keygen.hpp" @@ -414,378 +410,3 @@ TEST(OperationTest, AddSubTest) { delete key.pub_key; delete key.priv_key; } - -#ifdef IPCL_USE_OMP -void CtPlusCt_OMP(int num_threads, std::vector& res_v, - const std::vector& ct1_v, - const std::vector& ct2_v, - const ipcl::keyPair key) { - std::vector> sum_bn_v(num_threads); - -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - int size = ct1_v[i].getSize(); - sum_bn_v[i] = std::vector(size); - for (int j = 0; j < size; j++) { - ipcl::CipherText a(key.pub_key, ct1_v[i].getElement(j)); - ipcl::CipherText b(key.pub_key, ct2_v[i].getElement(j)); - ipcl::CipherText sum = a + b; - sum_bn_v[i][j] = sum.getElement(0); - } - res_v[i] = ipcl::CipherText(key.pub_key, sum_bn_v[i]); - } -} - -void CtPlusPt_OMP(int num_threads, std::vector& res_v, - const std::vector& ct1_v, - const std::vector& pt2_v, - const ipcl::keyPair key) { - std::vector> sum_bn_v(num_threads); - -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - int size = ct1_v[i].getSize(); - sum_bn_v[i] = std::vector(size); - for (int j = 0; j < size; j++) { - ipcl::CipherText a(key.pub_key, ct1_v[i].getElement(j)); - ipcl::PlainText b(pt2_v[i].getElement(j)); - ipcl::CipherText sum = a + b; - sum_bn_v[i][j] = sum.getElement(0); - } - res_v[i] = ipcl::CipherText(key.pub_key, sum_bn_v[i]); - } -} - -void CtPlusPtArray_OMP(int num_threads, std::vector& res_v, - const std::vector& ct1_v, - const std::vector& pt2_v, - const ipcl::keyPair key) { -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - res_v[i] = ct1_v[i] + pt2_v[i]; - } -} - -void CtMultiplyPtArray_OMP(int num_threads, - std::vector& res_v, - const std::vector& ct1_v, - const std::vector& pt2_v, - const ipcl::keyPair key) { -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - res_v[i] = ct1_v[i] * pt2_v[i]; - } -} - -void CtMultiplyPt_OMP(int num_threads, std::vector& res_v, - const std::vector& ct1_v, - const std::vector& pt2_v, - const ipcl::keyPair key) { - std::vector> product_bn_v(num_threads); - -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - int size = ct1_v[i].getSize(); - product_bn_v[i] = std::vector(size); - for (int j = 0; j < size; j++) { - ipcl::CipherText a(key.pub_key, ct1_v[i].getElement(j)); - ipcl::PlainText b(pt2_v[i].getElement(j)); - ipcl::CipherText product = a * b; - product_bn_v[i][j] = product.getElement(0); - } - res_v[i] = ipcl::CipherText(key.pub_key, product_bn_v[i]); - } -} - -TEST(OperationTest, CtPlusCtTest_OMP) { - const uint32_t num_values = SELF_DEF_NUM_VALUES; - - ipcl::keyPair key = ipcl::generateKeypair(2048); - - size_t num_threads = omp_get_max_threads(); - - std::vector> exp_value1_vv( - num_threads, std::vector(num_values)), - exp_value2_vv(num_threads, std::vector(num_values)); - std::vector pt1_v(num_threads), pt2_v(num_threads), - dt_sum_v(num_threads); - std::vector ct1_v(num_threads), ct2_v(num_threads), - ct_sum_v(num_threads); - - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < num_threads; i++) { - // for each threads, generated different rand testing value - for (int j = 0; j < num_values; j++) { - exp_value1_vv[i][j] = dist(rng); - exp_value2_vv[i][j] = dist(rng); - } - pt1_v[i] = ipcl::PlainText(exp_value1_vv[i]); - pt2_v[i] = ipcl::PlainText(exp_value2_vv[i]); - } - -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - ct1_v[i] = key.pub_key->encrypt(pt1_v[i]); - ct2_v[i] = key.pub_key->encrypt(pt2_v[i]); - } - - CtPlusCt_OMP(num_threads, ct_sum_v, ct1_v, ct2_v, key); - -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - dt_sum_v[i] = key.priv_key->decrypt(ct_sum_v[i]); - } - - // check output for all threads - for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < num_values; j++) { - std::vector v = dt_sum_v[i].getElementVec(j); - uint64_t sum = v[0]; - if (v.size() > 1) sum = ((uint64_t)v[1] << 32) | v[0]; - uint64_t exp_sum = - (uint64_t)exp_value1_vv[i][j] + (uint64_t)exp_value2_vv[i][j]; - - EXPECT_EQ(sum, exp_sum); - } - } - - delete key.pub_key; - delete key.priv_key; -} - -TEST(OperationTest, CtPlusPtTest_OMP) { - const uint32_t num_values = SELF_DEF_NUM_VALUES; - - ipcl::keyPair key = ipcl::generateKeypair(2048); - - size_t num_threads = omp_get_max_threads(); - - std::vector> exp_value1_vv( - num_threads, std::vector(num_values)), - exp_value2_vv(num_threads, std::vector(num_values)); - std::vector pt1_v(num_threads), pt2_v(num_threads), - dt_sum_v(num_threads); - std::vector ct1_v(num_threads), ct2_v(num_threads), - ct_sum_v(num_threads); - - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < num_threads; i++) { - // for each threads, generated different rand testing value - for (int j = 0; j < num_values; j++) { - exp_value1_vv[i][j] = dist(rng); - exp_value2_vv[i][j] = dist(rng); - } - pt1_v[i] = ipcl::PlainText(exp_value1_vv[i]); - pt2_v[i] = ipcl::PlainText(exp_value2_vv[i]); - } - -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - ct1_v[i] = key.pub_key->encrypt(pt1_v[i]); - } - - CtPlusPt_OMP(num_threads, ct_sum_v, ct1_v, pt2_v, key); - -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - dt_sum_v[i] = key.priv_key->decrypt(ct_sum_v[i]); - } - - // check output for all threads - for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < num_values; j++) { - std::vector v = dt_sum_v[i].getElementVec(j); - uint64_t sum = v[0]; - if (v.size() > 1) sum = ((uint64_t)v[1] << 32) | v[0]; - uint64_t exp_sum = - (uint64_t)exp_value1_vv[i][j] + (uint64_t)exp_value2_vv[i][j]; - - EXPECT_EQ(sum, exp_sum); - } - } - - delete key.pub_key; - delete key.priv_key; -} - -TEST(OperationTest, CtPlusPtArrayTest_OMP) { - const uint32_t num_values = SELF_DEF_NUM_VALUES; - - ipcl::keyPair key = ipcl::generateKeypair(2048); - - size_t num_threads = omp_get_max_threads(); - - std::vector> exp_value1_vv( - num_threads, std::vector(num_values)), - exp_value2_vv(num_threads, std::vector(num_values)); - std::vector pt1_v(num_threads), pt2_v(num_threads), - dt_sum_v(num_threads); - std::vector ct1_v(num_threads), ct2_v(num_threads), - ct_sum_v(num_threads); - - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < num_threads; i++) { - // for each threads, generated different rand testing value - for (int j = 0; j < num_values; j++) { - exp_value1_vv[i][j] = dist(rng); - exp_value2_vv[i][j] = dist(rng); - } - pt1_v[i] = ipcl::PlainText(exp_value1_vv[i]); - pt2_v[i] = ipcl::PlainText(exp_value2_vv[i]); - } - -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - ct1_v[i] = key.pub_key->encrypt(pt1_v[i]); - } - - CtPlusPtArray_OMP(num_threads, ct_sum_v, ct1_v, pt2_v, key); - -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - dt_sum_v[i] = key.priv_key->decrypt(ct_sum_v[i]); - } - - // check output for all threads - for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < num_values; j++) { - std::vector v = dt_sum_v[i].getElementVec(j); - uint64_t sum = v[0]; - if (v.size() > 1) sum = ((uint64_t)v[1] << 32) | v[0]; - uint64_t exp_sum = - (uint64_t)exp_value1_vv[i][j] + (uint64_t)exp_value2_vv[i][j]; - - EXPECT_EQ(sum, exp_sum); - } - } - - delete key.pub_key; - delete key.priv_key; -} - -TEST(OperationTest, CtMultiplyPtArrayTest_OMP) { - const uint32_t num_values = SELF_DEF_NUM_VALUES; - - ipcl::keyPair key = ipcl::generateKeypair(2048); - - size_t num_threads = omp_get_max_threads(); - - std::vector> exp_value1_vv( - num_threads, std::vector(num_values)), - exp_value2_vv(num_threads, std::vector(num_values)); - std::vector pt1_v(num_threads), pt2_v(num_threads), - dt_product_v(num_threads); - std::vector ct1_v(num_threads), ct2_v(num_threads), - ct_product_v(num_threads); - - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < num_threads; i++) { - // for each threads, generated different rand testing value - for (int j = 0; j < num_values; j++) { - exp_value1_vv[i][j] = dist(rng); - exp_value2_vv[i][j] = dist(rng); - } - pt1_v[i] = ipcl::PlainText(exp_value1_vv[i]); - pt2_v[i] = ipcl::PlainText(exp_value2_vv[i]); - } - -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - ct1_v[i] = key.pub_key->encrypt(pt1_v[i]); - } - - CtMultiplyPtArray_OMP(num_threads, ct_product_v, ct1_v, pt2_v, key); - -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - dt_product_v[i] = key.priv_key->decrypt(ct_product_v[i]); - } - - // check output for all threads - for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < num_values; j++) { - std::vector v = dt_product_v[i].getElementVec(j); - uint64_t product = v[0]; - if (v.size() > 1) product = ((uint64_t)v[1] << 32) | v[0]; - uint64_t exp_product = - (uint64_t)exp_value1_vv[i][j] * (uint64_t)exp_value2_vv[i][j]; - - EXPECT_EQ(product, exp_product); - } - } - - delete key.pub_key; - delete key.priv_key; -} - -TEST(OperationTest, CtMultiplyPtTest_OMP) { - const uint32_t num_values = SELF_DEF_NUM_VALUES; - - ipcl::keyPair key = ipcl::generateKeypair(2048); - - size_t num_threads = omp_get_max_threads(); - - std::vector> exp_value1_vv( - num_threads, std::vector(num_values)), - exp_value2_vv(num_threads, std::vector(num_values)); - std::vector pt1_v(num_threads), pt2_v(num_threads), - dt_product_v(num_threads); - std::vector ct1_v(num_threads), ct2_v(num_threads), - ct_product_v(num_threads); - - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < num_threads; i++) { - // for each threads, generated different rand testing value - for (int j = 0; j < num_values; j++) { - exp_value1_vv[i][j] = dist(rng); - exp_value2_vv[i][j] = dist(rng); - } - pt1_v[i] = ipcl::PlainText(exp_value1_vv[i]); - pt2_v[i] = ipcl::PlainText(exp_value2_vv[i]); - } - -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - ct1_v[i] = key.pub_key->encrypt(pt1_v[i]); - } - - CtMultiplyPt_OMP(num_threads, ct_product_v, ct1_v, pt2_v, key); - -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - dt_product_v[i] = key.priv_key->decrypt(ct_product_v[i]); - } - - // check output for all threads - for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < num_values; j++) { - std::vector v = dt_product_v[i].getElementVec(j); - uint64_t product = v[0]; - if (v.size() > 1) product = ((uint64_t)v[1] << 32) | v[0]; - uint64_t exp_product = - (uint64_t)exp_value1_vv[i][j] * (uint64_t)exp_value2_vv[i][j]; - - EXPECT_EQ(product, exp_product); - } - } - - delete key.pub_key; - delete key.priv_key; -} - -#endif // IPCL_USE_OMP From e39be90a5f608689ff2b9be8c9162f57525915de Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 27 Apr 2022 14:51:20 -0700 Subject: [PATCH 167/364] [Bug Fix]: crash for small batch sizes and multiple threads. --- CMakeLists.txt | 18 ++++++- he_qat/he_qat_bn_ops.c | 94 +++++++++++++++++++++++++--------- he_qat/he_qat_context.c | 3 +- he_qat/include/he_qat_bn_ops.h | 4 +- he_qat/include/he_qat_types.h | 13 +++-- samples/CMakeLists.txt | 19 ++++++- 6 files changed, 117 insertions(+), 34 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 63ebcb3..54ef689 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,8 +58,10 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) option(HE_QAT_MISC "Enable miscellaneous features" ON) option(HE_QAT_SYNC "Enable synchronous mode execution" OFF) +option(HE_QAT_MT "Enable interfaces for multithreaded programs" ON) option(HE_QAT_PERF "Show request performance" OFF) option(HE_QAT_TEST "Enable testing" OFF) +option(HE_QAT_OMP "Enable tests using OpenMP" ON) option(HE_QAT_SAMPLES "Enable examples" ON) option(HE_QAT_BENCHMARK "Enable benchmark" OFF) option(HE_QAT_DOCS "Enable document building" OFF) @@ -74,11 +76,25 @@ endif() # Why? set(HE_QAT_CMAKE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/he_qat") - set(HE_QAT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) set(HE_QAT_SRC_DIR ${HE_QAT_ROOT_DIR}/he_qat) set(HE_QAT_INC_DIR ${HE_QAT_ROOT_DIR}/he_qat/include) +if(HE_QAT_OMP) + find_package(OpenMP REQUIRED) + if(NOT TARGET OpenMP::OpenMP_CXX) + message(FATAL_ERROR "Missing OpenMP::OpenMP_CXX.") + endif() + if(NOT TARGET OpenMP::OpenMP_C) + message(FATAL_ERROR "Missing OpenMP::OpenMP_C.") + endif() +endif() + +if(HE_QAT_MT) + add_definitions(-DHE_QAT_MT) + message(STATUS "Compile with multithreaded interfaces.") +endif() + if(HE_QAT_MISC) # IPP Crypto installation if(IPPCP_PREFIX_PATH) diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index 700596e..49c8cb0 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -101,36 +101,43 @@ static void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { } static void submit_request_list(HE_QAT_RequestBuffer* _buffer, - const HE_QAT_TaskRequestList* _requests) { + HE_QAT_TaskRequestList* _requests) { +//#define HE_QAT_DEBUG #ifdef HE_QAT_DEBUG - printf("Lock write request\n"); +// printf("Lock submit request list\n"); #endif if (0 == _requests->count) return; pthread_mutex_lock(&_buffer->mutex); #ifdef HE_QAT_DEBUG - printf("Wait lock write request. [buffer size: %d]\n", _buffer->count); + printf( + "Wait lock submit request list. [internal buffer size: %d] [num " + "requests: %u]\n", + _buffer->count, _requests->count); #endif // Wait until buffer can accomodate the number of input requests while (_buffer->count >= HE_QAT_BUFFER_SIZE || - (HE_QAT_BUFFER_SIZE - _buffer->count + 1) < _requests->count) + (HE_QAT_BUFFER_SIZE - _buffer->count) < _requests->count) pthread_cond_wait(&_buffer->any_free_slot, &_buffer->mutex); assert(_buffer->count < HE_QAT_BUFFER_SIZE); - assert(_requests->count <= (HE_QAT_BUFFER_SIZE - _buffer->count + 1)); + assert(_requests->count <= (HE_QAT_BUFFER_SIZE - _buffer->count)); for (unsigned int i = 0; i < _requests->count; i++) { _buffer->data[_buffer->next_free_slot++] = _requests->request[i]; _buffer->next_free_slot %= HE_QAT_BUFFER_SIZE; + _requests->request[i] = NULL; } _buffer->count += _requests->count; + _requests->count = 0; pthread_cond_signal(&_buffer->any_more_data); pthread_mutex_unlock(&_buffer->mutex); #ifdef HE_QAT_DEBUG - printf("Unlocked write request. [buffer size: %d]\n", _buffer->count); + printf("Unlocked submit request list. [internal buffer size: %d]\n", + _buffer->count); #endif } @@ -141,7 +148,7 @@ static void submit_request_list(HE_QAT_RequestBuffer* _buffer, /// Stores requests in a buffer that will be sent to the HE QAT buffer. /// @unused static void push_request(HE_QAT_RequestBufferList* _outstanding_buffer, - void* args, unsigned int num_requests = 1) { + void* args, unsigned int num_requests) { #ifdef HE_QAT_DEBUG printf("Lock write outstanding requests\n"); #endif @@ -199,8 +206,13 @@ static void push_request(HE_QAT_RequestBufferList* _outstanding_buffer, /// Supported in single-threaded or multi-threaded mode. static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) { void* item = NULL; - + static unsigned int counter = 0; pthread_mutex_lock(&_buffer->mutex); +//#define HE_QAT_DEBUG +#ifdef HE_QAT_DEBUG + printf("Wait lock read request. [internal buffer size: %d] Request #%u\n", + _buffer->count, counter++); +#endif // Wait while buffer is empty while (_buffer->count <= 0) pthread_cond_wait(&_buffer->any_more_data, &_buffer->mutex); @@ -214,6 +226,10 @@ static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) { pthread_cond_signal(&_buffer->any_free_slot); pthread_mutex_unlock(&_buffer->mutex); +#ifdef HE_QAT_DEBUG + printf("Unlocked read request. [internal buffer count: %d]\n", + _buffer->count); +#endif return (HE_QAT_TaskRequest*)(item); } @@ -256,7 +272,7 @@ static void read_request_list(HE_QAT_TaskRequestList* _requests, static void pull_request(HE_QAT_TaskRequestList* _requests, // HE_QAT_OutstandingBuffer *_outstanding_buffer, HE_QAT_RequestBufferList* _outstanding_buffer, - unsigned int max_num_requests = 1) { + unsigned int max_num_requests) { if (NULL == _requests) return; pthread_mutex_lock(&_outstanding_buffer->mutex); @@ -301,7 +317,7 @@ static void pull_request(HE_QAT_TaskRequestList* _requests, static void pull_outstanding_requests( HE_QAT_TaskRequestList* _requests, HE_QAT_OutstandingBuffer* _outstanding_buffer, - unsigned int max_num_requests = 1) { + unsigned int max_num_requests) { if (NULL == _requests) return; _requests->count = 0; @@ -333,6 +349,8 @@ static void pull_outstanding_requests( if (!any_ready) return; + // printf("Buffer #%u is Ready\n",index); + // Extract outstanding requests from outstanding buffer // (this is the only function that reads from outstanding buffer, from a // single thread) @@ -414,7 +432,7 @@ HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id) { return HE_QAT_STATUS_SUCCESS; } -static void* schedule_requests(void* state) { +void* schedule_requests(void* state) { if (NULL == state) { printf("Failed at buffer_manager: argument is NULL.\n"); pthread_exit(NULL); @@ -424,19 +442,21 @@ static void* schedule_requests(void* state) { HE_QAT_TaskRequestList outstanding_requests; for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { - outstanding_requests->request[i] = NULL; + outstanding_requests.request[i] = NULL; } - outstading_requests->count = 0; + outstanding_requests.count = 0; // this thread should receive signal from context to exit while (*active) { // collect a set of requests from the outstanding buffer - // pull_request(&outstanding_requests, &outstanding_buffer, - // HE_QAT_BUFFER_SIZE); pull_outstanding_requests(&outstanding_requests, &outstanding, HE_QAT_BUFFER_SIZE); + // printf("Pulled %u outstanding + //requests\n",outstanding_requests.count); // submit them to the HE QAT buffer for offloading submit_request_list(&he_qat_buffer, &outstanding_requests); + // printf("Submitted %u outstanding + //requests\n",outstanding_requests.count); } pthread_exit(NULL); @@ -474,6 +494,7 @@ static void* start_inst_polling(void* _inst_config) { /// @param[in] HE_QAT_InstConfig *: contains the handle to CPA instance, pointer /// the global buffer of requests. void* start_perform_op(void* _inst_config) { + static unsigned int request_count = 0; if (NULL == _inst_config) { printf("Failed in start_perform_op: _inst_config is NULL.\n"); pthread_exit(NULL); @@ -530,6 +551,7 @@ void* start_perform_op(void* _inst_config) { pthread_cond_signal(&config->ready); continue; } +// printf("Try process request #%u\n", request_count++); #ifdef HE_QAT_SYNC_MODE COMPLETION_INIT(&request->callback); #endif @@ -770,20 +792,32 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, // Assume allocate_bnModExp_buffer(&_buffer_id) to be called first // to secure and allocate an outstanding buffer for the target thread. // Multithread support for release_bnModExp_buffer(_buffer_id, batch_size) -void release_bnModExp_buffer(int _buffer_id, unsigned int _batch_size) { +void release_bnModExp_buffer(unsigned int _buffer_id, + unsigned int _batch_size) { + unsigned int next_data_out = outstanding.buffer[_buffer_id].next_data_out; unsigned int j = 0; +#ifdef HE_QAT_DEBUG + printf("release_bnModExp_buffer #%u\n", _buffer_id); +#endif + #ifdef HE_QAT_PERF gettimeofday(&start_time, NULL); #endif - do { + + while (j < _batch_size) { // Buffer read may be safe for single-threaded blocking calls only. // Note: Not tested on multithreaded environment. HE_QAT_TaskRequest* task = - (HE_QAT_TaskRequest*)outstanding.buffer[_buffer_id].data[j]; + (HE_QAT_TaskRequest*)outstanding.buffer[_buffer_id] + .data[next_data_out]; - // if (NULL == task) - // continue; + if (NULL == task) continue; + +#ifdef HE_QAT_DEBUG + printf("BatchSize %u Buffer #%u Request #%u Waiting\n", _batch_size, + _buffer_id, j); +#endif // Block and synchronize: Wait for the most recently offloaded request // to complete processing @@ -815,10 +849,20 @@ void release_bnModExp_buffer(int _buffer_id, unsigned int _batch_size) { // Move forward to wait for the next request that will be offloaded pthread_mutex_unlock(&task->mutex); +#ifdef HE_QAT_DEBUG + printf("Buffer #%u Request #%u Completed\n", _buffer_id, j); +#endif + // outstanding.buffer[_buffer_id].count--; + // Fix segmentation fault? - free(outstanding.buffer[_buffer_id].data[j]); - outstanding.buffer[_buffer_id].data[j] = NULL; - } while (++j < batch_size); + free(outstanding.buffer[_buffer_id].data[next_data_out]); + outstanding.buffer[_buffer_id].data[next_data_out] = NULL; + + // update for next thread on the next external iteration + next_data_out = (next_data_out + 1) % HE_QAT_BUFFER_SIZE; + + j++; + } #ifdef HE_QAT_PERF gettimeofday(&end_time, NULL); @@ -828,6 +872,8 @@ void release_bnModExp_buffer(int _buffer_id, unsigned int _batch_size) { printf("Batch Wall Time: %.1lfus\n", time_taken); #endif + outstanding.buffer[_buffer_id].next_data_out = next_data_out; + // Release outstanding buffer for usage by another thread pthread_mutex_lock(&outstanding.mutex); @@ -1055,7 +1101,7 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, return HE_QAT_STATUS_SUCCESS; } -HE_QAT_STATUS HE_QAT_bnModExp_MT(int _buffer_id, unsigned char* r, +HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, unsigned char* b, unsigned char* e, unsigned char* m, int nbits) { #ifdef HE_QAT_DEBUG diff --git a/he_qat/he_qat_context.c b/he_qat/he_qat_context.c index f3a3748..5269781 100644 --- a/he_qat/he_qat_context.c +++ b/he_qat/he_qat_context.c @@ -153,12 +153,13 @@ HE_QAT_STATUS acquire_qat_devices() { outstanding.buffer[i].count = 0; outstanding.buffer[i].next_free_slot = 0; outstanding.buffer[i].next_data_slot = 0; + outstanding.buffer[i].next_data_out = 0; for (int j = 0; j < HE_QAT_BUFFER_SIZE; j++) { outstanding.buffer[i].data[j] = NULL; } pthread_mutex_init(&outstanding.buffer[i].mutex, NULL); pthread_cond_init(&outstanding.buffer[i].any_more_data, NULL); - pthread_cond_init(&outstanding.buffer[i].any_free_data, NULL); + pthread_cond_init(&outstanding.buffer[i].any_free_slot, NULL); } pthread_mutex_init(&outstanding.mutex, NULL); pthread_cond_init(&outstanding.any_free_buffer, NULL); diff --git a/he_qat/include/he_qat_bn_ops.h b/he_qat/include/he_qat_bn_ops.h index 48db5ac..bf51313 100644 --- a/he_qat/include/he_qat_bn_ops.h +++ b/he_qat/include/he_qat_bn_ops.h @@ -114,11 +114,11 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id); -HE_QAT_STATUS HE_QAT_bnModExp_MT(int _buffer_id, unsigned char* r, +HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, unsigned char* b, unsigned char* e, unsigned char* m, int nbits); -void release_bnModExp_buffer(int _buffer_id, unsigned int _batch_size); +void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size); #ifdef __cplusplus } // extern "C" { diff --git a/he_qat/include/he_qat_types.h b/he_qat/include/he_qat_types.h index b9f6921..dfc5b8a 100644 --- a/he_qat/include/he_qat_types.h +++ b/he_qat/include/he_qat_types.h @@ -33,11 +33,14 @@ typedef pthread_t HE_QAT_Inst; typedef struct { void* data[HE_QAT_BUFFER_SIZE]; // volatile unsigned int count; // occupied track number of buffer enties - unsigned int - next_free_slot; // nextin index of the next free slot for a request - unsigned int - next_data_slot; // nextout index of next request to be processed - pthread_mutex_t mutex; // + // nextin index of the next free slot for a request + unsigned int next_free_slot; + // nextout index of next request to be processed + unsigned int next_data_slot; + // index of next output data to be read by a thread waiting + // for all the request to complete processing + unsigned int next_data_out; + pthread_mutex_t mutex; // pthread_cond_t any_more_data; // more pthread_cond_t any_free_slot; // less } HE_QAT_RequestBuffer; diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 4311833..47b82f7 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -48,7 +48,7 @@ if(HE_QAT_MISC) install(TARGETS test_bnConversion RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) - # Sample demonstrating how to use bnModExp with BigNumber type + # Sample demonstrating how to use bnModExp add_executable(test_bnModExp test_bnModExp.cpp) target_include_directories(test_bnModExp PUBLIC ${COMMON_INC_DIR}) @@ -61,4 +61,21 @@ if(HE_QAT_MISC) target_link_libraries(test_bnModExp PUBLIC OpenSSL::SSL) # OpenSSL::Crypto) install(TARGETS test_bnModExp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + + if(OpenMP_CXX_FOUND) + # Sample demonstrating how to use multithread-supported interface bnModExp_MT + add_executable(test_bnModExp_MT test_bnModExp_MT.cpp) + + target_include_directories(test_bnModExp_MT PUBLIC ${COMMON_INC_DIR}) + target_include_directories(test_bnModExp_MT PUBLIC ${ICP_INC_DIR}) + target_include_directories(test_bnModExp_MT PUBLIC ${HE_QAT_MISC_INC_DIR}) + + target_link_libraries(test_bnModExp_MT PUBLIC he_qat) + target_link_libraries(test_bnModExp_MT PUBLIC he_qat_misc) + target_link_libraries(test_bnModExp_MT PUBLIC OpenMP::OpenMP_CXX) + target_link_libraries(test_bnModExp_MT PUBLIC IPPCP::ippcp) # IPPCP::crypto_mb) + target_link_libraries(test_bnModExp_MT PUBLIC OpenSSL::SSL) # OpenSSL::Crypto) + + install(TARGETS test_bnModExp_MT RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + endif() endif() From 0d450f96c80522ad05859c61a5662345016c757a Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Tue, 3 May 2022 02:09:41 +0800 Subject: [PATCH 168/364] update qat branch with new CipherText PlainText implementation (#84) * improve encrypt decrypt (#75) *Major updates: - Apply improved encrypt and decrypt to qat_integration branch - Improve the performance of encryption/decryption and CT+CT/PT CT*PT - Updated unit-test and benchmark dependencies to include he_qat and include paths * Minor updates and Bug fixes: - Fix OpenMP bug and performance issues - Remove OMP unittest, and clean unittest/benchmark Co-authored-by: Sejun Kim --- benchmark/CMakeLists.txt | 8 +- benchmark/bench_cryptography.cpp | 186 +------ benchmark/bench_ops.cpp | 375 ++------------ benchmark/main.cpp | 2 +- ipcl/CMakeLists.txt | 9 +- ipcl/base_text.cpp | 76 +++ ipcl/bignum.cpp | 6 +- ipcl/ciphertext.cpp | 144 ++++++ ipcl/include/ipcl/base_text.hpp | 83 ++++ ipcl/include/ipcl/bignum.h | 3 - ipcl/include/ipcl/ciphertext.hpp | 67 +++ ipcl/include/ipcl/ops.hpp | 132 ----- ipcl/include/ipcl/plaintext.hpp | 75 +++ ipcl/include/ipcl/pri_key.hpp | 18 +- ipcl/include/ipcl/pub_key.hpp | 40 +- ipcl/mod_exp.cpp | 154 ++++-- ipcl/ops.cpp | 157 ------ ipcl/plaintext.cpp | 46 ++ ipcl/pri_key.cpp | 74 +-- ipcl/pub_key.cpp | 65 +-- test/CMakeLists.txt | 6 - test/test_cryptography.cpp | 164 ++----- test/test_ops.cpp | 817 ++++++++----------------------- 23 files changed, 1000 insertions(+), 1707 deletions(-) create mode 100644 ipcl/base_text.cpp create mode 100644 ipcl/ciphertext.cpp create mode 100644 ipcl/include/ipcl/base_text.hpp create mode 100644 ipcl/include/ipcl/ciphertext.hpp delete mode 100644 ipcl/include/ipcl/ops.hpp create mode 100644 ipcl/include/ipcl/plaintext.hpp delete mode 100644 ipcl/ops.cpp create mode 100644 ipcl/plaintext.cpp diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index a0d5ae3..9b1a749 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -15,13 +15,7 @@ target_link_libraries(bench_ipcl PRIVATE ipcl libgbenchmark Threads::Threads ) -# enable OpenMP benchmarks -if(IPCL_ENABLE_OMP) - find_package(OpenMP REQUIRED) - target_link_libraries(bench_ipcl PRIVATE OpenMP::OpenMP_CXX) -endif() - -# enable QAT benchmarks +# enable QAT unittests if(IPCL_ENABLE_QAT) target_link_libraries(bench_ipcl PRIVATE libhe_qat) endif() diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index 1397867..2a96750 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -3,10 +3,8 @@ #include +#include #include -#ifdef IPCL_USE_OMP -#include -#endif // IPCL_USE_OMP #include "ipcl/keygen.hpp" @@ -22,188 +20,32 @@ static void BM_Encrypt(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize, std::vector(8)); - std::vector> ct(dsize, std::vector(8)); + std::vector exp_value_v(dsize); - for (size_t i = 0; i < dsize; ++i) { - pt[i][0] = BigNumber((unsigned int)i); - } - - for (auto _ : state) { - for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); - } -} - -BENCHMARK(BM_Encrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); - -static void BM_Encrypt_buff8(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); + for (size_t i = 0; i < dsize; i++) + exp_value_v[i] = (unsigned int)(i * 1024) + 999; - std::vector> pt(dsize / 8, std::vector(8)); - std::vector> ct(dsize / 8, std::vector(8)); + ipcl::PlainText pt(exp_value_v); + ipcl::CipherText ct; - for (size_t i = 0; i < dsize / 8; ++i) { - for (size_t j = 0; j < 8; ++j) - pt[i][j] = BigNumber((unsigned int)(i * 8 + j)); - } - - for (auto _ : state) { - for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); - } + for (auto _ : state) ct = key.pub_key->encrypt(pt); } -BENCHMARK(BM_Encrypt_buff8) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); +BENCHMARK(BM_Encrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); static void BM_Decrypt(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> pt(dsize, std::vector(8)); - std::vector> ct(dsize, std::vector(8)); - std::vector> de_ct(dsize, std::vector(8)); + std::vector exp_value_v(dsize); - for (size_t i = 0; i < dsize; ++i) { - pt[i][0] = BigNumber((unsigned int)i); - } + for (size_t i = 0; i < dsize; i++) + exp_value_v[i] = (unsigned int)(i * 1024) + 999; - for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); + ipcl::PlainText pt(exp_value_v), dt; + ipcl::CipherText ct = key.pub_key->encrypt(pt); - for (auto _ : state) { - for (size_t i = 0; i < dsize; ++i) { - key.priv_key->decrypt(de_ct[i], ct[i]); - } - } + for (auto _ : state) dt = key.priv_key->decrypt(ct); } BENCHMARK(BM_Decrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); - -static void BM_Decrypt_buff8(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> pt(dsize / 8, std::vector(8)); - std::vector> ct(dsize / 8, std::vector(8)); - std::vector> de_ct(dsize / 8, - std::vector(8)); - - for (size_t i = 0; i < dsize / 8; ++i) { - for (size_t j = 0; j < 8; ++j) - pt[i][j] = BigNumber((unsigned int)(i * 8 + j)); - } - - for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); - - for (auto _ : state) { - for (size_t i = 0; i < dsize / 8; ++i) - key.priv_key->decrypt(de_ct[i], ct[i]); - } -} - -BENCHMARK(BM_Decrypt_buff8) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - -#ifdef IPCL_USE_OMP -static void BM_Encrypt_OMP(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> pt(dsize, std::vector(8)); - std::vector> ct(dsize, std::vector(8)); - - for (size_t i = 0; i < dsize; ++i) { - pt[i][0] = BigNumber((unsigned int)i); - } - - for (auto _ : state) { -#pragma omp parallel for - for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); - } -} -BENCHMARK(BM_Encrypt_OMP) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - -static void BM_Encrypt_buff8_OMP(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> pt(dsize / 8, std::vector(8)); - std::vector> ct(dsize / 8, std::vector(8)); - - for (size_t i = 0; i < dsize / 8; ++i) { - for (size_t j = 0; j < 8; ++j) - pt[i][j] = BigNumber((unsigned int)(i * 8 + j)); - } - - for (auto _ : state) { -#pragma omp parallel for - for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); - } -} - -BENCHMARK(BM_Encrypt_buff8_OMP) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - -static void BM_Decrypt_OMP(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> pt(dsize, std::vector(8)); - std::vector> ct(dsize, std::vector(8)); - std::vector> de_ct(dsize, std::vector(8)); - for (size_t i = 0; i < dsize; ++i) { - pt[i][0] = BigNumber((unsigned int)i); - } - - for (size_t i = 0; i < dsize; ++i) key.pub_key->encrypt(ct[i], pt[i]); - - for (auto _ : state) { -#pragma omp parallel for - for (size_t i = 0; i < dsize; ++i) { - key.priv_key->decrypt(de_ct[i], ct[i]); - } - } -} - -BENCHMARK(BM_Decrypt_OMP) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - -static void BM_Decrypt_buff8_OMP(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> pt(dsize / 8, std::vector(8)); - std::vector> ct(dsize / 8, std::vector(8)); - std::vector> de_ct(dsize / 8, - std::vector(8)); - - for (size_t i = 0; i < dsize / 8; ++i) { - for (size_t j = 0; j < 8; ++j) - pt[i][j] = BigNumber((unsigned int)(i * 8 + j)); - } - - for (size_t i = 0; i < dsize / 8; ++i) key.pub_key->encrypt(ct[i], pt[i]); - - for (auto _ : state) { -#pragma omp parallel for - for (size_t i = 0; i < dsize / 8; ++i) - key.priv_key->decrypt(de_ct[i], ct[i]); - } -} - -BENCHMARK(BM_Decrypt_buff8_OMP) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); -#endif // IPCL_USE_OMP diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index a020678..452d777 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -3,378 +3,75 @@ #include -#include -#ifdef IPCL_USE_OMP -#include -#endif // IPCL_USE_OMP #include +#include +#include "ipcl/ciphertext.hpp" #include "ipcl/keygen.hpp" -#include "ipcl/ops.hpp" +#include "ipcl/plaintext.hpp" static void BM_Add_CTCT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, std::vector(8)); - std::vector> b(dsize, std::vector(8)); - std::vector> ct_a(dsize, std::vector(8)); - std::vector> ct_b(dsize, std::vector(8)); + std::vector exp_value1_v(dsize, 65535), exp_value2_v(dsize, 65535); - for (size_t i = 0; i < dsize; ++i) { - a[i][0] = BigNumber((unsigned int)i); - key.pub_key->encrypt(ct_a[i], a[i]); - - b[i][0] = BigNumber((unsigned int)i); - key.pub_key->encrypt(ct_b[i], b[i]); + ipcl::PlainText pt1, pt2; + for (int i = 0; i < dsize; i++) { + exp_value1_v[i] += (unsigned int)(i * 1024); + exp_value2_v[i] += (unsigned int)(i * 1024); } + pt1 = ipcl::PlainText(exp_value1_v); + pt2 = ipcl::PlainText(exp_value2_v); - for (auto _ : state) { - for (size_t i = 0; i < dsize; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber pen_b(key.pub_key, ct_b[i]); - ipcl::EncryptedNumber sum = pen_a + pen_b; - } - } + ipcl::CipherText ct1 = key.pub_key->encrypt(pt1); + ipcl::CipherText ct2 = key.pub_key->encrypt(pt2); + ipcl::CipherText sum; + for (auto _ : state) sum = ct1 + ct2; } BENCHMARK(BM_Add_CTCT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); -static void BM_Add_CTCT_buff8(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> a(dsize / 8, std::vector(8)); - std::vector> b(dsize / 8, std::vector(8)); - std::vector> ct_a(dsize / 8, - std::vector(8)); - std::vector> ct_b(dsize / 8, - std::vector(8)); - - for (size_t i = 0; i < dsize / 8; ++i) { - for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = BigNumber((unsigned int)(i * 8 + j)); - } - - key.pub_key->encrypt(ct_a[i], a[i]); - key.pub_key->encrypt(ct_b[i], b[i]); - } - - for (auto _ : state) { - for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber pen_b(key.pub_key, ct_b[i]); - ipcl::EncryptedNumber sum = pen_a + pen_b; - } - } -} - -BENCHMARK(BM_Add_CTCT_buff8) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - static void BM_Add_CTPT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, std::vector(8)); - std::vector> b(dsize, std::vector(8)); - std::vector> ct_a(dsize, std::vector(8)); + std::vector exp_value1_v(dsize, 65535), exp_value2_v(dsize, 65535); - for (size_t i = 0; i < dsize; ++i) { - a[i][0] = BigNumber((unsigned int)i); - b[i][0] = BigNumber((unsigned int)i); - key.pub_key->encrypt(ct_a[i], a[i]); + ipcl::PlainText pt1, pt2; + for (int i = 0; i < dsize; i++) { + exp_value1_v[i] += (unsigned int)(i * 1024); + exp_value2_v[i] += (unsigned int)(i * 1024); } + pt1 = ipcl::PlainText(exp_value1_v); + pt2 = ipcl::PlainText(exp_value2_v); - for (auto _ : state) { - for (size_t i = 0; i < dsize; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber sum = pen_a + b[i]; - } - } -} + ipcl::CipherText ct1 = key.pub_key->encrypt(pt1); + ipcl::CipherText sum; -BENCHMARK(BM_Add_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); - -static void BM_Add_CTPT_buff8(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> a(dsize / 8, std::vector(8)); - std::vector> b(dsize / 8, std::vector(8)); - std::vector> ct_a(dsize / 8, - std::vector(8)); - - for (size_t i = 0; i < dsize / 8; ++i) { - for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = BigNumber((unsigned int)(i * 8 + j)); - } - - key.pub_key->encrypt(ct_a[i], a[i]); - } - - for (auto _ : state) { - for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber sum = pen_a + b[i]; - } - } + for (auto _ : state) sum = ct1 + pt2; } -BENCHMARK(BM_Add_CTPT_buff8) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); +BENCHMARK(BM_Add_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); static void BM_Mul_CTPT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector> a(dsize, std::vector(8)); - std::vector> b(dsize, std::vector(8)); - std::vector> ct_a(dsize, std::vector(8)); - - for (size_t i = 0; i < dsize; ++i) { - a[i][0] = BigNumber((unsigned int)i); - b[i][0] = BigNumber((unsigned int)i); - key.pub_key->encrypt(ct_a[i], a[i]); - } - - for (auto _ : state) { - for (size_t i = 0; i < dsize; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber pen_b(key.pub_key, b[i]); - ipcl::EncryptedNumber sum = pen_a * pen_b; - } - } -} - -BENCHMARK(BM_Mul_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); - -static void BM_Mul_CTPT_buff8(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> a(dsize / 8, std::vector(8)); - std::vector> b(dsize / 8, std::vector(8)); - std::vector> ct_a(dsize / 8, - std::vector(8)); - - for (size_t i = 0; i < dsize / 8; ++i) { - for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = BigNumber((unsigned int)(i * 8 + j)); - } + std::vector exp_value1_v(dsize, 65535), exp_value2_v(dsize, 65535); - key.pub_key->encrypt(ct_a[i], a[i]); + ipcl::PlainText pt1, pt2; + for (int i = 0; i < dsize; i++) { + exp_value1_v[i] += (unsigned int)(i * 1024); + exp_value2_v[i] += (unsigned int)(i * 1024); } + pt1 = ipcl::PlainText(exp_value1_v); + pt2 = ipcl::PlainText(exp_value2_v); - for (auto _ : state) { - for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber pen_b(key.pub_key, b[i]); - ipcl::EncryptedNumber sum = pen_a * pen_b; - } - } -} - -BENCHMARK(BM_Mul_CTPT_buff8) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - -#ifdef IPCL_USE_OMP -static void BM_Add_CTCT_OMP(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> a(dsize, std::vector(8)); - std::vector> b(dsize, std::vector(8)); - std::vector> ct_a(dsize, std::vector(8)); - std::vector> ct_b(dsize, std::vector(8)); + ipcl::CipherText ct1 = key.pub_key->encrypt(pt1); + ipcl::CipherText product; - for (size_t i = 0; i < dsize; ++i) { - a[i][0] = BigNumber((unsigned int)i); - key.pub_key->encrypt(ct_a[i], a[i]); - - b[i][0] = BigNumber((unsigned int)i); - key.pub_key->encrypt(ct_b[i], b[i]); - } - - for (auto _ : state) { -#pragma omp parallel for - for (size_t i = 0; i < dsize; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber pen_b(key.pub_key, ct_b[i]); - ipcl::EncryptedNumber sum = pen_a + pen_b; - } - } + for (auto _ : state) product = ct1 * pt2; } -BENCHMARK(BM_Add_CTCT_OMP) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - -static void BM_Add_CTCT_buff8_OMP(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> a(dsize / 8, std::vector(8)); - std::vector> b(dsize / 8, std::vector(8)); - std::vector> ct_a(dsize / 8, - std::vector(8)); - std::vector> ct_b(dsize / 8, - std::vector(8)); - - for (size_t i = 0; i < dsize / 8; ++i) { - for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = BigNumber((unsigned int)(i * 8 + j)); - } - - key.pub_key->encrypt(ct_a[i], a[i]); - key.pub_key->encrypt(ct_b[i], b[i]); - } - - for (auto _ : state) { -#pragma omp parallel for - for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber pen_b(key.pub_key, ct_b[i]); - ipcl::EncryptedNumber sum = pen_a + pen_b; - } - } -} - -BENCHMARK(BM_Add_CTCT_buff8_OMP) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - -static void BM_Add_CTPT_OMP(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> a(dsize, std::vector(8)); - std::vector> b(dsize, std::vector(8)); - std::vector> ct_a(dsize, std::vector(8)); - - for (size_t i = 0; i < dsize; ++i) { - a[i][0] = BigNumber((unsigned int)i); - b[i][0] = BigNumber((unsigned int)i); - key.pub_key->encrypt(ct_a[i], a[i]); - } - - for (auto _ : state) { -#pragma omp parallel for - for (size_t i = 0; i < dsize; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber sum = pen_a + b[i]; - } - } -} - -BENCHMARK(BM_Add_CTPT_OMP) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - -static void BM_Add_CTPT_buff8_OMP(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> a(dsize / 8, std::vector(8)); - std::vector> b(dsize / 8, std::vector(8)); - std::vector> ct_a(dsize / 8, - std::vector(8)); - - for (size_t i = 0; i < dsize / 8; ++i) { - for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = BigNumber((unsigned int)(i * 8 + j)); - } - - key.pub_key->encrypt(ct_a[i], a[i]); - } - - for (auto _ : state) { -#pragma omp parallel for - for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber sum = pen_a + b[i]; - } - } -} - -BENCHMARK(BM_Add_CTPT_buff8_OMP) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - -static void BM_Mul_CTPT_OMP(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> a(dsize, std::vector(8)); - std::vector> b(dsize, std::vector(8)); - std::vector> ct_a(dsize, std::vector(8)); - - for (size_t i = 0; i < dsize; ++i) { - a[i][0] = BigNumber((unsigned int)i); - b[i][0] = BigNumber((unsigned int)i); - key.pub_key->encrypt(ct_a[i], a[i]); - } - - for (auto _ : state) { -#pragma omp parallel for - for (size_t i = 0; i < dsize; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber pen_b(key.pub_key, b[i]); - ipcl::EncryptedNumber sum = pen_a * pen_b; - } - } -} - -BENCHMARK(BM_Mul_CTPT_OMP) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); - -static void BM_Mul_CTPT_buff8_OMP(benchmark::State& state) { - size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector> a(dsize / 8, std::vector(8)); - std::vector> b(dsize / 8, std::vector(8)); - std::vector> ct_a(dsize / 8, - std::vector(8)); - - for (size_t i = 0; i < dsize / 8; ++i) { - for (size_t j = 0; j < 8; ++j) { - a[i][j] = BigNumber((unsigned int)(i * 8 + j)); - b[i][j] = BigNumber((unsigned int)(i * 8 + j)); - } - - key.pub_key->encrypt(ct_a[i], a[i]); - } - - for (auto _ : state) { -#pragma omp parallel for - for (size_t i = 0; i < dsize / 8; ++i) { - ipcl::EncryptedNumber pen_a(key.pub_key, ct_a[i]); - ipcl::EncryptedNumber pen_b(key.pub_key, b[i]); - ipcl::EncryptedNumber sum = pen_a * pen_b; - } - } -} - -BENCHMARK(BM_Mul_CTPT_buff8_OMP) - ->Unit(benchmark::kMicrosecond) - ->Args({16}) - ->Args({64}); -#endif // IPCL_USE_OMP +BENCHMARK(BM_Mul_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); diff --git a/benchmark/main.cpp b/benchmark/main.cpp index 6c55a8a..63ecedd 100644 --- a/benchmark/main.cpp +++ b/benchmark/main.cpp @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 #ifdef IPCL_USE_QAT -#include "he_qat_context.h" +#include #endif // IPCL_USE_QAT #include diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index c24312e..ed1b437 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -3,10 +3,12 @@ set(IPCL_SRCS pri_key.cpp pub_key.cpp - ops.cpp keygen.cpp bignum.cpp mod_exp.cpp + base_text.cpp + plaintext.cpp + ciphertext.cpp ) @@ -44,6 +46,11 @@ install(DIRECTORY ${IPPCRYPTO_INC_DIR}/ target_link_libraries(ipcl PUBLIC OpenSSL::SSL OpenSSL::Crypto Threads::Threads) +if(IPCL_ENABLE_OMP) + find_package(OpenMP REQUIRED) + target_link_libraries(ipcl PRIVATE OpenMP::OpenMP_CXX) +endif() + if(IPCL_SHARED) target_link_libraries(ipcl PRIVATE libippcrypto) target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) diff --git a/ipcl/base_text.cpp b/ipcl/base_text.cpp new file mode 100644 index 0000000..e4e43c5 --- /dev/null +++ b/ipcl/base_text.cpp @@ -0,0 +1,76 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/base_text.hpp" + +#include "ipcl/util.hpp" + +namespace ipcl { + +BaseText::BaseText(const uint32_t& n) : m_texts{BigNumber(n)}, m_size(1) {} + +BaseText::BaseText(const std::vector& n_v) { + for (auto& n : n_v) { + m_texts.push_back(BigNumber(n)); + } + m_size = m_texts.size(); +} + +BaseText::BaseText(const BigNumber& bn) : m_texts{bn}, m_size(1) {} + +BaseText::BaseText(const std::vector& bn_v) + : m_texts(bn_v), m_size(m_texts.size()) {} + +BaseText::BaseText(const BaseText& bt) { + this->m_texts = bt.getTexts(); + this->m_size = bt.getSize(); +} + +BaseText& BaseText::operator=(const BaseText& other) { + if (this == &other) return *this; + + this->m_texts = other.m_texts; + this->m_size = other.m_size; + return *this; +} + +BigNumber BaseText::getElement(const std::size_t& idx) const { + ERROR_CHECK(idx <= m_size, "BaseText: getElement index is out of range"); + + return m_texts[idx]; +} + +std::vector BaseText::getElementVec(const std::size_t& idx) const { + ERROR_CHECK(idx <= m_size, "BaseText: getElementVec index is out of range"); + + std::vector v; + m_texts[idx].num2vec(v); + + return v; +} + +std::string BaseText::getElementHex(const std::size_t& idx) const { + ERROR_CHECK(idx <= m_size, "BaseText: getElementHex index is out of range"); + std::string s; + m_texts[idx].num2hex(s); + + return s; +} + +std::vector BaseText::getChunk(const std::size_t& start, + const std::size_t& size) const { + ERROR_CHECK((start >= 0) && ((start + size) <= m_size), + "BaseText: getChunk parameter is incorrect"); + + auto it_start = m_texts.begin() + start; + auto it_end = it_start + size; + auto v = std::vector(it_start, it_end); + + return v; +} + +std::vector BaseText::getTexts() const { return m_texts; } + +std::size_t BaseText::getSize() const { return m_size; } + +} // namespace ipcl diff --git a/ipcl/bignum.cpp b/ipcl/bignum.cpp index e5eea58..4fd3bf3 100644 --- a/ipcl/bignum.cpp +++ b/ipcl/bignum.cpp @@ -25,8 +25,6 @@ // ////////////////////////////////////////////////////////////////////// -// namespace ipcl { - BigNumber::~BigNumber() { delete[](Ipp8u*) m_pBN; } bool BigNumber::create(const Ipp32u* pData, int length, IppsBigNumSGN sgn) { @@ -138,7 +136,7 @@ BigNumber& BigNumber::operator=(const BigNumber& bn) { Ipp32u* bnData; ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); - delete[](Ipp8u*) m_pBN; + delete (Ipp8u*)m_pBN; create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); } return *this; @@ -509,7 +507,6 @@ void BigNumber::num2char(std::vector& dest) const { dest.assign(bnData, bnData + len); } - bool BigNumber::fromBin(BigNumber& bn, const unsigned char* data, int len) { if (len <= 0) return false; @@ -540,4 +537,3 @@ bool BigNumber::toBin(unsigned char* data, int len, const BigNumber& bn) { return true; } -//} // namespace ipcl diff --git a/ipcl/ciphertext.cpp b/ipcl/ciphertext.cpp new file mode 100644 index 0000000..27cdcdb --- /dev/null +++ b/ipcl/ciphertext.cpp @@ -0,0 +1,144 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/ciphertext.hpp" + +#include + +#include "ipcl/mod_exp.hpp" + +namespace ipcl { +CipherText::CipherText(const PublicKey* pub_key, const uint32_t& n) + : BaseText(n), m_pubkey(pub_key) {} + +CipherText::CipherText(const PublicKey* pub_key, + const std::vector& n_v) + : BaseText(n_v), m_pubkey(pub_key) {} + +CipherText::CipherText(const PublicKey* pub_key, const BigNumber& bn) + : BaseText(bn), m_pubkey(pub_key) {} + +CipherText::CipherText(const PublicKey* pub_key, + const std::vector& bn_v) + : BaseText(bn_v), m_pubkey(pub_key) {} + +CipherText::CipherText(const CipherText& ct) : BaseText(ct) { + this->m_pubkey = ct.m_pubkey; +} + +CipherText& CipherText::operator=(const CipherText& other) { + BaseText::operator=(other); + this->m_pubkey = other.m_pubkey; + + return *this; +} + +// CT+CT +CipherText CipherText::operator+(const CipherText& other) const { + std::size_t b_size = other.getSize(); + ERROR_CHECK(this->m_size == b_size || b_size == 1, + "CT + CT error: Size mismatch!"); + ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), + "CT + CT error: 2 different public keys detected!"); + + const auto& a = *this; + const auto& b = other; + + if (m_size == 1) { + BigNumber sum = a.raw_add(a.m_texts.front(), b.getTexts().front()); + return CipherText(m_pubkey, sum); + } else { + std::vector sum(m_size); + + if (b_size == 1) { + // add vector by scalar +#ifdef IPCL_USE_OMP +#pragma omp parallel for +#endif // IPCL_USE_OMP + for (std::size_t i = 0; i < m_size; i++) + sum[i] = a.raw_add(a.m_texts[i], b.m_texts[0]); + } else { + // add vector by vector +#ifdef IPCL_USE_OMP +#pragma omp parallel for +#endif // IPCL_USE_OMP + for (std::size_t i = 0; i < m_size; i++) + sum[i] = a.raw_add(a.m_texts[i], b.m_texts[i]); + } + return CipherText(m_pubkey, sum); + } +} + +// CT + PT +CipherText CipherText::operator+(const PlainText& other) const { + // convert PT to CT + CipherText b = this->m_pubkey->encrypt(other, false); + // calculate CT + CT + return this->operator+(b); +} + +// CT * PT +CipherText CipherText::operator*(const PlainText& other) const { + std::size_t b_size = other.getSize(); + ERROR_CHECK(this->m_size == b_size || b_size == 1, + "CT * PT error: Size mismatch!"); + + const auto& a = *this; + const auto& b = other; + + if (m_size == 1) { + BigNumber product = a.raw_mul(a.m_texts.front(), b.getTexts().front()); + return CipherText(m_pubkey, product); + } else { + std::vector product; + if (b_size == 1) { + // multiply vector by scalar + std::vector b_v(a.m_size, b.getElement(0)); + product = a.raw_mul(a.m_texts, b_v); + } else { + // multiply vector by vector + product = a.raw_mul(a.m_texts, b.getTexts()); + } + return CipherText(m_pubkey, product); + } +} + +PublicKey CipherText::getPubKey() const { return *m_pubkey; } + +CipherText CipherText::rotate(int shift) const { + ERROR_CHECK(m_size != 1, "rotate: Cannot rotate single CipherText"); + ERROR_CHECK(shift >= -8 && shift <= 8, + "rotate: Cannot shift more than 8 or -8"); + + if (shift == 0 || shift == 8 || shift == -8) + return CipherText(m_pubkey, m_texts); + + if (shift > 0) + shift = 8 - shift; + else + shift = -shift; + + std::vector new_bn = getTexts(); + std::rotate(std::begin(new_bn), std::begin(new_bn) + shift, std::end(new_bn)); + return CipherText(m_pubkey, new_bn); +} + +BigNumber CipherText::raw_add(const BigNumber& a, const BigNumber& b) const { + // Hold a copy of nsquare for multi-threaded + const BigNumber& sq = m_pubkey->getNSQ(); + return a * b % sq; +} + +BigNumber CipherText::raw_mul(const BigNumber& a, const BigNumber& b) const { + const BigNumber& sq = m_pubkey->getNSQ(); + return ipcl::ippModExp(a, b, sq); +} + +std::vector CipherText::raw_mul( + const std::vector& a, const std::vector& b) const { + std::size_t v_size = a.size(); + std::vector sq(v_size, m_pubkey->getNSQ()); + return ipcl::ippModExp(a, b, sq); +} + +} // namespace ipcl diff --git a/ipcl/include/ipcl/base_text.hpp b/ipcl/include/ipcl/base_text.hpp new file mode 100644 index 0000000..0f9e10e --- /dev/null +++ b/ipcl/include/ipcl/base_text.hpp @@ -0,0 +1,83 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IPCL_INCLUDE_IPCL_BASE_TEXT_HPP_ +#define IPCL_INCLUDE_IPCL_BASE_TEXT_HPP_ + +#include +#include + +#include "ipcl/bignum.h" + +namespace ipcl { + +class BaseText { + public: + BaseText() = default; + ~BaseText() = default; + + /** + * BaseText constructors + */ + explicit BaseText(const uint32_t& n); + explicit BaseText(const std::vector& n_v); + explicit BaseText(const BigNumber& bn); + explicit BaseText(const std::vector& bn_v); + + /** + * BaseText copy constructor + */ + BaseText(const BaseText& bt); + + /** + * BaseText assignment constructor + */ + BaseText& operator=(const BaseText& other); + + /** + * Gets the specified BigNumber element in m_text + * @param[in] idx Element index + * return Element in m_text of type BigNumber + */ + BigNumber getElement(const std::size_t& idx) const; + + /** + * Gets the specified BigNumber vector form + * @param[in] idx Element index + * @return Element vector form + */ + std::vector getElementVec(const std::size_t& idx) const; + + /** + * Gets the specified BigNumber hex string form + * @param[in] idx Element index + * @return Element hex string form + */ + std::string getElementHex(const std::size_t& idx) const; + + /** + * Gets a chunk of BigNumber element in m_text + * @param[in] start Start position + * @param[in] size The number of element + * return A chunk of BigNumber element + */ + std::vector getChunk(const std::size_t& start, + const std::size_t& size) const; + + /** + * Gets the BigNumber container + */ + std::vector getTexts() const; + + /** + * Gets the size of the BigNumber container + */ + std::size_t getSize() const; + + protected: + std::vector m_texts; ///< Container used to store BigNumber + std::size_t m_size; ///< Container size +}; + +} // namespace ipcl +#endif // IPCL_INCLUDE_IPCL_BASE_TEXT_HPP_ diff --git a/ipcl/include/ipcl/bignum.h b/ipcl/include/ipcl/bignum.h index dd42d28..efe2245 100644 --- a/ipcl/include/ipcl/bignum.h +++ b/ipcl/include/ipcl/bignum.h @@ -24,8 +24,6 @@ #include #include -// namespace ipcl { - class BigNumber { public: BigNumber(Ipp32u value = 0); @@ -137,5 +135,4 @@ class BigNumber { constexpr int BITSIZE_WORD(int n) { return (((n) + 31) >> 5); } constexpr int BITSIZE_DWORD(int n) { return (((n) + 63) >> 6); } -//} // namespace ipcl #endif // _BIGNUM_H_ diff --git a/ipcl/include/ipcl/ciphertext.hpp b/ipcl/include/ipcl/ciphertext.hpp new file mode 100644 index 0000000..bd6d701 --- /dev/null +++ b/ipcl/include/ipcl/ciphertext.hpp @@ -0,0 +1,67 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IPCL_INCLUDE_IPCL_CIPHERTEXT_HPP_ +#define IPCL_INCLUDE_IPCL_CIPHERTEXT_HPP_ + +#include + +#include "ipcl/plaintext.hpp" +#include "ipcl/pub_key.hpp" +#include "ipcl/util.hpp" + +namespace ipcl { + +class CipherText : public BaseText { + public: + CipherText() = default; + ~CipherText() = default; + + /** + * CipherText constructors + */ + CipherText(const PublicKey* pub_key, const uint32_t& n); + CipherText(const PublicKey* pub_key, const std::vector& n_v); + CipherText(const PublicKey* pub_key, const BigNumber& bn); + CipherText(const PublicKey* pub_key, const std::vector& bn_vec); + + /** + * CipherText copy constructor + */ + CipherText(const CipherText& ct); + /** + * CipherText assignment constructor + */ + CipherText& operator=(const CipherText& other); + + // CT+CT + CipherText operator+(const CipherText& other) const; + // CT+PT + CipherText operator+(const PlainText& other) const; + // CT*PT + CipherText operator*(const PlainText& other) const; + + /** + * Get public key + */ + PublicKey getPubKey() const; + + /** + * Rotate CipherText + * @param[in] shift rotate length + */ + CipherText rotate(int shift) const; + + const void* addr = static_cast(this); + + private: + BigNumber raw_add(const BigNumber& a, const BigNumber& b) const; + BigNumber raw_mul(const BigNumber& a, const BigNumber& b) const; + std::vector raw_mul(const std::vector& a, + const std::vector& b) const; + + const PublicKey* m_pubkey; ///< Public key used to encrypt big number +}; + +} // namespace ipcl +#endif // IPCL_INCLUDE_IPCL_CIPHERTEXT_HPP_ diff --git a/ipcl/include/ipcl/ops.hpp b/ipcl/include/ipcl/ops.hpp deleted file mode 100644 index 6aab2f8..0000000 --- a/ipcl/include/ipcl/ops.hpp +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#ifndef IPCL_INCLUDE_IPCL_OPS_HPP_ -#define IPCL_INCLUDE_IPCL_OPS_HPP_ - -#include - -#include "ipcl/pub_key.hpp" -#include "ipcl/util.hpp" - -namespace ipcl { - -class EncryptedNumber { - public: - /** - * EncryptedNumber constructor - * @param[in] pub_key paillier public key - * @param[in] bn ciphertext encrypted by paillier public key - */ - EncryptedNumber(const PublicKey* pub_key, const BigNumber& bn); - - /** - * EncryptedNumber constructor - * @param[in] pub_key paillier public key - * @param[in] bn array of ciphertexts encrypted by paillier public key - * @param[in] length size of array(default value is IPCL_CRYPTO_MB_SIZE) - */ - EncryptedNumber(const PublicKey* pub_key, const std::vector& bn, - size_t length = IPCL_CRYPTO_MB_SIZE); - - /** - * EncryptedNumber constructor - * @param[in] pub_key paillier public key - * @param[in] scalar array of integer scalars - * @param[in] length size of array(default value is IPCL_CRYPTO_MB_SIZE) - */ - EncryptedNumber(const PublicKey* pub_key, const std::vector& scalar, - size_t length = IPCL_CRYPTO_MB_SIZE); - - /** - * Arithmetic addition operator - * @param[in] bn augend - */ - EncryptedNumber operator+(const EncryptedNumber& bn) const; - - /** - * Arithmetic addition operator - * @param[in] other augend - */ - EncryptedNumber operator+(const BigNumber& other) const; - - /** - * Arithmetic addition operator - * @param[in] other array of augend - */ - EncryptedNumber operator+(const std::vector& other) const; - - /** - * Arithmetic multiply operator - * @param[in] bn multiplicand - */ - EncryptedNumber operator*(const EncryptedNumber& bn) const; - - /** - * Arithmetic multiply operator - * @param[in] other multiplicand - */ - EncryptedNumber operator*(const BigNumber& other) const; - - /** - * Apply obfuscator for ciphertext, obfuscated needed only when the ciphertext - * is exposed - */ - void apply_obfuscator(); - - /** - * Return ciphertext - * @param[in] idx index of ciphertext stored in EncryptedNumber - * (default = 0) - */ - BigNumber getBN(size_t idx = 0) const { - ERROR_CHECK(m_available != 1 || idx <= 0, - "getBN: EncryptedNumber only has 1 BigNumber"); - - return m_bn[idx]; - } - - /** - * Get public key - */ - PublicKey getPK() const { return *m_pubkey; } - - /** - * Rotate EncryptedNumber - * @param[in] shift rotate length - */ - EncryptedNumber rotate(int shift) const; - - /** - * Return entire ciphertext array - * @param[out] bn output array - */ - std::vector getArrayBN() const { return m_bn; } - - /** - * Check if element in EncryptedNumber is single - */ - bool isSingle() const { return m_available == 1; } - - /** - * Get size of array in EncryptedNumber - */ - size_t getLength() const { return m_length; } - - const void* addr = static_cast(this); - - private: - bool b_isObfuscator; - int m_available; - const PublicKey* m_pubkey; - size_t m_length; - std::vector m_bn; - - BigNumber raw_add(const BigNumber& a, const BigNumber& b) const; - BigNumber raw_mul(const BigNumber& a, const BigNumber& b) const; - std::vector raw_mul(const std::vector& a, - const std::vector& b) const; -}; - -} // namespace ipcl -#endif // IPCL_INCLUDE_IPCL_OPS_HPP_ diff --git a/ipcl/include/ipcl/plaintext.hpp b/ipcl/include/ipcl/plaintext.hpp new file mode 100644 index 0000000..8b34e7d --- /dev/null +++ b/ipcl/include/ipcl/plaintext.hpp @@ -0,0 +1,75 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IPCL_INCLUDE_IPCL_PLAINTEXT_HPP_ +#define IPCL_INCLUDE_IPCL_PLAINTEXT_HPP_ + +#include + +#include "ipcl/base_text.hpp" + +namespace ipcl { +/** + * This structure encapsulates types uint32_t, + * uint32_t vector, BigNumber and BigNumber vector. + */ +class PlainText : public BaseText { + public: + PlainText() = default; + ~PlainText() = default; + + /** + * PlainText constructor + * @param[in] n Reference to a uint32_t integer + */ + explicit PlainText(const uint32_t& n); + + /** + * PlainText constructor + * @param[in] n_v Reference to a uint32_t vector + */ + explicit PlainText(const std::vector& n_v); + + /** + * PlainText constructor + * @param[in] bn Reference to a BigNumber + */ + explicit PlainText(const BigNumber& bn); + + /** + * PlainText constructor + * @param[in] bn_v Reference to a BigNumber vector + */ + explicit PlainText(const std::vector& bn_v); + + /** + * PlainText copy constructor + */ + PlainText(const PlainText& pt); + + /** + * PlainText assignment constructor + */ + PlainText& operator=(const PlainText& other); + + /** + * User define implicit type conversion + * Convert 1st element to uint32_t vector. + */ + operator std::vector(); + + /** + * User define implicit type conversion + * Convert 1st element to type BigNumber. + */ + operator BigNumber(); + + /** + * User define implicit type conversion + * Convert all element to type BigNumber. + */ + operator std::vector(); +}; + +} // namespace ipcl +#endif // IPCL_INCLUDE_IPCL_PLAINTEXT_HPP_ diff --git a/ipcl/include/ipcl/pri_key.hpp b/ipcl/include/ipcl/pri_key.hpp index b3466eb..d351d03 100644 --- a/ipcl/include/ipcl/pri_key.hpp +++ b/ipcl/include/ipcl/pri_key.hpp @@ -6,7 +6,8 @@ #include -#include "ipcl/ops.hpp" +#include "ipcl/ciphertext.hpp" +#include "ipcl/plaintext.hpp" namespace ipcl { @@ -29,19 +30,10 @@ class PrivateKey { /** * Decrypt ciphertext - * @param[out] plaintext output of the decryption - * @param[in] ciphertext ciphertext to be decrypted + * @param[in] ciphertext CipherText to be decrypted + * @return plaintext of type PlainText */ - void decrypt(std::vector& plaintext, - const std::vector& ciphertext) const; - - /** - * Decrypt ciphertext - * @param[out] plaintext output of the decryption - * @param[in] ciphertext EncryptedNumber to be decrypted - */ - void decrypt(std::vector& plaintext, - const EncryptedNumber ciphertext) const; + PlainText decrypt(const CipherText& ciphertext) const; const void* addr = static_cast(this); diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp index 61ae905..9f9c9b5 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -7,9 +7,12 @@ #include #include "ipcl/bignum.h" +#include "ipcl/plaintext.hpp" namespace ipcl { +class CipherText; + class PublicKey { public: /** @@ -37,20 +40,11 @@ class PublicKey { /** * Encrypt plaintext - * @param[out] ciphertext output of the encryption - * @param[in] value array of plaintext to be encrypted + * @param[in] plaintext of type PlainText * @param[in] make_secure apply obfuscator(default value is true) + * @return ciphertext of type CipherText */ - void encrypt(std::vector& ciphertext, - const std::vector& value, - bool make_secure = true) const; - - /** - * Encrypt plaintext - * @param[out] ciphertext output of the encryption - * @param[in] value plaintext to be encrypted - */ - void encrypt(BigNumber& ciphertext, const BigNumber& value) const; + CipherText encrypt(const PlainText& plaintext, bool make_secure = true) const; /** * Get N of public key in paillier scheme @@ -113,24 +107,14 @@ class PublicKey { std::vector randIpp32u(int size) const; /** - * Raw encrypt function - * @param[out] ciphertext array output of the encryption - * @param[in] plaintext plaintext array to be encrypted + * Big number vector multi buffer encryption + * @param[in] pt plaintext of BigNumber vector type * @param[in] make_secure apply obfuscator(default value is true) + * @return ciphertext of BigNumber vector type */ - void raw_encrypt(std::vector& ciphertext, - const std::vector& plaintext, - bool make_secure = true) const; - // /** - // * Raw Multi-buffered modular exponentiation - // * @param[in] base array base of the exponentiation - // * @param[in] pow arrya pow of the exponentiation - // * @param[in] m arrayodular - // * @return result of the modular exponentiation of type BigNumber vector - // */ - // std::vector raw_ippMultiBuffExp( - // const std::vector& base, const std::vector& - // pow, const std::vector& m) const; + std::vector raw_encrypt(const std::vector& pt, + bool make_secure = true) const; + /** * Get random value * @param[in] length bit length diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index 958987d..4128b21 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -4,21 +4,22 @@ #include "ipcl/mod_exp.hpp" #include -#include +#include #include - -#include "ipcl/util.hpp" +#include #ifdef IPCL_USE_QAT -#include "he_qat_bn_ops.h" -#include "he_qat_types.h" +#include +#include #endif +#include "ipcl/util.hpp" + namespace ipcl { #ifdef IPCL_USE_QAT - + // Multiple input QAT ModExp interface to offload computation to QAT static std::vector heQatBnModExp( const std::vector& base, const std::vector& exponent, @@ -215,20 +216,16 @@ static std::vector ippMBModExp(const std::vector& base, std::vector out_x(IPCL_CRYPTO_MB_SIZE); std::vector b_array(IPCL_CRYPTO_MB_SIZE); std::vector p_array(IPCL_CRYPTO_MB_SIZE); - int length = dwords * sizeof(int64u); - - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - out_x[i] = reinterpret_cast(alloca(length)); - b_array[i] = reinterpret_cast(alloca(length)); - p_array[i] = reinterpret_cast(alloca(length)); - ERROR_CHECK( - out_x[i] != nullptr && b_array[i] != nullptr && p_array[i] != nullptr, - "ippMultiBuffExp: alloc memory for error"); + int mem_pool_size = IPCL_CRYPTO_MB_SIZE * dwords; + std::vector out_mem_pool(mem_pool_size); + std::vector base_mem_pool(mem_pool_size); + std::vector pow_mem_pool(mem_pool_size); - memset(out_x[i], 0, length); - memset(b_array[i], 0, length); - memset(p_array[i], 0, length); + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + out_x[i] = &out_mem_pool[i * dwords]; + b_array[i] = &base_mem_pool[i * dwords]; + p_array[i] = &pow_mem_pool[i * dwords]; } /* @@ -240,27 +237,29 @@ static std::vector ippMBModExp(const std::vector& base, std::vector pow_b(IPCL_CRYPTO_MB_SIZE); std::vector pow_p(IPCL_CRYPTO_MB_SIZE); std::vector pow_nsquare(IPCL_CRYPTO_MB_SIZE); - int nsqBitLen; - int expBitLen = 0; + std::vector b_size_v(IPCL_CRYPTO_MB_SIZE); + std::vector p_size_v(IPCL_CRYPTO_MB_SIZE); + std::vector n_size_v(IPCL_CRYPTO_MB_SIZE); - for (int i = 0, bBitLen, pBitLen; i < IPCL_CRYPTO_MB_SIZE; i++) { - ippsRef_BN(nullptr, &bBitLen, reinterpret_cast(&pow_b[i]), + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + ippsRef_BN(nullptr, &b_size_v[i], reinterpret_cast(&pow_b[i]), base[i]); - ippsRef_BN(nullptr, &pBitLen, reinterpret_cast(&pow_p[i]), + ippsRef_BN(nullptr, &p_size_v[i], reinterpret_cast(&pow_p[i]), pow[i]); - ippsRef_BN(nullptr, &nsqBitLen, &pow_nsquare[i], m[i]); - - memcpy(b_array[i], pow_b[i], BITSIZE_WORD(bBitLen) * 4); - memcpy(p_array[i], pow_p[i], BITSIZE_WORD(pBitLen) * 4); + ippsRef_BN(nullptr, &n_size_v[i], &pow_nsquare[i], m[i]); - if (expBitLen < pBitLen) expBitLen = pBitLen; + memcpy(b_array[i], pow_b[i], BITSIZE_WORD(b_size_v[i]) * 4); + memcpy(p_array[i], pow_p[i], BITSIZE_WORD(p_size_v[i]) * 4); } - /* - *Note: If actual sizes of exp are different, set the exp_bits parameter equal - *to maximum size of the actual module in bit size and extend all the modules - *with zero bits - */ + // Find the biggest size of module and exp + int nsqBitLen = *std::max_element(n_size_v.begin(), n_size_v.end()); + int expBitLen = *std::max_element(p_size_v.begin(), p_size_v.end()); + + // If actual sizes of modules are different, + // set the mod_bits parameter equal to maximum size of the actual module in + // bit size and extend all the modules with zero bits to the mod_bits value. + // The same is applicable for the exp_bits parameter and actual exponents. st = mbx_exp_mb8(out_x.data(), b_array.data(), p_array.data(), expBitLen, reinterpret_cast(pow_nsquare.data()), nsqBitLen, reinterpret_cast(buffer.data()), bufferLen); @@ -273,13 +272,11 @@ static std::vector ippMBModExp(const std::vector& base, } // It is important to hold a copy of nsquare for thread-safe purpose - BigNumber bn_c(m.front()); + std::vector res(IPCL_CRYPTO_MB_SIZE, m.front()); - std::vector res(IPCL_CRYPTO_MB_SIZE, 0); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - bn_c.Set(reinterpret_cast(out_x[i]), BITSIZE_WORD(nsqBitLen), - IppsBigNumPOS); - res[i] = bn_c; + res[i].Set(reinterpret_cast(out_x[i]), BITSIZE_WORD(nsqBitLen), + IppsBigNumPOS); } return res; } @@ -312,7 +309,7 @@ static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, ippsMontSet(pow_m, nlen, reinterpret_cast(pMont.data())); ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: set Mont input error."); - // encode base into Montfomery form + // encode base into Montgomery form BigNumber bform(m); stat = ippsMontForm(BN(base), reinterpret_cast(pMont.data()), BN(bform)); @@ -344,28 +341,87 @@ std::vector ippModExp(const std::vector& base, remainder = heQatBnModExp(base, pow, m); return remainder; #else + std::size_t v_size = base.size(); + std::vector res(v_size); + #ifdef IPCL_CRYPTO_MB_MOD_EXP - return ippMBModExp(base, pow, m); -#else - std::vector res(IPCL_CRYPTO_MB_SIZE); + + // If there is only 1 big number, we don't need to use MBModExp + if (v_size == 1) { + res[0] = ippSBModExp(base[0], pow[0], m[0]); + return res; + } + + std::size_t offset = 0; + std::size_t num_chunk = v_size / IPCL_CRYPTO_MB_SIZE; + std::size_t remainder = v_size % IPCL_CRYPTO_MB_SIZE; + #ifdef IPCL_USE_OMP #pragma omp parallel for #endif // IPCL_USE_OMP - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - res[i] = ippSBModExp(base[i], pow[i], m[i]); + for (std::size_t i = 0; i < num_chunk; i++) { + auto base_start = base.begin() + i * IPCL_CRYPTO_MB_SIZE; + auto base_end = base_start + IPCL_CRYPTO_MB_SIZE; + + auto pow_start = pow.begin() + i * IPCL_CRYPTO_MB_SIZE; + auto pow_end = pow_start + IPCL_CRYPTO_MB_SIZE; + + auto m_start = m.begin() + i * IPCL_CRYPTO_MB_SIZE; + auto m_end = m_start + IPCL_CRYPTO_MB_SIZE; + + auto base_chunk = std::vector(base_start, base_end); + auto pow_chunk = std::vector(pow_start, pow_end); + auto m_chunk = std::vector(m_start, m_end); + + auto tmp = ippMBModExp(base_chunk, pow_chunk, m_chunk); + std::copy(tmp.begin(), tmp.end(), res.begin() + i * IPCL_CRYPTO_MB_SIZE); } + + offset = num_chunk * IPCL_CRYPTO_MB_SIZE; + // If only 1 big number left, we don't need to make padding + if (remainder == 1) + res[offset] = ippSBModExp(base[offset], pow[offset], m[offset]); + + // If the 1 < remainder < IPCL_CRYPTO_MB_SIZE, we need to make padding + if (remainder > 1) { + auto base_start = base.begin() + offset; + auto base_end = base_start + remainder; + + auto pow_start = pow.begin() + offset; + auto pow_end = pow_start + remainder; + + auto m_start = m.begin() + offset; + auto m_end = m_start + remainder; + + std::vector base_chunk(IPCL_CRYPTO_MB_SIZE, 0); + std::vector pow_chunk(IPCL_CRYPTO_MB_SIZE, 0); + std::vector m_chunk(IPCL_CRYPTO_MB_SIZE, 0); + + std::copy(base_start, base_end, base_chunk.begin()); + std::copy(pow_start, pow_end, pow_chunk.begin()); + std::copy(m_start, m_end, m_chunk.begin()); + + auto tmp = ippMBModExp(base_chunk, pow_chunk, m_chunk); + std::copy(tmp.begin(), tmp.begin() + remainder, res.begin() + offset); + } + return res; -#endif // else + +#else + +#ifdef IPCL_USE_OMP +#pragma omp parallel for +#endif // IPCL_USE_OMP + for (int i = 0; i < v_size; i++) res[i] = ippSBModExp(base[i], pow[i], m[i]); + return res; + +#endif // IPCL_CRYPTO_MB_MOD_EXP #endif // IPCL_USE_QAT } BigNumber ippModExp(const BigNumber& base, const BigNumber& pow, const BigNumber& m) { -#ifdef IPCL_USE_QAT - return heQatBnModExp(base, pow, m); -#else return ippSBModExp(base, pow, m); -#endif // IPCL_USE_QAT } } // namespace ipcl diff --git a/ipcl/ops.cpp b/ipcl/ops.cpp deleted file mode 100644 index 2deaf5d..0000000 --- a/ipcl/ops.cpp +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include "ipcl/ops.hpp" - -#include - -#include "ipcl/mod_exp.hpp" - -namespace ipcl { -// constructors -// -EncryptedNumber::EncryptedNumber(const PublicKey* pub_key, const BigNumber& bn) - : b_isObfuscator(false), - m_available(1), - m_pubkey(pub_key), - m_length(1), - m_bn{bn} {} - -EncryptedNumber::EncryptedNumber(const PublicKey* pub_key, - const std::vector& bn, - size_t length) - : b_isObfuscator(false), - m_pubkey(pub_key), - m_available(IPCL_CRYPTO_MB_SIZE), - m_length(length), - m_bn{bn[0], bn[1], bn[2], bn[3], bn[4], bn[5], bn[6], bn[7]} {} - -EncryptedNumber::EncryptedNumber(const PublicKey* pub_key, - const std::vector& scalar, - size_t length) - : b_isObfuscator(false), - m_pubkey(pub_key), - m_available(IPCL_CRYPTO_MB_SIZE), - m_length(length), - m_bn{scalar[0], scalar[1], scalar[2], scalar[3], - scalar[4], scalar[5], scalar[6], scalar[7]} {} - -// CT+CT -EncryptedNumber EncryptedNumber::operator+(const EncryptedNumber& other) const { - ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), - "operator+: two different public keys detected!!"); - - const auto& a = *this; - const auto& b = other; - - if (m_available == 1) { - BigNumber sum = a.raw_add(a.m_bn.front(), b.m_bn.front()); - return EncryptedNumber(m_pubkey, sum); - } - std::vector sum(IPCL_CRYPTO_MB_SIZE); - for (int i = 0; i < m_available; i++) - sum[i] = a.raw_add(a.m_bn[i], b.m_bn[i]); - return EncryptedNumber(m_pubkey, sum); -} - -// CT+PT -EncryptedNumber EncryptedNumber::operator+(const BigNumber& other) const { - const auto& a = *this; - BigNumber b; - a.m_pubkey->encrypt(b, other); - - BigNumber sum = a.raw_add(a.m_bn.front(), b); - return EncryptedNumber(m_pubkey, sum); -} - -// multi encrypted CT+PT -EncryptedNumber EncryptedNumber::operator+( - const std::vector& other) const { - VEC_SIZE_CHECK(other); - - const auto& a = *this; - - std::vector b(IPCL_CRYPTO_MB_SIZE); - std::vector sum(IPCL_CRYPTO_MB_SIZE); - a.m_pubkey->encrypt(b, other, false); - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) - sum[i] = a.raw_add(a.m_bn[i], b[i]); - return EncryptedNumber(m_pubkey, sum); -} - -// CT*PT EncryptedNumber store a plaintext integer, not an encrypted -// integer -EncryptedNumber EncryptedNumber::operator*(const EncryptedNumber& other) const { - ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), - "operator*: two different public keys detected!!"); - - const auto& a = *this; - const auto& b = other; - - if (m_available == 1) { - BigNumber product = a.raw_mul(a.m_bn.front(), b.m_bn.front()); - return EncryptedNumber(m_pubkey, product); - } - - std::vector&& product = a.raw_mul(a.m_bn, b.m_bn); - return EncryptedNumber(m_pubkey, product); -} - -// CT*PT -EncryptedNumber EncryptedNumber::operator*(const BigNumber& other) const { - const auto& a = *this; - - BigNumber b = other; - BigNumber product = a.raw_mul(a.m_bn.front(), b); - return EncryptedNumber(m_pubkey, product); -} - -BigNumber EncryptedNumber::raw_add(const BigNumber& a, - const BigNumber& b) const { - // Hold a copy of nsquare for multi-threaded - const BigNumber& sq = m_pubkey->getNSQ(); - return a * b % sq; -} - -std::vector EncryptedNumber::raw_mul( - const std::vector& a, const std::vector& b) const { - std::vector sq(IPCL_CRYPTO_MB_SIZE, m_pubkey->getNSQ()); - return ipcl::ippModExp(a, b, sq); -} - -BigNumber EncryptedNumber::raw_mul(const BigNumber& a, - const BigNumber& b) const { - const BigNumber& sq = m_pubkey->getNSQ(); - return ipcl::ippModExp(a, b, sq); -} - -EncryptedNumber EncryptedNumber::rotate(int shift) const { - ERROR_CHECK(m_available != 1, "rotate: Cannot rotate single EncryptedNumber"); - ERROR_CHECK(shift >= -8 && shift <= 8, - "rotate: Cannot shift more than 8 or -8"); - - if (shift == 0 || shift == 8 || shift == -8) - return EncryptedNumber(m_pubkey, m_bn); - - if (shift > 0) - shift = 8 - shift; - else - shift = -shift; - - std::vector new_bn = getArrayBN(); - - std::rotate(std::begin(new_bn), std::begin(new_bn) + shift, std::end(new_bn)); - return EncryptedNumber(m_pubkey, new_bn); -} - -void EncryptedNumber::apply_obfuscator() { - b_isObfuscator = true; - std::vector obfuscator(IPCL_CRYPTO_MB_SIZE); - m_pubkey->applyObfuscator(obfuscator); - - BigNumber sq = m_pubkey->getNSQ(); - for (int i = 0; i < m_available; i++) - m_bn[i] = sq.ModMul(m_bn[i], obfuscator[i]); -} - -} // namespace ipcl diff --git a/ipcl/plaintext.cpp b/ipcl/plaintext.cpp new file mode 100644 index 0000000..a4feccf --- /dev/null +++ b/ipcl/plaintext.cpp @@ -0,0 +1,46 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/plaintext.hpp" + +#include "ipcl/util.hpp" + +namespace ipcl { + +PlainText::PlainText(const uint32_t& n) : BaseText(n) {} + +PlainText::PlainText(const std::vector& n_v) : BaseText(n_v) {} + +PlainText::PlainText(const BigNumber& bn) : BaseText(bn) {} + +PlainText::PlainText(const std::vector& bn_v) : BaseText(bn_v) {} + +PlainText::PlainText(const PlainText& pt) : BaseText(pt) {} + +PlainText& PlainText::operator=(const PlainText& other) { + BaseText::operator=(other); + + return *this; +} + +PlainText::operator std::vector() { + ERROR_CHECK(m_size > 0, + "PlainText: type conversion to uint32_t vector error"); + std::vector v; + m_texts[0].num2vec(v); + + return v; +} + +PlainText::operator BigNumber() { + ERROR_CHECK(m_size > 0, "PlainText: type conversion to BigNumber error"); + return m_texts[0]; +} + +PlainText::operator std::vector() { + ERROR_CHECK(m_size > 0, + "PlainText: type conversion to BigNumber vector error"); + return m_texts; +} + +} // namespace ipcl diff --git a/ipcl/pri_key.cpp b/ipcl/pri_key.cpp index 083c708..3d8c80c 100644 --- a/ipcl/pri_key.cpp +++ b/ipcl/pri_key.cpp @@ -53,54 +53,53 @@ PrivateKey::PrivateKey(const PublicKey* public_key, const BigNumber& p, ERROR_CHECK(p != q, "PrivateKey ctor: p and q are same"); } -void PrivateKey::decryptRAW(std::vector& plaintext, - const std::vector& ciphertext) const { - std::vector pow_lambda(IPCL_CRYPTO_MB_SIZE, m_lambda); - std::vector modulo(IPCL_CRYPTO_MB_SIZE, m_nsquare); - std::vector res = ipcl::ippModExp(ciphertext, pow_lambda, modulo); - - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - BigNumber m = (res[i] - 1) / m_n; - m *= m_x; - plaintext[i] = m % m_n; - } -} +PlainText PrivateKey::decrypt(const CipherText& ct) const { + ERROR_CHECK(ct.getPubKey().getN() == m_pubkey->getN(), + "decrypt: The value of N in public key mismatch."); -void PrivateKey::decrypt(std::vector& plaintext, - const std::vector& ciphertext) const { - VEC_SIZE_CHECK(plaintext); - VEC_SIZE_CHECK(ciphertext); + std::size_t ct_size = ct.getSize(); + std::vector pt_bn(ct_size); + std::vector ct_bn = ct.getTexts(); if (m_enable_crt) - decryptCRT(plaintext, ciphertext); + decryptCRT(pt_bn, ct_bn); else - decryptRAW(plaintext, ciphertext); + decryptRAW(pt_bn, ct_bn); + + return PlainText(pt_bn); } -void PrivateKey::decrypt(std::vector& plaintext, - const EncryptedNumber ciphertext) const { - VEC_SIZE_CHECK(plaintext); - // check key match - ERROR_CHECK(ciphertext.getPK().getN() == m_pubkey->getN(), - "decrypt: public key mismatch error."); +void PrivateKey::decryptRAW(std::vector& plaintext, + const std::vector& ciphertext) const { + std::size_t v_size = plaintext.size(); + + std::vector pow_lambda(v_size, m_lambda); + std::vector modulo(v_size, m_nsquare); + std::vector res = ipcl::ippModExp(ciphertext, pow_lambda, modulo); - const std::vector& res = ciphertext.getArrayBN(); - if (m_enable_crt) - decryptCRT(plaintext, res); - else - decryptRAW(plaintext, res); + BigNumber nn = m_n; + BigNumber xx = m_x; + +#ifdef IPCL_USE_OMP +#pragma omp parallel for +#endif // IPCL_USE_OMP + for (int i = 0; i < v_size; i++) { + BigNumber m = (res[i] - 1) / nn; + m = m * xx; + plaintext[i] = m % nn; + } } // CRT to calculate base^exp mod n^2 void PrivateKey::decryptCRT(std::vector& plaintext, const std::vector& ciphertext) const { - std::vector basep(IPCL_CRYPTO_MB_SIZE), baseq(IPCL_CRYPTO_MB_SIZE); - std::vector pm1(IPCL_CRYPTO_MB_SIZE, m_pminusone), - qm1(IPCL_CRYPTO_MB_SIZE, m_qminusone); - std::vector psq(IPCL_CRYPTO_MB_SIZE, m_psquare), - qsq(IPCL_CRYPTO_MB_SIZE, m_qsquare); + std::size_t v_size = plaintext.size(); + + std::vector basep(v_size), baseq(v_size); + std::vector pm1(v_size, m_pminusone), qm1(v_size, m_qminusone); + std::vector psq(v_size, m_psquare), qsq(v_size, m_qsquare); - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + for (int i = 0; i < v_size; i++) { basep[i] = ciphertext[i] % psq[i]; baseq[i] = ciphertext[i] % qsq[i]; } @@ -109,7 +108,10 @@ void PrivateKey::decryptCRT(std::vector& plaintext, std::vector resp = ipcl::ippModExp(basep, pm1, psq); std::vector resq = ipcl::ippModExp(baseq, qm1, qsq); - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { +#ifdef IPCL_USE_OMP +#pragma omp parallel for +#endif // IPCL_USE_OMP + for (int i = 0; i < v_size; i++) { BigNumber dp = computeLfun(resp[i], m_p) * m_hp % m_p; BigNumber dq = computeLfun(resq[i], m_q) * m_hq % m_q; plaintext[i] = computeCRT(dp, dq); diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index f3d347b..5ebb419 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -10,10 +10,7 @@ #include #include -#ifdef IPCL_CRYPTO_OMP -#include -#endif - +#include "ipcl/ciphertext.hpp" #include "ipcl/mod_exp.hpp" #include "ipcl/util.hpp" @@ -110,12 +107,11 @@ void PublicKey::enableDJN() { } void PublicKey::applyObfuscator(std::vector& obfuscator) const { - std::vector r(IPCL_CRYPTO_MB_SIZE); - std::vector pown(IPCL_CRYPTO_MB_SIZE, m_n); - std::vector base(IPCL_CRYPTO_MB_SIZE, m_hs); - std::vector sq(IPCL_CRYPTO_MB_SIZE, m_nsquare); - - VEC_SIZE_CHECK(obfuscator); + std::size_t obf_size = obfuscator.size(); + std::vector r(obf_size); + std::vector pown(obf_size, m_n); + std::vector base(obf_size, m_hs); + std::vector sq(obf_size, m_nsquare); if (m_enable_DJN) { for (auto& r_ : r) { @@ -123,7 +119,7 @@ void PublicKey::applyObfuscator(std::vector& obfuscator) const { } obfuscator = ipcl::ippModExp(base, r, sq); } else { - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + for (int i = 0; i < obf_size; i++) { if (m_testv) { r[i] = m_r[i]; } else { @@ -138,49 +134,36 @@ void PublicKey::applyObfuscator(std::vector& obfuscator) const { } void PublicKey::setRandom(const std::vector& r) { - VEC_SIZE_CHECK(r); - std::copy(r.begin(), r.end(), std::back_inserter(m_r)); m_testv = true; } -void PublicKey::raw_encrypt(std::vector& ciphertext, - const std::vector& plaintext, - bool make_secure) const { - // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 +std::vector PublicKey::raw_encrypt(const std::vector& pt, + bool make_secure) const { + std::size_t pt_size = pt.size(); + + std::vector ct(pt_size); BigNumber sq = m_nsquare; - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - BigNumber bn(plaintext[i]); - ciphertext[i] = (m_n * bn + 1) % sq; + + for (std::size_t i = 0; i < pt_size; i++) { + ct[i] = (m_n * pt[i] + 1) % m_nsquare; } if (make_secure) { - std::vector obfuscator(IPCL_CRYPTO_MB_SIZE); + std::vector obfuscator(pt_size); applyObfuscator(obfuscator); - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) - ciphertext[i] = sq.ModMul(ciphertext[i], obfuscator[i]); + for (std::size_t i = 0; i < pt_size; i++) + ct[i] = sq.ModMul(ct[i], obfuscator[i]); } + return ct; } -void PublicKey::encrypt(std::vector& ciphertext, - const std::vector& value, - bool make_secure) const { - VEC_SIZE_CHECK(ciphertext); - VEC_SIZE_CHECK(value); +CipherText PublicKey::encrypt(const PlainText& pt, bool make_secure) const { + std::size_t pt_size = pt.getSize(); + std::vector ct_bn_v(pt_size); - raw_encrypt(ciphertext, value, make_secure); + ct_bn_v = raw_encrypt(pt.getTexts(), make_secure); + return CipherText(this, ct_bn_v); } - -// Used for CT+PT, where PT do not need to add obfuscator -void PublicKey::encrypt(BigNumber& ciphertext, const BigNumber& value) const { - // Based on the fact that: (n+1)^plaintext mod n^2 = n*plaintext + 1 mod n^2 - ciphertext = (m_n * value + 1) % m_nsquare; - - /*----- Path to caculate (n+1)^plaintext mod n^2 ------------ - BigNumber bn(value); - ciphertext = ippMontExp(m_g, bn, m_nsquare); - ---------------------------------------------------------- */ -} - } // namespace ipcl diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 1cd5c4c..6d0bd6d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -15,12 +15,6 @@ target_link_libraries(unittest_ipcl PRIVATE ipcl libgtest Threads::Threads ) -# enable OpenMP unittests -if(IPCL_ENABLE_OMP) - find_package(OpenMP REQUIRED) - target_link_libraries(unittest_ipcl PRIVATE OpenMP::OpenMP_CXX) -endif() - # enable QAT unittests if(IPCL_ENABLE_QAT) target_link_libraries(unittest_ipcl PRIVATE libhe_qat) diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index c88eaba..eaaf3e3 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -6,108 +6,47 @@ #include #include -#ifdef IPCL_USE_OMP -#include -#endif // IPCL_USE_OMP - #include "gtest/gtest.h" +#include "ipcl/ciphertext.hpp" #include "ipcl/keygen.hpp" -#include "ipcl/ops.hpp" - -TEST(CryptoTest, CryptoTest) { - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector ct(8); - std::vector dt(8); - - std::vector pt(8); - std::vector ptbn(8); - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < 8; i++) { - pt[i] = dist(rng); - ptbn[i] = pt[i]; - } - - key.pub_key->encrypt(ct, ptbn); - key.priv_key->decrypt(dt, ct); - - for (int i = 0; i < 8; i++) { - std::vector v; - dt[i].num2vec(v); - EXPECT_EQ(v[0], pt[i]); - } +#include "ipcl/plaintext.hpp" - delete key.pub_key; - delete key.priv_key; -} +constexpr int SELF_DEF_NUM_VALUES = 20; -#ifdef IPCL_USE_OMP -void Encryption(int num_threads, std::vector>& v_ct, - const std::vector>& v_ptbn, - const ipcl::keyPair key) { -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - key.pub_key->encrypt(v_ct[i], v_ptbn[i]); - } -} - -void Decryption(int num_threads, std::vector>& v_dt, - const std::vector>& v_ct, - const ipcl::keyPair key) { -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - key.priv_key->decrypt(v_dt[i], v_ct[i]); - } -} +TEST(CryptoTest, CryptoTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; -TEST(CryptoTest, CryptoTest_OMP) { - // use one keypair to do several encryption/decryption ipcl::keyPair key = ipcl::generateKeypair(2048, true); - size_t num_threads = omp_get_max_threads(); - - std::vector> v_ct(num_threads, - std::vector(8)); - std::vector> v_dt(num_threads, - std::vector(8)); - std::vector> v_pt(num_threads, - std::vector(8)); - std::vector> v_ptbn(num_threads, - std::vector(8)); + std::vector exp_value(num_values); + ipcl::PlainText pt; + ipcl::CipherText ct; + ipcl::PlainText dt; std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); - for (int i = 0; i < num_threads; i++) { - // for each threads, generated different rand testing value - for (int j = 0; j < 8; j++) { - v_pt[i][j] = dist(rng); - v_ptbn[i][j] = v_pt[i][j]; - } + for (int i = 0; i < num_values; i++) { + exp_value[i] = dist(rng); } - Encryption(num_threads, v_ct, v_ptbn, key); - Decryption(num_threads, v_dt, v_ct, key); + pt = ipcl::PlainText(exp_value); + ct = key.pub_key->encrypt(pt); + dt = key.priv_key->decrypt(ct); - // check output for all threads - for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < 8; j++) { - std::vector v; - v_dt[i][j].num2vec(v); - EXPECT_EQ(v[0], v_pt[i][j]); - } + for (int i = 0; i < num_values; i++) { + std::vector v = dt.getElementVec(i); + EXPECT_EQ(v[0], exp_value[i]); } delete key.pub_key; delete key.priv_key; } -#endif // IPCL_USE_OMP TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + BigNumber p = "0xff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c" "8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b4" @@ -127,10 +66,8 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { ipcl::keyPair key = {public_key, private_key}; - std::vector ptbn(8); - std::vector ct(8); - std::vector dt(8); - std::vector ir(8); + std::vector pt_bn_v(num_values); + std::vector ir_bn_v(num_values); BigNumber c1 = "0x1fb7f08a42deb47876e4cbdc3f0b172c033563a696ad7a7c76fa5971b793fa488dcdd6" @@ -204,48 +141,47 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { "4883680e42b5d8582344e3e07a01fbd6c46328dcfa03074d0bc02927f58466c2fa74ab60" "8177e3ec1b"; - for (int i = 0; i < 8; i++) { - ir[i] = r0; - ptbn[i] = "0x414243444546474849404a4b4c4d4e4f"; + for (int i = 0; i < num_values; i++) { + ir_bn_v[i] = r0; + pt_bn_v[i] = "0x414243444546474849404a4b4c4d4e4f"; } - ir[1] = r1; - ptbn[1] = "0x20202020202020202020202020202020"; + ir_bn_v[1] = r1; + pt_bn_v[1] = "0x20202020202020202020202020202020"; - key.pub_key->setRandom(ir); + ipcl::PlainText pt; + ipcl::CipherText ct; - key.pub_key->encrypt(ct, ptbn); + key.pub_key->setRandom(ir_bn_v); - ipcl::EncryptedNumber a(key.pub_key, ct[0]); - ipcl::EncryptedNumber b(key.pub_key, ct[1]); - ipcl::EncryptedNumber sum = a + b; - BigNumber res = sum.getBN(); + pt = ipcl::PlainText(pt_bn_v); + ct = key.pub_key->encrypt(pt); - std::vector ct12(8); - std::vector dt12(8); - for (int i = 0; i < 8; i++) { - ct12[i] = res; + ipcl::PlainText dt; + dt = key.priv_key->decrypt(ct); + for (int i = 0; i < num_values; i++) { + EXPECT_EQ(dt.getElement(i), pt_bn_v[i]); } - key.priv_key->decrypt(dt, ct); - key.priv_key->decrypt(dt12, ct12); - std::string str1, str2; - c1.num2hex(str1); - ct[0].num2hex(str2); - EXPECT_EQ(str1, str2); + EXPECT_EQ(str1, ct.getElementHex(0)); + c2.num2hex(str2); + EXPECT_EQ(str2, ct.getElementHex(1)); + + ipcl::CipherText a(key.pub_key, ct.getElement(0)); + ipcl::CipherText b(key.pub_key, ct.getElement(1)); + ipcl::CipherText sum = a + b; - c2.num2hex(str1); - ct[1].num2hex(str2); - EXPECT_EQ(str1, str2); + std::string str3; + c1c2.num2hex(str3); + EXPECT_EQ(str3, sum.getElementHex(0)); - c1c2.num2hex(str1); - res.num2hex(str2); - EXPECT_EQ(str1, str2); + std::string str4; + ipcl::PlainText dt_sum; - m1m2.num2hex(str1); - dt12[0].num2hex(str2); - EXPECT_EQ(str1, str2); + dt_sum = key.priv_key->decrypt(sum); + m1m2.num2hex(str4); + EXPECT_EQ(str4, dt_sum.getElementHex(0)); delete key.pub_key; delete key.priv_key; diff --git a/test/test_ops.cpp b/test/test_ops.cpp index 8d1d63a..6bb9c4e 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -6,120 +6,122 @@ #include #include -#ifdef IPCL_USE_OMP -#include -#endif // IPCL_USE_OMP - #include "gtest/gtest.h" +#include "ipcl/ciphertext.hpp" #include "ipcl/keygen.hpp" -#include "ipcl/ops.hpp" - -void CtPlusCt(std::vector& res, const std::vector& ct1, - const std::vector& ct2, const ipcl::keyPair key) { - for (int i = 0; i < 8; i++) { - ipcl::EncryptedNumber a(key.pub_key, ct1[i]); - ipcl::EncryptedNumber b(key.pub_key, ct2[i]); - ipcl::EncryptedNumber sum = a + b; - res[i] = sum.getBN(); +#include "ipcl/plaintext.hpp" + +constexpr int SELF_DEF_NUM_VALUES = 20; + +void CtPlusCt(ipcl::CipherText& res, const ipcl::CipherText& ct1, + const ipcl::CipherText& ct2, const ipcl::keyPair key) { + int size = ct1.getSize(); + std::vector sum_bn_v(size); + + for (int i = 0; i < size; i++) { + ipcl::CipherText a(key.pub_key, ct1.getElement(i)); + ipcl::CipherText b(key.pub_key, ct2.getElement(i)); + ipcl::CipherText sum = a + b; + sum_bn_v[i] = sum.getElement(0); } + res = ipcl::CipherText(key.pub_key, sum_bn_v); } -void CtPlusCtArray(std::vector& res, - const std::vector& ct1, - const std::vector& ct2, const ipcl::keyPair key) { - ipcl::EncryptedNumber a(key.pub_key, ct1); - ipcl::EncryptedNumber b(key.pub_key, ct2); - ipcl::EncryptedNumber sum = a + b; - res = sum.getArrayBN(); +void CtPlusCtArray(ipcl::CipherText& res, const ipcl::CipherText& ct1, + const ipcl::CipherText& ct2, const ipcl::keyPair key) { + res = ct1 + ct2; } -void CtPlusPt(std::vector& res, const std::vector& ct1, - const std::vector& pt2, const ipcl::keyPair key) { - for (int i = 0; i < 8; i++) { - ipcl::EncryptedNumber a(key.pub_key, ct1[i]); - BigNumber b = pt2[i]; - ipcl::EncryptedNumber sum = a + b; - res[i] = sum.getBN(); +void CtPlusPt(ipcl::CipherText& res, const ipcl::CipherText& ct1, + const ipcl::PlainText& pt2, const ipcl::keyPair key) { + int size = ct1.getSize(); + std::vector sum_bn_v(size); + + for (int i = 0; i < size; i++) { + ipcl::CipherText a(key.pub_key, ct1.getElement(i)); + ipcl::PlainText b(pt2.getElement(i)); + ipcl::CipherText sum = a + b; + sum_bn_v[i] = sum.getElement(0); } + res = ipcl::CipherText(key.pub_key, sum_bn_v); } -void CtPlusPtArray(std::vector& res, - const std::vector& ct1, - const std::vector& ptbn2, - const ipcl::keyPair key) { - ipcl::EncryptedNumber a(key.pub_key, ct1); - ipcl::EncryptedNumber sum = a + ptbn2; - res = sum.getArrayBN(); +void CtPlusPtArray(ipcl::CipherText& res, const ipcl::CipherText& ct1, + const ipcl::PlainText& pt2, const ipcl::keyPair key) { + res = ct1 + pt2; } -void CtMultiplyPt(std::vector& res, - const std::vector& ct1, - const std::vector& pt2, const ipcl::keyPair key) { - for (int i = 0; i < 8; i++) { - ipcl::EncryptedNumber a(key.pub_key, ct1[i]); - ipcl::EncryptedNumber b(key.pub_key, pt2[i]); - ipcl::EncryptedNumber sum = a * b; - res[i] = sum.getBN(); +void CtMultiplyPt(ipcl::CipherText& res, const ipcl::CipherText& ct1, + const ipcl::PlainText& pt2, const ipcl::keyPair key) { + int size = ct1.getSize(); + std::vector product_bn_v(size); + + for (int i = 0; i < size; i++) { + ipcl::CipherText a(key.pub_key, ct1.getElement(i)); + ipcl::PlainText b(pt2.getElement(i)); + ipcl::CipherText product = a * b; + product_bn_v[i] = product.getElement(0); } + res = ipcl::CipherText(key.pub_key, product_bn_v); } -void CtMultiplyPtArray(std::vector& res, - const std::vector& ct1, - const std::vector& pt2, - const ipcl::keyPair key) { - ipcl::EncryptedNumber a(key.pub_key, ct1); - ipcl::EncryptedNumber b(key.pub_key, pt2); - ipcl::EncryptedNumber sum = a * b; - res = sum.getArrayBN(); +void CtMultiplyPtArray(ipcl::CipherText& res, const ipcl::CipherText& ct1, + const ipcl::PlainText& pt2, const ipcl::keyPair key) { + res = ct1 * pt2; } -void AddSub(std::vector& res, const std::vector& ct1, - const std::vector& ct2, const ipcl::keyPair key) { - for (int i = 0; i < 8; i++) { - ipcl::EncryptedNumber a(key.pub_key, ct1[i]); - ipcl::EncryptedNumber b(key.pub_key, ct2[i]); - BigNumber m1(2); +void AddSub(ipcl::CipherText& res, const ipcl::CipherText& ct1, + const ipcl::CipherText& ct2, const ipcl::keyPair key) { + int size = ct1.getSize(); + std::vector sum_bn_v(size); + + for (int i = 0; i < size; i++) { + ipcl::CipherText a(key.pub_key, ct1.getElement(i)); + ipcl::CipherText b(key.pub_key, ct2.getElement(i)); + ipcl::PlainText m1(2); + a = a + b * m1; - ipcl::EncryptedNumber sum = a + b; - res[i] = sum.getBN(); + ipcl::CipherText sum = a + b; + sum_bn_v[i] = sum.getElement(0); } + res = ipcl::CipherText(key.pub_key, sum_bn_v); } TEST(OperationTest, CtPlusCtTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_sum; + ipcl::CipherText ct1, ct2, ct_sum; - std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; - ptbn2[i] = pt2[i]; + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); - key.pub_key->encrypt(ct1, ptbn1); - key.pub_key->encrypt(ct2, ptbn2); + ct1 = key.pub_key->encrypt(pt1); + ct2 = key.pub_key->encrypt(pt2); - CtPlusCt(res, ct1, ct2, key); + CtPlusCt(ct_sum, ct1, ct2, key); - key.priv_key->decrypt(dt, res); + dt_sum = key.priv_key->decrypt(ct_sum); - for (int i = 0; i < 8; i++) { - std::vector v; - dt[i].num2vec(v); + for (int i = 0; i < num_values; i++) { + std::vector v = dt_sum.getElementVec(i); + uint64_t sum = v[0]; + if (v.size() > 1) sum = ((uint64_t)v[1] << 32) | v[0]; - uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + uint64_t exp_sum = (uint64_t)exp_value1[i] + (uint64_t)exp_value2[i]; - EXPECT_EQ(v_dp, v_pp); + EXPECT_EQ(sum, exp_sum); } delete key.pub_key; @@ -127,40 +129,40 @@ TEST(OperationTest, CtPlusCtTest) { } TEST(OperationTest, CtPlusCtArrayTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_sum; + ipcl::CipherText ct1, ct2, ct_sum; - std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; - ptbn2[i] = pt2[i]; + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); - key.pub_key->encrypt(ct1, ptbn1); - key.pub_key->encrypt(ct2, ptbn2); + ct1 = key.pub_key->encrypt(pt1); + ct2 = key.pub_key->encrypt(pt2); - CtPlusCtArray(res, ct1, ct2, key); + CtPlusCtArray(ct_sum, ct1, ct2, key); - key.priv_key->decrypt(dt, res); + dt_sum = key.priv_key->decrypt(ct_sum); - for (int i = 0; i < 8; i++) { - std::vector v; - dt[i].num2vec(v); + for (int i = 0; i < num_values; i++) { + std::vector v = dt_sum.getElementVec(i); + uint64_t sum = v[0]; + if (v.size() > 1) sum = ((uint64_t)v[1] << 32) | v[0]; - uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + uint64_t exp_sum = (uint64_t)exp_value1[i] + (uint64_t)exp_value2[i]; - EXPECT_EQ(v_dp, v_pp); + EXPECT_EQ(sum, exp_sum); } delete key.pub_key; @@ -168,38 +170,39 @@ TEST(OperationTest, CtPlusCtArrayTest) { } TEST(OperationTest, CtPlusPtTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_sum; + ipcl::CipherText ct1, ct2, ct_sum; - std::vector pt1(8), pt2(8); - std::vector ptbn1(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); - key.pub_key->encrypt(ct1, ptbn1); + ct1 = key.pub_key->encrypt(pt1); - CtPlusPt(res, ct1, pt2, key); + CtPlusPt(ct_sum, ct1, pt2, key); - key.priv_key->decrypt(dt, res); + dt_sum = key.priv_key->decrypt(ct_sum); - for (int i = 0; i < 8; i++) { - std::vector v; - dt[i].num2vec(v); + for (int i = 0; i < num_values; i++) { + std::vector v = dt_sum.getElementVec(i); + uint64_t sum = v[0]; + if (v.size() > 1) sum = ((uint64_t)v[1] << 32) | v[0]; - uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + uint64_t exp_sum = (uint64_t)exp_value1[i] + (uint64_t)exp_value2[i]; - EXPECT_EQ(v_dp, v_pp); + EXPECT_EQ(sum, exp_sum); } delete key.pub_key; @@ -207,39 +210,39 @@ TEST(OperationTest, CtPlusPtTest) { } TEST(OperationTest, CtPlusPtArrayTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_sum; + ipcl::CipherText ct1, ct2, ct_sum; - std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; - ptbn2[i] = pt2[i]; + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); - key.pub_key->encrypt(ct1, ptbn1); + ct1 = key.pub_key->encrypt(pt1); - CtPlusPtArray(res, ct1, ptbn2, key); + CtPlusPtArray(ct_sum, ct1, pt2, key); - key.priv_key->decrypt(dt, res); + dt_sum = key.priv_key->decrypt(ct_sum); - for (int i = 0; i < 8; i++) { - std::vector v; - dt[i].num2vec(v); + for (int i = 0; i < num_values; i++) { + std::vector v = dt_sum.getElementVec(i); + uint64_t sum = v[0]; + if (v.size() > 1) sum = ((uint64_t)v[1] << 32) | v[0]; - uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + uint64_t exp_sum = (uint64_t)exp_value1[i] + (uint64_t)exp_value2[i]; - EXPECT_EQ(v_dp, v_pp); + EXPECT_EQ(sum, exp_sum); } delete key.pub_key; @@ -247,38 +250,39 @@ TEST(OperationTest, CtPlusPtArrayTest) { } TEST(OperationTest, CtMultiplyPtTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_product; + ipcl::CipherText ct1, ct2, ct_product; - std::vector pt1(8), pt2(8); - std::vector ptbn1(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); - key.pub_key->encrypt(ct1, ptbn1); + ct1 = key.pub_key->encrypt(pt1); - CtMultiplyPt(res, ct1, pt2, key); + CtMultiplyPt(ct_product, ct1, pt2, key); - key.priv_key->decrypt(dt, res); + dt_product = key.priv_key->decrypt(ct_product); - for (int i = 0; i < 8; i++) { - std::vector v; - dt[i].num2vec(v); + for (int i = 0; i < num_values; i++) { + std::vector v = dt_product.getElementVec(i); + uint64_t product = v[0]; + if (v.size() > 1) product = ((uint64_t)v[1] << 32) | v[0]; - uint64_t v_pp = (uint64_t)pt1[i] * (uint64_t)pt2[i]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + uint64_t exp_product = (uint64_t)exp_value1[i] * (uint64_t)exp_value2[i]; - EXPECT_EQ(v_dp, v_pp); + EXPECT_EQ(product, exp_product); } delete key.pub_key; @@ -286,516 +290,123 @@ TEST(OperationTest, CtMultiplyPtTest) { } TEST(OperationTest, CtMultiplyZeroPtTest) { - ipcl::keyPair key = ipcl::generateKeypair(2048); - - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); + const uint32_t num_values = SELF_DEF_NUM_VALUES; - std::vector pt1(8), pt2(8); - std::vector ptbn1(8); - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = 0; - ptbn1[i] = pt1[i]; - } - - key.pub_key->encrypt(ct1, ptbn1); - - CtMultiplyPt(res, ct1, pt2, key); - - key.priv_key->decrypt(dt, res); - - for (int i = 0; i < 8; i++) { - std::vector v; - dt[i].num2vec(v); - - uint64_t v_pp = (uint64_t)pt1[i] * (uint64_t)pt2[i]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; - - EXPECT_EQ(v_dp, v_pp); - } - - delete key.pub_key; - delete key.priv_key; -} - -TEST(OperationTest, CtMultiplyPtArrayTest) { ipcl::keyPair key = ipcl::generateKeypair(2048); - std::vector ct1(8); - std::vector dt(8), res(8); + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_product; + ipcl::CipherText ct1, ct2, ct_product; - std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; - ptbn2[i] = pt2[i]; + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = 0; } - key.pub_key->encrypt(ct1, ptbn1); + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); - CtMultiplyPtArray(res, ct1, pt2, key); + ct1 = key.pub_key->encrypt(pt1); - key.priv_key->decrypt(dt, res); + CtMultiplyPt(ct_product, ct1, pt2, key); - for (int i = 0; i < 8; i++) { - std::vector v; - dt[i].num2vec(v); + dt_product = key.priv_key->decrypt(ct_product); - uint64_t v_pp = (uint64_t)pt1[i] * (uint64_t)pt2[i]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + for (int i = 0; i < num_values; i++) { + std::vector v = dt_product.getElementVec(i); + uint64_t product = v[0]; + if (v.size() > 1) product = ((uint64_t)v[1] << 32) | v[0]; - EXPECT_EQ(v_dp, v_pp); - } - - delete key.pub_key; - delete key.priv_key; -} - -TEST(OperationTest, AddSubTest) { - ipcl::keyPair key = ipcl::generateKeypair(2048); - - std::vector ct1(8), ct2(8); - std::vector dt(8), res(8); - - std::vector pt1(8), pt2(8); - std::vector ptbn1(8), ptbn2(8); - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < 8; i++) { - pt1[i] = dist(rng); - pt2[i] = dist(rng); - ptbn1[i] = pt1[i]; - ptbn2[i] = pt2[i]; - } - - key.pub_key->encrypt(ct1, ptbn1); - key.pub_key->encrypt(ct2, ptbn2); + uint64_t exp_product = (uint64_t)exp_value1[i] * (uint64_t)exp_value2[i]; - AddSub(res, ct1, ct2, key); - key.priv_key->decrypt(dt, res); - - for (int i = 0; i < 8; i++) { - std::vector v; - dt[i].num2vec(v); - - uint64_t v_pp = (uint64_t)pt1[i] + (uint64_t)pt2[i] * 3; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; - - EXPECT_EQ(v_dp, v_pp); + EXPECT_EQ(product, exp_product); } delete key.pub_key; delete key.priv_key; } -#ifdef IPCL_USE_OMP -void CtPlusCt_OMP(int num_threads, std::vector>& v_sum, - const std::vector>& v_ct1, - const std::vector>& v_ct2, - const ipcl::keyPair key) { -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < 8; j++) { - ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); - ipcl::EncryptedNumber b(key.pub_key, v_ct2[i][j]); - ipcl::EncryptedNumber sum = a + b; - v_sum[i][j] = sum.getBN(); - } - } -} - -void CtPlusPt_OMP(int num_threads, std::vector>& v_sum, - const std::vector>& v_ct1, - const std::vector>& v_pt2, - const ipcl::keyPair key) { -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < 8; j++) { - BigNumber b = v_pt2[i][j]; - ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); - ipcl::EncryptedNumber sum = a + b; - v_sum[i][j] = sum.getBN(); - } - } -} - -void CtPlusPtArray_OMP(int num_threads, - std::vector>& v_sum, - const std::vector>& v_ct1, - const std::vector>& v_pt2, - const ipcl::keyPair key) { -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - ipcl::EncryptedNumber a(key.pub_key, v_ct1[i]); - std::vector b(8); - for (int j = 0; j < 8; j++) { - b[j] = v_pt2[i][j]; - } - ipcl::EncryptedNumber sum = a + b; - v_sum[i] = sum.getArrayBN(); - } -} - -void CtMultiplyPt_OMP(int num_threads, - std::vector>& v_product, - const std::vector>& v_ct1, - const std::vector>& v_pt2, - const ipcl::keyPair key) { -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < 8; j++) { - ipcl::EncryptedNumber a(key.pub_key, v_ct1[i][j]); - BigNumber b = v_pt2[i][j]; - ipcl::EncryptedNumber product = a * b; - v_product[i][j] = product.getBN(); - } - } -} - -void CtMultiplyPtArray_OMP(int num_threads, - std::vector>& v_product, - const std::vector>& v_ct1, - const std::vector>& v_pt2, - const ipcl::keyPair key) { -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - ipcl::EncryptedNumber a(key.pub_key, v_ct1[i]); - ipcl::EncryptedNumber b(key.pub_key, v_pt2[i]); - ipcl::EncryptedNumber product = a * b; - v_product[i] = product.getArrayBN(); - } -} +TEST(OperationTest, CtMultiplyPtArrayTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; -TEST(OperationTest, CtPlusCtTest_OMP) { ipcl::keyPair key = ipcl::generateKeypair(2048); - size_t num_threads = omp_get_max_threads(); - - std::vector> v_ct1(num_threads, - std::vector(8)); - std::vector> v_ct2(num_threads, - std::vector(8)); - std::vector> v_dt(num_threads, - std::vector(8)); - std::vector> v_sum(num_threads, - std::vector(8)); - std::vector> v_pt1(num_threads, - std::vector(8)); - std::vector> v_pt2(num_threads, - std::vector(8)); - std::vector> v_ptbn1(num_threads, - std::vector(8)); - std::vector> v_ptbn2(num_threads, - std::vector(8)); - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < num_threads; i++) { - // for each threads, generated different rand testing value - for (int j = 0; j < 8; j++) { - v_pt1[i][j] = dist(rng); - v_pt2[i][j] = dist(rng); - v_ptbn1[i][j] = v_pt1[i][j]; - v_ptbn2[i][j] = v_pt2[i][j]; - } - } - -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - key.pub_key->encrypt(v_ct1[i], v_ptbn1[i]); - key.pub_key->encrypt(v_ct2[i], v_ptbn2[i]); - } + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_product; + ipcl::CipherText ct1, ct2, ct_product; - CtPlusCt_OMP(num_threads, v_sum, v_ct1, v_ct2, key); - -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - key.priv_key->decrypt(v_dt[i], v_sum[i]); - } - - // check output for all threads - for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < 8; j++) { - std::vector v; - v_dt[i][j].num2vec(v); - - uint64_t v_pp = (uint64_t)v_pt1[i][j] + (uint64_t)v_pt2[i][j]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; - - EXPECT_EQ(v_dp, v_pp); - } - } - - delete key.pub_key; - delete key.priv_key; -} - -TEST(OperationTest, CtPlusPtTest_OMP) { - ipcl::keyPair key = ipcl::generateKeypair(2048); - - size_t num_threads = omp_get_max_threads(); - - std::vector> v_ct1(num_threads, - std::vector(8)); - std::vector> v_dt(num_threads, - std::vector(8)); - std::vector> v_sum(num_threads, - std::vector(8)); - std::vector> v_pt1(num_threads, - std::vector(8)); - std::vector> v_pt2(num_threads, - std::vector(8)); - std::vector> v_ptbn1(num_threads, - std::vector(8)); - std::vector> v_ptbn2(num_threads, - std::vector(8)); std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); - for (int i = 0; i < num_threads; i++) { - // for each threads, generated different rand testing value - for (int j = 0; j < 8; j++) { - v_pt1[i][j] = dist(rng); - v_pt2[i][j] = dist(rng); - v_ptbn1[i][j] = v_pt1[i][j]; - v_ptbn2[i][j] = v_pt2[i][j]; - } + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - key.pub_key->encrypt(v_ct1[i], v_ptbn1[i]); - } + ct1 = key.pub_key->encrypt(pt1); - CtPlusPt_OMP(num_threads, v_sum, v_ct1, v_pt2, key); + CtMultiplyPtArray(ct_product, ct1, pt2, key); -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - key.priv_key->decrypt(v_dt[i], v_sum[i]); - } + dt_product = key.priv_key->decrypt(ct_product); - // check output for all threads - for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < 8; j++) { - std::vector v; - v_dt[i][j].num2vec(v); + for (int i = 0; i < num_values; i++) { + std::vector v = dt_product.getElementVec(i); + uint64_t product = v[0]; + if (v.size() > 1) product = ((uint64_t)v[1] << 32) | v[0]; - uint64_t v_pp = (uint64_t)v_pt1[i][j] + (uint64_t)v_pt2[i][j]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; + uint64_t exp_product = (uint64_t)exp_value1[i] * (uint64_t)exp_value2[i]; - EXPECT_EQ(v_dp, v_pp); - } + EXPECT_EQ(product, exp_product); } delete key.pub_key; delete key.priv_key; } -TEST(OperationTest, CtPlusPtArrayTest_OMP) { - ipcl::keyPair key = ipcl::generateKeypair(2048); - - size_t num_threads = omp_get_max_threads(); - - std::vector> v_ct1(num_threads, - std::vector(8)); - std::vector> v_dt(num_threads, - std::vector(8)); - std::vector> v_sum(num_threads, - std::vector(8)); - std::vector> v_pt1(num_threads, - std::vector(8)); - std::vector> v_pt2(num_threads, - std::vector(8)); - std::vector> v_ptbn1(num_threads, - std::vector(8)); - std::vector> v_ptbn2(num_threads, - std::vector(8)); - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < num_threads; i++) { - // for each threads, generated different rand testing value - for (int j = 0; j < 8; j++) { - v_pt1[i][j] = dist(rng); - v_pt2[i][j] = dist(rng); - v_ptbn1[i][j] = v_pt1[i][j]; - v_ptbn2[i][j] = v_pt2[i][j]; - } - } - -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - key.pub_key->encrypt(v_ct1[i], v_ptbn1[i]); - } - - CtPlusPtArray_OMP(num_threads, v_sum, v_ct1, v_pt2, key); - -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - key.priv_key->decrypt(v_dt[i], v_sum[i]); - } - - // check output for all threads - for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < 8; j++) { - std::vector v; - v_dt[i][j].num2vec(v); - - uint64_t v_pp = (uint64_t)v_pt1[i][j] + (uint64_t)v_pt2[i][j]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; - - EXPECT_EQ(v_dp, v_pp); - } - } - - delete key.pub_key; - delete key.priv_key; -} +TEST(OperationTest, AddSubTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; -TEST(OperationTest, CtMultiplyPtTest_OMP) { ipcl::keyPair key = ipcl::generateKeypair(2048); - size_t num_threads = omp_get_max_threads(); - - std::vector> v_ct1(num_threads, - std::vector(8)); - std::vector> v_dt(num_threads, - std::vector(8)); - std::vector> v_product(num_threads, - std::vector(8)); - std::vector> v_pt1(num_threads, - std::vector(8)); - std::vector> v_pt2(num_threads, - std::vector(8)); - std::vector> v_ptbn1(num_threads, - std::vector(8)); - std::vector> v_ptbn2(num_threads, - std::vector(8)); + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_sum; + ipcl::CipherText ct1, ct2, ct_sum; std::random_device dev; std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); - for (int i = 0; i < num_threads; i++) { - // for each threads, generated different rand testing value - for (int j = 0; j < 8; j++) { - v_pt1[i][j] = dist(rng); - v_pt2[i][j] = dist(rng); - v_ptbn1[i][j] = v_pt1[i][j]; - v_ptbn2[i][j] = v_pt2[i][j]; - } - } - -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - key.pub_key->encrypt(v_ct1[i], v_ptbn1[i]); - } - - CtMultiplyPt_OMP(num_threads, v_product, v_ct1, v_pt2, key); - -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - key.priv_key->decrypt(v_dt[i], v_product[i]); - } - - // check output for all threads - for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < 8; j++) { - std::vector v; - v_dt[i][j].num2vec(v); - - uint64_t v_pp = (uint64_t)v_pt1[i][j] * (uint64_t)v_pt2[i][j]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; - EXPECT_EQ(v_dp, v_pp); - } + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); - delete key.pub_key; - delete key.priv_key; -} - -TEST(OperationTest, CtMultiplyPtArrayTest_OMP) { - ipcl::keyPair key = ipcl::generateKeypair(2048); - - size_t num_threads = omp_get_max_threads(); - - std::vector> v_ct1(num_threads, - std::vector(8)); - std::vector> v_dt(num_threads, - std::vector(8)); - std::vector> v_product(num_threads, - std::vector(8)); - std::vector> v_pt1(num_threads, - std::vector(8)); - std::vector> v_pt2(num_threads, - std::vector(8)); - std::vector> v_ptbn1(num_threads, - std::vector(8)); - std::vector> v_ptbn2(num_threads, - std::vector(8)); - - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); + ct1 = key.pub_key->encrypt(pt1); + ct2 = key.pub_key->encrypt(pt2); - for (int i = 0; i < num_threads; i++) { - // for each threads, generated different rand testing value - for (int j = 0; j < 8; j++) { - v_pt1[i][j] = dist(rng); - v_pt2[i][j] = dist(rng); - v_ptbn1[i][j] = v_pt1[i][j]; - v_ptbn2[i][j] = v_pt2[i][j]; - } - } + AddSub(ct_sum, ct1, ct2, key); - for (int i = 0; i < num_threads; i++) { - key.pub_key->encrypt(v_ct1[i], v_ptbn1[i]); - } + dt_sum = key.priv_key->decrypt(ct_sum); - CtMultiplyPtArray_OMP(num_threads, v_product, v_ct1, v_pt2, key); + for (int i = 0; i < num_values; i++) { + std::vector v = dt_sum.getElementVec(i); + uint64_t sum = v[0]; + if (v.size() > 1) sum = ((uint64_t)v[1] << 32) | v[0]; -#pragma omp parallel for - for (int i = 0; i < num_threads; i++) { - key.priv_key->decrypt(v_dt[i], v_product[i]); - } + uint64_t exp_sum = (uint64_t)exp_value1[i] + (uint64_t)exp_value2[i] * 3; - // check output for all threads - for (int i = 0; i < num_threads; i++) { - for (int j = 0; j < 8; j++) { - std::vector v; - v_dt[i][j].num2vec(v); - - uint64_t v_pp = (uint64_t)v_pt1[i][j] * (uint64_t)v_pt2[i][j]; - uint64_t v_dp = v[0]; - if (v.size() > 1) v_dp = ((uint64_t)v[1] << 32) | v[0]; - EXPECT_EQ(v_dp, v_pp); - } + EXPECT_EQ(sum, exp_sum); } delete key.pub_key; delete key.priv_key; } -#endif // IPCL_USE_OMP From 22919236a5507455f58337e6be0c4cc9f1a86d74 Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Tue, 3 May 2022 02:11:45 +0800 Subject: [PATCH 169/364] Custom batch size for heQatBnModExp (#87) Co-authored-by: Sejun Kim --- ipcl/mod_exp.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index 4128b21..20dc169 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -23,7 +23,8 @@ namespace ipcl { // Multiple input QAT ModExp interface to offload computation to QAT static std::vector heQatBnModExp( const std::vector& base, const std::vector& exponent, - const std::vector& modulus) { + const std::vector& modulus, + std::size_t batch_size = IPCL_CRYPTO_MB_SIZE) { static unsigned int counter = 0; int nbits = modulus.front().BitSize(); int length = BITSIZE_WORD(nbits) * 4; @@ -32,11 +33,11 @@ static std::vector heQatBnModExp( HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; // TODO(fdiasmor): Try replace calloc by alloca to see impact on performance. - unsigned char* bn_base_data_[IPCL_CRYPTO_MB_SIZE]; - unsigned char* bn_exponent_data_[IPCL_CRYPTO_MB_SIZE]; - unsigned char* bn_modulus_data_[IPCL_CRYPTO_MB_SIZE]; - unsigned char* bn_remainder_data_[IPCL_CRYPTO_MB_SIZE]; - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + unsigned char* bn_base_data_[batch_size]; + unsigned char* bn_exponent_data_[batch_size]; + unsigned char* bn_modulus_data_[batch_size]; + unsigned char* bn_remainder_data_[batch_size]; + for (int i = 0; i < batch_size; i++) { bn_base_data_[i] = reinterpret_cast( malloc(length * sizeof(unsigned char))); bn_exponent_data_[i] = reinterpret_cast( @@ -57,9 +58,7 @@ static std::vector heQatBnModExp( memset(bn_remainder_data_[i], 0, length); } - // TODO(fdiasmor): Define and use IPCL_QAT_BATCH_SIZE instead of - // IPCL_CRYPTO_MB_SIZE. - for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + for (unsigned int i = 0; i < batch_size; i++) { bool ret = BigNumber::toBin(bn_base_data_[i], length, base[i]); if (!ret) { printf("bn_base_data_: failed at bigNumberToBin()\n"); @@ -91,11 +90,11 @@ static std::vector heQatBnModExp( PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); } } - getBnModExpRequest(IPCL_CRYPTO_MB_SIZE); + getBnModExpRequest(batch_size); - std::vector remainder(IPCL_CRYPTO_MB_SIZE, 0); + std::vector remainder(batch_size, 0); // Collect results and pack them into BigNumber - for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + for (unsigned int i = 0; i < batch_size; i++) { unsigned char* bn_remainder_ = bn_remainder_data_[i]; bool ret = BigNumber::fromBin(remainder[i], bn_remainder_, length); if (!ret) { @@ -104,7 +103,7 @@ static std::vector heQatBnModExp( } } - for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + for (unsigned int i = 0; i < batch_size; i++) { free(bn_base_data_[i]); bn_base_data_[i] = NULL; free(bn_exponent_data_[i]); @@ -113,7 +112,7 @@ static std::vector heQatBnModExp( bn_modulus_data_[i] = NULL; } - for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + for (unsigned int i = 0; i < batch_size; i++) { free(bn_remainder_data_[i]); bn_remainder_data_[i] = NULL; } From 70a1c7f6dc765aee694fb2921141da73d5a71965 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Mon, 2 May 2022 14:30:09 -0700 Subject: [PATCH 170/364] Revert "Custom batch size for heQatBnModExp (#87)" (#88) This reverts commit 22919236a5507455f58337e6be0c4cc9f1a86d74. --- ipcl/mod_exp.cpp | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index 20dc169..4128b21 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -23,8 +23,7 @@ namespace ipcl { // Multiple input QAT ModExp interface to offload computation to QAT static std::vector heQatBnModExp( const std::vector& base, const std::vector& exponent, - const std::vector& modulus, - std::size_t batch_size = IPCL_CRYPTO_MB_SIZE) { + const std::vector& modulus) { static unsigned int counter = 0; int nbits = modulus.front().BitSize(); int length = BITSIZE_WORD(nbits) * 4; @@ -33,11 +32,11 @@ static std::vector heQatBnModExp( HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; // TODO(fdiasmor): Try replace calloc by alloca to see impact on performance. - unsigned char* bn_base_data_[batch_size]; - unsigned char* bn_exponent_data_[batch_size]; - unsigned char* bn_modulus_data_[batch_size]; - unsigned char* bn_remainder_data_[batch_size]; - for (int i = 0; i < batch_size; i++) { + unsigned char* bn_base_data_[IPCL_CRYPTO_MB_SIZE]; + unsigned char* bn_exponent_data_[IPCL_CRYPTO_MB_SIZE]; + unsigned char* bn_modulus_data_[IPCL_CRYPTO_MB_SIZE]; + unsigned char* bn_remainder_data_[IPCL_CRYPTO_MB_SIZE]; + for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { bn_base_data_[i] = reinterpret_cast( malloc(length * sizeof(unsigned char))); bn_exponent_data_[i] = reinterpret_cast( @@ -58,7 +57,9 @@ static std::vector heQatBnModExp( memset(bn_remainder_data_[i], 0, length); } - for (unsigned int i = 0; i < batch_size; i++) { + // TODO(fdiasmor): Define and use IPCL_QAT_BATCH_SIZE instead of + // IPCL_CRYPTO_MB_SIZE. + for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { bool ret = BigNumber::toBin(bn_base_data_[i], length, base[i]); if (!ret) { printf("bn_base_data_: failed at bigNumberToBin()\n"); @@ -90,11 +91,11 @@ static std::vector heQatBnModExp( PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); } } - getBnModExpRequest(batch_size); + getBnModExpRequest(IPCL_CRYPTO_MB_SIZE); - std::vector remainder(batch_size, 0); + std::vector remainder(IPCL_CRYPTO_MB_SIZE, 0); // Collect results and pack them into BigNumber - for (unsigned int i = 0; i < batch_size; i++) { + for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { unsigned char* bn_remainder_ = bn_remainder_data_[i]; bool ret = BigNumber::fromBin(remainder[i], bn_remainder_, length); if (!ret) { @@ -103,7 +104,7 @@ static std::vector heQatBnModExp( } } - for (unsigned int i = 0; i < batch_size; i++) { + for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { free(bn_base_data_[i]); bn_base_data_[i] = NULL; free(bn_exponent_data_[i]); @@ -112,7 +113,7 @@ static std::vector heQatBnModExp( bn_modulus_data_[i] = NULL; } - for (unsigned int i = 0; i < batch_size; i++) { + for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { free(bn_remainder_data_[i]); bn_remainder_data_[i] = NULL; } From 3164c6aee6f3b890a92bdd653d9974f5b1851c4c Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Wed, 4 May 2022 14:01:50 -0700 Subject: [PATCH 171/364] Add address handler in base_text --- ipcl/include/ipcl/base_text.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ipcl/include/ipcl/base_text.hpp b/ipcl/include/ipcl/base_text.hpp index 0f9e10e..daeac2c 100644 --- a/ipcl/include/ipcl/base_text.hpp +++ b/ipcl/include/ipcl/base_text.hpp @@ -74,6 +74,8 @@ class BaseText { */ std::size_t getSize() const; + const void* addr = static_cast(this); + protected: std::vector m_texts; ///< Container used to store BigNumber std::size_t m_size; ///< Container size From 98e121b04b08a249a9f508751ccecda2d638a876 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Wed, 4 May 2022 14:40:33 -0700 Subject: [PATCH 172/364] implemented rotate to CipherText and PlainText --- ipcl/ciphertext.cpp | 8 ++++---- ipcl/include/ipcl/ciphertext.hpp | 2 -- ipcl/include/ipcl/plaintext.hpp | 6 ++++++ ipcl/plaintext.cpp | 20 ++++++++++++++++++++ 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/ipcl/ciphertext.cpp b/ipcl/ciphertext.cpp index 27cdcdb..44c898b 100644 --- a/ipcl/ciphertext.cpp +++ b/ipcl/ciphertext.cpp @@ -107,14 +107,14 @@ PublicKey CipherText::getPubKey() const { return *m_pubkey; } CipherText CipherText::rotate(int shift) const { ERROR_CHECK(m_size != 1, "rotate: Cannot rotate single CipherText"); - ERROR_CHECK(shift >= -8 && shift <= 8, - "rotate: Cannot shift more than 8 or -8"); + ERROR_CHECK(shift >= -m_size && shift <= m_size, + "rotate: Cannot shift more than the test size"); - if (shift == 0 || shift == 8 || shift == -8) + if (shift == 0 || shift == m_size || shift == -m_size) return CipherText(m_pubkey, m_texts); if (shift > 0) - shift = 8 - shift; + shift = m_size - shift; else shift = -shift; diff --git a/ipcl/include/ipcl/ciphertext.hpp b/ipcl/include/ipcl/ciphertext.hpp index bd6d701..2b46966 100644 --- a/ipcl/include/ipcl/ciphertext.hpp +++ b/ipcl/include/ipcl/ciphertext.hpp @@ -52,8 +52,6 @@ class CipherText : public BaseText { */ CipherText rotate(int shift) const; - const void* addr = static_cast(this); - private: BigNumber raw_add(const BigNumber& a, const BigNumber& b) const; BigNumber raw_mul(const BigNumber& a, const BigNumber& b) const; diff --git a/ipcl/include/ipcl/plaintext.hpp b/ipcl/include/ipcl/plaintext.hpp index 8b34e7d..2e8ef99 100644 --- a/ipcl/include/ipcl/plaintext.hpp +++ b/ipcl/include/ipcl/plaintext.hpp @@ -69,6 +69,12 @@ class PlainText : public BaseText { * Convert all element to type BigNumber. */ operator std::vector(); + + /** + * Rotate PlainText + * @param[in] shift rotate length + */ + PlainText rotate(int shift) const; }; } // namespace ipcl diff --git a/ipcl/plaintext.cpp b/ipcl/plaintext.cpp index a4feccf..8c447c8 100644 --- a/ipcl/plaintext.cpp +++ b/ipcl/plaintext.cpp @@ -3,6 +3,8 @@ #include "ipcl/plaintext.hpp" +#include + #include "ipcl/util.hpp" namespace ipcl { @@ -43,4 +45,22 @@ PlainText::operator std::vector() { return m_texts; } +PlainText PlainText::rotate(int shift) const { + ERROR_CHECK(m_size != 1, "rotate: Cannot rotate single CipherText"); + ERROR_CHECK(shift >= -m_size && shift <= m_size, + "rotate: Cannot shift more than the test size"); + + if (shift == 0 || shift == m_size || shift == -m_size) + return PlainText(m_texts); + + if (shift > 0) + shift = m_size - shift; + else + shift = -shift; + + std::vector new_bn = getTexts(); + std::rotate(std::begin(new_bn), std::begin(new_bn) + shift, std::end(new_bn)); + return PlainText(new_bn); +} + } // namespace ipcl From 3e5941456b6607b32c5b566ff3bbd75b15974961 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Wed, 4 May 2022 17:02:07 -0700 Subject: [PATCH 173/364] Added TODO for heQatBnModExp works --- ipcl/mod_exp.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index 4128b21..65b6346 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -337,6 +337,7 @@ std::vector ippModExp(const std::vector& base, const std::vector& pow, const std::vector& m) { #ifdef IPCL_USE_QAT + // TODO(fdiasmor): Slice with custom batches, test OMP std::vector remainder(IPCL_CRYPTO_MB_SIZE); remainder = heQatBnModExp(base, pow, m); return remainder; From d77a01974b7849bf3918c20e2b924e3f2d49d01d Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 4 May 2022 19:59:45 -0700 Subject: [PATCH 174/364] Add multi-threading testing sample. --- samples/test_bnModExp_MT.cpp | 297 +++++++++++++++++++++++++++++++++++ 1 file changed, 297 insertions(+) create mode 100644 samples/test_bnModExp_MT.cpp diff --git a/samples/test_bnModExp_MT.cpp b/samples/test_bnModExp_MT.cpp new file mode 100644 index 0000000..115eac2 --- /dev/null +++ b/samples/test_bnModExp_MT.cpp @@ -0,0 +1,297 @@ + +#include "he_qat_misc.h" +#include "he_qat_utils.h" +#include "he_qat_bn_ops.h" +#include "he_qat_context.h" +#include "cpa_sample_utils.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef _DESTINY_DEBUG_VERBOSE +int gDebugParam = 1; +#endif + +const unsigned int BATCH_SIZE = 2048; + +using namespace std::chrono; + +int main(int argc, const char** argv) { + const int bit_length = 4096; + const size_t num_trials = 10000; + + double avg_speed_up = 0.0; + double ssl_avg_time = 0.0; + double qat_avg_time = 0.0; + + // clock_t start = CLOCKS_PER_SEC; + // clock_t ssl_elapsed = CLOCKS_PER_SEC; + // clock_t qat_elapsed = CLOCKS_PER_SEC; + + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + // Set up QAT runtime context + acquire_qat_devices(); + + // Set up OpenSSL context (as baseline) + BN_CTX* ctx = BN_CTX_new(); + BN_CTX_start(ctx); + + int nthreads = 2; + for (unsigned int mod = 0; mod < num_trials; mod++) { + // Generate modulus number + BIGNUM* bn_mod = generateTestBNData(bit_length); + + if (!bn_mod) continue; + + char* bn_str = BN_bn2hex(bn_mod); +#ifdef _DESTINY_DEBUG_VERBOSE + printf("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, + BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); +#endif + OPENSSL_free(bn_str); + + // Generate exponent in [0..bn_mod] + BIGNUM* bn_exponent = BN_new(); + if (!BN_rand_range(bn_exponent, bn_mod)) { + BN_free(bn_mod); + continue; + } + + // Generate base number + BIGNUM* bn_base = generateTestBNData(bit_length); + + // Perform OpenSSL ModExp Op + BIGNUM* ssl_res = BN_new(); + auto start = high_resolution_clock::now(); + // start = clock(); + BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); + auto stop = high_resolution_clock::now(); + auto ssl_duration = duration_cast(stop - start); + // ssl_elapsed = clock() - start; + + int len_ = (bit_length + 7) >> 3; + + // Start QAT timer (including data conversion overhead) + // start = clock(); + start = high_resolution_clock::now(); + unsigned char* bn_base_data_ = + (unsigned char*)calloc(len_, sizeof(unsigned char)); + if (NULL == bn_base_data_) exit(1); + BN_bn2binpad(bn_base, bn_base_data_, len_); + unsigned char* bn_mod_data_ = + (unsigned char*)calloc(len_, sizeof(unsigned char)); + if (NULL == bn_mod_data_) exit(1); + BN_bn2binpad(bn_mod, bn_mod_data_, len_); + unsigned char* bn_exponent_data_ = + (unsigned char*)calloc(len_, sizeof(unsigned char)); + if (NULL == bn_exponent_data_) exit(1); + BN_bn2binpad(bn_exponent, bn_exponent_data_, len_); + unsigned char* bn_remainder_data_ = + (unsigned char*)calloc(nthreads * len_, sizeof(unsigned char)); + if (NULL == bn_remainder_data_) exit(1); + stop = high_resolution_clock::now(); + auto cvt_duration = duration_cast(stop - start); + // clock_t cvt_elapsed = clock() - start; + + // Simulate input number in BigNumber representation + BigNumber big_num_base((Ipp32u)0); + BigNumber big_num_mod((Ipp32u)0); + BigNumber big_num_exponent((Ipp32u)0); + status = binToBigNumber(big_num_base, bn_base_data_, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("Failed at binToBigNumber()\n"); + exit(1); + } + status = binToBigNumber(big_num_mod, bn_mod_data_, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("Failed at binToBigNumber()\n"); + exit(1); + } + status = + binToBigNumber(big_num_exponent, bn_exponent_data_, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("Failed at binToBigNumber()\n"); + exit(1); + } + + // Reset numbers to 0 + memset(bn_base_data_, 0, len_); + memset(bn_mod_data_, 0, len_); + memset(bn_exponent_data_, 0, len_); + // Make sure variables are reset + if (memcmp(bn_base_data_, bn_mod_data_, len_) || + memcmp(bn_base_data_, bn_exponent_data_, len_)) { + PRINT_ERR("Pointers are not reset to zero!"); + exit(1); + } + + // start = clock(); + start = high_resolution_clock::now(); + status = bigNumberToBin(bn_base_data_, bit_length, big_num_base); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("bn_base_data_: failed at bignumbertobin()\n"); + exit(1); + } + status = bigNumberToBin(bn_mod_data_, bit_length, big_num_mod); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("bn_base_data_: failed at bignumbertobin()\n"); + exit(1); + } + status = + bigNumberToBin(bn_exponent_data_, bit_length, big_num_exponent); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("bn_base_data_: failed at bignumbertobin()\n"); + exit(1); + } + // cvt_elapsed += (clock() - start); + cvt_duration += + duration_cast(high_resolution_clock::now() - start); + + omp_set_num_threads(nthreads); + + // Perform BigNumber modular exponentiation on QAT + start = high_resolution_clock::now(); + +#pragma omp parallel private(status) +{ + int thread_id = omp_get_thread_num(); + unsigned int buffer_id = thread_id; + + // Secure one of the distributed outstanding buffers + status = acquire_bnModExp_buffer(&buffer_id); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("Error: acquire_bnModExp_buffer()\n"); + exit(1); + } +#ifdef HE_QAT_DEBUG + printf("Thread #%d HE QAT ACQUIRED BUFFER ID: %u\n",thread_id,buffer_id); +#endif + // Divide work among threads + unsigned int worksize = BATCH_SIZE/nthreads; + unsigned int begin = thread_id*worksize; + unsigned int end = begin + worksize; + +#ifdef HE_QAT_DEBUG + printf("Thread #%d Begin: %u End: %u\n",thread_id,begin,end); +#endif + + // For local thread, schedule work execution + for (unsigned int b = begin; b < end; b++) + status = HE_QAT_bnModExp_MT(buffer_id, bn_remainder_data_ + thread_id*len_, + bn_base_data_, bn_exponent_data_, bn_mod_data_, bit_length); + +#ifdef HE_QAT_DEBUG + printf("Thread #%d Waiting\n",thread_id); +#endif + + // Wait for the request to complete + release_bnModExp_buffer(buffer_id, BATCH_SIZE/nthreads); + +#ifdef HE_QAT_DEBUG + printf("Thread #%d Completed\n",thread_id); +#endif +} // pragma omp parallel + + stop = high_resolution_clock::now(); + auto qat_duration = duration_cast(stop - start); + + ssl_avg_time = + (mod * ssl_avg_time + ((double)(ssl_duration.count()))) / (mod + 1); + qat_avg_time = (mod * qat_avg_time + + ((double)(qat_duration.count())) / BATCH_SIZE) / + (mod + 1); + avg_speed_up = (mod * avg_speed_up + + (ssl_duration.count() / + (double)(qat_duration.count() / BATCH_SIZE))) / + (mod + 1); + // qat_elapsed = clock() - start; + + // printf("BigNumber data conversion overhead: %.1lfus.\n", + // (cvt_elapsed / (CLOCKS_PER_SEC / 1000000.0))); + // printf("BigNumber modular exponentiation on QAT: %.1lfus.\n", + // (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); + // qat_elapsed += cvt_elapsed; + printf("Request #%u\t", mod + 1); + printf("Overhead: %.1luus", cvt_duration.count()); + printf("\tOpenSSL: %.1lfus", ssl_avg_time); + printf("\tQAT: %.1lfus", qat_avg_time); + printf("\tSpeed-up: %.1lfx", avg_speed_up); + // qat_elapsed += cvt_elapsed; + + BIGNUM* qat_res = BN_new(); + BN_bin2bn(bn_remainder_data_, len_, qat_res); + + if (HE_QAT_STATUS_SUCCESS != status) { + PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); + } +#ifdef _DESTINY_DEBUG_VERBOSE + else { + PRINT_DBG("\nQAT bnModExpOp finished\n"); + } +#endif + + // start = clock(); + BigNumber big_num((Ipp32u)0); + status = binToBigNumber(big_num, bn_remainder_data_, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("bn_remainder_data_: Failed at bigNumberToBin()\n"); + exit(1); + } + // qat_elapsed += (clock() - start); + // printf("BigNumber ModExp total time: %.1lfus.\n", + // (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); + +#ifdef _DESTINY_DEBUG_VERBOSE + bn_str = BN_bn2hex(qat_res); + printf("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, + BN_num_bytes(qat_res), BN_num_bits(qat_res)); +#endif + +#ifdef _DESTINY_DEBUG_VERBOSE + int bit_len = 0; + ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); + std::string str; + big_num.num2hex(str); + printf("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, + bit_len); + printf( + "---------------------################-----------------------\n"); +#endif + + if (BN_cmp(qat_res, ssl_res) != 0) + printf("\t** FAIL **\n"); + else + printf("\t** PASS **\n"); + + BN_free(bn_mod); + BN_free(bn_base); + BN_free(bn_exponent); + BN_free(qat_res); + BN_free(ssl_res); + + // OPENSSL_free(bn_str); + + free(bn_mod_data_); + free(bn_base_data_); + free(bn_exponent_data_); + free(bn_remainder_data_); + +// break; + } + + // Tear down OpenSSL context + BN_CTX_end(ctx); + + // Tear down QAT runtime context + release_qat_devices(); + + return (int)status; +} From 6723d24473d96bd74f274ed167f49a3afec38e8e Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Thu, 5 May 2022 17:02:17 -0700 Subject: [PATCH 175/364] set DJN function added to development --- ipcl/include/ipcl/pub_key.hpp | 10 ++++++++++ ipcl/pub_key.cpp | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp index 9f9c9b5..621fa05 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -38,6 +38,16 @@ class PublicKey { */ void enableDJN(); + /** + * Set DJN with given parameters + * @param[in] hs hs value for DJN scheme + * @param[in] randbit random bit for DJN scheme + */ + void setDJN(const BigNumber& hs, int randbit) { + m_hs = hs; + m_randbits = randbit; + } + /** * Encrypt plaintext * @param[in] plaintext of type PlainText diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index 5ebb419..5e92b08 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -166,4 +166,12 @@ CipherText PublicKey::encrypt(const PlainText& pt, bool make_secure) const { ct_bn_v = raw_encrypt(pt.getTexts(), make_secure); return CipherText(this, ct_bn_v); } + +void PublicKey::setDJN(const BigNumber& hs, int randbit) { + if (m_enable_DJN) return; + + m_hs = hs; + m_randbits = randbit; + m_enable_DJN = true; +} } // namespace ipcl From 1c4d041dfbfbdb2822ab3aed61034fe13305f52e Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Thu, 5 May 2022 17:42:23 -0700 Subject: [PATCH 176/364] Fix dJN bug --- ipcl/include/ipcl/pub_key.hpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp index 621fa05..ac17ade 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -43,10 +43,7 @@ class PublicKey { * @param[in] hs hs value for DJN scheme * @param[in] randbit random bit for DJN scheme */ - void setDJN(const BigNumber& hs, int randbit) { - m_hs = hs; - m_randbits = randbit; - } + void setDJN(const BigNumber& hs, int randbit); /** * Encrypt plaintext From 5d4c508e5a2f10a4865fa415593e2fe309c64f5b Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Thu, 5 May 2022 17:53:30 -0700 Subject: [PATCH 177/364] Added m_enableDJN getter --- ipcl/include/ipcl/pub_key.hpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp index ac17ade..a5d7328 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -85,12 +85,17 @@ class PublicKey { void applyObfuscator(std::vector& obfuscator) const; /** - * @brief Set the Random object for ISO/IEC 18033-6 compliance check - * - * @param r + * Set the Random object for ISO/IEC 18033-6 compliance check + * @param[in] r */ void setRandom(const std::vector& r); + /** + * Check if using DJN scheme + * @return boolean output + */ + bool isDJN() const { return m_enable_DJN; } + const void* addr = static_cast(this); private: From 23bec824a5018385b728888764a8fc2687c3aa84 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Thu, 5 May 2022 18:08:09 -0700 Subject: [PATCH 178/364] Added getters for hs and randbits for DJN scheme --- ipcl/include/ipcl/pub_key.hpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp index a5d7328..b40b7fd 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -92,10 +92,25 @@ class PublicKey { /** * Check if using DJN scheme - * @return boolean output */ bool isDJN() const { return m_enable_DJN; } + /** + * Get hs for DJN scheme + */ + BigNumber getHS() const { + if (m_enable_DJN) return m_hs; + return BigNumber::Zero(); + } + + /** + * Get randbits for DJN scheme + */ + int getRandBits() const { + if (m_enable_DJN) return m_randbits; + return -1; + } + const void* addr = static_cast(this); private: From de0134aa0bd696fc499cd922351c9eaee6dc3a39 Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Tue, 10 May 2022 02:31:42 +0800 Subject: [PATCH 179/364] Add operators/functions to PlainText&BaseText (#94) * add support for PT+CT and PT*CT * add unit tests for PT+CT, PT*CT * add container modification functions to BaseText * Modify getPubKey() in CipherText * Added error check for encrypt/decrypt on empty plaintext/ciphertexts Co-authored-by: Sejun Kim --- ipcl/base_text.cpp | 36 +++++- ipcl/ciphertext.cpp | 2 +- ipcl/include/ipcl/base_text.hpp | 24 ++++ ipcl/include/ipcl/ciphertext.hpp | 2 +- ipcl/include/ipcl/plaintext.hpp | 12 ++ ipcl/plaintext.cpp | 9 ++ ipcl/pri_key.cpp | 4 +- ipcl/pub_key.cpp | 1 + test/test_ops.cpp | 198 +++++++++++++++++++++++++++++++ 9 files changed, 282 insertions(+), 6 deletions(-) diff --git a/ipcl/base_text.cpp b/ipcl/base_text.cpp index e4e43c5..4a1b0a6 100644 --- a/ipcl/base_text.cpp +++ b/ipcl/base_text.cpp @@ -34,14 +34,44 @@ BaseText& BaseText::operator=(const BaseText& other) { return *this; } +BigNumber& BaseText::operator[](const std::size_t idx) { + ERROR_CHECK(idx < m_size, "BaseText:operator[] index is out of range"); + + return m_texts[idx]; +} + +void BaseText::insert(const std::size_t pos, BigNumber& bn) { + ERROR_CHECK((pos >= 0) && (pos <= m_size), + "BaseText: insert position is out of range"); + + auto it = m_texts.begin() + pos; + m_texts.insert(it, bn); + m_size++; +} + +void BaseText::clear() { + m_texts.clear(); + m_size = 0; +} + +void BaseText::remove(const std::size_t pos, const std::size_t length) { + ERROR_CHECK((pos >= 0) && (pos + length < m_size), + "BaseText: remove position is out of range"); + + auto start = m_texts.begin() + pos; + auto end = start + length; + m_texts.erase(start, end); + m_size = m_size - length; +} + BigNumber BaseText::getElement(const std::size_t& idx) const { - ERROR_CHECK(idx <= m_size, "BaseText: getElement index is out of range"); + ERROR_CHECK(idx < m_size, "BaseText: getElement index is out of range"); return m_texts[idx]; } std::vector BaseText::getElementVec(const std::size_t& idx) const { - ERROR_CHECK(idx <= m_size, "BaseText: getElementVec index is out of range"); + ERROR_CHECK(idx < m_size, "BaseText: getElementVec index is out of range"); std::vector v; m_texts[idx].num2vec(v); @@ -50,7 +80,7 @@ std::vector BaseText::getElementVec(const std::size_t& idx) const { } std::string BaseText::getElementHex(const std::size_t& idx) const { - ERROR_CHECK(idx <= m_size, "BaseText: getElementHex index is out of range"); + ERROR_CHECK(idx < m_size, "BaseText: getElementHex index is out of range"); std::string s; m_texts[idx].num2hex(s); diff --git a/ipcl/ciphertext.cpp b/ipcl/ciphertext.cpp index 44c898b..b0358eb 100644 --- a/ipcl/ciphertext.cpp +++ b/ipcl/ciphertext.cpp @@ -103,7 +103,7 @@ CipherText CipherText::operator*(const PlainText& other) const { } } -PublicKey CipherText::getPubKey() const { return *m_pubkey; } +const PublicKey* CipherText::getPubKey() const { return m_pubkey; } CipherText CipherText::rotate(int shift) const { ERROR_CHECK(m_size != 1, "rotate: Cannot rotate single CipherText"); diff --git a/ipcl/include/ipcl/base_text.hpp b/ipcl/include/ipcl/base_text.hpp index daeac2c..8c027b4 100644 --- a/ipcl/include/ipcl/base_text.hpp +++ b/ipcl/include/ipcl/base_text.hpp @@ -34,6 +34,30 @@ class BaseText { */ BaseText& operator=(const BaseText& other); + /** + * Overloading [] operator to access BigNumber elements + */ + BigNumber& operator[](const std::size_t idx); + + /** + * Insert a big number before pos + * @param[in] pos Position in m_texts + * @bn[in] Big number need to be inserted + */ + void insert(const std::size_t pos, BigNumber& bn); + + /** + * Clear all big number element + */ + void clear(); + + /** + * Remove big number element for pos to pos+length. + * @param[in] pos Position in m_texts + * @length[in] Length need to be removed(default value is 1) + */ + void remove(const std::size_t pos, const std::size_t length = 1); + /** * Gets the specified BigNumber element in m_text * @param[in] idx Element index diff --git a/ipcl/include/ipcl/ciphertext.hpp b/ipcl/include/ipcl/ciphertext.hpp index 2b46966..0dcb337 100644 --- a/ipcl/include/ipcl/ciphertext.hpp +++ b/ipcl/include/ipcl/ciphertext.hpp @@ -44,7 +44,7 @@ class CipherText : public BaseText { /** * Get public key */ - PublicKey getPubKey() const; + const PublicKey* getPubKey() const; /** * Rotate CipherText diff --git a/ipcl/include/ipcl/plaintext.hpp b/ipcl/include/ipcl/plaintext.hpp index 2e8ef99..fcdb49d 100644 --- a/ipcl/include/ipcl/plaintext.hpp +++ b/ipcl/include/ipcl/plaintext.hpp @@ -9,6 +9,8 @@ #include "ipcl/base_text.hpp" namespace ipcl { + +class CipherText; /** * This structure encapsulates types uint32_t, * uint32_t vector, BigNumber and BigNumber vector. @@ -58,6 +60,16 @@ class PlainText : public BaseText { */ operator std::vector(); + /** + * PT + CT + */ + CipherText operator+(const CipherText& other) const; + + /** + * PT * CT + */ + CipherText operator*(const CipherText& other) const; + /** * User define implicit type conversion * Convert 1st element to type BigNumber. diff --git a/ipcl/plaintext.cpp b/ipcl/plaintext.cpp index 8c447c8..4e4498d 100644 --- a/ipcl/plaintext.cpp +++ b/ipcl/plaintext.cpp @@ -5,6 +5,7 @@ #include +#include "ipcl/ciphertext.hpp" #include "ipcl/util.hpp" namespace ipcl { @@ -25,6 +26,14 @@ PlainText& PlainText::operator=(const PlainText& other) { return *this; } +CipherText PlainText::operator+(const CipherText& other) const { + return other.operator+(*this); +} + +CipherText PlainText::operator*(const CipherText& other) const { + return other.operator*(*this); +} + PlainText::operator std::vector() { ERROR_CHECK(m_size > 0, "PlainText: type conversion to uint32_t vector error"); diff --git a/ipcl/pri_key.cpp b/ipcl/pri_key.cpp index 3d8c80c..cbcace5 100644 --- a/ipcl/pri_key.cpp +++ b/ipcl/pri_key.cpp @@ -54,10 +54,12 @@ PrivateKey::PrivateKey(const PublicKey* public_key, const BigNumber& p, } PlainText PrivateKey::decrypt(const CipherText& ct) const { - ERROR_CHECK(ct.getPubKey().getN() == m_pubkey->getN(), + ERROR_CHECK(ct.getPubKey()->getN() == m_pubkey->getN(), "decrypt: The value of N in public key mismatch."); std::size_t ct_size = ct.getSize(); + ERROR_CHECK(ct_size > 0, "decrypt: Cannot decrypt empty CipherText"); + std::vector pt_bn(ct_size); std::vector ct_bn = ct.getTexts(); diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index 5e92b08..512b6ad 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -161,6 +161,7 @@ std::vector PublicKey::raw_encrypt(const std::vector& pt, CipherText PublicKey::encrypt(const PlainText& pt, bool make_secure) const { std::size_t pt_size = pt.getSize(); + ERROR_CHECK(pt_size > 0, "encrypt: Cannot encrypt emtpy PlainText"); std::vector ct_bn_v(pt_size); ct_bn_v = raw_encrypt(pt.getTexts(), make_secure); diff --git a/test/test_ops.cpp b/test/test_ops.cpp index 6bb9c4e..30ad188 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -87,6 +87,44 @@ void AddSub(ipcl::CipherText& res, const ipcl::CipherText& ct1, res = ipcl::CipherText(key.pub_key, sum_bn_v); } +void PtPlusCt(ipcl::CipherText& res, const ipcl::PlainText& pt2, + const ipcl::CipherText& ct1, const ipcl::keyPair key) { + int size = ct1.getSize(); + std::vector sum_bn_v(size); + + for (int i = 0; i < size; i++) { + ipcl::CipherText a(key.pub_key, ct1.getElement(i)); + ipcl::PlainText b(pt2.getElement(i)); + ipcl::CipherText sum = b + a; + sum_bn_v[i] = sum.getElement(0); + } + res = ipcl::CipherText(key.pub_key, sum_bn_v); +} + +void PtPlusCtArray(ipcl::CipherText& res, const ipcl::PlainText& pt2, + const ipcl::CipherText& ct1, const ipcl::keyPair key) { + res = pt2 + ct1; +} + +void PtMultiplyCt(ipcl::CipherText& res, const ipcl::PlainText& pt2, + const ipcl::CipherText& ct1, const ipcl::keyPair key) { + int size = ct1.getSize(); + std::vector product_bn_v(size); + + for (int i = 0; i < size; i++) { + ipcl::CipherText a(key.pub_key, ct1.getElement(i)); + ipcl::PlainText b(pt2.getElement(i)); + ipcl::CipherText product = b * a; + product_bn_v[i] = product.getElement(0); + } + res = ipcl::CipherText(key.pub_key, product_bn_v); +} + +void PtMultiplyCtArray(ipcl::CipherText& res, const ipcl::PlainText& pt2, + const ipcl::CipherText& ct1, const ipcl::keyPair key) { + res = pt2 * ct1; +} + TEST(OperationTest, CtPlusCtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; @@ -410,3 +448,163 @@ TEST(OperationTest, AddSubTest) { delete key.pub_key; delete key.priv_key; } + +TEST(OperationTest, PtPlusCtTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + + ipcl::keyPair key = ipcl::generateKeypair(2048); + + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_sum; + ipcl::CipherText ct1, ct2, ct_sum; + + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); + } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); + + ct1 = key.pub_key->encrypt(pt1); + + PtPlusCt(ct_sum, pt2, ct1, key); + + dt_sum = key.priv_key->decrypt(ct_sum); + + for (int i = 0; i < num_values; i++) { + std::vector v = dt_sum.getElementVec(i); + uint64_t sum = v[0]; + if (v.size() > 1) sum = ((uint64_t)v[1] << 32) | v[0]; + + uint64_t exp_sum = (uint64_t)exp_value1[i] + (uint64_t)exp_value2[i]; + + EXPECT_EQ(sum, exp_sum); + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, PtPlusCtArrayTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + + ipcl::keyPair key = ipcl::generateKeypair(2048); + + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_sum; + ipcl::CipherText ct1, ct2, ct_sum; + + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); + } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); + + ct1 = key.pub_key->encrypt(pt1); + + PtPlusCtArray(ct_sum, pt2, ct1, key); + + dt_sum = key.priv_key->decrypt(ct_sum); + + for (int i = 0; i < num_values; i++) { + std::vector v = dt_sum.getElementVec(i); + uint64_t sum = v[0]; + if (v.size() > 1) sum = ((uint64_t)v[1] << 32) | v[0]; + + uint64_t exp_sum = (uint64_t)exp_value1[i] + (uint64_t)exp_value2[i]; + + EXPECT_EQ(sum, exp_sum); + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, PtMultiplyCtTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + + ipcl::keyPair key = ipcl::generateKeypair(2048); + + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_product; + ipcl::CipherText ct1, ct2, ct_product; + + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); + } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); + + ct1 = key.pub_key->encrypt(pt1); + + PtMultiplyCt(ct_product, pt2, ct1, key); + + dt_product = key.priv_key->decrypt(ct_product); + + for (int i = 0; i < num_values; i++) { + std::vector v = dt_product.getElementVec(i); + uint64_t product = v[0]; + if (v.size() > 1) product = ((uint64_t)v[1] << 32) | v[0]; + + uint64_t exp_product = (uint64_t)exp_value1[i] * (uint64_t)exp_value2[i]; + + EXPECT_EQ(product, exp_product); + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, PtMultiplyCtArrayTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + + ipcl::keyPair key = ipcl::generateKeypair(2048); + + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_product; + ipcl::CipherText ct1, ct2, ct_product; + + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); + } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); + + ct1 = key.pub_key->encrypt(pt1); + + PtMultiplyCtArray(ct_product, pt2, ct1, key); + + dt_product = key.priv_key->decrypt(ct_product); + + for (int i = 0; i < num_values; i++) { + std::vector v = dt_product.getElementVec(i); + uint64_t product = v[0]; + if (v.size() > 1) product = ((uint64_t)v[1] << 32) | v[0]; + + uint64_t exp_product = (uint64_t)exp_value1[i] * (uint64_t)exp_value2[i]; + + EXPECT_EQ(product, exp_product); + } + + delete key.pub_key; + delete key.priv_key; +} From c13e0ec4511a63d4b8d7384054b99b8435caa636 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Tue, 10 May 2022 12:25:03 -0700 Subject: [PATCH 180/364] Fixed rotate negative size_t bug --- ipcl/ciphertext.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ipcl/ciphertext.cpp b/ipcl/ciphertext.cpp index b0358eb..7e8150f 100644 --- a/ipcl/ciphertext.cpp +++ b/ipcl/ciphertext.cpp @@ -107,10 +107,10 @@ const PublicKey* CipherText::getPubKey() const { return m_pubkey; } CipherText CipherText::rotate(int shift) const { ERROR_CHECK(m_size != 1, "rotate: Cannot rotate single CipherText"); - ERROR_CHECK(shift >= -m_size && shift <= m_size, + ERROR_CHECK(shift >= (-1) * static_cast(m_size) && shift <= m_size, "rotate: Cannot shift more than the test size"); - if (shift == 0 || shift == m_size || shift == -m_size) + if (shift == 0 || shift == m_size || shift == (-1) * static_cast(m_size)) return CipherText(m_pubkey, m_texts); if (shift > 0) From 738b4eefb646e9f9f9615c3bf55857408c4bc6fc Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Thu, 19 May 2022 09:39:33 +0800 Subject: [PATCH 181/364] Remove seed from pub key getRandom function (#98) --- ipcl/pub_key.cpp | 36 ++++++++---------------------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index 512b6ad..b4fe94f 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -45,44 +45,24 @@ std::vector PublicKey::randIpp32u(int size) const { } // length is arbitrary -BigNumber PublicKey::getRandom(int length) const { +BigNumber PublicKey::getRandom(int bit_len) const { IppStatus stat; - int size; - constexpr int seedBitSize = 160; - constexpr int seedSize = BITSIZE_WORD(seedBitSize); - - stat = ippsPRNGGetSize(&size); - ERROR_CHECK(stat == ippStsNoErr, - "getRandom: get IppsPRNGState context error."); - - auto rands = std::vector(size); - - stat = - ippsPRNGInit(seedBitSize, reinterpret_cast(rands.data())); - ERROR_CHECK(stat == ippStsNoErr, "getRandom: init rand context error."); - - auto seed = randIpp32u(seedSize); - BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); - - stat = ippsPRNGSetSeed(BN(bseed), - reinterpret_cast(rands.data())); - ERROR_CHECK(stat == ippStsNoErr, "getRandom: set up seed value error."); + int bn_buf_size; // define length Big Numbers - int bn_size = BITSIZE_WORD(length); - stat = ippsBigNumGetSize(bn_size, &size); + int bn_len = BITSIZE_WORD(bit_len); + stat = ippsBigNumGetSize(bn_len, &bn_buf_size); ERROR_CHECK(stat == ippStsNoErr, "getRandom: get IppsBigNumState context error."); - IppsBigNumState* pBN = reinterpret_cast(alloca(size)); + IppsBigNumState* pBN = + reinterpret_cast(alloca(bn_buf_size)); ERROR_CHECK(pBN != nullptr, "getRandom: big number alloca error"); - stat = ippsBigNumInit(bn_size, pBN); + stat = ippsBigNumInit(bn_len, pBN); ERROR_CHECK(stat == ippStsNoErr, "getRandom: init big number context error."); - int bnBitSize = length; - ippsPRNGenRDRAND_BN(pBN, bnBitSize, - reinterpret_cast(rands.data())); + ippsPRNGenRDRAND_BN(pBN, bit_len, NULL); return BigNumber{pBN}; } From 369b81fad296c730730101335f1692339ef3876b Mon Sep 17 00:00:00 2001 From: fdiasmor Date: Mon, 23 May 2022 13:43:24 -0700 Subject: [PATCH 182/364] Custom batch size support for QAT mod exp (#100) * WIP: custom batch size support - phase 2 * WIP: support variable-bitsize base and exponent * WIP: provide more robust QAT support to custom batch size * WIP: Fix segfault on QAT lite version * Functional custom-adaptive batch size support for QAT mod exp. * Update cmake/heqat. --- CMakeLists.txt | 7 + benchmark/bench_cryptography.cpp | 4 +- benchmark/bench_ops.cpp | 2 +- cmake/heqat/heqat.cmake | 4 +- ipcl/bignum.cpp | 26 ++++ ipcl/include/ipcl/bignum.h | 1 + ipcl/mod_exp.cpp | 259 ++++++++++++++++++++++++++++++- 7 files changed, 297 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 59c7573..caa0016 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,7 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) option(IPCL_TEST "Enable testing" ON) option(IPCL_BENCHMARK "Enable benchmark" ON) option(IPCL_ENABLE_QAT "Enable QAT" OFF) +option(IPCL_USE_QAT_LITE "Enable uses QAT for base and exponent length different than modulus" OFF) option(IPCL_ENABLE_OMP "Enable OpenMP testing/benchmarking" ON) option(IPCL_DOCS "Enable document building" OFF) option(IPCL_SHARED "Build shared library" ON) @@ -61,6 +62,12 @@ if(IPCL_ENABLE_QAT) add_compile_definitions(IPCL_USE_QAT) message(STATUS "QAT enabled - IPCL_ENABLE_OMP set to OFF") set(IPCL_ENABLE_OMP OFF) + if(IPCL_USE_QAT_LITE) + add_compile_definitions(IPCL_USE_QAT_LITE) + message(STATUS "QAT Lite enabled - IPCL_USE_QAT_LITE set to ON") + else() + message(STATUS "QAT Lite disabled - IPCL_USE_QAT_LITE set to OFF") + endif() endif() if(IPCL_ENABLE_OMP) diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index 2a96750..31cf04f 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -31,7 +31,7 @@ static void BM_Encrypt(benchmark::State& state) { for (auto _ : state) ct = key.pub_key->encrypt(pt); } -BENCHMARK(BM_Encrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); +BENCHMARK(BM_Encrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64})->Args({128})->Args({256})->Args({512})->Args({1024})->Args({2048})->Args({2100}); static void BM_Decrypt(benchmark::State& state) { size_t dsize = state.range(0); @@ -48,4 +48,4 @@ static void BM_Decrypt(benchmark::State& state) { for (auto _ : state) dt = key.priv_key->decrypt(ct); } -BENCHMARK(BM_Decrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); +BENCHMARK(BM_Decrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64})->Args({128})->Args({256})->Args({512})->Args({1024})->Args({2048})->Args({2100}); diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index 452d777..ac944df 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -74,4 +74,4 @@ static void BM_Mul_CTPT(benchmark::State& state) { for (auto _ : state) product = ct1 * pt2; } -BENCHMARK(BM_Mul_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); +BENCHMARK(BM_Mul_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64})->Args({128})->Args({256})->Args({512})->Args({1024})->Args({2048})->Args({2100}); diff --git a/cmake/heqat/heqat.cmake b/cmake/heqat/heqat.cmake index 53a2654..c7c4286 100644 --- a/cmake/heqat/heqat.cmake +++ b/cmake/heqat/heqat.cmake @@ -5,7 +5,9 @@ include(ExternalProject) MESSAGE(STATUS "Configuring HE QAT") set(HEQAT_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_he_qat) set(HEQAT_GIT_REPO_URL git@github.com:intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.project-destiny.git) -set(HEQAT_GIT_LABEL development) +#set(HEQAT_GIT_REPO_URL https://github.com/intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.project-destiny.git) +#set(HEQAT_GIT_LABEL development) +set(HEQAT_GIT_LABEL fdiasmor/modexp_latency) set(HEQAT_SRC_DIR ${HEQAT_PREFIX}/src/ext_he_qat/) set(HEQAT_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS}") diff --git a/ipcl/bignum.cpp b/ipcl/bignum.cpp index 4fd3bf3..0f7768b 100644 --- a/ipcl/bignum.cpp +++ b/ipcl/bignum.cpp @@ -19,6 +19,8 @@ #include #include +#include + ////////////////////////////////////////////////////////////////////// // // BigNumber @@ -537,3 +539,27 @@ bool BigNumber::toBin(unsigned char* data, int len, const BigNumber& bn) { return true; } + +bool BigNumber::toBin(unsigned char** bin, int *len, const BigNumber& bn) +{ + if (NULL == bin) return false; + if (NULL == len) return false; + + // Extract raw vector of data in little endian format + int bitSize = 0; + Ipp32u* ref_bn_data_ = NULL; + ippsRef_BN(NULL, &bitSize, &ref_bn_data_, BN(bn)); + + // Revert it to big endian format + int bitSizeLen = BITSIZE_WORD(bitSize) * 4; + *len = bitSizeLen; + bin[0] = reinterpret_cast(malloc(bitSizeLen*sizeof(unsigned char))); + memset(bin[0],0,*len); + if(NULL == bin[0]) return false; + + unsigned char* data_out = bin[0]; + unsigned char* bn_data_ = reinterpret_cast(ref_bn_data_); + for (int i = 0; i < bitSizeLen; i++) data_out[bitSizeLen - 1 - i] = bn_data_[i]; + + return true; +} diff --git a/ipcl/include/ipcl/bignum.h b/ipcl/include/ipcl/bignum.h index efe2245..e07d393 100644 --- a/ipcl/include/ipcl/bignum.h +++ b/ipcl/include/ipcl/bignum.h @@ -125,6 +125,7 @@ class BigNumber { // Support QAT data format static bool fromBin(BigNumber& bn, const unsigned char* data, int len); static bool toBin(unsigned char* data, int len, const BigNumber& bn); + static bool toBin(unsigned char** data, int *len, const BigNumber& bn); protected: bool create(const Ipp32u* pData, int length, diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index 65b6346..2df24ab 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -20,6 +20,259 @@ namespace ipcl { #ifdef IPCL_USE_QAT +// Multiple input QAT ModExp interface to offload computation to QAT +static std::vector heQatBnModExp( + const std::vector& base, const std::vector& exponent, + const std::vector& modulus, unsigned int batch_size) { + static unsigned int counter = 0; + int nbits = modulus.front().BitSize(); + int length = BITSIZE_WORD(nbits) * 4; + nbits = 8 * length; + + // Check if QAT Exec Env supports requested batch size + unsigned int worksize = base.size(); + unsigned int nslices = worksize / batch_size; + unsigned int residue = worksize % batch_size; + + if (0 == nslices) { + nslices = 1; + residue = 0; + batch_size = worksize; + } + + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + // TODO(fdiasmor): Try replace calloc by alloca to see impact on performance. + unsigned char* bn_base_data_[batch_size]; + unsigned char* bn_exponent_data_[batch_size]; + unsigned char* bn_modulus_data_[batch_size]; + unsigned char* bn_remainder_data_[batch_size]; + +#if defined(IPCL_USE_QAT_LITE) + int base_len_[batch_size]; + int exp_len_[batch_size]; +#endif + + // Pre-allocate memory used to batch input data + for (int i = 0; i < batch_size; i++) { +#if !defined(IPCL_USE_QAT_LITE) + bn_base_data_[i] = reinterpret_cast( + malloc(length * sizeof(unsigned char))); + bn_exponent_data_[i] = reinterpret_cast( + malloc(length * sizeof(unsigned char))); +#endif + + bn_modulus_data_[i] = reinterpret_cast( + malloc(length * sizeof(unsigned char))); + bn_remainder_data_[i] = reinterpret_cast( + malloc(length * sizeof(unsigned char))); + +#if !defined(IPCL_USE_QAT_LITE) + ERROR_CHECK( + bn_base_data_[i] != nullptr && bn_exponent_data_[i] != nullptr && + bn_modulus_data_[i] != nullptr && bn_remainder_data_[i] != nullptr, + "qatMultiBuffExp: alloc memory for error"); +#else + ERROR_CHECK( + bn_modulus_data_[i] != nullptr && bn_remainder_data_[i] != nullptr, + "qatMultiBuffExp: alloc memory for error"); +#endif + } // End preparing input containers + + // Container to hold total number of outputs to be returned + std::vector remainder(worksize, 0); + + for (unsigned int j = 0; j < nslices; j++) { + // Prepare batch of input data + for (unsigned int i = 0; i < batch_size; i++) { + bool ret = false; + +#if !defined(IPCL_USE_QAT_LITE) + memset(bn_base_data_[i], 0, length); + memset(bn_exponent_data_[i], 0, length); + memset(bn_modulus_data_[i], 0, length); + memset(bn_remainder_data_[i], 0, length); + + ret = + BigNumber::toBin(bn_base_data_[i], length, base[j * batch_size + i]); + if (!ret) { + printf("bn_base_data_: failed at bigNumberToBin()\n"); + exit(1); + } + + ret = BigNumber::toBin(bn_exponent_data_[i], length, + exponent[j * batch_size + i]); + if (!ret) { + printf("bn_exponent_data_: failed at bigNumberToBin()\n"); + exit(1); + } +#else + base_len_[i] = 0; + ret = BigNumber::toBin(&bn_base_data_[i], &base_len_[i], + base[j * batch_size + i]); + if (!ret) { + printf("bn_base_data_: failed at bigNumberToBin()\n"); + exit(1); + } + exp_len_[i] = 0; + ret = BigNumber::toBin(&bn_exponent_data_[i], &exp_len_[i], + exponent[j * batch_size + i]); + if (!ret) { + printf("bn_exponent_data_: failed at bigNumberToBin()\n"); + exit(1); + } +#endif + + ret = BigNumber::toBin(bn_modulus_data_[i], length, + modulus[j * batch_size + i]); + if (!ret) { + printf("bn_modulus_data_: failed at bigNumberToBin()\n"); + exit(1); + } + } // End input setup + + // Process batch of input + for (unsigned int i = 0; i < batch_size; i++) { +#if !defined(IPCL_USE_QAT_LITE) + // Assumes all inputs and the output have the same length + status = + HE_QAT_bnModExp(bn_remainder_data_[i], bn_base_data_[i], + bn_exponent_data_[i], bn_modulus_data_[i], nbits); +#else + // Base and exponent can be of variable length (for more or less) + status = HE_QAT_bnModExp_lite(bn_remainder_data_[i], bn_base_data_[i], + base_len_[i], bn_exponent_data_[i], + exp_len_[i], bn_modulus_data_[i], nbits); +#endif + if (HE_QAT_STATUS_SUCCESS != status) { + PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); + } + } + getBnModExpRequest(batch_size); + + // Collect results and pack them into BigNumber + for (unsigned int i = 0; i < batch_size; i++) { + bool ret = BigNumber::fromBin(remainder[j * batch_size + i], + bn_remainder_data_[i], length); + if (!ret) { + printf("bn_remainder_data_: failed at bignumbertobin()\n"); + exit(1); + } +#if defined(IPCL_USE_QAT_LITE) + free(bn_base_data_[i]); + bn_base_data_[i] = NULL; + free(bn_exponent_data_[i]); + bn_exponent_data_[i] = NULL; +#endif + } + } // Batch Process + + // Takes care of remaining + if (residue) { + for (unsigned int i = 0; i < residue; i++) { +#if !defined(IPCL_USE_QAT_LITE) + memset(bn_base_data_[i], 0, length); + memset(bn_exponent_data_[i], 0, length); +#endif + memset(bn_modulus_data_[i], 0, length); + memset(bn_remainder_data_[i], 0, length); + } + + for (unsigned int i = 0; i < residue; i++) { + bool ret = false; +#if !defined(IPCL_USE_QAT_LITE) + ret = BigNumber::toBin(bn_base_data_[i], length, + base[nslices * batch_size + i]); + if (!ret) { + printf("bn_base_data_: failed at bigNumberToBin()\n"); + exit(1); + } + ret = BigNumber::toBin(bn_exponent_data_[i], length, + exponent[nslices * batch_size + i]); + if (!ret) { + printf("bn_exponent_data_: failed at bigNumberToBin()\n"); + exit(1); + } +#else + base_len_[i] = 0; + ret = BigNumber::toBin(&bn_base_data_[i], &base_len_[i], + base[nslices * batch_size + i]); + if (!ret) { + printf("bn_base_data_: failed at bigNumberToBin()\n"); + exit(1); + } + exp_len_[i] = 0; + ret = BigNumber::toBin(&bn_exponent_data_[i], &exp_len_[i], + exponent[nslices * batch_size + i]); + if (!ret) { + printf("bn_exponent_data_: failed at bigNumberToBin()\n"); + exit(1); + } +#endif + + ret = BigNumber::toBin(bn_modulus_data_[i], length, + modulus[nslices * batch_size + i]); + if (!ret) { + printf("bn_modulus_data_: failed at bigNumberToBin()\n"); + exit(1); + } + } // + + for (unsigned int i = 0; i < residue; i++) { +#if !defined(IPCL_USE_QAT_LITE) + // Assumes all inputs and the output have the same length + status = + HE_QAT_bnModExp(bn_remainder_data_[i], bn_base_data_[i], + bn_exponent_data_[i], bn_modulus_data_[i], nbits); +#else + // Base and exponent can be of variable length (for more or less) + status = HE_QAT_bnModExp_lite(bn_remainder_data_[i], bn_base_data_[i], + base_len_[i], bn_exponent_data_[i], + exp_len_[i], bn_modulus_data_[i], nbits); +#endif + if (HE_QAT_STATUS_SUCCESS != status) { + PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); + } + } + getBnModExpRequest(residue); + + // Collect results and pack them into BigNumber + for (unsigned int i = 0; i < residue; i++) { + unsigned char* bn_remainder_ = bn_remainder_data_[i]; + bool ret = BigNumber::fromBin(remainder[nslices * batch_size + i], + bn_remainder_, length); + if (!ret) { + printf("residue bn_remainder_data_: failed at BigNumber::fromBin()\n"); + exit(1); + } +#if defined(IPCL_USE_QAT_LITE) + free(bn_base_data_[i]); + bn_base_data_[i] = NULL; + free(bn_exponent_data_[i]); + bn_exponent_data_[i] = NULL; +#endif + } + } + + for (unsigned int i = 0; i < batch_size; i++) { +#if !defined(IPCL_USE_QAT_LITE) + free(bn_base_data_[i]); + bn_base_data_[i] = NULL; + free(bn_exponent_data_[i]); + bn_exponent_data_[i] = NULL; +#endif + free(bn_modulus_data_[i]); + bn_modulus_data_[i] = NULL; + } + + for (unsigned int i = 0; i < batch_size; i++) { + free(bn_remainder_data_[i]); + bn_remainder_data_[i] = NULL; + } + + return remainder; +} + // Multiple input QAT ModExp interface to offload computation to QAT static std::vector heQatBnModExp( const std::vector& base, const std::vector& exponent, @@ -338,8 +591,10 @@ std::vector ippModExp(const std::vector& base, const std::vector& m) { #ifdef IPCL_USE_QAT // TODO(fdiasmor): Slice with custom batches, test OMP - std::vector remainder(IPCL_CRYPTO_MB_SIZE); - remainder = heQatBnModExp(base, pow, m); + std::size_t worksize = base.size(); + std::vector remainder(worksize); + // remainder = heQatBnModExp(base, pow, m); + remainder = heQatBnModExp(base, pow, m, 1024); return remainder; #else std::size_t v_size = base.size(); From 223f430018118850a69825b2642a373102abd004 Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Tue, 24 May 2022 04:44:59 +0800 Subject: [PATCH 183/364] specify omp thread num (#97) * specify OMP num_threads * Update readme: add a description of OMP_THREAD_LIMIT --- README.md | 2 +- ipcl/ciphertext.cpp | 4 ++-- ipcl/mod_exp.cpp | 4 ++-- ipcl/pri_key.cpp | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index ca17e85..9a7e9de 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ Then, run ```bash cmake --build build --target benchmark ``` -Setting the CMake flag ```-DIPCL_ENABLE_OMP=ON``` during configuration will automatically enable OpenMP unit-tests and benchmarks. +Setting the CMake flag ```-DIPCL_ENABLE_OMP=ON``` during configuration will automatically enable OpenMP unit-tests and benchmarks. The `OMP_THREAD_LIMIT` environment variable can be used to set the maximum number of OpenMP threads. The executables are located at `${IPCL_DIR}/build/test/unittest_ipcl` and `${IPCL_DIR}/build/benchmark/bench_ipcl`. diff --git a/ipcl/ciphertext.cpp b/ipcl/ciphertext.cpp index 7e8150f..0f57b0d 100644 --- a/ipcl/ciphertext.cpp +++ b/ipcl/ciphertext.cpp @@ -53,14 +53,14 @@ CipherText CipherText::operator+(const CipherText& other) const { if (b_size == 1) { // add vector by scalar #ifdef IPCL_USE_OMP -#pragma omp parallel for +#pragma omp parallel for num_threads(m_size) #endif // IPCL_USE_OMP for (std::size_t i = 0; i < m_size; i++) sum[i] = a.raw_add(a.m_texts[i], b.m_texts[0]); } else { // add vector by vector #ifdef IPCL_USE_OMP -#pragma omp parallel for +#pragma omp parallel for num_threads(m_size) #endif // IPCL_USE_OMP for (std::size_t i = 0; i < m_size; i++) sum[i] = a.raw_add(a.m_texts[i], b.m_texts[i]); diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index 950b388..75981d9 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -166,7 +166,7 @@ std::vector ippModExp(const std::vector& base, std::size_t remainder = v_size % IPCL_CRYPTO_MB_SIZE; #ifdef IPCL_USE_OMP -#pragma omp parallel for +#pragma omp parallel for num_threads(num_chunk) #endif // IPCL_USE_OMP for (std::size_t i = 0; i < num_chunk; i++) { auto base_start = base.begin() + i * IPCL_CRYPTO_MB_SIZE; @@ -219,7 +219,7 @@ std::vector ippModExp(const std::vector& base, #else #ifdef IPCL_USE_OMP -#pragma omp parallel for +#pragma omp parallel for num_threads(v_size) #endif // IPCL_USE_OMP for (int i = 0; i < v_size; i++) res[i] = ippSBModExp(base[i], pow[i], m[i]); return res; diff --git a/ipcl/pri_key.cpp b/ipcl/pri_key.cpp index cbcace5..f8781e1 100644 --- a/ipcl/pri_key.cpp +++ b/ipcl/pri_key.cpp @@ -83,7 +83,7 @@ void PrivateKey::decryptRAW(std::vector& plaintext, BigNumber xx = m_x; #ifdef IPCL_USE_OMP -#pragma omp parallel for +#pragma omp parallel for num_threads(v_size) #endif // IPCL_USE_OMP for (int i = 0; i < v_size; i++) { BigNumber m = (res[i] - 1) / nn; @@ -111,7 +111,7 @@ void PrivateKey::decryptCRT(std::vector& plaintext, std::vector resq = ipcl::ippModExp(baseq, qm1, qsq); #ifdef IPCL_USE_OMP -#pragma omp parallel for +#pragma omp parallel for num_threads(v_size) #endif // IPCL_USE_OMP for (int i = 0; i < v_size; i++) { BigNumber dp = computeLfun(resp[i], m_p) * m_hp % m_p; From 71a82036373325b06d0fed0ca6c4c84a07be1291 Mon Sep 17 00:00:00 2001 From: fdiasmor Date: Tue, 31 May 2022 22:23:16 -0700 Subject: [PATCH 184/364] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index abfc796..d170954 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,7 @@ sudo apt install -y libnl-3-dev sudo apt install -y linux-headers-$(uname -r) sudo apt install -y build-essential sudo apt install -y libboost-regex-dev +sudo apt install -y pkg-config ``` #### Installing OpenSSL From 846630661ee16fb82ba47caf103bfe3f9a969e8b Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Fri, 3 Jun 2022 06:42:30 +0800 Subject: [PATCH 185/364] test avx512ifma with larger input size (#101) * benchmark: add larger input size * Remove OMP specifed num_threads * Add OMP thread managment --- benchmark/bench_cryptography.cpp | 23 ++++++++++++++++++----- benchmark/bench_ops.cpp | 22 +++++++++++++++++++--- ipcl/CMakeLists.txt | 1 + ipcl/ciphertext.cpp | 12 ++++++++---- ipcl/include/ipcl/util.hpp | 16 ++++++++++++++++ ipcl/mod_exp.cpp | 8 ++++++-- ipcl/pri_key.cpp | 8 ++++++-- ipcl/util.cpp | 12 ++++++++++++ 8 files changed, 86 insertions(+), 16 deletions(-) create mode 100644 ipcl/util.cpp diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index 2a96750..c8b8165 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -8,13 +8,23 @@ #include "ipcl/keygen.hpp" +#define ADD_SAMPLE_KEY_LENGTH_ARGS Args({1024})->Args({2048}) +#define ADD_SAMPLE_VECTOR_SIZE_ARGS \ + Args({16}) \ + ->Args({64}) \ + ->Args({128}) \ + ->Args({256}) \ + ->Args({512}) \ + ->Args({1024}) \ + ->Args({2048}) + static void BM_KeyGen(benchmark::State& state) { int64_t n_length = state.range(0); for (auto _ : state) { ipcl::keyPair key = ipcl::generateKeypair(n_length, true); } } -BENCHMARK(BM_KeyGen)->Unit(benchmark::kMicrosecond)->Args({1024})->Args({2048}); +BENCHMARK(BM_KeyGen)->Unit(benchmark::kMicrosecond)->ADD_SAMPLE_KEY_LENGTH_ARGS; static void BM_Encrypt(benchmark::State& state) { size_t dsize = state.range(0); @@ -26,12 +36,13 @@ static void BM_Encrypt(benchmark::State& state) { exp_value_v[i] = (unsigned int)(i * 1024) + 999; ipcl::PlainText pt(exp_value_v); - ipcl::CipherText ct; + ipcl::CipherText ct; for (auto _ : state) ct = key.pub_key->encrypt(pt); } - -BENCHMARK(BM_Encrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); +BENCHMARK(BM_Encrypt) + ->Unit(benchmark::kMicrosecond) + ->ADD_SAMPLE_VECTOR_SIZE_ARGS; static void BM_Decrypt(benchmark::State& state) { size_t dsize = state.range(0); @@ -48,4 +59,6 @@ static void BM_Decrypt(benchmark::State& state) { for (auto _ : state) dt = key.priv_key->decrypt(ct); } -BENCHMARK(BM_Decrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); +BENCHMARK(BM_Decrypt) + ->Unit(benchmark::kMicrosecond) + ->ADD_SAMPLE_VECTOR_SIZE_ARGS; diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index 452d777..a8835f8 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -10,6 +10,15 @@ #include "ipcl/keygen.hpp" #include "ipcl/plaintext.hpp" +#define ADD_SAMPLE_VECTOR_SIZE_ARGS \ + Args({16}) \ + ->Args({64}) \ + ->Args({128}) \ + ->Args({256}) \ + ->Args({512}) \ + ->Args({1024}) \ + ->Args({2048}) + static void BM_Add_CTCT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); @@ -26,11 +35,14 @@ static void BM_Add_CTCT(benchmark::State& state) { ipcl::CipherText ct1 = key.pub_key->encrypt(pt1); ipcl::CipherText ct2 = key.pub_key->encrypt(pt2); + ipcl::CipherText sum; for (auto _ : state) sum = ct1 + ct2; } -BENCHMARK(BM_Add_CTCT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); +BENCHMARK(BM_Add_CTCT) + ->Unit(benchmark::kMicrosecond) + ->ADD_SAMPLE_VECTOR_SIZE_ARGS; static void BM_Add_CTPT(benchmark::State& state) { size_t dsize = state.range(0); @@ -52,7 +64,9 @@ static void BM_Add_CTPT(benchmark::State& state) { for (auto _ : state) sum = ct1 + pt2; } -BENCHMARK(BM_Add_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); +BENCHMARK(BM_Add_CTPT) + ->Unit(benchmark::kMicrosecond) + ->ADD_SAMPLE_VECTOR_SIZE_ARGS; static void BM_Mul_CTPT(benchmark::State& state) { size_t dsize = state.range(0); @@ -74,4 +88,6 @@ static void BM_Mul_CTPT(benchmark::State& state) { for (auto _ : state) product = ct1 * pt2; } -BENCHMARK(BM_Mul_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); +BENCHMARK(BM_Mul_CTPT) + ->Unit(benchmark::kMicrosecond) + ->ADD_SAMPLE_VECTOR_SIZE_ARGS; diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index c424388..1c03a70 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -9,6 +9,7 @@ set(IPCL_SRCS pri_key.cpp base_text.cpp plaintext.cpp ciphertext.cpp + util.cpp ) diff --git a/ipcl/ciphertext.cpp b/ipcl/ciphertext.cpp index 0f57b0d..a478639 100644 --- a/ipcl/ciphertext.cpp +++ b/ipcl/ciphertext.cpp @@ -51,16 +51,20 @@ CipherText CipherText::operator+(const CipherText& other) const { std::vector sum(m_size); if (b_size == 1) { - // add vector by scalar +// add vector by scalar #ifdef IPCL_USE_OMP -#pragma omp parallel for num_threads(m_size) + int omp_remaining_threads = OMPUtilities::MaxThreads; +#pragma omp parallel for num_threads( \ + OMPUtilities::assignOMPThreads(omp_remaining_threads, m_size)) #endif // IPCL_USE_OMP for (std::size_t i = 0; i < m_size; i++) sum[i] = a.raw_add(a.m_texts[i], b.m_texts[0]); } else { - // add vector by vector +// add vector by vector #ifdef IPCL_USE_OMP -#pragma omp parallel for num_threads(m_size) + int omp_remaining_threads = OMPUtilities::MaxThreads; +#pragma omp parallel for num_threads( \ + OMPUtilities::assignOMPThreads(omp_remaining_threads, m_size)) #endif // IPCL_USE_OMP for (std::size_t i = 0; i < m_size; i++) sum[i] = a.raw_add(a.m_texts[i], b.m_texts[i]); diff --git a/ipcl/include/ipcl/util.hpp b/ipcl/include/ipcl/util.hpp index 8bd0356..5877abd 100644 --- a/ipcl/include/ipcl/util.hpp +++ b/ipcl/include/ipcl/util.hpp @@ -36,5 +36,21 @@ inline void vec_size_check(const std::vector& v, const char* file, #define VEC_SIZE_CHECK(v) vec_size_check(v, __FILE__, __LINE__) +class OMPUtilities { + public: + static const int MaxThreads; + + static int assignOMPThreads(int& remaining_threads, int requested_threads) { + int retval = (requested_threads > 0 ? requested_threads : 1); + if (retval > remaining_threads) retval = remaining_threads; + if (retval > 1) + remaining_threads -= retval; + else + retval = 1; + return retval; + } +}; + } // namespace ipcl + #endif // IPCL_INCLUDE_IPCL_UTIL_HPP_ diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index 75981d9..d7fd91a 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -166,7 +166,9 @@ std::vector ippModExp(const std::vector& base, std::size_t remainder = v_size % IPCL_CRYPTO_MB_SIZE; #ifdef IPCL_USE_OMP -#pragma omp parallel for num_threads(num_chunk) + int omp_remaining_threads = OMPUtilities::MaxThreads; +#pragma omp parallel for num_threads( \ + OMPUtilities::assignOMPThreads(omp_remaining_threads, num_chunk)) #endif // IPCL_USE_OMP for (std::size_t i = 0; i < num_chunk; i++) { auto base_start = base.begin() + i * IPCL_CRYPTO_MB_SIZE; @@ -219,7 +221,9 @@ std::vector ippModExp(const std::vector& base, #else #ifdef IPCL_USE_OMP -#pragma omp parallel for num_threads(v_size) + int omp_remaining_threads = OMPUtilities::MaxThreads; +#pragma omp parallel for num_threads( \ + OMPUtilities::assignOMPThreads(omp_remaining_threads, v_size)) #endif // IPCL_USE_OMP for (int i = 0; i < v_size; i++) res[i] = ippSBModExp(base[i], pow[i], m[i]); return res; diff --git a/ipcl/pri_key.cpp b/ipcl/pri_key.cpp index f8781e1..8e77ad7 100644 --- a/ipcl/pri_key.cpp +++ b/ipcl/pri_key.cpp @@ -83,7 +83,9 @@ void PrivateKey::decryptRAW(std::vector& plaintext, BigNumber xx = m_x; #ifdef IPCL_USE_OMP -#pragma omp parallel for num_threads(v_size) + int omp_remaining_threads = OMPUtilities::MaxThreads; +#pragma omp parallel for num_threads( \ + OMPUtilities::assignOMPThreads(omp_remaining_threads, v_size)) #endif // IPCL_USE_OMP for (int i = 0; i < v_size; i++) { BigNumber m = (res[i] - 1) / nn; @@ -111,7 +113,9 @@ void PrivateKey::decryptCRT(std::vector& plaintext, std::vector resq = ipcl::ippModExp(baseq, qm1, qsq); #ifdef IPCL_USE_OMP -#pragma omp parallel for num_threads(v_size) + int omp_remaining_threads = OMPUtilities::MaxThreads; +#pragma omp parallel for num_threads( \ + OMPUtilities::assignOMPThreads(omp_remaining_threads, v_size)) #endif // IPCL_USE_OMP for (int i = 0; i < v_size; i++) { BigNumber dp = computeLfun(resp[i], m_p) * m_hp % m_p; diff --git a/ipcl/util.cpp b/ipcl/util.cpp new file mode 100644 index 0000000..a75ead5 --- /dev/null +++ b/ipcl/util.cpp @@ -0,0 +1,12 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/util.hpp" + +#include + +namespace ipcl { + +const int OMPUtilities::MaxThreads = omp_get_max_threads(); + +} // namespace ipcl From 34b9c02dc8a52c22eb0970fffc7d77a821625ff2 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Thu, 2 Jun 2022 16:19:41 -0700 Subject: [PATCH 186/364] Updated version number to v1.1.3 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8fef7f0..6dcd3ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.15.1) -project(IPCL VERSION 1.0.0 LANGUAGES C CXX) +project(IPCL VERSION 1.1.3 LANGUAGES C CXX) include(CMakePackageConfigHelpers) include(CheckCCompilerFlag) From f01774e25c1e27fadfc2ff1a53e111c8492801cb Mon Sep 17 00:00:00 2001 From: fdiasmor Date: Fri, 3 Jun 2022 16:26:31 -0700 Subject: [PATCH 187/364] Update README.md Update installation instruction for nasm-2.15 --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index d170954..9424527 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ pthread OpenSSL >=1.1.0 gcc >= 9.1 QAT20.L.0.8.0-00071.tar.gz (qatlib and QAT drivers) +nasm >= 2.15 ipp-crypto ``` @@ -151,7 +152,21 @@ $ cmake --install build The cmake configuration variable `HE_QAT_MISC=ON` enables `BigNumber` resources and samples, requiring IPP Crypto installation as a dependency. If usage of the utility functions that support `BigNumber` data type is needed, follow the building instructions below to install IPP Crypto and then rebuild the library with the cmake flag `HE_QAT_MISC=ON`: +Installing `nasm-2.15`: + +``` +$ wget -c https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.xz +$ tar -xf nasm-2.15.05.tar.xz +$ cd nasm-2.15.05/ +$ ./configure --prefix=/opt/nasm-2.15 +$ make -j +$ sudo make install +``` + +Installing `ippcrypto`: + ``` +$ cd ~ $ git clone https://github.com/intel/ipp-crypto.git $ cd ipp-crypto $ CC=gcc CXX=g++ cmake CMakeLists.txt -B_build -DARCH=intel64 -DMERGED_BLD:BOOL=ON -DCMAKE_INSTALL_PREFIX=/opt/ipp-crypto -DOPENSSL_INCLUDE_DIR=/opt/openssl/include -DOPENSSL_LIBRARIES=/opt/openssl/lib -DOPENSSL_ROOT_DIR=/opt/openssl -DCMAKE_ASM_NASM_COMPILER=/opt/nasm-2.15/bin/nasm From 874e53af02f759a08f4c39d71a21e75482e4748c Mon Sep 17 00:00:00 2001 From: fdiasmor Date: Fri, 3 Jun 2022 17:45:58 -0700 Subject: [PATCH 188/364] Update README.md with Troubleshooting section --- README.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/README.md b/README.md index 9424527..ff5ed16 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ Intel Homomorphic Encryption Acceleration Library for QAT (HE QAT Lib) is an ope - [Requirements](#requirements) - [Dependencies](#dependencies) - [Instructions](#instructions) + - [Troubleshooting](#troubleshooting) - [Testing and Benchmarking](#testing-and-benchmarking) - [Contributors](#contributors) @@ -221,6 +222,43 @@ Test showing functional correctness and performance using `BigNumber` data types ``` ./build/samples/test_bnModExp ``` +## Troubleshooting + +- **Issue #1** + +``` +xuser@ubuntu-guest:~/heqat$ cmake -S . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHE_QAT_MISC=ON +-- CMAKE_INSTALL_PREFIX: /usr/local +-- CMAKE_PREFIX_PATH /home/xuser/ipp-crypto/_build/ +-- Missed required Intel IPP Cryptography component: ippcp +-- library not found: + /opt/ipp-crypto/lib/intel64/libippcp.a +CMake Error at CMakeLists.txt:93 (find_package): + Found package configuration file: + + /opt/ipp-crypto/lib/cmake/ippcp/ippcp-config.cmake + + but it set IPPCP_FOUND to FALSE so package "IPPCP" is considered to be NOT + FOUND. +``` + +To resolve the error below simply create the symbolic link `/opt/ipp-crypto/lib/intel64/libippcp.a` from the apropriate static ippcp library that was compiled. For example: + +``` +xuser@ubuntu-guest:/opt/ipp-crypto/lib/intel64$ ls -lha +total 7.3M +drwxr-xr-x 2 root root 4.0K Jun 3 16:29 . +drwxr-xr-x 5 root root 4.0K Jun 3 16:29 .. +-rw-r--r-- 1 root root 1.6M Jun 3 16:28 libcrypto_mb.a +lrwxrwxrwx 1 root root 18 Jun 3 16:29 libcrypto_mb.so -> libcrypto_mb.so.11 +lrwxrwxrwx 1 root root 20 Jun 3 16:29 libcrypto_mb.so.11 -> libcrypto_mb.so.11.5 +-rw-r--r-- 1 root root 1.3M Jun 3 16:28 libcrypto_mb.so.11.5 +lrwxrwxrwx 1 root root 16 Jun 3 16:29 libippcpmx.so -> libippcpmx.so.11 +lrwxrwxrwx 1 root root 18 Jun 3 16:29 libippcpmx.so.11 -> libippcpmx.so.11.5 +-rw-r--r-- 1 root root 1.7M Jun 3 16:28 libippcpmx.so.11.5 +-rw-r--r-- 1 root root 2.9M Jun 3 16:28 libippcp_s_mx.a +xuser@ubuntu-guest:/opt/ipp-crypto/lib/intel64$ sudo ln -s libippcp_s_mx.a libippcp.a +``` ## Testing and Benchmarking From d7c55c9f777cb89ccf475d420d321418cd6b1719 Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Tue, 7 Jun 2022 00:46:04 +0800 Subject: [PATCH 189/364] Fix IPCL_USE_OMP missing issue (#103) --- ipcl/include/ipcl/util.hpp | 2 ++ ipcl/util.cpp | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/ipcl/include/ipcl/util.hpp b/ipcl/include/ipcl/util.hpp index 5877abd..576859c 100644 --- a/ipcl/include/ipcl/util.hpp +++ b/ipcl/include/ipcl/util.hpp @@ -36,6 +36,7 @@ inline void vec_size_check(const std::vector& v, const char* file, #define VEC_SIZE_CHECK(v) vec_size_check(v, __FILE__, __LINE__) +#ifdef IPCL_USE_OMP class OMPUtilities { public: static const int MaxThreads; @@ -50,6 +51,7 @@ class OMPUtilities { return retval; } }; +#endif // IPCL_USE_OMP } // namespace ipcl diff --git a/ipcl/util.cpp b/ipcl/util.cpp index a75ead5..d00cf04 100644 --- a/ipcl/util.cpp +++ b/ipcl/util.cpp @@ -3,10 +3,14 @@ #include "ipcl/util.hpp" +#ifdef IPCL_USE_OMP #include +#endif // IPCL_USE_OMP namespace ipcl { +#ifdef IPCL_USE_OMP const int OMPUtilities::MaxThreads = omp_get_max_threads(); +#endif // IPCL_USE_OMP } // namespace ipcl From ea695308ba6fe64d8aded00d60d4591ac8d57580 Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Wed, 8 Jun 2022 06:36:52 +0800 Subject: [PATCH 190/364] Fix OMP issue in decryptRAW (#104) --- ipcl/pri_key.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/ipcl/pri_key.cpp b/ipcl/pri_key.cpp index 8e77ad7..bfa135e 100644 --- a/ipcl/pri_key.cpp +++ b/ipcl/pri_key.cpp @@ -79,17 +79,15 @@ void PrivateKey::decryptRAW(std::vector& plaintext, std::vector modulo(v_size, m_nsquare); std::vector res = ipcl::ippModExp(ciphertext, pow_lambda, modulo); - BigNumber nn = m_n; - BigNumber xx = m_x; - #ifdef IPCL_USE_OMP int omp_remaining_threads = OMPUtilities::MaxThreads; #pragma omp parallel for num_threads( \ OMPUtilities::assignOMPThreads(omp_remaining_threads, v_size)) #endif // IPCL_USE_OMP for (int i = 0; i < v_size; i++) { - BigNumber m = (res[i] - 1) / nn; - m = m * xx; + BigNumber nn = m_n; + BigNumber xx = m_x; + BigNumber m = ((res[i] - 1) / nn) * xx; plaintext[i] = m % nn; } } From 72dd1f2db92036706ab8d95e667db7ea792cb289 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Mon, 20 Jun 2022 00:27:39 -0700 Subject: [PATCH 191/364] getCipherText function (#108) * added getCipherText function * Pre-commit hook check --- CMakeLists.txt | 4 ++-- ipcl/ciphertext.cpp | 7 +++++++ ipcl/include/ipcl/ciphertext.hpp | 5 +++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6dcd3ac..f590be1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,8 +36,8 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_INSTALL_MESSAGE LAZY) set(CMAKE_INSTALL_RPATH "\$ORIGIN") -set(CMAKE_C_FLAGS "-O2") -set(CMAKE_CXX_FLAGS "-O2 -fpermissive") +set(CMAKE_C_FLAGS "-O2 -Wno-error=deprecated-declarations") +set(CMAKE_CXX_FLAGS "-O2 -fpermissive -Wno-error=deprecated-declarations") if(NOT CMAKE_INSTALL_PREFIX) set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/ipcl/ciphertext.cpp b/ipcl/ciphertext.cpp index a478639..685b264 100644 --- a/ipcl/ciphertext.cpp +++ b/ipcl/ciphertext.cpp @@ -107,6 +107,13 @@ CipherText CipherText::operator*(const PlainText& other) const { } } +CipherText CipherText::getCipherText(const size_t& idx) const { + ERROR_CHECK((idx >= 0) && (idx < m_size), + "CipherText::getCipherText index is out of range"); + + return CipherText(m_pubkey, m_texts[idx]); +} + const PublicKey* CipherText::getPubKey() const { return m_pubkey; } CipherText CipherText::rotate(int shift) const { diff --git a/ipcl/include/ipcl/ciphertext.hpp b/ipcl/include/ipcl/ciphertext.hpp index 0dcb337..a742921 100644 --- a/ipcl/include/ipcl/ciphertext.hpp +++ b/ipcl/include/ipcl/ciphertext.hpp @@ -41,6 +41,11 @@ class CipherText : public BaseText { // CT*PT CipherText operator*(const PlainText& other) const; + /** + * Get ciphertext of idx + */ + CipherText getCipherText(const size_t& idx) const; + /** * Get public key */ From 9db0b6e95031357720a18970f7b76f648f1240da Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Wed, 22 Jun 2022 14:18:54 +0800 Subject: [PATCH 192/364] Add support for -DIPCL_THREAD_COUNT (#107) --- CMakeLists.txt | 9 +++++++++ README.md | 12 +++++++++--- ipcl/CMakeLists.txt | 2 +- ipcl/include/ipcl/util.hpp | 13 +++++++++++++ ipcl/pri_key.cpp | 7 ++++++- ipcl/util.cpp | 7 +++++-- 6 files changed, 43 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f590be1..4bdaf00 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,11 +51,15 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) option(IPCL_TEST "Enable testing" ON) option(IPCL_BENCHMARK "Enable benchmark" ON) option(IPCL_ENABLE_OMP "Enable OpenMP testing/benchmarking" ON) +option(IPCL_THREAD_COUNT "The max number of threads used by OpenMP(If the value is OFF/0, it is determined at runtime)" OFF) option(IPCL_DOCS "Enable document building" OFF) option(IPCL_SHARED "Build shared library" ON) option(IPCL_DEBUG_DISABLE_AVX512IFMA "(Debugging) Disable usage of AVX512IFMA instructions" OFF) if(IPCL_ENABLE_OMP) add_compile_definitions(IPCL_USE_OMP) + if(IPCL_THREAD_COUNT) + add_compile_definitions(IPCL_NUM_THREADS=${IPCL_THREAD_COUNT}) + endif() endif() if(CMAKE_BUILD_TYPE STREQUAL "Debug") @@ -73,6 +77,11 @@ message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") message(STATUS "IPCL_TEST: ${IPCL_TEST}") message(STATUS "IPCL_BENCHMARK: ${IPCL_BENCHMARK}") message(STATUS "IPCL_ENABLE_OMP: ${IPCL_ENABLE_OMP}") +if (IPCL_ENABLE_OMP) + message(STATUS "IPCL_THREAD_COUNT: ${IPCL_THREAD_COUNT}") +else() + message(STATUS "IPCL_THREAD_COUNT: IGNORE") +endif() message(STATUS "IPCL_DOCS: ${IPCL_DOCS}") message(STATUS "IPCL_SHARED: ${IPCL_SHARED}") diff --git a/README.md b/README.md index 9a7e9de..0bdf06f 100644 --- a/README.md +++ b/README.md @@ -56,16 +56,21 @@ The following libraries and tools are also required, ``` nasm >= 2.15 OpenSSL >= 1.1.0 +numa >= 2.0.12 ``` For ```nasm```, please refer to the [Netwide Assembler](https://nasm.us/) for installation details. -On Ubuntu, ```OpenSSL``` can be installed with: +On Ubuntu, ```OpenSSL``` and ```numa``` can be installed with: ```bash sudo apt update sudo apt install libssl-dev +sudo apt install libnuma-dev +``` +For RHEL, ```OpenSSL``` needs to be built and installed from source as the static libraries are missing when installed through the package managers. Please refer to [OpenSSL Project](https://github.com/openssl/openssl) for installation details for static libraries. ```numa``` can be installed with: +``` +sudo yum install numactl-devel ``` -For RHEL, ```OpenSSL``` needs to be built and installed from source as the static libraries are missing when installed through the package managers. Please refer to [OpenSSL Project](https://github.com/openssl/openssl) for installation details for static libraries. ### Instructions The library can be built using the following commands: @@ -82,6 +87,7 @@ It is possible to pass additional options to enable more features. The following |`IPCL_TEST` | ON/OFF | ON | unit-test | |`IPCL_BENCHMARK` | ON/OFF | ON | benchmark | |`IPCL_ENABLE_OMP` | ON/OFF | ON | enables OpenMP functionalities | +|`IPCL_THREAD_COUNT` | Integer | OFF | The max number of threads | |`IPCL_DOCS` | ON/OFF | OFF | build doxygen documentation | |`IPCL_SHARED` | ON/OFF | ON | build shared library | @@ -97,7 +103,7 @@ Then, run ```bash cmake --build build --target benchmark ``` -Setting the CMake flag ```-DIPCL_ENABLE_OMP=ON``` during configuration will automatically enable OpenMP unit-tests and benchmarks. The `OMP_THREAD_LIMIT` environment variable can be used to set the maximum number of OpenMP threads. +Setting the CMake flag ```-DIPCL_ENABLE_OMP=ON``` during configuration will use OpenMP for acceleration. Setting the value of `-DIPCL_THREAD_COUNT` will limit the maximum number of threads used by OpenMP (If set to OFF or 0, its actual value will be determined at run time). The executables are located at `${IPCL_DIR}/build/test/unittest_ipcl` and `${IPCL_DIR}/build/benchmark/bench_ipcl`. diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 1c03a70..ef76656 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -46,7 +46,7 @@ install(DIRECTORY ${IPPCRYPTO_INC_DIR}/ PATTERN "*.hpp" PATTERN "*.h") -target_link_libraries(ipcl PUBLIC OpenSSL::SSL OpenSSL::Crypto Threads::Threads) +target_link_libraries(ipcl PUBLIC OpenSSL::SSL OpenSSL::Crypto Threads::Threads -lnuma) if(IPCL_ENABLE_OMP) find_package(OpenMP REQUIRED) diff --git a/ipcl/include/ipcl/util.hpp b/ipcl/include/ipcl/util.hpp index 576859c..b264816 100644 --- a/ipcl/include/ipcl/util.hpp +++ b/ipcl/include/ipcl/util.hpp @@ -50,7 +50,20 @@ class OMPUtilities { retval = 1; return retval; } + + private: + static const int nodes; + static const int cpus; + + static int getMaxThreads() { +#ifdef IPCL_NUM_THREADS + return IPCL_NUM_THREADS; +#else + return cpus / nodes; +#endif // IPCL_NUM_THREADS + } }; + #endif // IPCL_USE_OMP } // namespace ipcl diff --git a/ipcl/pri_key.cpp b/ipcl/pri_key.cpp index bfa135e..060e858 100644 --- a/ipcl/pri_key.cpp +++ b/ipcl/pri_key.cpp @@ -101,6 +101,11 @@ void PrivateKey::decryptCRT(std::vector& plaintext, std::vector pm1(v_size, m_pminusone), qm1(v_size, m_qminusone); std::vector psq(v_size, m_psquare), qsq(v_size, m_qsquare); +#ifdef IPCL_USE_OMP + int omp_remaining_threads = OMPUtilities::MaxThreads; +#pragma omp parallel for num_threads( \ + OMPUtilities::assignOMPThreads(omp_remaining_threads, v_size)) +#endif // IPCL_USE_OMP for (int i = 0; i < v_size; i++) { basep[i] = ciphertext[i] % psq[i]; baseq[i] = ciphertext[i] % qsq[i]; @@ -111,7 +116,7 @@ void PrivateKey::decryptCRT(std::vector& plaintext, std::vector resq = ipcl::ippModExp(baseq, qm1, qsq); #ifdef IPCL_USE_OMP - int omp_remaining_threads = OMPUtilities::MaxThreads; + omp_remaining_threads = OMPUtilities::MaxThreads; #pragma omp parallel for num_threads( \ OMPUtilities::assignOMPThreads(omp_remaining_threads, v_size)) #endif // IPCL_USE_OMP diff --git a/ipcl/util.cpp b/ipcl/util.cpp index d00cf04..1de2b49 100644 --- a/ipcl/util.cpp +++ b/ipcl/util.cpp @@ -4,13 +4,16 @@ #include "ipcl/util.hpp" #ifdef IPCL_USE_OMP -#include +#include #endif // IPCL_USE_OMP namespace ipcl { #ifdef IPCL_USE_OMP -const int OMPUtilities::MaxThreads = omp_get_max_threads(); +const int OMPUtilities::nodes = numa_num_configured_nodes(); +const int OMPUtilities::cpus = numa_num_configured_cpus(); +const int OMPUtilities::MaxThreads = OMPUtilities::getMaxThreads(); + #endif // IPCL_USE_OMP } // namespace ipcl From e9a2c318035478653809459579aac4149c99684c Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Sat, 25 Jun 2022 02:03:34 +0800 Subject: [PATCH 193/364] 1. Add error log when key size is not >=16 or not divisible by 4. (#113) 2. Add key length check in getDJNBN(). 3. Add check for close prime factors --- ipcl/keygen.cpp | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/ipcl/keygen.cpp b/ipcl/keygen.cpp index 9a8dcbf..efbf1d6 100644 --- a/ipcl/keygen.cpp +++ b/ipcl/keygen.cpp @@ -12,6 +12,7 @@ namespace ipcl { constexpr int N_BIT_SIZE_MAX = 2048; +constexpr int N_BIT_SIZE_MIN = 16; static void rand32u(std::vector& addr) { std::random_device dev; @@ -52,9 +53,27 @@ BigNumber getPrimeBN(int maxBitSize) { return pBN; } +static BigNumber getPrimeDistance(int64_t key_size) { + uint64_t count = key_size / 2 - 100; + uint64_t ct32 = count / 32; // number of 2**32 needed + uint64_t res = count & 0x1F; // count % 32 + std::vector tmp(ct32 + 1, 0); + tmp[ct32] = 1 << res; + + BigNumber ref_dist(tmp.data(), tmp.size()); + return ref_dist; +} + +static bool isClosePrimeBN(const BigNumber& p, const BigNumber& q, + const BigNumber& ref_dist) { + BigNumber real_dist = (p >= q) ? (p - q) : (q - p); + return (real_dist > ref_dist) ? false : true; +} + static void getNormalBN(int64_t n_length, BigNumber& p, BigNumber& q, - BigNumber& n) { - for (int64_t len = 0; len != n_length; len = n.BitSize()) { + BigNumber& n, const BigNumber& ref_dist) { + for (int64_t len = 0; (len != n_length) || isClosePrimeBN(p, q, ref_dist); + len = n.BitSize()) { p = getPrimeBN(n_length / 2); q = p; while (q == p) { @@ -64,8 +83,8 @@ static void getNormalBN(int64_t n_length, BigNumber& p, BigNumber& q, } } -static void getDJNBN(int64_t n_length, BigNumber& p, BigNumber& q, - BigNumber& n) { +static void getDJNBN(int64_t n_length, BigNumber& p, BigNumber& q, BigNumber& n, + BigNumber& ref_dist) { BigNumber gcd; do { do { @@ -77,9 +96,9 @@ static void getDJNBN(int64_t n_length, BigNumber& p, BigNumber& q, } while (q == p || !p.TestBit(1)); // get q: q!=p and q mod 4 = 3 gcd = (p - 1).gcd(q - 1); // (p - 1) is a BigNumber - } while (gcd.compare(2)); // gcd(p-1,q-1)=2 - - n = p * q; + n = p * q; + } while ((gcd.compare(2)) || (n.BitSize() != n_length) || + isClosePrimeBN(p, q, ref_dist)); // gcd(p-1,q-1)=2 } keyPair generateKeypair(int64_t n_length, bool enable_DJN) { @@ -91,13 +110,17 @@ keyPair generateKeypair(int64_t n_length, bool enable_DJN) { n_length <= N_BIT_SIZE_MAX, "generateKeyPair: modulus size in bits should belong to either 1Kb, 2Kb, " "3Kb or 4Kb range only, key size exceed the range!!!"); + ERROR_CHECK((n_length >= N_BIT_SIZE_MIN) && (n_length % 4 == 0), + "generateKeyPair: key size should >=16, and divisible by 4"); + + BigNumber ref_dist = getPrimeDistance(n_length); BigNumber p, q, n; if (enable_DJN) - getDJNBN(n_length, p, q, n); + getDJNBN(n_length, p, q, n, ref_dist); else - getNormalBN(n_length, p, q, n); + getNormalBN(n_length, p, q, n, ref_dist); PublicKey* public_key = new PublicKey(n, n_length, enable_DJN); PrivateKey* private_key = new PrivateKey(public_key, p, q); From 896d61ed69478900c2423d4b423170af3582df7a Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Tue, 28 Jun 2022 05:20:54 +0800 Subject: [PATCH 194/364] qat integration update (#115) Applied development branch changes to QAT branch Co-authored-by: Sejun Kim --- CMakeLists.txt | 24 ++-- README.md | 12 +- benchmark/CMakeLists.txt | 3 +- benchmark/bench_cryptography.cpp | 23 +++- benchmark/bench_ops.cpp | 23 +++- ipcl/CMakeLists.txt | 3 +- ipcl/base_text.cpp | 36 +++++- ipcl/ciphertext.cpp | 29 +++-- ipcl/include/ipcl/base_text.hpp | 26 ++++ ipcl/include/ipcl/ciphertext.hpp | 9 +- ipcl/include/ipcl/plaintext.hpp | 18 +++ ipcl/include/ipcl/pub_key.hpp | 33 +++++- ipcl/include/ipcl/util.hpp | 31 +++++ ipcl/keygen.cpp | 41 +++++-- ipcl/mod_exp.cpp | 14 ++- ipcl/plaintext.cpp | 29 +++++ ipcl/pri_key.cpp | 25 ++-- ipcl/pub_key.cpp | 45 +++---- ipcl/util.cpp | 19 +++ test/CMakeLists.txt | 3 +- test/test_ops.cpp | 198 +++++++++++++++++++++++++++++++ 21 files changed, 555 insertions(+), 89 deletions(-) create mode 100644 ipcl/util.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index caa0016..d9826b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.15.1) -project(IPCL VERSION 1.0.0 LANGUAGES C CXX) +project(IPCL VERSION 1.1.3 LANGUAGES C CXX) include(CMakePackageConfigHelpers) include(CheckCCompilerFlag) @@ -36,10 +36,8 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_INSTALL_MESSAGE LAZY) set(CMAKE_INSTALL_RPATH "\$ORIGIN") -#set(CMAKE_C_FLAGS "-O2 -pthread") -#set(CMAKE_CXX_FLAGS "-O2 -fpermissive -pthread") -set(CMAKE_C_FLAGS "-pthread") -set(CMAKE_CXX_FLAGS "-fpermissive -pthread") +set(CMAKE_C_FLAGS "-O2 -Wno-error=deprecated-declarations") +set(CMAKE_CXX_FLAGS "-O2 -fpermissive -Wno-error=deprecated-declarations") if(NOT CMAKE_INSTALL_PREFIX) set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}) @@ -55,6 +53,7 @@ option(IPCL_BENCHMARK "Enable benchmark" ON) option(IPCL_ENABLE_QAT "Enable QAT" OFF) option(IPCL_USE_QAT_LITE "Enable uses QAT for base and exponent length different than modulus" OFF) option(IPCL_ENABLE_OMP "Enable OpenMP testing/benchmarking" ON) +option(IPCL_THREAD_COUNT "The max number of threads used by OpenMP(If the value is OFF/0, it is determined at runtime)" OFF) option(IPCL_DOCS "Enable document building" OFF) option(IPCL_SHARED "Build shared library" ON) @@ -72,6 +71,9 @@ endif() if(IPCL_ENABLE_OMP) add_compile_definitions(IPCL_USE_OMP) + if(IPCL_THREAD_COUNT) + add_compile_definitions(IPCL_NUM_THREADS=${IPCL_THREAD_COUNT}) + endif() endif() @@ -91,6 +93,11 @@ message(STATUS "IPCL_TEST: ${IPCL_TEST}") message(STATUS "IPCL_BENCHMARK: ${IPCL_BENCHMARK}") message(STATUS "IPCL_ENABLE_OMP: ${IPCL_ENABLE_OMP}") message(STATUS "IPCL_ENABLE_QAT: ${IPCL_ENABLE_QAT}") +if (IPCL_ENABLE_OMP) + message(STATUS "IPCL_THREAD_COUNT: ${IPCL_THREAD_COUNT}") +else() + message(STATUS "IPCL_THREAD_COUNT: IGNORE") +endif() message(STATUS "IPCL_DOCS: ${IPCL_DOCS}") message(STATUS "IPCL_SHARED: ${IPCL_SHARED}") @@ -111,14 +118,13 @@ set(IPCL_FORWARD_CMAKE_ARGS ) # find package for OpenSSL and Threads -set(OPENSSL_USE_STATIC_LIBS TRUE) +set(CMAKE_THREAD_PREFER_PTHREAD ON) +# set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) +set(OPENSSL_USE_STATIC_LIBS TRUE) find_package(OpenSSL REQUIRED) # External dependencies -set(CMAKE_THREAD_PREFER_PTHREAD ON) -set(THREADS_PREFER_PTHREAD_FLAG ON) - set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ipcl) include(ipcl-util) diff --git a/README.md b/README.md index 3b5059b..a37c07d 100644 --- a/README.md +++ b/README.md @@ -56,16 +56,21 @@ The following libraries and tools are also required, ``` nasm >= 2.15 OpenSSL >= 1.1.0 +numa >= 2.0.12 ``` For ```nasm```, please refer to the [Netwide Assembler](https://nasm.us/) for installation details. -On Ubuntu, ```OpenSSL``` can be installed with: +On Ubuntu, ```OpenSSL``` and ```numa``` can be installed with: ```bash sudo apt update sudo apt install libssl-dev +sudo apt install libnuma-dev +``` +For RHEL, ```OpenSSL``` needs to be built and installed from source as the static libraries are missing when installed through the package managers. Please refer to [OpenSSL Project](https://github.com/openssl/openssl) for installation details for static libraries. ```numa``` can be installed with: +``` +sudo yum install numactl-devel ``` -For RHEL, ```OpenSSL``` needs to be built and installed from source as the static libraries are missing when installed through the package managers. Please refer to [OpenSSL Project](https://github.com/openssl/openssl) for installation details for static libraries. ### Instructions The library can be built using the following commands: @@ -83,6 +88,7 @@ It is possible to pass additional options to enable more features. The following |`IPCL_BENCHMARK` | ON/OFF | ON | benchmark | |`IPCL_ENABLE_QAT` | ON/OFF | OFF | enables QAT functionalities | |`IPCL_ENABLE_OMP` | ON/OFF | ON | enables OpenMP functionalities | +|`IPCL_THREAD_COUNT` | Integer | OFF | The max number of threads | |`IPCL_DOCS` | ON/OFF | OFF | build doxygen documentation | |`IPCL_SHARED` | ON/OFF | ON | build shared library | @@ -109,7 +115,7 @@ Then, run ```bash cmake --build build --target benchmark ``` -Setting the CMake flag ```-DIPCL_ENABLE_OMP=ON``` during configuration will automatically enable OpenMP unit-tests and benchmarks. +Setting the CMake flag ```-DIPCL_ENABLE_OMP=ON``` during configuration will use OpenMP for acceleration. Setting the value of `-DIPCL_THREAD_COUNT` will limit the maximum number of threads used by OpenMP (If set to OFF or 0, its actual value will be determined at run time). The executables are located at `${IPCL_DIR}/build/test/unittest_ipcl` and `${IPCL_DIR}/build/benchmark/bench_ipcl`. diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 9b1a749..56f25a2 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -12,7 +12,8 @@ target_include_directories(bench_ipcl PRIVATE ) target_link_libraries(bench_ipcl PRIVATE - ipcl libgbenchmark Threads::Threads + # ipcl Threads::Threads libgbenchmark + ipcl -pthread libgbenchmark ) # enable QAT unittests diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index 31cf04f..4d740c4 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -8,13 +8,24 @@ #include "ipcl/keygen.hpp" +#define ADD_SAMPLE_KEY_LENGTH_ARGS Args({1024})->Args({2048}) +#define ADD_SAMPLE_VECTOR_SIZE_ARGS \ + Args({16}) \ + ->Args({64}) \ + ->Args({128}) \ + ->Args({256}) \ + ->Args({512}) \ + ->Args({1024}) \ + ->Args({2048}) \ + ->Args({2100}) + static void BM_KeyGen(benchmark::State& state) { int64_t n_length = state.range(0); for (auto _ : state) { ipcl::keyPair key = ipcl::generateKeypair(n_length, true); } } -BENCHMARK(BM_KeyGen)->Unit(benchmark::kMicrosecond)->Args({1024})->Args({2048}); +BENCHMARK(BM_KeyGen)->Unit(benchmark::kMicrosecond)->ADD_SAMPLE_KEY_LENGTH_ARGS; static void BM_Encrypt(benchmark::State& state) { size_t dsize = state.range(0); @@ -26,12 +37,14 @@ static void BM_Encrypt(benchmark::State& state) { exp_value_v[i] = (unsigned int)(i * 1024) + 999; ipcl::PlainText pt(exp_value_v); - ipcl::CipherText ct; + ipcl::CipherText ct; for (auto _ : state) ct = key.pub_key->encrypt(pt); } -BENCHMARK(BM_Encrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64})->Args({128})->Args({256})->Args({512})->Args({1024})->Args({2048})->Args({2100}); +BENCHMARK(BM_Encrypt) + ->Unit(benchmark::kMicrosecond) + ->ADD_SAMPLE_VECTOR_SIZE_ARGS; static void BM_Decrypt(benchmark::State& state) { size_t dsize = state.range(0); @@ -48,4 +61,6 @@ static void BM_Decrypt(benchmark::State& state) { for (auto _ : state) dt = key.priv_key->decrypt(ct); } -BENCHMARK(BM_Decrypt)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64})->Args({128})->Args({256})->Args({512})->Args({1024})->Args({2048})->Args({2100}); +BENCHMARK(BM_Decrypt) + ->Unit(benchmark::kMicrosecond) + ->ADD_SAMPLE_VECTOR_SIZE_ARGS; diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index ac944df..42311ec 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -10,6 +10,16 @@ #include "ipcl/keygen.hpp" #include "ipcl/plaintext.hpp" +#define ADD_SAMPLE_VECTOR_SIZE_ARGS \ + Args({16}) \ + ->Args({64}) \ + ->Args({128}) \ + ->Args({256}) \ + ->Args({512}) \ + ->Args({1024}) \ + ->Args({2048}) \ + ->Args({2100}) + static void BM_Add_CTCT(benchmark::State& state) { size_t dsize = state.range(0); ipcl::keyPair key = ipcl::generateKeypair(2048, true); @@ -26,11 +36,14 @@ static void BM_Add_CTCT(benchmark::State& state) { ipcl::CipherText ct1 = key.pub_key->encrypt(pt1); ipcl::CipherText ct2 = key.pub_key->encrypt(pt2); + ipcl::CipherText sum; for (auto _ : state) sum = ct1 + ct2; } -BENCHMARK(BM_Add_CTCT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); +BENCHMARK(BM_Add_CTCT) + ->Unit(benchmark::kMicrosecond) + ->ADD_SAMPLE_VECTOR_SIZE_ARGS; static void BM_Add_CTPT(benchmark::State& state) { size_t dsize = state.range(0); @@ -52,7 +65,9 @@ static void BM_Add_CTPT(benchmark::State& state) { for (auto _ : state) sum = ct1 + pt2; } -BENCHMARK(BM_Add_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64}); +BENCHMARK(BM_Add_CTPT) + ->Unit(benchmark::kMicrosecond) + ->ADD_SAMPLE_VECTOR_SIZE_ARGS; static void BM_Mul_CTPT(benchmark::State& state) { size_t dsize = state.range(0); @@ -74,4 +89,6 @@ static void BM_Mul_CTPT(benchmark::State& state) { for (auto _ : state) product = ct1 * pt2; } -BENCHMARK(BM_Mul_CTPT)->Unit(benchmark::kMicrosecond)->Args({16})->Args({64})->Args({128})->Args({256})->Args({512})->Args({1024})->Args({2048})->Args({2100}); +BENCHMARK(BM_Mul_CTPT) + ->Unit(benchmark::kMicrosecond) + ->ADD_SAMPLE_VECTOR_SIZE_ARGS; diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index ed1b437..5bfe2ec 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -9,6 +9,7 @@ set(IPCL_SRCS pri_key.cpp base_text.cpp plaintext.cpp ciphertext.cpp + util.cpp ) @@ -44,7 +45,7 @@ install(DIRECTORY ${IPPCRYPTO_INC_DIR}/ PATTERN "*.hpp" PATTERN "*.h") -target_link_libraries(ipcl PUBLIC OpenSSL::SSL OpenSSL::Crypto Threads::Threads) +target_link_libraries(ipcl PUBLIC OpenSSL::SSL OpenSSL::Crypto Threads::Threads -lnuma) if(IPCL_ENABLE_OMP) find_package(OpenMP REQUIRED) diff --git a/ipcl/base_text.cpp b/ipcl/base_text.cpp index e4e43c5..4a1b0a6 100644 --- a/ipcl/base_text.cpp +++ b/ipcl/base_text.cpp @@ -34,14 +34,44 @@ BaseText& BaseText::operator=(const BaseText& other) { return *this; } +BigNumber& BaseText::operator[](const std::size_t idx) { + ERROR_CHECK(idx < m_size, "BaseText:operator[] index is out of range"); + + return m_texts[idx]; +} + +void BaseText::insert(const std::size_t pos, BigNumber& bn) { + ERROR_CHECK((pos >= 0) && (pos <= m_size), + "BaseText: insert position is out of range"); + + auto it = m_texts.begin() + pos; + m_texts.insert(it, bn); + m_size++; +} + +void BaseText::clear() { + m_texts.clear(); + m_size = 0; +} + +void BaseText::remove(const std::size_t pos, const std::size_t length) { + ERROR_CHECK((pos >= 0) && (pos + length < m_size), + "BaseText: remove position is out of range"); + + auto start = m_texts.begin() + pos; + auto end = start + length; + m_texts.erase(start, end); + m_size = m_size - length; +} + BigNumber BaseText::getElement(const std::size_t& idx) const { - ERROR_CHECK(idx <= m_size, "BaseText: getElement index is out of range"); + ERROR_CHECK(idx < m_size, "BaseText: getElement index is out of range"); return m_texts[idx]; } std::vector BaseText::getElementVec(const std::size_t& idx) const { - ERROR_CHECK(idx <= m_size, "BaseText: getElementVec index is out of range"); + ERROR_CHECK(idx < m_size, "BaseText: getElementVec index is out of range"); std::vector v; m_texts[idx].num2vec(v); @@ -50,7 +80,7 @@ std::vector BaseText::getElementVec(const std::size_t& idx) const { } std::string BaseText::getElementHex(const std::size_t& idx) const { - ERROR_CHECK(idx <= m_size, "BaseText: getElementHex index is out of range"); + ERROR_CHECK(idx < m_size, "BaseText: getElementHex index is out of range"); std::string s; m_texts[idx].num2hex(s); diff --git a/ipcl/ciphertext.cpp b/ipcl/ciphertext.cpp index 27cdcdb..685b264 100644 --- a/ipcl/ciphertext.cpp +++ b/ipcl/ciphertext.cpp @@ -51,16 +51,20 @@ CipherText CipherText::operator+(const CipherText& other) const { std::vector sum(m_size); if (b_size == 1) { - // add vector by scalar +// add vector by scalar #ifdef IPCL_USE_OMP -#pragma omp parallel for + int omp_remaining_threads = OMPUtilities::MaxThreads; +#pragma omp parallel for num_threads( \ + OMPUtilities::assignOMPThreads(omp_remaining_threads, m_size)) #endif // IPCL_USE_OMP for (std::size_t i = 0; i < m_size; i++) sum[i] = a.raw_add(a.m_texts[i], b.m_texts[0]); } else { - // add vector by vector +// add vector by vector #ifdef IPCL_USE_OMP -#pragma omp parallel for + int omp_remaining_threads = OMPUtilities::MaxThreads; +#pragma omp parallel for num_threads( \ + OMPUtilities::assignOMPThreads(omp_remaining_threads, m_size)) #endif // IPCL_USE_OMP for (std::size_t i = 0; i < m_size; i++) sum[i] = a.raw_add(a.m_texts[i], b.m_texts[i]); @@ -103,18 +107,25 @@ CipherText CipherText::operator*(const PlainText& other) const { } } -PublicKey CipherText::getPubKey() const { return *m_pubkey; } +CipherText CipherText::getCipherText(const size_t& idx) const { + ERROR_CHECK((idx >= 0) && (idx < m_size), + "CipherText::getCipherText index is out of range"); + + return CipherText(m_pubkey, m_texts[idx]); +} + +const PublicKey* CipherText::getPubKey() const { return m_pubkey; } CipherText CipherText::rotate(int shift) const { ERROR_CHECK(m_size != 1, "rotate: Cannot rotate single CipherText"); - ERROR_CHECK(shift >= -8 && shift <= 8, - "rotate: Cannot shift more than 8 or -8"); + ERROR_CHECK(shift >= (-1) * static_cast(m_size) && shift <= m_size, + "rotate: Cannot shift more than the test size"); - if (shift == 0 || shift == 8 || shift == -8) + if (shift == 0 || shift == m_size || shift == (-1) * static_cast(m_size)) return CipherText(m_pubkey, m_texts); if (shift > 0) - shift = 8 - shift; + shift = m_size - shift; else shift = -shift; diff --git a/ipcl/include/ipcl/base_text.hpp b/ipcl/include/ipcl/base_text.hpp index 0f9e10e..8c027b4 100644 --- a/ipcl/include/ipcl/base_text.hpp +++ b/ipcl/include/ipcl/base_text.hpp @@ -34,6 +34,30 @@ class BaseText { */ BaseText& operator=(const BaseText& other); + /** + * Overloading [] operator to access BigNumber elements + */ + BigNumber& operator[](const std::size_t idx); + + /** + * Insert a big number before pos + * @param[in] pos Position in m_texts + * @bn[in] Big number need to be inserted + */ + void insert(const std::size_t pos, BigNumber& bn); + + /** + * Clear all big number element + */ + void clear(); + + /** + * Remove big number element for pos to pos+length. + * @param[in] pos Position in m_texts + * @length[in] Length need to be removed(default value is 1) + */ + void remove(const std::size_t pos, const std::size_t length = 1); + /** * Gets the specified BigNumber element in m_text * @param[in] idx Element index @@ -74,6 +98,8 @@ class BaseText { */ std::size_t getSize() const; + const void* addr = static_cast(this); + protected: std::vector m_texts; ///< Container used to store BigNumber std::size_t m_size; ///< Container size diff --git a/ipcl/include/ipcl/ciphertext.hpp b/ipcl/include/ipcl/ciphertext.hpp index bd6d701..a742921 100644 --- a/ipcl/include/ipcl/ciphertext.hpp +++ b/ipcl/include/ipcl/ciphertext.hpp @@ -41,10 +41,15 @@ class CipherText : public BaseText { // CT*PT CipherText operator*(const PlainText& other) const; + /** + * Get ciphertext of idx + */ + CipherText getCipherText(const size_t& idx) const; + /** * Get public key */ - PublicKey getPubKey() const; + const PublicKey* getPubKey() const; /** * Rotate CipherText @@ -52,8 +57,6 @@ class CipherText : public BaseText { */ CipherText rotate(int shift) const; - const void* addr = static_cast(this); - private: BigNumber raw_add(const BigNumber& a, const BigNumber& b) const; BigNumber raw_mul(const BigNumber& a, const BigNumber& b) const; diff --git a/ipcl/include/ipcl/plaintext.hpp b/ipcl/include/ipcl/plaintext.hpp index 8b34e7d..fcdb49d 100644 --- a/ipcl/include/ipcl/plaintext.hpp +++ b/ipcl/include/ipcl/plaintext.hpp @@ -9,6 +9,8 @@ #include "ipcl/base_text.hpp" namespace ipcl { + +class CipherText; /** * This structure encapsulates types uint32_t, * uint32_t vector, BigNumber and BigNumber vector. @@ -58,6 +60,16 @@ class PlainText : public BaseText { */ operator std::vector(); + /** + * PT + CT + */ + CipherText operator+(const CipherText& other) const; + + /** + * PT * CT + */ + CipherText operator*(const CipherText& other) const; + /** * User define implicit type conversion * Convert 1st element to type BigNumber. @@ -69,6 +81,12 @@ class PlainText : public BaseText { * Convert all element to type BigNumber. */ operator std::vector(); + + /** + * Rotate PlainText + * @param[in] shift rotate length + */ + PlainText rotate(int shift) const; }; } // namespace ipcl diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp index 9f9c9b5..b40b7fd 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -38,6 +38,13 @@ class PublicKey { */ void enableDJN(); + /** + * Set DJN with given parameters + * @param[in] hs hs value for DJN scheme + * @param[in] randbit random bit for DJN scheme + */ + void setDJN(const BigNumber& hs, int randbit); + /** * Encrypt plaintext * @param[in] plaintext of type PlainText @@ -78,12 +85,32 @@ class PublicKey { void applyObfuscator(std::vector& obfuscator) const; /** - * @brief Set the Random object for ISO/IEC 18033-6 compliance check - * - * @param r + * Set the Random object for ISO/IEC 18033-6 compliance check + * @param[in] r */ void setRandom(const std::vector& r); + /** + * Check if using DJN scheme + */ + bool isDJN() const { return m_enable_DJN; } + + /** + * Get hs for DJN scheme + */ + BigNumber getHS() const { + if (m_enable_DJN) return m_hs; + return BigNumber::Zero(); + } + + /** + * Get randbits for DJN scheme + */ + int getRandBits() const { + if (m_enable_DJN) return m_randbits; + return -1; + } + const void* addr = static_cast(this); private: diff --git a/ipcl/include/ipcl/util.hpp b/ipcl/include/ipcl/util.hpp index 8bd0356..b264816 100644 --- a/ipcl/include/ipcl/util.hpp +++ b/ipcl/include/ipcl/util.hpp @@ -36,5 +36,36 @@ inline void vec_size_check(const std::vector& v, const char* file, #define VEC_SIZE_CHECK(v) vec_size_check(v, __FILE__, __LINE__) +#ifdef IPCL_USE_OMP +class OMPUtilities { + public: + static const int MaxThreads; + + static int assignOMPThreads(int& remaining_threads, int requested_threads) { + int retval = (requested_threads > 0 ? requested_threads : 1); + if (retval > remaining_threads) retval = remaining_threads; + if (retval > 1) + remaining_threads -= retval; + else + retval = 1; + return retval; + } + + private: + static const int nodes; + static const int cpus; + + static int getMaxThreads() { +#ifdef IPCL_NUM_THREADS + return IPCL_NUM_THREADS; +#else + return cpus / nodes; +#endif // IPCL_NUM_THREADS + } +}; + +#endif // IPCL_USE_OMP + } // namespace ipcl + #endif // IPCL_INCLUDE_IPCL_UTIL_HPP_ diff --git a/ipcl/keygen.cpp b/ipcl/keygen.cpp index 9a8dcbf..efbf1d6 100644 --- a/ipcl/keygen.cpp +++ b/ipcl/keygen.cpp @@ -12,6 +12,7 @@ namespace ipcl { constexpr int N_BIT_SIZE_MAX = 2048; +constexpr int N_BIT_SIZE_MIN = 16; static void rand32u(std::vector& addr) { std::random_device dev; @@ -52,9 +53,27 @@ BigNumber getPrimeBN(int maxBitSize) { return pBN; } +static BigNumber getPrimeDistance(int64_t key_size) { + uint64_t count = key_size / 2 - 100; + uint64_t ct32 = count / 32; // number of 2**32 needed + uint64_t res = count & 0x1F; // count % 32 + std::vector tmp(ct32 + 1, 0); + tmp[ct32] = 1 << res; + + BigNumber ref_dist(tmp.data(), tmp.size()); + return ref_dist; +} + +static bool isClosePrimeBN(const BigNumber& p, const BigNumber& q, + const BigNumber& ref_dist) { + BigNumber real_dist = (p >= q) ? (p - q) : (q - p); + return (real_dist > ref_dist) ? false : true; +} + static void getNormalBN(int64_t n_length, BigNumber& p, BigNumber& q, - BigNumber& n) { - for (int64_t len = 0; len != n_length; len = n.BitSize()) { + BigNumber& n, const BigNumber& ref_dist) { + for (int64_t len = 0; (len != n_length) || isClosePrimeBN(p, q, ref_dist); + len = n.BitSize()) { p = getPrimeBN(n_length / 2); q = p; while (q == p) { @@ -64,8 +83,8 @@ static void getNormalBN(int64_t n_length, BigNumber& p, BigNumber& q, } } -static void getDJNBN(int64_t n_length, BigNumber& p, BigNumber& q, - BigNumber& n) { +static void getDJNBN(int64_t n_length, BigNumber& p, BigNumber& q, BigNumber& n, + BigNumber& ref_dist) { BigNumber gcd; do { do { @@ -77,9 +96,9 @@ static void getDJNBN(int64_t n_length, BigNumber& p, BigNumber& q, } while (q == p || !p.TestBit(1)); // get q: q!=p and q mod 4 = 3 gcd = (p - 1).gcd(q - 1); // (p - 1) is a BigNumber - } while (gcd.compare(2)); // gcd(p-1,q-1)=2 - - n = p * q; + n = p * q; + } while ((gcd.compare(2)) || (n.BitSize() != n_length) || + isClosePrimeBN(p, q, ref_dist)); // gcd(p-1,q-1)=2 } keyPair generateKeypair(int64_t n_length, bool enable_DJN) { @@ -91,13 +110,17 @@ keyPair generateKeypair(int64_t n_length, bool enable_DJN) { n_length <= N_BIT_SIZE_MAX, "generateKeyPair: modulus size in bits should belong to either 1Kb, 2Kb, " "3Kb or 4Kb range only, key size exceed the range!!!"); + ERROR_CHECK((n_length >= N_BIT_SIZE_MIN) && (n_length % 4 == 0), + "generateKeyPair: key size should >=16, and divisible by 4"); + + BigNumber ref_dist = getPrimeDistance(n_length); BigNumber p, q, n; if (enable_DJN) - getDJNBN(n_length, p, q, n); + getDJNBN(n_length, p, q, n, ref_dist); else - getNormalBN(n_length, p, q, n); + getNormalBN(n_length, p, q, n, ref_dist); PublicKey* public_key = new PublicKey(n, n_length, enable_DJN); PrivateKey* private_key = new PrivateKey(public_key, p, q); diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index 2df24ab..327ea0c 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -49,8 +49,10 @@ static std::vector heQatBnModExp( unsigned char* bn_remainder_data_[batch_size]; #if defined(IPCL_USE_QAT_LITE) - int base_len_[batch_size]; - int exp_len_[batch_size]; + // int base_len_[batch_size]; + std::vector base_len_(batch_size, 0); + // int exp_len_[batch_size]; + std::vector exp_len_(batch_size, 0); #endif // Pre-allocate memory used to batch input data @@ -613,7 +615,9 @@ std::vector ippModExp(const std::vector& base, std::size_t remainder = v_size % IPCL_CRYPTO_MB_SIZE; #ifdef IPCL_USE_OMP -#pragma omp parallel for + int omp_remaining_threads = OMPUtilities::MaxThreads; +#pragma omp parallel for num_threads( \ + OMPUtilities::assignOMPThreads(omp_remaining_threads, num_chunk)) #endif // IPCL_USE_OMP for (std::size_t i = 0; i < num_chunk; i++) { auto base_start = base.begin() + i * IPCL_CRYPTO_MB_SIZE; @@ -666,7 +670,9 @@ std::vector ippModExp(const std::vector& base, #else #ifdef IPCL_USE_OMP -#pragma omp parallel for + int omp_remaining_threads = OMPUtilities::MaxThreads; +#pragma omp parallel for num_threads( \ + OMPUtilities::assignOMPThreads(omp_remaining_threads, v_size)) #endif // IPCL_USE_OMP for (int i = 0; i < v_size; i++) res[i] = ippSBModExp(base[i], pow[i], m[i]); return res; diff --git a/ipcl/plaintext.cpp b/ipcl/plaintext.cpp index a4feccf..4e4498d 100644 --- a/ipcl/plaintext.cpp +++ b/ipcl/plaintext.cpp @@ -3,6 +3,9 @@ #include "ipcl/plaintext.hpp" +#include + +#include "ipcl/ciphertext.hpp" #include "ipcl/util.hpp" namespace ipcl { @@ -23,6 +26,14 @@ PlainText& PlainText::operator=(const PlainText& other) { return *this; } +CipherText PlainText::operator+(const CipherText& other) const { + return other.operator+(*this); +} + +CipherText PlainText::operator*(const CipherText& other) const { + return other.operator*(*this); +} + PlainText::operator std::vector() { ERROR_CHECK(m_size > 0, "PlainText: type conversion to uint32_t vector error"); @@ -43,4 +54,22 @@ PlainText::operator std::vector() { return m_texts; } +PlainText PlainText::rotate(int shift) const { + ERROR_CHECK(m_size != 1, "rotate: Cannot rotate single CipherText"); + ERROR_CHECK(shift >= -m_size && shift <= m_size, + "rotate: Cannot shift more than the test size"); + + if (shift == 0 || shift == m_size || shift == -m_size) + return PlainText(m_texts); + + if (shift > 0) + shift = m_size - shift; + else + shift = -shift; + + std::vector new_bn = getTexts(); + std::rotate(std::begin(new_bn), std::begin(new_bn) + shift, std::end(new_bn)); + return PlainText(new_bn); +} + } // namespace ipcl diff --git a/ipcl/pri_key.cpp b/ipcl/pri_key.cpp index 3d8c80c..060e858 100644 --- a/ipcl/pri_key.cpp +++ b/ipcl/pri_key.cpp @@ -54,10 +54,12 @@ PrivateKey::PrivateKey(const PublicKey* public_key, const BigNumber& p, } PlainText PrivateKey::decrypt(const CipherText& ct) const { - ERROR_CHECK(ct.getPubKey().getN() == m_pubkey->getN(), + ERROR_CHECK(ct.getPubKey()->getN() == m_pubkey->getN(), "decrypt: The value of N in public key mismatch."); std::size_t ct_size = ct.getSize(); + ERROR_CHECK(ct_size > 0, "decrypt: Cannot decrypt empty CipherText"); + std::vector pt_bn(ct_size); std::vector ct_bn = ct.getTexts(); @@ -77,15 +79,15 @@ void PrivateKey::decryptRAW(std::vector& plaintext, std::vector modulo(v_size, m_nsquare); std::vector res = ipcl::ippModExp(ciphertext, pow_lambda, modulo); - BigNumber nn = m_n; - BigNumber xx = m_x; - #ifdef IPCL_USE_OMP -#pragma omp parallel for + int omp_remaining_threads = OMPUtilities::MaxThreads; +#pragma omp parallel for num_threads( \ + OMPUtilities::assignOMPThreads(omp_remaining_threads, v_size)) #endif // IPCL_USE_OMP for (int i = 0; i < v_size; i++) { - BigNumber m = (res[i] - 1) / nn; - m = m * xx; + BigNumber nn = m_n; + BigNumber xx = m_x; + BigNumber m = ((res[i] - 1) / nn) * xx; plaintext[i] = m % nn; } } @@ -99,6 +101,11 @@ void PrivateKey::decryptCRT(std::vector& plaintext, std::vector pm1(v_size, m_pminusone), qm1(v_size, m_qminusone); std::vector psq(v_size, m_psquare), qsq(v_size, m_qsquare); +#ifdef IPCL_USE_OMP + int omp_remaining_threads = OMPUtilities::MaxThreads; +#pragma omp parallel for num_threads( \ + OMPUtilities::assignOMPThreads(omp_remaining_threads, v_size)) +#endif // IPCL_USE_OMP for (int i = 0; i < v_size; i++) { basep[i] = ciphertext[i] % psq[i]; baseq[i] = ciphertext[i] % qsq[i]; @@ -109,7 +116,9 @@ void PrivateKey::decryptCRT(std::vector& plaintext, std::vector resq = ipcl::ippModExp(baseq, qm1, qsq); #ifdef IPCL_USE_OMP -#pragma omp parallel for + omp_remaining_threads = OMPUtilities::MaxThreads; +#pragma omp parallel for num_threads( \ + OMPUtilities::assignOMPThreads(omp_remaining_threads, v_size)) #endif // IPCL_USE_OMP for (int i = 0; i < v_size; i++) { BigNumber dp = computeLfun(resp[i], m_p) * m_hp % m_p; diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index 5ebb419..b4fe94f 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -45,44 +45,24 @@ std::vector PublicKey::randIpp32u(int size) const { } // length is arbitrary -BigNumber PublicKey::getRandom(int length) const { +BigNumber PublicKey::getRandom(int bit_len) const { IppStatus stat; - int size; - constexpr int seedBitSize = 160; - constexpr int seedSize = BITSIZE_WORD(seedBitSize); - - stat = ippsPRNGGetSize(&size); - ERROR_CHECK(stat == ippStsNoErr, - "getRandom: get IppsPRNGState context error."); - - auto rands = std::vector(size); - - stat = - ippsPRNGInit(seedBitSize, reinterpret_cast(rands.data())); - ERROR_CHECK(stat == ippStsNoErr, "getRandom: init rand context error."); - - auto seed = randIpp32u(seedSize); - BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); - - stat = ippsPRNGSetSeed(BN(bseed), - reinterpret_cast(rands.data())); - ERROR_CHECK(stat == ippStsNoErr, "getRandom: set up seed value error."); + int bn_buf_size; // define length Big Numbers - int bn_size = BITSIZE_WORD(length); - stat = ippsBigNumGetSize(bn_size, &size); + int bn_len = BITSIZE_WORD(bit_len); + stat = ippsBigNumGetSize(bn_len, &bn_buf_size); ERROR_CHECK(stat == ippStsNoErr, "getRandom: get IppsBigNumState context error."); - IppsBigNumState* pBN = reinterpret_cast(alloca(size)); + IppsBigNumState* pBN = + reinterpret_cast(alloca(bn_buf_size)); ERROR_CHECK(pBN != nullptr, "getRandom: big number alloca error"); - stat = ippsBigNumInit(bn_size, pBN); + stat = ippsBigNumInit(bn_len, pBN); ERROR_CHECK(stat == ippStsNoErr, "getRandom: init big number context error."); - int bnBitSize = length; - ippsPRNGenRDRAND_BN(pBN, bnBitSize, - reinterpret_cast(rands.data())); + ippsPRNGenRDRAND_BN(pBN, bit_len, NULL); return BigNumber{pBN}; } @@ -161,9 +141,18 @@ std::vector PublicKey::raw_encrypt(const std::vector& pt, CipherText PublicKey::encrypt(const PlainText& pt, bool make_secure) const { std::size_t pt_size = pt.getSize(); + ERROR_CHECK(pt_size > 0, "encrypt: Cannot encrypt emtpy PlainText"); std::vector ct_bn_v(pt_size); ct_bn_v = raw_encrypt(pt.getTexts(), make_secure); return CipherText(this, ct_bn_v); } + +void PublicKey::setDJN(const BigNumber& hs, int randbit) { + if (m_enable_DJN) return; + + m_hs = hs; + m_randbits = randbit; + m_enable_DJN = true; +} } // namespace ipcl diff --git a/ipcl/util.cpp b/ipcl/util.cpp new file mode 100644 index 0000000..1de2b49 --- /dev/null +++ b/ipcl/util.cpp @@ -0,0 +1,19 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/util.hpp" + +#ifdef IPCL_USE_OMP +#include +#endif // IPCL_USE_OMP + +namespace ipcl { + +#ifdef IPCL_USE_OMP +const int OMPUtilities::nodes = numa_num_configured_nodes(); +const int OMPUtilities::cpus = numa_num_configured_cpus(); +const int OMPUtilities::MaxThreads = OMPUtilities::getMaxThreads(); + +#endif // IPCL_USE_OMP + +} // namespace ipcl diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6d0bd6d..ac7389d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -12,7 +12,8 @@ target_include_directories(unittest_ipcl PRIVATE ${IPCL_INC_DIR} ) target_link_libraries(unittest_ipcl PRIVATE - ipcl libgtest Threads::Threads + ipcl -pthread libgtest + # ipcl Threads::Threads libgtest ) # enable QAT unittests diff --git a/test/test_ops.cpp b/test/test_ops.cpp index 6bb9c4e..30ad188 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -87,6 +87,44 @@ void AddSub(ipcl::CipherText& res, const ipcl::CipherText& ct1, res = ipcl::CipherText(key.pub_key, sum_bn_v); } +void PtPlusCt(ipcl::CipherText& res, const ipcl::PlainText& pt2, + const ipcl::CipherText& ct1, const ipcl::keyPair key) { + int size = ct1.getSize(); + std::vector sum_bn_v(size); + + for (int i = 0; i < size; i++) { + ipcl::CipherText a(key.pub_key, ct1.getElement(i)); + ipcl::PlainText b(pt2.getElement(i)); + ipcl::CipherText sum = b + a; + sum_bn_v[i] = sum.getElement(0); + } + res = ipcl::CipherText(key.pub_key, sum_bn_v); +} + +void PtPlusCtArray(ipcl::CipherText& res, const ipcl::PlainText& pt2, + const ipcl::CipherText& ct1, const ipcl::keyPair key) { + res = pt2 + ct1; +} + +void PtMultiplyCt(ipcl::CipherText& res, const ipcl::PlainText& pt2, + const ipcl::CipherText& ct1, const ipcl::keyPair key) { + int size = ct1.getSize(); + std::vector product_bn_v(size); + + for (int i = 0; i < size; i++) { + ipcl::CipherText a(key.pub_key, ct1.getElement(i)); + ipcl::PlainText b(pt2.getElement(i)); + ipcl::CipherText product = b * a; + product_bn_v[i] = product.getElement(0); + } + res = ipcl::CipherText(key.pub_key, product_bn_v); +} + +void PtMultiplyCtArray(ipcl::CipherText& res, const ipcl::PlainText& pt2, + const ipcl::CipherText& ct1, const ipcl::keyPair key) { + res = pt2 * ct1; +} + TEST(OperationTest, CtPlusCtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; @@ -410,3 +448,163 @@ TEST(OperationTest, AddSubTest) { delete key.pub_key; delete key.priv_key; } + +TEST(OperationTest, PtPlusCtTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + + ipcl::keyPair key = ipcl::generateKeypair(2048); + + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_sum; + ipcl::CipherText ct1, ct2, ct_sum; + + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); + } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); + + ct1 = key.pub_key->encrypt(pt1); + + PtPlusCt(ct_sum, pt2, ct1, key); + + dt_sum = key.priv_key->decrypt(ct_sum); + + for (int i = 0; i < num_values; i++) { + std::vector v = dt_sum.getElementVec(i); + uint64_t sum = v[0]; + if (v.size() > 1) sum = ((uint64_t)v[1] << 32) | v[0]; + + uint64_t exp_sum = (uint64_t)exp_value1[i] + (uint64_t)exp_value2[i]; + + EXPECT_EQ(sum, exp_sum); + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, PtPlusCtArrayTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + + ipcl::keyPair key = ipcl::generateKeypair(2048); + + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_sum; + ipcl::CipherText ct1, ct2, ct_sum; + + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); + } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); + + ct1 = key.pub_key->encrypt(pt1); + + PtPlusCtArray(ct_sum, pt2, ct1, key); + + dt_sum = key.priv_key->decrypt(ct_sum); + + for (int i = 0; i < num_values; i++) { + std::vector v = dt_sum.getElementVec(i); + uint64_t sum = v[0]; + if (v.size() > 1) sum = ((uint64_t)v[1] << 32) | v[0]; + + uint64_t exp_sum = (uint64_t)exp_value1[i] + (uint64_t)exp_value2[i]; + + EXPECT_EQ(sum, exp_sum); + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, PtMultiplyCtTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + + ipcl::keyPair key = ipcl::generateKeypair(2048); + + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_product; + ipcl::CipherText ct1, ct2, ct_product; + + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); + } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); + + ct1 = key.pub_key->encrypt(pt1); + + PtMultiplyCt(ct_product, pt2, ct1, key); + + dt_product = key.priv_key->decrypt(ct_product); + + for (int i = 0; i < num_values; i++) { + std::vector v = dt_product.getElementVec(i); + uint64_t product = v[0]; + if (v.size() > 1) product = ((uint64_t)v[1] << 32) | v[0]; + + uint64_t exp_product = (uint64_t)exp_value1[i] * (uint64_t)exp_value2[i]; + + EXPECT_EQ(product, exp_product); + } + + delete key.pub_key; + delete key.priv_key; +} + +TEST(OperationTest, PtMultiplyCtArrayTest) { + const uint32_t num_values = SELF_DEF_NUM_VALUES; + + ipcl::keyPair key = ipcl::generateKeypair(2048); + + std::vector exp_value1(num_values), exp_value2(num_values); + ipcl::PlainText pt1, pt2, dt_product; + ipcl::CipherText ct1, ct2, ct_product; + + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < num_values; i++) { + exp_value1[i] = dist(rng); + exp_value2[i] = dist(rng); + } + pt1 = ipcl::PlainText(exp_value1); + pt2 = ipcl::PlainText(exp_value2); + + ct1 = key.pub_key->encrypt(pt1); + + PtMultiplyCtArray(ct_product, pt2, ct1, key); + + dt_product = key.priv_key->decrypt(ct_product); + + for (int i = 0; i < num_values; i++) { + std::vector v = dt_product.getElementVec(i); + uint64_t product = v[0]; + if (v.size() > 1) product = ((uint64_t)v[1] << 32) | v[0]; + + uint64_t exp_product = (uint64_t)exp_value1[i] * (uint64_t)exp_value2[i]; + + EXPECT_EQ(product, exp_product); + } + + delete key.pub_key; + delete key.priv_key; +} From 154bdc6e53e376c8887c0c059e11cfa14b18e624 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Mon, 27 Jun 2022 14:18:05 -0700 Subject: [PATCH 195/364] Updated version - QAT 2.0.0 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d9826b2..f608f99 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.15.1) -project(IPCL VERSION 1.1.3 LANGUAGES C CXX) +project(IPCL VERSION 2.0.0 LANGUAGES C CXX) include(CMakePackageConfigHelpers) include(CheckCCompilerFlag) From 05ed8a535ef8a998281e4af8be897d48d719ae8f Mon Sep 17 00:00:00 2001 From: fdiasmor Date: Mon, 11 Jul 2022 23:53:23 -0700 Subject: [PATCH 196/364] Static Lib Build (#20) * Enabled static library build Co-authored-by: sejunkim --- .clang-format | 9 + .gitignore | 12 +- CMakeLists.txt | 19 ++- add_pci_vf.xml | 6 + cmake/he_qat-0.1.0/HE_QATConfig.cmake | 45 +++++ cmake/he_qat/he_qatConfig.cmake | 1 + cmake/he_qat/heqat-util.cmake | 31 ++++ cmake/heqat-0.1.0/HEQATConfig.cmake | 45 +++++ cmake/ippcrypto.cmake | 65 ++++++++ common/CMakeLists.txt | 23 ++- extract/qae_mem_hugepage_utils.o | Bin 0 -> 8688 bytes extract/qae_mem_utils.o | Bin 0 -> 32216 bytes he_qat/CMakeLists.txt | 20 ++- icp/CMakeLists.txt | 24 ++- misc/CMakeLists.txt | 30 +++- perf_data/bs1bit1024.txt | 101 +++++++++++ perf_data/bs1bit8192.txt | 101 +++++++++++ perf_data/bs8bit1024.txt | 101 +++++++++++ perf_data/bs8bit4096.txt | 101 +++++++++++ perf_data/bs8bit8192.txt | 101 +++++++++++ profiling/README.md | 2 + samples/test_bnModExpBatch.cpp | 232 ++++++++++++++++++++++++++ signit.txt | 2 + start_qat_dev.sh | 12 ++ stop_qat_dev.sh | 12 ++ telemetry_helper.sh | 41 +++++ 26 files changed, 1110 insertions(+), 26 deletions(-) create mode 100644 .clang-format create mode 100644 add_pci_vf.xml create mode 100644 cmake/he_qat-0.1.0/HE_QATConfig.cmake create mode 100644 cmake/he_qat/he_qatConfig.cmake create mode 100644 cmake/he_qat/heqat-util.cmake create mode 100644 cmake/heqat-0.1.0/HEQATConfig.cmake create mode 100644 cmake/ippcrypto.cmake create mode 100644 extract/qae_mem_hugepage_utils.o create mode 100644 extract/qae_mem_utils.o create mode 100644 perf_data/bs1bit1024.txt create mode 100644 perf_data/bs1bit8192.txt create mode 100644 perf_data/bs8bit1024.txt create mode 100644 perf_data/bs8bit4096.txt create mode 100644 perf_data/bs8bit8192.txt create mode 100644 profiling/README.md create mode 100644 samples/test_bnModExpBatch.cpp create mode 100644 signit.txt create mode 100755 start_qat_dev.sh create mode 100755 stop_qat_dev.sh create mode 100755 telemetry_helper.sh diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..c16dae7 --- /dev/null +++ b/.clang-format @@ -0,0 +1,9 @@ +BasedOnStyle: Google +Language: Cpp +DerivePointerAlignment: false +PointerAlignment: Left +IndentWidth: 4 +AccessModifierOffset: -4 +IndentCaseLabels: false +SortIncludes: false +ColumnLimit: 80 diff --git a/.gitignore b/.gitignore index bcdff71..3b962b7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,12 @@ -build +.vscode/ +.vs/ + + +build*/ install + +cmake/he_qat-*.*.*/HE_QATConfig.cmake +*.log +Doxyfile + +**.swp \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 63ebcb3..c663c0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,10 +36,12 @@ set(CMAKE_CXX_FLAGS "-O2 -fpermissive") # What does it do? set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -# When to use it? +# When to use it? To build with shared libraries. set(CMAKE_POSITION_INDEPENDENT_CODE ON) + # Why? set(CMAKE_INSTALL_MESSAGE LAZY) + # Why? set(CMAKE_INSTALL_RPATH "\$ORIGIN") @@ -51,7 +53,7 @@ message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") # Which features or functions does it bring? include(GNUInstallDirs) -# What is CMAKE_ARCHIVE_OUTPUT_DIRECTORY? +# Location where to unpack and pack static libraries set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) # ------------------------------------------------------------------- @@ -83,11 +85,14 @@ if(HE_QAT_MISC) # IPP Crypto installation if(IPPCP_PREFIX_PATH) list(APPEND CMAKE_PREFIX_PATH "${IPPCP_PREFIX_PATH}") + set(IPPCP_DIR "${IPPCP_PREFIX_PATH}/../../../") + message(STATUS "IPPCP_DIR=${IPPCP_DIR}") else() # Default to this set(IPPCP_DIR "/opt/ipp-crypto") set(IPPCP_PREFIX_PATH "${IPPCP_DIR}/lib/cmake") list(APPEND CMAKE_PREFIX_PATH "${IPPCP_PREFIX_PATH}") + message(STATUS "Else IPPCP_DIR=${IPPCP_DIR}") endif() find_package(IPPCP REQUIRED) message(STATUS "IPPCP_LIBRARIES ${IPPCP_LIBRARIES}") @@ -103,6 +108,7 @@ endif() set(HE_QAT_FORWARD_CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -DCMAKE_C_STANDARD=${CMAKE_C_STANDARD} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED=${CMAKE_CXX_STANDARD_REQUIRED} @@ -115,6 +121,12 @@ set(HE_QAT_FORWARD_CMAKE_ARGS #OpenSSL installation +if(NOT HE_QAT_SHARED) + set(OPENSSL_USE_STATIC_LIBS TRUE) + message(STATUS "OPENSSL_USE_STATIC_LIBS TRUE") +else() + message(STATUS "OPENSSL_USE_STATIC_LIBS FALSE") +endif() find_package(OpenSSL REQUIRED) # External dependencies @@ -124,7 +136,8 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) #set(OPENSSL_INC_DIR /opt/openssl/include) #set(OPENSSL_LIB_DIR /opt/openssl/lib) -#set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/he_qat) +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/he_qat) +include(heqat-util) set(COMMON_INC_DIR ${CMAKE_CURRENT_LIST_DIR}/include) if(NOT CMAKE_INSTALL_PREFIX) diff --git a/add_pci_vf.xml b/add_pci_vf.xml new file mode 100644 index 0000000..a55b6ac --- /dev/null +++ b/add_pci_vf.xml @@ -0,0 +1,6 @@ + + + +
+ + diff --git a/cmake/he_qat-0.1.0/HE_QATConfig.cmake b/cmake/he_qat-0.1.0/HE_QATConfig.cmake new file mode 100644 index 0000000..6f9b195 --- /dev/null +++ b/cmake/he_qat-0.1.0/HE_QATConfig.cmake @@ -0,0 +1,45 @@ +# Copyright (C) 2021 Intel Corporation + + +####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() ####### +####### Any changes to this file will be overwritten by the next CMake run #### +####### The input file was HE_QATConfig.cmake.in ######## + +get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE) + +macro(set_and_check _var _file) + set(${_var} "${_file}") + if(NOT EXISTS "${_file}") + message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !") + endif() +endmacro() + +macro(check_required_components _NAME) + foreach(comp ${${_NAME}_FIND_COMPONENTS}) + if(NOT ${_NAME}_${comp}_FOUND) + if(${_NAME}_FIND_REQUIRED_${comp}) + set(${_NAME}_FOUND FALSE) + endif() + endif() + endforeach() +endmacro() + +#################################################################################### + +include(CMakeFindDependencyMacro) + +include(${CMAKE_CURRENT_LIST_DIR}/he_qatTargets.cmake) + +if(TARGET HE_QAT::he_qat) + set(HE_QAT_FOUND TRUE) + message(STATUS "Intel Homomorphic Encryption Acceleration Library for QAT found") +else() + message(STATUS "Intel Homomorphic Encryption Acceleraiton Library for QAT not found") +endif() + +set(HE_QAT_VERSION "@HE_QAT_VERSION") +set(HE_QAT_VERSION_MAJOR "@HE_QAT_VERSION_MAJOR") +set(HE_QAT_VERSION_MINOR "@HE_QAT_VERSION") +set(HE_QAT_VERSION_PATCH "@HE_QAT_VERSION") + +set(HE_QAT_DEBUG "@HE_QAT_DEBUG") diff --git a/cmake/he_qat/he_qatConfig.cmake b/cmake/he_qat/he_qatConfig.cmake new file mode 100644 index 0000000..eed8897 --- /dev/null +++ b/cmake/he_qat/he_qatConfig.cmake @@ -0,0 +1 @@ +include("${CMAKE_CURRENT_LIST_DIR}/he_qatTargets.cmake") diff --git a/cmake/he_qat/heqat-util.cmake b/cmake/he_qat/heqat-util.cmake new file mode 100644 index 0000000..0b5ca8a --- /dev/null +++ b/cmake/he_qat/heqat-util.cmake @@ -0,0 +1,31 @@ +# Copyright (C) 2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Add dependency to the target archive +function(heqat_create_archive target dependency) + # For proper export of IPCLConfig.cmake / IPCLTargets.cmake, + # we avoid explicitly linking dependencies via target_link_libraries, since + # this would add dependencies to the exported ipcl target. + add_dependencies(${target} ${dependency}) + + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + add_custom_command(TARGET ${target} POST_BUILD + COMMAND ar -x $ + COMMAND ar -x $ + COMMAND ar -qcs $ *.o + COMMAND rm -f *.o + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${target} ${dependency} + ) + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + add_custom_command(TARGET ${target} POST_BUILD + COMMAND lib.exe /OUT:$ + $ + $ + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${target} ${dependency} + ) + else() + message(WARNING "Unsupported compiler ${CMAKE_CXX_COMPILER_ID}") + endif() +endfunction() diff --git a/cmake/heqat-0.1.0/HEQATConfig.cmake b/cmake/heqat-0.1.0/HEQATConfig.cmake new file mode 100644 index 0000000..6f9b195 --- /dev/null +++ b/cmake/heqat-0.1.0/HEQATConfig.cmake @@ -0,0 +1,45 @@ +# Copyright (C) 2021 Intel Corporation + + +####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() ####### +####### Any changes to this file will be overwritten by the next CMake run #### +####### The input file was HE_QATConfig.cmake.in ######## + +get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE) + +macro(set_and_check _var _file) + set(${_var} "${_file}") + if(NOT EXISTS "${_file}") + message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !") + endif() +endmacro() + +macro(check_required_components _NAME) + foreach(comp ${${_NAME}_FIND_COMPONENTS}) + if(NOT ${_NAME}_${comp}_FOUND) + if(${_NAME}_FIND_REQUIRED_${comp}) + set(${_NAME}_FOUND FALSE) + endif() + endif() + endforeach() +endmacro() + +#################################################################################### + +include(CMakeFindDependencyMacro) + +include(${CMAKE_CURRENT_LIST_DIR}/he_qatTargets.cmake) + +if(TARGET HE_QAT::he_qat) + set(HE_QAT_FOUND TRUE) + message(STATUS "Intel Homomorphic Encryption Acceleration Library for QAT found") +else() + message(STATUS "Intel Homomorphic Encryption Acceleraiton Library for QAT not found") +endif() + +set(HE_QAT_VERSION "@HE_QAT_VERSION") +set(HE_QAT_VERSION_MAJOR "@HE_QAT_VERSION_MAJOR") +set(HE_QAT_VERSION_MINOR "@HE_QAT_VERSION") +set(HE_QAT_VERSION_PATCH "@HE_QAT_VERSION") + +set(HE_QAT_DEBUG "@HE_QAT_DEBUG") diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake new file mode 100644 index 0000000..a12ad08 --- /dev/null +++ b/cmake/ippcrypto.cmake @@ -0,0 +1,65 @@ +# Copyright (C) 2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +include(ExternalProject) +MESSAGE(STATUS "Configuring ipp-crypto") +set(IPPCRYPTO_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_ipp-crypto) +set(IPPCRYPTO_GIT_REPO_URL https://github.com/intel/ipp-crypto.git) +set(IPPCRYPTO_GIT_LABEL ipp-crypto_2021_4) +set(IPPCRYPTO_SRC_DIR ${IPPCRYPTO_PREFIX}/src/ext_ipp-crypto/) + +set(IPPCRYPTO_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS} -DNONPIC_LIB:BOOL=off -DMERGED_BLD:BOOL=on") + +set(IPPCRYPTO_ARCH intel64) +set(BUILD_x64 ON) +if(BUILD_x64) + if(NOT ${BUILD_x64}) + set(IPPCRYPTO_ARCH ia32) + endif() +endif() + +ExternalProject_Add( + ext_ipp-crypto + GIT_REPOSITORY ${IPPCRYPTO_GIT_REPO_URL} + GIT_TAG ${IPPCRYPTO_GIT_LABEL} + PREFIX ${IPPCRYPTO_PREFIX} + INSTALL_DIR ${IPPCRYPTO_PREFIX} + CMAKE_ARGS ${IPPCRYPTO_CXX_FLAGS} + -DCMAKE_INSTALL_PREFIX=${IPPCRYPTO_PREFIX} + -DARCH=${IPPCRYPTO_ARCH} + -DCMAKE_ASM_NASM_COMPILER=nasm + -DCMAKE_BUILD_TYPE=Release + UPDATE_COMMAND "" +) + +set(IPPCRYPTO_INC_DIR ${IPPCRYPTO_PREFIX}/include) + +if(IPCL_SHARED) + add_library(libippcrypto INTERFACE) + add_dependencies(libippcrypto ext_ipp-crypto) + + ExternalProject_Get_Property(ext_ipp-crypto SOURCE_DIR BINARY_DIR) + + target_link_libraries(libippcrypto INTERFACE ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libippcp.a ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libcrypto_mb.a) + target_include_directories(libippcrypto SYSTEM INTERFACE ${IPPCRYPTO_PREFIX}/include) + +else() + + add_library(libippcrypto::ippcp STATIC IMPORTED GLOBAL) + add_library(libippcrypto::crypto_mb STATIC IMPORTED GLOBAL) + + add_dependencies(libippcrypto::ippcp ext_ipp-crypto) + add_dependencies(libippcrypto::crypto_mb ext_ipp-crypto) + + find_package(OpenSSL REQUIRED) + + set_target_properties(libippcrypto::ippcp PROPERTIES + IMPORTED_LOCATION ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libippcp.a + INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} + ) + + set_target_properties(libippcrypto::crypto_mb PROPERTIES + IMPORTED_LOCATION ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libcrypto_mb.a + INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} + ) +endif() diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 6ce9dce..eb0ed9b 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -9,7 +9,12 @@ message(STATUS "ICP_INC_DIR: ${ICP_INC_DIR}") # Source files set(COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/cpa_sample_utils.c) -add_library(cpa_sample_utils ${COMMON_SRC}) +if(HE_QAT_SHARED) + add_library(cpa_sample_utils SHARED ${COMMON_SRC}) +else() + add_library(cpa_sample_utils STATIC ${COMMON_SRC}) +endif() + target_include_directories(cpa_sample_utils PRIVATE $ # Public headers PRIVATE $ # Public headers @@ -17,11 +22,21 @@ target_include_directories(cpa_sample_utils PRIVATE ${COMMON_INC_DIR} # Private headers PRIVATE ${ICP_INC_DIR} # Private headers ) + target_link_libraries(cpa_sample_utils PRIVATE udev z) -target_link_libraries(cpa_sample_utils PRIVATE ${ICP_BUILDOUTPUT_PATH}/libqat_s.so) -target_link_libraries(cpa_sample_utils PRIVATE ${ICP_BUILDOUTPUT_PATH}/libusdm_drv_s.so) -install(TARGETS cpa_sample_utils DESTINATION ${CMAKE_INSTALL_LIBDIR}) +if(HE_QAT_SHARED) + target_link_libraries(cpa_sample_utils PRIVATE ${ICP_BUILDOUTPUT_PATH}/libqat_s.so) + target_link_libraries(cpa_sample_utils PRIVATE ${ICP_BUILDOUTPUT_PATH}/libusdm_drv_s.so) +else() + heqat_create_archive(cpa_sample_utils libadf_static) + heqat_create_archive(cpa_sample_utils libosal_static) + heqat_create_archive(cpa_sample_utils libqat_static) + heqat_create_archive(cpa_sample_utils libusdm_drv_static) +endif() + +#install(TARGETS cpa_sample_utils DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install(TARGETS cpa_sample_utils EXPORT he_qatTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}) set(COMMON_INC_DIR ${COMMON_INC_DIR} PARENT_SCOPE) diff --git a/extract/qae_mem_hugepage_utils.o b/extract/qae_mem_hugepage_utils.o new file mode 100644 index 0000000000000000000000000000000000000000..5c82e82b428039bbc6eb714266c55f7069d4e61d GIT binary patch literal 8688 zcmcIoeQ+Da6<^zO5ZIN>M_Nxpk}H)#2BJubLlRS3%aQHPRFKrzG#wxpMLOB4^%d!q zCQwR1G37>aN&o8yf20i4P78(nK_R$|M-Vv4AL$@&@_~E#C)Aju zM=JiVDlpR0WwUhh6@APEuM*(12o9Uz@_FD5Cb)PW=mqeex2tXtc%;(KryS4HE;3iG z(hKK~x>xLDRs_mN<8hxD#Sb*HXLCJ!dh6NKWvZ^OK-I!3rkWh*szZc;UiS)U8|nLA zJ$?Q4^sO{ONz-Im@1#dgw}S(iM;&ur=m}8RhkC!zdWY)iUp-$xEDBUD167Ods^Y?< zc761ocV7d?Z!%!lbq{RQh{sQjuxEYP2zmO#(4+gx`Z{-a$g{=W9rkQ@caM0o?(PRY zdx6c}{jlc%YajI-WbG54L#%zqQ-(H1OO7rtbSOyc43z2AKF@JBd?ReUf}oR5g*?g( zhA0j@XsH#tWY*zvB2-#G8}c~((5)a$OCTmj*O)>JPI}KVwEifYWcwE!4Ns-3!IALP zZy}z^=*`sllosE0iuKddHFWZnzU)S*+QPyuXn@hk)d7FvAgEbabus)Ra@oM`!gJ|Y<+g^PQ|m#_!*pb4*k z##j4)vj_a`U9j^;k7uTJXJ;8Btb-c=rm(S2TrKm-WVx`6mcndv+s%l9t#%f!goS&- z_ry3dy%SwCwHA3Wl5W6G<(ucL)sxRL8P@p?-Vz+$WSqy{DZaZt?#{4~nrD$WP~K#` z4JLGMg+dQU^i_p?EahV{7&guv-nx~LI0WS7&xbtAA@Q-I>@x?-_wCAo7rR>qs6mT_r5=YmD3kN#e!{?O~Pu`O-9nwiSZ1s;_>XBd<^Jd z#c=qJv#1Mh6LH7*!p8g44*jI7kv=acgc|~Hw(rp5N+2dpw=VP# zTgLQk%}5a-OJQYo=%@d=kaX^oYBgB;k*AX{`W{Z#xPGyYYQzJF>xNU`MKzBJj{zMvSUKVgPUO=1 zPY6wxbOO?)``G;?6LS>hbme=yVoD+t)sspzl1wV`OimfobR|2!C!YXBiNs<#B_2s6 zwb->v4rXppx?*@hSuy!j6M0=rWxZYbZYE$nJEq2CoJ;v(LLXPOTrQpIwOCEQoe@n< zr6ON|QK*#oBC%bGy!QDz87sFFboDCQ?x?24w3w2L>{iALW15nUjA?lVmY<16^h73| zXRFZ16L}?@%S5$&-p5y5lcQwPHD)EHr82oak_f(d;V6@DS0bmc2G4$RUX#zZKZ#5# zRZt3PSk0H)C!3t;xE7sAq{ozWA+|CnG!L>DoMofeNlsG2Ut<7Qb*^ZHo0)#k5_k1W|s~PBOG{W3S>J-BC#E1!aS; z$LC)eD6moB$E*E5e~&NFZQ_jI0X1X|1W&}!O``;|kTPN{%YgPWc(63xF-)3vcQh?+ zzrc9_PAT$S&SnTH@)j{a?@ve=yk1zzOBlQ^S&8zt6WS#2{~6mM*YT$2nTuS`U|SCi z@8@&h$F|?qG1WZi>fGN#UCMoqpvzlq9dh~aaCw6+CFtse`F@v^AYU2jq1=nrAo6WO zKA^kL5#oH!+vhVP-&v%G@@4pN4Svi_q1=fTb@`jau!K+>Sr5Z7pDSPsw*0iY-_<$Q zGT>77;~MU34Y{^AKXH-E8*(WyW3Ga>kuZ?o&v~oRCpTHV{T6S~~i z&eym+wm!7;yUf*WUq9q??2ZRo1s*2^29~F>0^9dDH;*um=G(#3W}IBhY1)zIa|)_( zkoVbg?4&Jqzd$i2MO4n`XaPy~vIKx;Nsfq7562I11`(&L1wCK8h}G*kzL(=7UMa`t zIL=}guwjmuxi46}0+!&o!k57O4%l5BKV-uJhSgfHI~=ky1$7fyM6!H*32%SJ@hyD( zHQxS?;Whu@USYv~L^ zTgV0S(CW943$4D~X(8e*BBLm$Z9V{_GYnbiw{r|%sMq}U(MtN*e63o<7T8J-)gabu zKgsFKoSxl{K>uI^`iC3fk2Js!HNX!yz+Y^D zzXUj27Y}uDalI*U9$MmDpXK<=92e)P4ekY$GskgupTc^V0A6pu)-=Ee8sN8Z`G@#H zweDh;YHBGfcTo#^BANF^Niq|OnMsG$Qz3sf@d<5@)nVwy8$;^A@bKng63=Oxidm4F z)OKk}UpA7{eSQhnBRi5BW2%udjHqh7kdCUVuV?Ls4btd3|2i_JLNaDqnU`k+Yvs}E z)j(@yKB|^RbupP@ji30!8(GzZy#Q8guv(4PTCCP#bsbjgu>xy`!khbpVRiH1;LQUg z>PWCZJfM=i9)koPgzt)HbBVMbSEJ(-FwERT{s+F{{#IsSd$G;v( zA)QR5CkSSOBxPpzpn`oks3J2b(PSpC)g(!2rKMF)MJB9S@2=RyIYIv@M2YxZI@=K26F~3T}pOSE|gg5c`A<}nCxY_`J zuK}Lt_X;-GNOB(HII739DRR$8Bph=HVgFN-9NEslOY}=6`lb98gwyyFLddyV!hI4R zlJHd$9+7arg#SXq0}}oi$HlrZcf|5X3CFx$*z=MkNA~lp5-!VsQ<8&z6Y@_<_%ccU zXObMuv4q}>`8|sMk>x8Kx7&ZUgfExm1SC1~z6?q9s005YV2Mlg*Gh68kZ_D$VdudH za-NfL^aIMm@)rqT0b?O&PQqpSGZL;y^o#iW0d1H4cA13B`{m`h@SCt_m4ts?l7E*Z zM?M$7k?7IRc6hM-LBg+qu~^rPBuDoDKO}nD{~z0MA*a>J)UZrmw&zlgzG9Nx<-^$n*_yImac`I;8_F1{jhVSKg)`pAk zqy08qd>+weYq-u`9BxxX-P!y@F1{H+}U z2^aaB--e64i}><;QjqOHtLMyiT=a5UGUC&<-8%8bB6@`QcI5NKm&@P)$pb#fMa-dS zebKxgfHWlvf4;OdFs3uQ=7S$LD_I7@$7AV&5B}F>wVb{OI8lu@4lnmeN;9qh-)jX# zpo_R0ErET!_Y99mF=5YX@g0dV+9wEjyXC89=OBMydo86&hNMJzs&i?dqYeMyG5&VelaiFbDUp{MJxEkI0GF# zYWDSu7mXqac`N)U;GaMTW!m`_{-Wx$P1yO-zxCp84g(X4_)f?8!zBrR5r6e`Bj0ux v*6^Q>$1e`M;IZ>#m@J4rz$%wQ1!c@;zukWq15G{tt(bH{`I*^RwVnUJ=tn9T literal 0 HcmV?d00001 diff --git a/extract/qae_mem_utils.o b/extract/qae_mem_utils.o new file mode 100644 index 0000000000000000000000000000000000000000..7c4fb5af9db4e823df554901e0b876b9f9bed0b5 GIT binary patch literal 32216 zcmcJ13w)Ht)%UXrmvAu~1>1OK)ubj0F^MRNSlNYKp2ZDBNQ4R+Lb8F>+)Q>66qT5) z@^p!&ciZ~*wbj4_s);q z=b8VUIdkUBnKNf*Hr!C|t4MP=44oXtMMgZQQNviiA^z?buWsWw<5=SZ=c%8V)~Go& zQkWY>MKe5o*bMCstdZcE8hnJnB@#R}0sN)}k52&e0Cv9>b%Np0$W&D{?h!NB7>!2F zNu%4HGkS#-MT6U$nhJETsXvuG%aX}6KbbtU66Haop}|15IrQFC2qbzqZZwx9gA8uN z-o6?7II!4L>+5TadTM-qcNpjytJo0oj8hw~( zC_^1Gd$wozO5X@RZ}#lSSaG>$rRVbPyoYA@p?x6pTF`nR2WqOxDKsr#PKnPd%W?bg zX7&yS<~Z}qa;lyAzMNIg{F--_B`T-bnDJFdmeQwrt9vZ0WUAwy~1bhqG7)R<^}yglA_%QLrvPk ztE|^A?i)AGJM{Wwuj3Q*n+DYGym=2q@L6y9`c5HXnkuZ`HOonXL+?StlRqNR+c*6L zPtSpQ!CIe1qC$}q0<*l1QL}H{k%fKJMK?^x^UfKYh};}@S3^|DI+$UW4hIkW98aK= zPnwg`NKgnVjFY4k^jqDiRA#;A%ir%S9rQXY2hll4Re1JxZ~mZn&s)Ap#ooS}6EY5V zqbs6cP~pD@Zh@3!X6K={VfKBK9wXVGL5Jw|k38F`dp_&6fd`V&js9EEMXrRLT0b=Z zY5LtqlM1F~TA#&dAKLYW{YF*jK;XoOVNziI_Q*nT5mS&d)V|rX6I1Zr;B#i*wHf9x z(UFY9Jx4L=DVaTQA2sto?F&;ILy`0kOfh(Bwla5w`7Y)0TL19WU?^+7Lx*N9^>iN~ zR;KlV*YR&MeQ$VX4tWLm$9=G>oLo`t*r|kd_TEITin5bLnb)yH)p7O?P}$JIiMkwqo(tL>x|%ax+kIY{~!6~Q#~zX@Hj1B@3FumpM9=|Q1t2G z>+$|Y&P6%P29RX~B-aa1t=IYp<1_T`EU)!kt*84<(*IJg<1-AA9G_NrrFR3JW5%Zy z#`LbU_t!KA3FEWV8y0n(y|2g0j*E}0s`oW9Ne@nyV^?K0CXAg}U%uM-J+5?fo#6}- zQ{8%KA?Yn{4qtivf~e<%zQy=CL(ifUKJN4nfXs3eXa z5BA82N6}!>$ENlCHUs6D;SPhGjPj2}78b7397e-3ed%i`di{7I%)?-*+bkLskR{ky zJ0a)hAuMse@GRmgZ2Jj#3`um@W0lKS>d!p#Hi%}VP(JCx5!R?~4DBC>Njd@3CYT** z1ApoF&2Xy;%-OpF5C+aXyFAaFTb|MN){*io_q((jbqPQM z0vRYl&{GYHau?p+W#L>B*9=#gaG%pfbcV&-+50t7bD;?$vSrXYO|q`DQzw>}nxIYU320Pfv8HbY}_$?{y`snhFtSy+S+<)N3H)~Pgy z>M$r+$9&-_RiVe7y-%TMKI`uYh4JDHRiVc|>j^Xe9n*T&9Ewaf`!-e?WzIj}O!0@$ z8Z1YbdnbYx3wl$T^<#n;_Fd>OyQ8$WJ8ymiW#-U3S!UmL)jnzaUTcrpH~k-CND<#= z`1)pk9T7{Q*z-3xKyUstRi(pK&dQ_Sp6!l{!_zL!sNX>dAaHh}k;=;Z%IN71s(|vs_k2m@$&JhhE&heIRN1TJk5a>LCK+$_zxl!JG zAdo|0b+%_{|Kz5AlOkFZQ4^w@Mse5cLZKi-iP5QD4JoJTCBAAB%F;y4Tt%S}edI4;+W~QEn>3BT3%+G#VW!CTSCF z742P$_Dt!bG|w>(OSB~Y7p8qQau{(~Q~$u!G4hXOko4zEJ2d-Ra$K>^lJ%aRS&`qO zI_%UM8t5klNr`9<3P(AzMTXo1IV@}XgvgudReVQDdw`S7 z;rUYkJ`~Xt z<5x6T4kcNUfl>0h3FA1@4^ooqETQ^dVha<57u`iKNpy0KAlxMAhRaLn8TpnRH}w0| zvHdPkEj&hJFXMe+YJ{c?0XW0IeNIw=M34LO`Z;SJdkN0yRjJ%C$sNxCG z{U%PQ^bSkCm*`qQA!jKjqL6tFxMTXdu%N`(7BZ38+5%7b5=c$!lK9$EMB>KRmR77S zuvM%XLA|yF#M*Kl)|QQ8ZE4kOON&@rf>>JuYHhKGLW9A&*vhg6jfs`z-y|AeSI`HN zndqIpcl`^!nTFY9_8mj$!1Va+jO%9WVNh)XDW58FmHY(72Sa4|8!*Uj;v?2iJwYf| zvYVk0*Ds8)7R3Yk@pj{k-C!);fT$k%>?o<3+xbomm}E_jjh#lnLOCDrIPU}Rp-&sp zG>h&jewOD!!Uu@+ny-=9I~DjHm& z1dCKbEGCiOZ>VB@^db0ptQ|C&9~4$3Y!S{EVPY0$T!#&tBUP6Og;a#F-&hq_AVg)-x6R09KBW2cpwOQ_$0dZ(>!=A{=s3q5@ z$h9<(aetSvUXAee>OH|*`DD}DF4n70AedUOaL6WODw-WN;L6vlqCw9?9|F^2-f@WR zQP>LNSi$*ASFICJpX|&U_B=%07PSTzjWK^2z+HqEBA>vB6Ui@2LGC2-Cqe#2)7kS7 z2%;lz90YBc<_DX5_8vYAB0d9GfS#GBKCie`+o#<4^c-51uG864s||qKUg##oV;s@b!uCMOn1uqGNg59PPzGMoM5bY&}jMM9F=?*bTt%NwXH) z0PG+j?xbtsq^D7opXJP7kwx)6oO1&??bbqP{*|;9Ag|ozrriPd9UF74uRtQgLfz`s(qYL^?5X3v7-x~6FGo4z0Xc6?$6P>*!(>RN}u&^Rk)RQUoPRT z$LzB9k?Z41K1@Jd$+XK#hbF6_OQUO`HxZB>IiiIQi6RZPhyGPDYY zDo9OZH6TtWs!*2LebJLq^dzo_gJ*qV|JPwOzk2`I+WUWXV*e=;I2)Y|qW@jge~JLE zrT&+r{|l)9Rp|f4$@>2gtUuQOeaQUZ^q)^UHvi(U<)H)4TmMDUvZDpE?N`J!Da%>T z_Koil*0W=k-ZYB!RK?pATnGcxjB4J7r%{t5^ag^KWRBrJv`j>iM?fI`y-AzQN|I10-7 zJsufHbj?C4&5y;*R z%gKU{L?h3m`BeRAq;?C1R=!Za3yJQZh`r$LW5TjPB4IF>e>~ zLP*Fb&JXPTc7QH&R)YTil#Ji)M3)9Sp$rwT@-xuepc@tq^yX{^0R7W3=&djwv+uH~ z*V=1#V+`iuG~-&D%ct$Zxfi`ypQ!=$HM|v5_vj=nGJSug6QwHaBk$1R$vBFi?Cq-@ zFK-H(Id8rPzQ>CT#^?-WevXU^vV1aLLmNLFbpC13F^F5&nNlNk z|5}Cph|k-wqnwV5%W^Wp$747Q?A<2QsT7X1CI)eQh10qBd{%Vime->goFR&mL%Tue z#VMAz=krNdPpS&vPy$}Tzp3`{?(FTwA%-_xSt6Nw8=ms?{5u*r2HYok=Q^FCHIUpJ zUR>x6FGDmVS{D9$1_so$JS9|DMCAVg07T-@RuJRB&pTXMJp(dG(Y(WD&x;F32s`rj zYcVlqCTEO#@3|r7zr=Q&MHUUv3@U=5S#<1ThSp_E~b) zd96q3+Rxeh7)E#innWMpVq2xquYgz4J^bDDVy(;bhAUiZ7lK1AH)`MzRUd~~kKjOc zoauPN3{MsYFo6umT4egHtHddms_Bz+)@RLjDE)cE>+*2pv6t*JyvP+A^oFm;p=|&^ zEa*FL6?`DB=l3GOHZ4pP(u>PHVR!fI#wbqSy5BJj7vdolK2~+Y0TRbN?Fn)C@9jQd zWbKcdlXiK#cMugRKb!XMv-G+EmElJi*jY_ar&+$fdmsz?pC*$fDdp2TB zoxM?*4#dmz3|CC2AwDuhzyENC{)Trb2DjmIf*pZsq)iWvz`n~K6&5{`{XcPYei@pH znR7+lobSS*d94bVa|g_s+bDUF3^DxVMKUnLy;WFe^aa4*AzPwR%dO^~SA=CpP7`aA zAzc%KD{C_xbL3&Y{tbKw^|4LdChp6((sffJw~_CF5skh#e5qUQU}6JLJCz@hm*m7~fLisiX#VySA zCxI!3$}KirEy#!yvFAkxnbLHpif-r(I#3zEPZdVfGO(|T2$JYX&nWj5IzTLOGxU^IfS(dipI zI;WWri__80*B~I#V#g^w8`ug9kU1912^8Y8C}k%Ge1IHa(V*8F@mc?}jpx8iG@g|h z&t;gKdJ5A>u0sdl&ecdRlOwrZfR$n-ak-OIxNSOm>$5%=Q}Tmf(Vh)^!;Lx1g)HJ6 zGIR_oVeYswcNVHw+={&*Y#+W2)LCMSth@kK3Y^HtN+|;6Qy?x)!!+erouOv*Z5uua z(Qwm`$qi>J+9t0?4zQXm{0uRu#=!5#%#V?+FUqMg0h2&fWRB9;us@Zryd6_NnXlXc zT=>ds@gmeg6SW#Q*xdOFrzTp1ZAj+WoA0WEw~Wk1RiD+F0b&y*M&x~1y^d#xg%ksijA>iCuj#7!)glCT z%d0QC!SX_TVRuR7>LWrf)=OM5q>bS=^5i}&B4PBuh!)*=|7jLRAs~E225LnqVz^*X{Nia7IFmz;bb&zaPvP(~;CC<> zKY>~ic-h>~T*#NWoQP#D(G%SY#$(o$e+e+YrkpQUM!GU7q}Aejy|B>T3i9i)uplB5 zMS5Y`n6pY0VPOfVg+(u_p^u=R*y_@Vwgh{z#B4(mg^m=fu_Z=V?Og)%NVV2nyq8=# z7VgMQQ1v5*mG)xdf?nt}W^qLnB*tU9$n!Xx=0o9l%)X2LrEE9p27J#yUOrimC;9bLDfrS z^(>TL{C1RZQR6KEp}j58+1}z>-O}E0rK`Qu)zy5B-__CCzOK2^-zed_hCpYF>zl6J z4p)6!qohFYnxG3CP07yFg8KD==Jqz1zq1o;X1SL5uL?GIY93uK|M~{Mzp=};x;fBV z-{HEtxvjDN>H^n%(J(Up_0+^Q!I={3a&>A3vMp+QKCesUjU<9dQVwrhM=;>(sPC+A z^#}Z&u7>)yw)TK)wcoX<*5_mLHa2$pySiL~b}DP?gk(u*iLvBcE;@zY1=e=@>l+ z(*}`LO=`eS7wl-P4`8I~*NEZj@OK89{SZacEpGF>+M6IPQ7C0}xthC#8Vbe?s~mmk zvqP&>@sXobFSV7I+mVl+cL{yA23rEn9q0<0sYPFfS>)w5<|__T4zDsZ*?{5`H?LV^ zhrhs8-QLyJyt-wBtFb*u%B0aLu*vnMd}V_z{L-tuge8i-vZf|bGTuJDskc&o>IFGgYSbvp1 zVjXU%Z-B`qQBP|9boyKT^*(2DK~L(b3)+fPQs14JpwQl8)TFaaFzF6R2qKyi(*0DzBqCrm_aT z*U{XHm($c)R9oc{h#0Usp|HBHmipDY9`O;V0-E4wIDxFe7%Mu+Q{`{;~X@V8YoCe-)BBTGQilgNrdJt#(?MCZtqaH=B`&Ot?@lYC0^Hm26zey@DvR26cXSm7~m-+z%wfO#p5JmKsYg=Co!NWF`y?gpeHe)CovFDNFbhI zAf8|#o?sxJU?84gAf8|#o?sxK4)sh|&xz{kRL>deIZr)rP|v7-IwYScomNnqC?8R$ zdd^VKdFpwCdP0H}sdB-B3tV}%tAlNUpsTcCc0u8+qM*nXU0+;SP&m7wC|}}&0nP;I zq}f1}Yg8_(rSs-N!sMtL1|2R^a$K{-aIDXAoHTV}2Az{pos&fgP8QXZutN3TrJl68 zE>rKd^sLOx>PxH0%-)i2X1Z<~=gG|L8DE)M*pZp%$#i)#v*%}K&Cks6Y=88rr?Wx6 ziRvIdNne$j`yFWyPe$<+AF{U-hD1L@F;MT8wE4srd=%fZ%)<0>j>(yMWtpxr&AMVr z+K(j^Yt5Wu%m#}?#0=?1`l=u~y)k}eO3t)ZiGr>IX^xtV->0XjS5EcN=uP9wsoo`- zg=sZtGogo5(o7pPKN$p;)W&Aj#@DH@@iv4GO=@Ey+UT$`EKkNT&1a*kz|ERL`aGoC zcmTJ9q|aMPpSPsX&vf;To1dAtWxOY|@TLi#%#xmom6?N%^rzD%XO;lN7=i}0a_pc@ zX&)DotVmPkL)c7p609)^wq9YGsxH|Y{cR4V1@u*(nbnhaIc%X~%HqrngY4{HRsKDC z+Qv`V8SEi#6urmD#KwO96k(quy1fip_ZAxaKI;1xveBEU?>!UBGW#9rQ^!pfea2|U z`dqGcSg0mWI!y-1@P#_uXq~^n9f`_mIMV zpzLx>nwgn>6U~pFacL_jXJ&iET$?||gZBlQS<5mrU@=!A1HqSMW(Xmufh37ojx*j* z>W9(|Wk|Mq=`pX8SddOXFt?>+kxyfMdQ|yI3h!5W?Pqcno~4==z6Kc0YvR+P@F!J0 zdZY`l#{j%ugb&fXl|2aG0?fq6L949dlcCC&D10rRlyso73h%_HUv=$9Dn#nQhj14; zTqNN$@Wj$0@Il0*T! z%4}@hza?<-8xm2X-i2ve}|&aQqTWV z_-2*Y?b7cU$)49MT5esUy*AzMB3mg-fcqucv%^EGpHd@|n)YiQQ#0sIj1$Y>@3Ht4c~aNRFm`nkZz&aZSazsDP!Bp(Zr8$f{=_1oTR?O5s@w*YR_w z!V48HVrZ(01DQHH90~@STe=DwjF$HLMtQ&_-mdg-kY`SGvR~KYU*~Tz7F3nhl`mPc zc!@ZjlBY^_b>bqW>q?`pt|{2oP*+!Q-kjo6RyROb5k^-42b+R_-P(>dEK9s%Ct2b? z!w{#pbsf!(#+o|OykxOPoLkkkGz>)OPth7tpD%iF*;5#rc&Fv~j>k zrseomnWFzW{vN@tmeha!{Ng??OCdGnbv7kY3sU5+qSTHCSf)q&_-MXfZPTU_f)itaoQ|t=VH(W{Y zb#z*7(7CnIAukZ>gpt*?;G&Uiugf1W8d}=B{6;&@FO4<+02v-#o7JriuJM!obs6Gx z)y6=c_(OtDNYLIXY7#M-V{3imx@NG{9K=zsJa&yi&F!tN!8&n~V?YQ=5;u2gK2$(f zN(Z!w2qvfmV86+K_X}nRw#$sZOM0hbintunwiI1kgn&Ia%`ezhQ z58ki8s5pu6<&1uciihm@iWK;*4CnmmKi{BaZ})d8@N2~>wWR0rJedMNL#=OiIlEHe zcQc&J`CtnCkreo|Dex232A0N)WYTB2rz@PWZ{efIvB*Z>sP^%dHhd*w14>m4r=?TJ zCp8SGHZ*cjrPHkvCzs>ku&iMS3;a4zxoZ6V{@zr{s zG6qK_r0EQ&@zVX;%y2H}QH7I?+&<4z0TtnOjE`I4S{`k0;=mMiM8AsBS2I5K3}4Ck zkUzN)A4&}jKM#2=|FtRj+|1}XpIaDyKI5~8;am^Z%CMD1Umk|f z1+MvArEucS?O`Lsx&H5De2D){d??+^aMGFPzl-5qp63}(KP%Mq8ESK<`$ck5DrPw6 zQ_65UtJi!Q7|!Xx&G31Q{yPjOdOa@RXE-01|7JL+-^Oq^*3c7Cpqu!b@K%S}iQ2MhC*JC+s!?pfD zRyfhM;G^*@bq=ESaEO>AoyhP7$ZPsih7&J6uPYQz7?0DI+vv65ZnNP!9tbd;_xD2Vvb{oyMN=kwx# z!eyW0a=ydpxtyOeoa$(Oj-M{uCyd8qnGEOgm`mX_?o>yQV=kj#1zhWGKBMRIT*BzN z{ns;mHRIFGaK658X8d`-?qc)}jL%j^&*$$j!}R!*TWG;PkgjKk5%W4#Dm9^rzl*{$Cpt~DTm=a4s@sB<74!sAI)be!_Nb*mf!@1x7DZ@GaZy7$H@&5zExt_Nvob`2wS-GHtg<89nzu6Tb!`ByHz< zz8tG?;=%3nWQNzEOzY=t8y`LH=i6}Ym)v7;k^(=yU^w@0RSYMYw4bkGIM>ey3MX1F z=ZvpYD{@Zrb-6&{S`V84MK)aT3$C=`ntmhW--vd!er{$sk27yc!RMz8=l%Kx!>Mod zp>&T8UnybZ?+Pb6-rwcfl7MiopX(Xkh%zm|#c(eFPZUmi<8t1?aB4&IdC-Q(WWYD2GI_t?^XC{Jxo0j z86=X2{J_1GL7K*J9_O5;aN@HXAI;}HhVyZ}o$=xP?_~G|jL!h$!};%IIOjj}BveMS z%YQDzIsb(Ux65D4aL)f8#)pr~WTjYpyVDrX+bw1|*TYSB zrw=on(?6|n>Jzu~R~Wv6@qdHyq4}lT{ehQKscQ!su5r{4+++<;S1i ziKNFx>-ltrQ@fWlKE({bg5j4lyo2G5HvYtq(t3t-dA?`Eb-$itIPuW&z}pNbKAL{2 z3mGKcFCAB`bqP3zYk4-Oz#n8d+5hdbx-r0T6PRxIQ-u>>u7~4K1As*G@cuR{oapQD z(R{AA(QAA7Z$`hI(LclR28JJIe5ehw2}=2=%V$hKGHVo$!5yMxuEOp8nsY`XA1bG` zECqgr4cC5Pt-`7PDtxpaHZr`P;hPyBJ}$R1{5(egJBFtN*J&@qiBGR8c!l9!U|OD0 zhI2lRIkFGMta^-3llDQ@c7oxu4-~;JV#s8K2b*|Cr(29>(W_2#NTQ!$;5S zT!jV>pZX0^JSOh-Fr1IqQia>c>oSJB8UI#>^ZssT{I6p4zhU$w zzxFftG5lgiKg9TOdw7-M+#Wt<4b zKHMJu$Z)RbCmA2ogXX`R;cmwNAj7E-y4`7c$RKI^*Z5q86D{{Am5iS2e-XpaM;*=Q zX2ys2>xYb<%YQq=s~Dd@GCo`nC+33)$*$)!7`_PQTAmt)Q{SdiWuzvB6V`~2rte_5 zpW!`>56OQoK9sgFoX5Qb45v2q`tni={2hf8Ew|f`7|!*Xdlt1G*F&$&8Z#Nr=k+{> z^Lh7Ig;Tqn|51i>{ZBhvHl+2h^>8x7-5}BWyh!18{!17=m1Rh_Mw1QKdJ8k0>;DG~ z=lZ`#;l#U<$@52s^YML}@!|aUGMw|DG*b$!=aH841cuLM?dCF^_&+798wCvaF#2+Z zllsXMyv6u%J^z#8 zT+hc55fbrl#7EoJsSM}ic#gvD_IW|}u&hFjr;@qOhY8~qeTe}xU#W8Y@O z=|3i+w9$s^cDof$?XJQ{kK?_Jp1M92A4(50yaIVmzn$^n>(n!hp7Ytua31#_WjLpg zGJG*>H~SotD(-K!oHH2C=`UnB=f8mA)!?W5wVdHZukj{^U&8QB4CnN>GMv-@hT)w4 zPYmbuFS2{dZ?kssDiT>A*ARq<9ytzkx?72<;hd^G#}S^Nw~#^4^EKys14t*7BJn8=5vSAV~uKG zmb9(1z>Z#Tx}(8(Q%@b36l`^0`*O;lBo{FTj7a6EF(!pWW0O1*^Nd zjDpT~$`E-`0e;WSv-s(<%;HIP1tH!F@Z;S27Nej6KmEmj3St!CKZo!a;Lp`(iQg-$ z{F=640si9@`mc00CH;Yq&I zt@8TeS|s19RebD3mfF$rQ???cZ4KdS7!(Sgh4NL?>jG+vCt8k)#$Mm0>UZb~s4BVC zQ$LFELhTo8Ks|N+Z8pVdd8iI0H$KVgzd)M}B)9mEf9ZPqxfn(CuFOA1=$a#6Gi)7m z#VF(p#ZOeEOT-F>paCg$;Pi^oun`oA&npPUH4z}Z2?B@D|O>dCbw#z z#)l`}Z~Y9SP``7!7FC~P^lqmO0h@@AU4I>_z6)hMY56twA9x|2_WJ$0eVf7A>)(dD z$@I5X>F=l#nDloHKDxfvU$VAAX7pb~-}oCL72wdkTZ)gp{v=@bu?J+_;iYfG*l3gA XuD@eJldS&z>qT|rZuy9P+w1=y--g9V literal 0 HcmV?d00001 diff --git a/he_qat/CMakeLists.txt b/he_qat/CMakeLists.txt index aded1b4..f8f22e9 100644 --- a/he_qat/CMakeLists.txt +++ b/he_qat/CMakeLists.txt @@ -16,13 +16,10 @@ add_library(HE_QAT::he_qat ALIAS he_qat) target_include_directories(he_qat PUBLIC $ #Public headers PUBLIC $ #Public headers - # PUBLIC $ #Public headers PUBLIC $ #Public headers - PRIVATE ${COMMON_INC_DIR} #Private headers + PRIVATE ${COMMON_INC_DIR} #Private headers PRIVATE ${ICP_INC_DIR} #Private headers - #PRIVATE ${OPENSSL_INC_DIR} #Private headers ) -#target_include_directories(he_qat PUBLIC ${HE_QAT_UTILS_INC_DIR}) install(DIRECTORY ${COMMON_INC_DIR}/ DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ @@ -37,13 +34,18 @@ install(DIRECTORY ${HE_QAT_INC_DIR}/ PATTERN "*.h") target_link_directories(he_qat PUBLIC ${ICP_BUILDOUTPUT_PATH}) -#target_link_directories(he_qat PUBLIC ${OPENSSL_LIB_DIR}) target_link_libraries(he_qat PRIVATE OpenSSL::SSL Threads::Threads) -target_link_libraries(he_qat PRIVATE cpa_sample_utils) -target_link_libraries(he_qat PRIVATE qat_s usdm_drv_s) -target_link_libraries(he_qat PRIVATE z) +target_link_libraries(he_qat PRIVATE udev z) + if(HE_QAT_MISC) - target_link_libraries(he_qat PRIVATE he_qat_misc) + target_link_libraries(he_qat PRIVATE he_qat_misc) +endif() + +if(HE_QAT_SHARED) + target_link_libraries(he_qat PRIVATE qat_s usdm_drv_s) + target_link_libraries(he_qat PRIVATE cpa_sample_utils) +else() + heqat_create_archive(he_qat cpa_sample_utils) endif() set_target_properties(he_qat PROPERTIES POSITION_INDEPENDENT_CODE ON) diff --git a/icp/CMakeLists.txt b/icp/CMakeLists.txt index fbe3816..5040fc4 100644 --- a/icp/CMakeLists.txt +++ b/icp/CMakeLists.txt @@ -24,11 +24,31 @@ set(ICP_INC_DIR ${ICP_API_DIR}/include ${ICP_LAC_DIR}/include ${ICP_ADF_DIR}/include ${CMN_ROOT} - ${ICP_API_DIR}/include/dc + ${ICP_API_DIR}/include/dc ${ICP_API_DIR}/include/lac) -#Macros for the test case +# Macros for the test case add_definitions(-DDO_CRYPTO) add_definitions(-DUSER_SPACE) add_compile_options(-fPIC) +add_library(libadf_static STATIC IMPORTED GLOBAL) +add_library(libosal_static STATIC IMPORTED GLOBAL) +add_library(libqat_static STATIC IMPORTED GLOBAL) +add_library(libusdm_drv_static STATIC IMPORTED GLOBAL) + +set_target_properties(libadf_static PROPERTIES + IMPORTED_LOCATION ${ICP_BUILDOUTPUT_PATH}/libadf.a +) + +set_target_properties(libosal_static PROPERTIES + IMPORTED_LOCATION ${ICP_BUILDOUTPUT_PATH}/libosal.a +) + +set_target_properties(libqat_static PROPERTIES + IMPORTED_LOCATION ${ICP_BUILDOUTPUT_PATH}/libqat.a +) + +set_target_properties(libusdm_drv_static PROPERTIES + IMPORTED_LOCATION ${ICP_BUILDOUTPUT_PATH}/libusdm_drv.a +) diff --git a/misc/CMakeLists.txt b/misc/CMakeLists.txt index 68c0e1f..f37b8db 100644 --- a/misc/CMakeLists.txt +++ b/misc/CMakeLists.txt @@ -4,32 +4,48 @@ set(HE_QAT_MISC_INC_DIR ${COMMON_INC_DIR} ${HE_QAT_INC_DIR} ${CMAKE_CURRENT_LIST_DIR} - # ${IPPCP_DIR}/include + # ${IPPCP_DIR}/include ) message(STATUS "HE_QAT_MISC_INC_DIR: ${HE_QAT_MISC_INC_DIR}") #Source files #list(APPEND HE_QAT_MISC_SRC ${CMAKE_CURRENT_LIST_DIR} / utils.cpp -set(HE_QAT_MISC_SRC ${CMAKE_CURRENT_LIST_DIR}/he_qat_misc.cpp +set(HE_QAT_MISC_SRC + ${CMAKE_CURRENT_LIST_DIR}/he_qat_misc.cpp ${CMAKE_CURRENT_LIST_DIR}/utils.cpp ${CMAKE_CURRENT_LIST_DIR}/bignum.cpp) -add_library(he_qat_misc ${HE_QAT_MISC_SRC}) -target_include_directories(he_qat_misc PUBLIC $ #Public headers - PUBLIC $ #Public headers +if(HE_QAT_SHARED) + add_library(he_qat_misc SHARED ${HE_QAT_MISC_SRC}) +else() + add_library(he_qat_misc STATIC ${HE_QAT_MISC_SRC}) +endif() + +message(STATUS "IPPCP Headers Directory ${IPPCP_DIR}/include") +target_include_directories(he_qat_misc #PUBLIC $ #Public headers + #PUBLIC $ #Public headers + PRIVATE ${IPPCP_DIR}/../../../include PRIVATE ${HE_QAT_MISC_INC_DIR} #Private headers PRIVATE ${ICP_INC_DIR} #Private headers + ) #target_link_directories(he_qat_misc PUBLIC ${IPPCP_DIR}/lib/intel64) #target_link_libraries(he_qat_misc PRIVATE ippcpmx crypto_mb) -target_link_libraries(he_qat_misc PRIVATE IPPCP::ippcp IPPCP::crypto_mb) + +if(HE_QAT_SHARED) + target_link_libraries(he_qat_misc PRIVATE IPPCP::ippcp IPPCP::crypto_mb) +else() + heqat_create_archive(he_qat_misc IPPCP::ippcp) + heqat_create_archive(he_qat_misc IPPCP::crypto_mb) +endif() install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/ DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h") -install(TARGETS he_qat_misc DESTINATION ${CMAKE_INSTALL_LIBDIR}) +#install(TARGETS he_qat_misc DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install(TARGETS he_qat_misc EXPORT he_qatTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}) set(HE_QAT_MISC_INC_DIR ${HE_QAT_MISC_INC_DIR} PARENT_SCOPE) diff --git a/perf_data/bs1bit1024.txt b/perf_data/bs1bit1024.txt new file mode 100644 index 0000000..adc583f --- /dev/null +++ b/perf_data/bs1bit1024.txt @@ -0,0 +1,101 @@ +Cpa CyInstance has successfully started. +Trial #001 OpenSSL: 3115.0us QAT: 170.0us Speed Up:18.3x ** PASS ** +Trial #002 OpenSSL: 3705.0us QAT: 124.5us Speed Up:36.3x ** PASS ** +Trial #003 OpenSSL: 2840.7us QAT: 106.0us Speed Up:29.6x ** PASS ** +Trial #004 OpenSSL: 2404.2us QAT: 96.8us Speed Up:26.2x ** PASS ** +Trial #005 OpenSSL: 2772.6us QAT: 91.4us Speed Up:33.1x ** PASS ** +Trial #006 OpenSSL: 3013.0us QAT: 88.8us Speed Up:36.8x ** PASS ** +Trial #007 OpenSSL: 3009.3us QAT: 85.9us Speed Up:37.8x ** PASS ** +Trial #008 OpenSSL: 2771.0us QAT: 83.8us Speed Up:35.1x ** PASS ** +Trial #009 OpenSSL: 2936.2us QAT: 82.0us Speed Up:38.1x ** PASS ** +Trial #010 OpenSSL: 3061.3us QAT: 80.7us Speed Up:40.4x ** PASS ** +Trial #011 OpenSSL: 3058.7us QAT: 79.7us Speed Up:40.7x ** PASS ** +Trial #012 OpenSSL: 2896.5us QAT: 78.6us Speed Up:38.7x ** PASS ** +Trial #013 OpenSSL: 2757.8us QAT: 77.7us Speed Up:37.0x ** PASS ** +Trial #014 OpenSSL: 2779.4us QAT: 76.9us Speed Up:37.6x ** PASS ** +Trial #015 OpenSSL: 2876.7us QAT: 76.1us Speed Up:39.5x ** PASS ** +Trial #016 OpenSSL: 2963.4us QAT: 75.6us Speed Up:40.9x ** PASS ** +Trial #017 OpenSSL: 2853.6us QAT: 75.1us Speed Up:39.4x ** PASS ** +Trial #018 OpenSSL: 2932.4us QAT: 74.5us Speed Up:40.9x ** PASS ** +Trial #019 OpenSSL: 2835.7us QAT: 74.0us Speed Up:39.6x ** PASS ** +Trial #020 OpenSSL: 2846.8us QAT: 73.9us Speed Up:39.8x ** PASS ** +Trial #021 OpenSSL: 2912.5us QAT: 73.5us Speed Up:40.9x ** PASS ** +Trial #022 OpenSSL: 2830.3us QAT: 73.2us Speed Up:39.8x ** PASS ** +Trial #023 OpenSSL: 2754.8us QAT: 72.9us Speed Up:38.8x ** PASS ** +Trial #024 OpenSSL: 2816.4us QAT: 72.6us Speed Up:39.9x ** PASS ** +Trial #025 OpenSSL: 2747.4us QAT: 72.4us Speed Up:38.9x ** PASS ** +Trial #026 OpenSSL: 2683.8us QAT: 72.1us Speed Up:38.1x ** PASS ** +Trial #027 OpenSSL: 2625.1us QAT: 71.9us Speed Up:37.3x ** PASS ** +Trial #028 OpenSSL: 2570.3us QAT: 71.6us Speed Up:36.5x ** PASS ** +Trial #029 OpenSSL: 2587.1us QAT: 71.4us Speed Up:36.9x ** PASS ** +Trial #030 OpenSSL: 2537.5us QAT: 71.2us Speed Up:36.2x ** PASS ** +Trial #031 OpenSSL: 2592.1us QAT: 71.0us Speed Up:37.2x ** PASS ** +Trial #032 OpenSSL: 2545.3us QAT: 70.8us Speed Up:36.5x ** PASS ** +Trial #033 OpenSSL: 2560.2us QAT: 70.7us Speed Up:36.8x ** PASS ** +Trial #034 OpenSSL: 2516.9us QAT: 70.6us Speed Up:36.2x ** PASS ** +Trial #035 OpenSSL: 2476.4us QAT: 70.3us Speed Up:35.7x ** PASS ** +Trial #036 OpenSSL: 2438.2us QAT: 70.2us Speed Up:35.2x ** PASS ** +Trial #037 OpenSSL: 2454.9us QAT: 70.1us Speed Up:35.5x ** PASS ** +Trial #038 OpenSSL: 2469.8us QAT: 69.9us Speed Up:35.8x ** PASS ** +Trial #039 OpenSSL: 2515.1us QAT: 69.8us Speed Up:36.6x ** PASS ** +Trial #040 OpenSSL: 2528.3us QAT: 69.7us Speed Up:36.8x ** PASS ** +Trial #041 OpenSSL: 2569.2us QAT: 69.6us Speed Up:37.4x ** PASS ** +Trial #042 OpenSSL: 2534.0us QAT: 69.5us Speed Up:37.0x ** PASS ** +Trial #043 OpenSSL: 2500.8us QAT: 69.4us Speed Up:36.5x ** PASS ** +Trial #044 OpenSSL: 2513.5us QAT: 69.3us Speed Up:36.7x ** PASS ** +Trial #045 OpenSSL: 2524.2us QAT: 69.3us Speed Up:36.9x ** PASS ** +Trial #046 OpenSSL: 2535.2us QAT: 69.2us Speed Up:37.1x ** PASS ** +Trial #047 OpenSSL: 2504.5us QAT: 69.2us Speed Up:36.6x ** PASS ** +Trial #048 OpenSSL: 2475.2us QAT: 69.1us Speed Up:36.2x ** PASS ** +Trial #049 OpenSSL: 2484.9us QAT: 69.0us Speed Up:36.4x ** PASS ** +Trial #050 OpenSSL: 2457.2us QAT: 68.9us Speed Up:36.0x ** PASS ** +Trial #051 OpenSSL: 2430.6us QAT: 68.9us Speed Up:35.6x ** PASS ** +Trial #052 OpenSSL: 2465.8us QAT: 68.8us Speed Up:36.2x ** PASS ** +Trial #053 OpenSSL: 2440.1us QAT: 68.8us Speed Up:35.8x ** PASS ** +Trial #054 OpenSSL: 2473.1us QAT: 68.8us Speed Up:36.3x ** PASS ** +Trial #055 OpenSSL: 2448.1us QAT: 68.7us Speed Up:36.0x ** PASS ** +Trial #056 OpenSSL: 2459.4us QAT: 68.7us Speed Up:36.2x ** PASS ** +Trial #057 OpenSSL: 2469.6us QAT: 68.5us Speed Up:36.4x ** PASS ** +Trial #058 OpenSSL: 2479.6us QAT: 68.5us Speed Up:36.5x ** PASS ** +Trial #059 OpenSSL: 2509.4us QAT: 68.5us Speed Up:37.0x ** PASS ** +Trial #060 OpenSSL: 2485.9us QAT: 68.5us Speed Up:36.7x ** PASS ** +Trial #061 OpenSSL: 2494.6us QAT: 68.4us Speed Up:36.8x ** PASS ** +Trial #062 OpenSSL: 2523.0us QAT: 68.4us Speed Up:37.2x ** PASS ** +Trial #063 OpenSSL: 2530.2us QAT: 68.4us Speed Up:37.4x ** PASS ** +Trial #064 OpenSSL: 2557.0us QAT: 68.3us Speed Up:37.8x ** PASS ** +Trial #065 OpenSSL: 2563.8us QAT: 68.4us Speed Up:37.9x ** PASS ** +Trial #066 OpenSSL: 2571.3us QAT: 68.4us Speed Up:38.0x ** PASS ** +Trial #067 OpenSSL: 2549.3us QAT: 68.3us Speed Up:37.7x ** PASS ** +Trial #068 OpenSSL: 2528.1us QAT: 68.3us Speed Up:37.4x ** PASS ** +Trial #069 OpenSSL: 2507.3us QAT: 68.3us Speed Up:37.1x ** PASS ** +Trial #070 OpenSSL: 2532.5us QAT: 68.3us Speed Up:37.4x ** PASS ** +Trial #071 OpenSSL: 2539.5us QAT: 68.2us Speed Up:37.6x ** PASS ** +Trial #072 OpenSSL: 2519.6us QAT: 68.2us Speed Up:37.3x ** PASS ** +Trial #073 OpenSSL: 2500.1us QAT: 68.1us Speed Up:37.0x ** PASS ** +Trial #074 OpenSSL: 2481.1us QAT: 68.1us Speed Up:36.7x ** PASS ** +Trial #075 OpenSSL: 2487.6us QAT: 68.1us Speed Up:36.8x ** PASS ** +Trial #076 OpenSSL: 2510.9us QAT: 68.1us Speed Up:37.2x ** PASS ** +Trial #077 OpenSSL: 2492.5us QAT: 68.1us Speed Up:36.9x ** PASS ** +Trial #078 OpenSSL: 2499.6us QAT: 68.1us Speed Up:37.0x ** PASS ** +Trial #079 OpenSSL: 2481.9us QAT: 68.0us Speed Up:36.8x ** PASS ** +Trial #080 OpenSSL: 2464.6us QAT: 68.0us Speed Up:36.5x ** PASS ** +Trial #081 OpenSSL: 2472.1us QAT: 67.9us Speed Up:36.6x ** PASS ** +Trial #082 OpenSSL: 2479.5us QAT: 67.9us Speed Up:36.8x ** PASS ** +Trial #083 OpenSSL: 2462.7us QAT: 67.9us Speed Up:36.5x ** PASS ** +Trial #084 OpenSSL: 2484.3us QAT: 67.9us Speed Up:36.9x ** PASS ** +Trial #085 OpenSSL: 2505.3us QAT: 67.9us Speed Up:37.1x ** PASS ** +Trial #086 OpenSSL: 2488.8us QAT: 67.9us Speed Up:36.9x ** PASS ** +Trial #087 OpenSSL: 2508.5us QAT: 67.8us Speed Up:37.2x ** PASS ** +Trial #088 OpenSSL: 2492.5us QAT: 67.8us Speed Up:37.0x ** PASS ** +Trial #089 OpenSSL: 2498.1us QAT: 67.8us Speed Up:37.1x ** PASS ** +Trial #090 OpenSSL: 2517.3us QAT: 67.8us Speed Up:37.4x ** PASS ** +Trial #091 OpenSSL: 2501.6us QAT: 67.7us Speed Up:37.1x ** PASS ** +Trial #092 OpenSSL: 2486.3us QAT: 67.7us Speed Up:36.9x ** PASS ** +Trial #093 OpenSSL: 2471.3us QAT: 67.7us Speed Up:36.7x ** PASS ** +Trial #094 OpenSSL: 2456.7us QAT: 67.6us Speed Up:36.5x ** PASS ** +Trial #095 OpenSSL: 2442.4us QAT: 67.6us Speed Up:36.3x ** PASS ** +Trial #096 OpenSSL: 2428.4us QAT: 67.6us Speed Up:36.1x ** PASS ** +Trial #097 OpenSSL: 2414.7us QAT: 67.6us Speed Up:35.9x ** PASS ** +Trial #098 OpenSSL: 2421.2us QAT: 67.6us Speed Up:36.0x ** PASS ** +Trial #099 OpenSSL: 2407.9us QAT: 67.5us Speed Up:35.8x ** PASS ** +Trial #100 OpenSSL: 2394.7us QAT: 67.5us Speed Up:35.6x ** PASS ** diff --git a/perf_data/bs1bit8192.txt b/perf_data/bs1bit8192.txt new file mode 100644 index 0000000..07d8f57 --- /dev/null +++ b/perf_data/bs1bit8192.txt @@ -0,0 +1,101 @@ +Cpa CyInstance has successfully started. +Trial #001 OpenSSL: 416765.0us QAT: 242.0us Speed Up:1722.2x ** PASS ** +Trial #002 OpenSSL: 371030.0us QAT: 197.0us Speed Up:1931.1x ** PASS ** +Trial #003 OpenSSL: 384466.7us QAT: 183.7us Speed Up:2160.8x ** PASS ** +Trial #004 OpenSSL: 375548.2us QAT: 166.5us Speed Up:2378.8x ** PASS ** +Trial #005 OpenSSL: 343536.6us QAT: 157.0us Speed Up:2265.2x ** PASS ** +Trial #006 OpenSSL: 322819.8us QAT: 151.3us Speed Up:2184.7x ** PASS ** +Trial #007 OpenSSL: 312659.3us QAT: 151.0us Speed Up:2114.0x ** PASS ** +Trial #008 OpenSSL: 326272.0us QAT: 150.6us Speed Up:2205.8x ** PASS ** +Trial #009 OpenSSL: 326400.8us QAT: 153.2us Speed Up:2169.8x ** PASS ** +Trial #010 OpenSSL: 318748.4us QAT: 152.1us Speed Up:2128.8x ** PASS ** +Trial #011 OpenSSL: 319286.8us QAT: 150.4us Speed Up:2157.2x ** PASS ** +Trial #012 OpenSSL: 319728.6us QAT: 148.7us Speed Up:2185.5x ** PASS ** +Trial #013 OpenSSL: 322086.2us QAT: 145.6us Speed Up:2264.6x ** PASS ** +Trial #014 OpenSSL: 323654.2us QAT: 143.0us Speed Up:2328.3x ** PASS ** +Trial #015 OpenSSL: 316293.1us QAT: 140.6us Speed Up:2305.9x ** PASS ** +Trial #016 OpenSSL: 309997.5us QAT: 138.9us Speed Up:2281.1x ** PASS ** +Trial #017 OpenSSL: 304461.3us QAT: 137.9us Speed Up:2251.0x ** PASS ** +Trial #018 OpenSSL: 309513.6us QAT: 140.1us Speed Up:2250.0x ** PASS ** +Trial #019 OpenSSL: 315520.6us QAT: 140.2us Speed Up:2287.5x ** PASS ** +Trial #020 OpenSSL: 316112.0us QAT: 140.1us Speed Up:2292.6x ** PASS ** +Trial #021 OpenSSL: 321244.4us QAT: 139.8us Speed Up:2333.0x ** PASS ** +Trial #022 OpenSSL: 323171.5us QAT: 138.5us Speed Up:2377.2x ** PASS ** +Trial #023 OpenSSL: 318626.0us QAT: 137.7us Speed Up:2351.7x ** PASS ** +Trial #024 OpenSSL: 316617.0us QAT: 136.8us Speed Up:2351.7x ** PASS ** +Trial #025 OpenSSL: 318861.8us QAT: 136.3us Speed Up:2377.9x ** PASS ** +Trial #026 OpenSSL: 322852.6us QAT: 136.5us Speed Up:2401.7x ** PASS ** +Trial #027 OpenSSL: 326495.4us QAT: 136.9us Speed Up:2418.9x ** PASS ** +Trial #028 OpenSSL: 329951.8us QAT: 137.9us Speed Up:2423.0x ** PASS ** +Trial #029 OpenSSL: 327162.7us QAT: 138.1us Speed Up:2400.0x ** PASS ** +Trial #030 OpenSSL: 330461.2us QAT: 138.1us Speed Up:2421.4x ** PASS ** +Trial #031 OpenSSL: 327979.4us QAT: 137.9us Speed Up:2405.3x ** PASS ** +Trial #032 OpenSSL: 330974.3us QAT: 138.1us Speed Up:2422.7x ** PASS ** +Trial #033 OpenSSL: 330758.0us QAT: 138.2us Speed Up:2417.9x ** PASS ** +Trial #034 OpenSSL: 333490.8us QAT: 138.1us Speed Up:2439.1x ** PASS ** +Trial #035 OpenSSL: 331162.5us QAT: 137.8us Speed Up:2426.6x ** PASS ** +Trial #036 OpenSSL: 330943.2us QAT: 137.9us Speed Up:2422.4x ** PASS ** +Trial #037 OpenSSL: 328889.9us QAT: 137.8us Speed Up:2408.4x ** PASS ** +Trial #038 OpenSSL: 331389.9us QAT: 137.8us Speed Up:2427.0x ** PASS ** +Trial #039 OpenSSL: 331224.0us QAT: 137.5us Speed Up:2430.4x ** PASS ** +Trial #040 OpenSSL: 333505.7us QAT: 138.3us Speed Up:2431.7x ** PASS ** +Trial #041 OpenSSL: 333300.1us QAT: 138.2us Speed Up:2431.2x ** PASS ** +Trial #042 OpenSSL: 333182.5us QAT: 138.1us Speed Up:2431.6x ** PASS ** +Trial #043 OpenSSL: 332990.2us QAT: 138.2us Speed Up:2427.9x ** PASS ** +Trial #044 OpenSSL: 332832.3us QAT: 138.4us Speed Up:2423.8x ** PASS ** +Trial #045 OpenSSL: 332669.9us QAT: 138.2us Speed Up:2424.8x ** PASS ** +Trial #046 OpenSSL: 332447.8us QAT: 138.0us Speed Up:2426.4x ** PASS ** +Trial #047 OpenSSL: 330764.3us QAT: 138.0us Speed Up:2413.8x ** PASS ** +Trial #048 OpenSSL: 332568.4us QAT: 137.7us Speed Up:2435.4x ** PASS ** +Trial #049 OpenSSL: 331273.7us QAT: 137.2us Speed Up:2433.0x ** PASS ** +Trial #050 OpenSSL: 329913.4us QAT: 136.7us Speed Up:2433.1x ** PASS ** +Trial #051 OpenSSL: 330081.1us QAT: 136.3us Speed Up:2441.7x ** PASS ** +Trial #052 OpenSSL: 328792.5us QAT: 135.8us Speed Up:2441.1x ** PASS ** +Trial #053 OpenSSL: 326560.7us QAT: 135.4us Speed Up:2429.0x ** PASS ** +Trial #054 OpenSSL: 326427.3us QAT: 135.5us Speed Up:2426.9x ** PASS ** +Trial #055 OpenSSL: 325038.8us QAT: 135.7us Speed Up:2413.1x ** PASS ** +Trial #056 OpenSSL: 323779.7us QAT: 135.7us Speed Up:2403.4x ** PASS ** +Trial #057 OpenSSL: 325537.8us QAT: 135.6us Speed Up:2419.8x ** PASS ** +Trial #058 OpenSSL: 324271.7us QAT: 135.3us Speed Up:2413.7x ** PASS ** +Trial #059 OpenSSL: 323053.5us QAT: 136.0us Speed Up:2397.4x ** PASS ** +Trial #060 OpenSSL: 323080.6us QAT: 136.0us Speed Up:2397.2x ** PASS ** +Trial #061 OpenSSL: 321949.5us QAT: 136.1us Speed Up:2387.5x ** PASS ** +Trial #062 OpenSSL: 323559.7us QAT: 136.1us Speed Up:2398.6x ** PASS ** +Trial #063 OpenSSL: 323559.6us QAT: 136.0us Speed Up:2399.5x ** PASS ** +Trial #064 OpenSSL: 322406.5us QAT: 136.2us Speed Up:2388.0x ** PASS ** +Trial #065 OpenSSL: 323951.9us QAT: 136.2us Speed Up:2400.2x ** PASS ** +Trial #066 OpenSSL: 325425.0us QAT: 136.2us Speed Up:2411.1x ** PASS ** +Trial #067 OpenSSL: 324327.9us QAT: 136.1us Speed Up:2404.2x ** PASS ** +Trial #068 OpenSSL: 325751.3us QAT: 136.1us Speed Up:2413.1x ** PASS ** +Trial #069 OpenSSL: 324638.5us QAT: 136.1us Speed Up:2404.9x ** PASS ** +Trial #070 OpenSSL: 323598.7us QAT: 136.0us Speed Up:2398.0x ** PASS ** +Trial #071 OpenSSL: 322600.1us QAT: 136.1us Speed Up:2389.6x ** PASS ** +Trial #072 OpenSSL: 321604.8us QAT: 136.2us Speed Up:2381.3x ** PASS ** +Trial #073 OpenSSL: 320660.3us QAT: 136.1us Speed Up:2374.3x ** PASS ** +Trial #074 OpenSSL: 320675.5us QAT: 136.2us Speed Up:2373.1x ** PASS ** +Trial #075 OpenSSL: 319747.0us QAT: 136.3us Speed Up:2365.4x ** PASS ** +Trial #076 OpenSSL: 318875.2us QAT: 136.3us Speed Up:2358.4x ** PASS ** +Trial #077 OpenSSL: 320238.9us QAT: 136.1us Speed Up:2371.8x ** PASS ** +Trial #078 OpenSSL: 319009.6us QAT: 135.8us Speed Up:2366.6x ** PASS ** +Trial #079 OpenSSL: 319321.7us QAT: 135.5us Speed Up:2377.0x ** PASS ** +Trial #080 OpenSSL: 317989.7us QAT: 135.2us Speed Up:2370.4x ** PASS ** +Trial #081 OpenSSL: 319249.5us QAT: 135.3us Speed Up:2379.0x ** PASS ** +Trial #082 OpenSSL: 319313.4us QAT: 135.4us Speed Up:2376.5x ** PASS ** +Trial #083 OpenSSL: 318499.8us QAT: 135.5us Speed Up:2369.4x ** PASS ** +Trial #084 OpenSSL: 317718.5us QAT: 135.9us Speed Up:2358.9x ** PASS ** +Trial #085 OpenSSL: 316934.0us QAT: 136.0us Speed Up:2351.8x ** PASS ** +Trial #086 OpenSSL: 318171.3us QAT: 136.0us Speed Up:2360.9x ** PASS ** +Trial #087 OpenSSL: 317438.2us QAT: 135.8us Speed Up:2357.4x ** PASS ** +Trial #088 OpenSSL: 317528.7us QAT: 135.8us Speed Up:2357.8x ** PASS ** +Trial #089 OpenSSL: 316834.8us QAT: 135.9us Speed Up:2352.1x ** PASS ** +Trial #090 OpenSSL: 316135.5us QAT: 135.9us Speed Up:2345.8x ** PASS ** +Trial #091 OpenSSL: 315430.1us QAT: 135.8us Speed Up:2341.7x ** PASS ** +Trial #092 OpenSSL: 314767.1us QAT: 135.8us Speed Up:2337.0x ** PASS ** +Trial #093 OpenSSL: 314077.4us QAT: 135.9us Speed Up:2330.7x ** PASS ** +Trial #094 OpenSSL: 315281.7us QAT: 136.0us Speed Up:2337.3x ** PASS ** +Trial #095 OpenSSL: 316394.6us QAT: 136.0us Speed Up:2345.3x ** PASS ** +Trial #096 OpenSSL: 316501.2us QAT: 136.0us Speed Up:2346.0x ** PASS ** +Trial #097 OpenSSL: 316606.8us QAT: 136.0us Speed Up:2346.3x ** PASS ** +Trial #098 OpenSSL: 315942.8us QAT: 136.0us Speed Up:2341.6x ** PASS ** +Trial #099 OpenSSL: 316011.4us QAT: 136.0us Speed Up:2341.9x ** PASS ** +Trial #100 OpenSSL: 316066.4us QAT: 135.9us Speed Up:2342.9x ** PASS ** diff --git a/perf_data/bs8bit1024.txt b/perf_data/bs8bit1024.txt new file mode 100644 index 0000000..d4250f8 --- /dev/null +++ b/perf_data/bs8bit1024.txt @@ -0,0 +1,101 @@ +Cpa CyInstance has successfully started. +Trial #001 OpenSSL: 4340.0us QAT: 67.0us Speed Up:64.8x ** PASS ** +Trial #002 OpenSSL: 2726.5us QAT: 59.5us Speed Up:43.1x ** PASS ** +Trial #003 OpenSSL: 2803.0us QAT: 56.3us Speed Up:48.5x ** PASS ** +Trial #004 OpenSSL: 2377.8us QAT: 54.5us Speed Up:42.0x ** PASS ** +Trial #005 OpenSSL: 2509.8us QAT: 53.4us Speed Up:46.0x ** PASS ** +Trial #006 OpenSSL: 2273.3us QAT: 52.9us Speed Up:41.9x ** PASS ** +Trial #007 OpenSSL: 2551.3us QAT: 52.3us Speed Up:48.4x ** PASS ** +Trial #008 OpenSSL: 2611.6us QAT: 52.1us Speed Up:49.8x ** PASS ** +Trial #009 OpenSSL: 2444.0us QAT: 52.0us Speed Up:46.6x ** PASS ** +Trial #010 OpenSSL: 2502.6us QAT: 51.8us Speed Up:48.1x ** PASS ** +Trial #011 OpenSSL: 2374.5us QAT: 51.9us Speed Up:45.6x ** PASS ** +Trial #012 OpenSSL: 2268.1us QAT: 51.8us Speed Up:43.6x ** PASS ** +Trial #013 OpenSSL: 2177.6us QAT: 51.6us Speed Up:42.0x ** PASS ** +Trial #014 OpenSSL: 2323.6us QAT: 51.5us Speed Up:45.0x ** PASS ** +Trial #015 OpenSSL: 2452.6us QAT: 51.4us Speed Up:47.7x ** PASS ** +Trial #016 OpenSSL: 2367.5us QAT: 51.2us Speed Up:46.1x ** PASS ** +Trial #017 OpenSSL: 2404.4us QAT: 51.2us Speed Up:46.9x ** PASS ** +Trial #018 OpenSSL: 2331.1us QAT: 51.1us Speed Up:45.5x ** PASS ** +Trial #019 OpenSSL: 2265.7us QAT: 51.0us Speed Up:44.3x ** PASS ** +Trial #020 OpenSSL: 2207.2us QAT: 50.9us Speed Up:43.2x ** PASS ** +Trial #021 OpenSSL: 2247.6us QAT: 50.8us Speed Up:44.1x ** PASS ** +Trial #022 OpenSSL: 2336.4us QAT: 50.7us Speed Up:45.9x ** PASS ** +Trial #023 OpenSSL: 2418.3us QAT: 50.7us Speed Up:47.6x ** PASS ** +Trial #024 OpenSSL: 2363.3us QAT: 50.7us Speed Up:46.6x ** PASS ** +Trial #025 OpenSSL: 2390.2us QAT: 50.6us Speed Up:47.2x ** PASS ** +Trial #026 OpenSSL: 2412.6us QAT: 50.5us Speed Up:47.7x ** PASS ** +Trial #027 OpenSSL: 2433.8us QAT: 50.4us Speed Up:48.2x ** PASS ** +Trial #028 OpenSSL: 2454.4us QAT: 50.4us Speed Up:48.7x ** PASS ** +Trial #029 OpenSSL: 2407.2us QAT: 50.3us Speed Up:47.8x ** PASS ** +Trial #030 OpenSSL: 2425.3us QAT: 50.3us Speed Up:48.2x ** PASS ** +Trial #031 OpenSSL: 2483.7us QAT: 50.2us Speed Up:49.5x ** PASS ** +Trial #032 OpenSSL: 2440.2us QAT: 50.2us Speed Up:48.7x ** PASS ** +Trial #033 OpenSSL: 2399.4us QAT: 50.1us Speed Up:47.9x ** PASS ** +Trial #034 OpenSSL: 2361.4us QAT: 50.1us Speed Up:47.1x ** PASS ** +Trial #035 OpenSSL: 2325.3us QAT: 50.0us Speed Up:46.4x ** PASS ** +Trial #036 OpenSSL: 2291.2us QAT: 50.0us Speed Up:45.8x ** PASS ** +Trial #037 OpenSSL: 2342.9us QAT: 50.0us Speed Up:46.8x ** PASS ** +Trial #038 OpenSSL: 2309.8us QAT: 50.0us Speed Up:46.1x ** PASS ** +Trial #039 OpenSSL: 2358.2us QAT: 50.0us Speed Up:47.1x ** PASS ** +Trial #040 OpenSSL: 2373.8us QAT: 50.0us Speed Up:47.4x ** PASS ** +Trial #041 OpenSSL: 2389.0us QAT: 49.9us Speed Up:47.7x ** PASS ** +Trial #042 OpenSSL: 2358.2us QAT: 49.9us Speed Up:47.1x ** PASS ** +Trial #043 OpenSSL: 2401.2us QAT: 49.9us Speed Up:48.0x ** PASS ** +Trial #044 OpenSSL: 2371.4us QAT: 49.9us Speed Up:47.4x ** PASS ** +Trial #045 OpenSSL: 2412.4us QAT: 49.9us Speed Up:48.3x ** PASS ** +Trial #046 OpenSSL: 2383.9us QAT: 49.9us Speed Up:47.7x ** PASS ** +Trial #047 OpenSSL: 2356.7us QAT: 49.9us Speed Up:47.2x ** PASS ** +Trial #048 OpenSSL: 2395.2us QAT: 49.9us Speed Up:47.9x ** PASS ** +Trial #049 OpenSSL: 2368.6us QAT: 49.9us Speed Up:47.4x ** PASS ** +Trial #050 OpenSSL: 2343.2us QAT: 49.9us Speed Up:46.9x ** PASS ** +Trial #051 OpenSSL: 2380.8us QAT: 49.9us Speed Up:47.7x ** PASS ** +Trial #052 OpenSSL: 2393.9us QAT: 49.9us Speed Up:48.0x ** PASS ** +Trial #053 OpenSSL: 2369.3us QAT: 49.9us Speed Up:47.5x ** PASS ** +Trial #054 OpenSSL: 2380.7us QAT: 49.9us Speed Up:47.7x ** PASS ** +Trial #055 OpenSSL: 2414.3us QAT: 49.9us Speed Up:48.3x ** PASS ** +Trial #056 OpenSSL: 2423.9us QAT: 49.9us Speed Up:48.5x ** PASS ** +Trial #057 OpenSSL: 2400.6us QAT: 49.9us Speed Up:48.1x ** PASS ** +Trial #058 OpenSSL: 2431.7us QAT: 49.9us Speed Up:48.7x ** PASS ** +Trial #059 OpenSSL: 2440.9us QAT: 49.9us Speed Up:48.8x ** PASS ** +Trial #060 OpenSSL: 2418.4us QAT: 50.0us Speed Up:48.4x ** PASS ** +Trial #061 OpenSSL: 2396.9us QAT: 50.0us Speed Up:47.9x ** PASS ** +Trial #062 OpenSSL: 2376.0us QAT: 50.0us Speed Up:47.5x ** PASS ** +Trial #063 OpenSSL: 2355.7us QAT: 50.0us Speed Up:47.1x ** PASS ** +Trial #064 OpenSSL: 2366.4us QAT: 50.0us Speed Up:47.3x ** PASS ** +Trial #065 OpenSSL: 2376.3us QAT: 49.9us Speed Up:47.5x ** PASS ** +Trial #066 OpenSSL: 2357.0us QAT: 50.0us Speed Up:47.2x ** PASS ** +Trial #067 OpenSSL: 2365.9us QAT: 50.0us Speed Up:47.3x ** PASS ** +Trial #068 OpenSSL: 2347.4us QAT: 50.0us Speed Up:47.0x ** PASS ** +Trial #069 OpenSSL: 2374.6us QAT: 49.9us Speed Up:47.5x ** PASS ** +Trial #070 OpenSSL: 2400.8us QAT: 49.9us Speed Up:48.1x ** PASS ** +Trial #071 OpenSSL: 2408.6us QAT: 49.9us Speed Up:48.2x ** PASS ** +Trial #072 OpenSSL: 2390.4us QAT: 49.9us Speed Up:47.8x ** PASS ** +Trial #073 OpenSSL: 2372.6us QAT: 49.9us Speed Up:47.5x ** PASS ** +Trial #074 OpenSSL: 2397.2us QAT: 49.9us Speed Up:48.0x ** PASS ** +Trial #075 OpenSSL: 2380.0us QAT: 49.9us Speed Up:47.7x ** PASS ** +Trial #076 OpenSSL: 2388.5us QAT: 49.9us Speed Up:47.9x ** PASS ** +Trial #077 OpenSSL: 2371.8us QAT: 49.9us Speed Up:47.5x ** PASS ** +Trial #078 OpenSSL: 2380.6us QAT: 49.9us Speed Up:47.7x ** PASS ** +Trial #079 OpenSSL: 2364.3us QAT: 49.8us Speed Up:47.4x ** PASS ** +Trial #080 OpenSSL: 2348.4us QAT: 49.8us Speed Up:47.1x ** PASS ** +Trial #081 OpenSSL: 2371.8us QAT: 49.8us Speed Up:47.6x ** PASS ** +Trial #082 OpenSSL: 2394.2us QAT: 49.8us Speed Up:48.1x ** PASS ** +Trial #083 OpenSSL: 2378.6us QAT: 49.8us Speed Up:47.8x ** PASS ** +Trial #084 OpenSSL: 2386.3us QAT: 49.8us Speed Up:47.9x ** PASS ** +Trial #085 OpenSSL: 2371.1us QAT: 49.8us Speed Up:47.6x ** PASS ** +Trial #086 OpenSSL: 2392.3us QAT: 49.8us Speed Up:48.1x ** PASS ** +Trial #087 OpenSSL: 2377.4us QAT: 49.8us Speed Up:47.8x ** PASS ** +Trial #088 OpenSSL: 2385.5us QAT: 49.7us Speed Up:47.9x ** PASS ** +Trial #089 OpenSSL: 2405.8us QAT: 49.7us Speed Up:48.4x ** PASS ** +Trial #090 OpenSSL: 2391.2us QAT: 49.7us Speed Up:48.1x ** PASS ** +Trial #091 OpenSSL: 2376.9us QAT: 49.7us Speed Up:47.8x ** PASS ** +Trial #092 OpenSSL: 2396.9us QAT: 49.7us Speed Up:48.2x ** PASS ** +Trial #093 OpenSSL: 2382.8us QAT: 49.7us Speed Up:47.9x ** PASS ** +Trial #094 OpenSSL: 2369.2us QAT: 49.7us Speed Up:47.6x ** PASS ** +Trial #095 OpenSSL: 2355.8us QAT: 49.7us Speed Up:47.4x ** PASS ** +Trial #096 OpenSSL: 2342.7us QAT: 49.7us Speed Up:47.1x ** PASS ** +Trial #097 OpenSSL: 2329.8us QAT: 49.7us Speed Up:46.9x ** PASS ** +Trial #098 OpenSSL: 2317.2us QAT: 49.7us Speed Up:46.6x ** PASS ** +Trial #099 OpenSSL: 2336.4us QAT: 49.7us Speed Up:47.0x ** PASS ** +Trial #100 OpenSSL: 2324.0us QAT: 49.7us Speed Up:46.7x ** PASS ** diff --git a/perf_data/bs8bit4096.txt b/perf_data/bs8bit4096.txt new file mode 100644 index 0000000..0a5c8f9 --- /dev/null +++ b/perf_data/bs8bit4096.txt @@ -0,0 +1,101 @@ +Cpa CyInstance has successfully started. +Trial #001 OpenSSL: 55741.0us QAT: 75.5us Speed Up:738.3x ** PASS ** +Trial #002 OpenSSL: 75929.0us QAT: 67.7us Speed Up:1171.8x ** PASS ** +Trial #003 OpenSSL: 81653.0us QAT: 64.9us Speed Up:1305.0x ** PASS ** +Trial #004 OpenSSL: 90997.5us QAT: 63.0us Speed Up:1497.4x ** PASS ** +Trial #005 OpenSSL: 91945.4us QAT: 62.0us Speed Up:1528.0x ** PASS ** +Trial #006 OpenSSL: 86562.3us QAT: 62.1us Speed Up:1431.5x ** PASS ** +Trial #007 OpenSSL: 82684.9us QAT: 62.3us Speed Up:1361.7x ** PASS ** +Trial #008 OpenSSL: 79768.5us QAT: 62.3us Speed Up:1309.7x ** PASS ** +Trial #009 OpenSSL: 81429.0us QAT: 62.2us Speed Up:1335.3x ** PASS ** +Trial #010 OpenSSL: 85043.1us QAT: 62.1us Speed Up:1394.9x ** PASS ** +Trial #011 OpenSSL: 82742.4us QAT: 63.0us Speed Up:1343.3x ** PASS ** +Trial #012 OpenSSL: 85945.3us QAT: 62.6us Speed Up:1407.0x ** PASS ** +Trial #013 OpenSSL: 88348.0us QAT: 62.2us Speed Up:1453.8x ** PASS ** +Trial #014 OpenSSL: 86296.7us QAT: 62.2us Speed Up:1418.0x ** PASS ** +Trial #015 OpenSSL: 88532.7us QAT: 61.9us Speed Up:1462.4x ** PASS ** +Trial #016 OpenSSL: 90321.9us QAT: 61.5us Speed Up:1504.4x ** PASS ** +Trial #017 OpenSSL: 92032.1us QAT: 61.4us Speed Up:1534.5x ** PASS ** +Trial #018 OpenSSL: 92206.6us QAT: 61.2us Speed Up:1539.4x ** PASS ** +Trial #019 OpenSSL: 92367.7us QAT: 61.0us Speed Up:1545.2x ** PASS ** +Trial #020 OpenSSL: 92508.2us QAT: 60.9us Speed Up:1550.2x ** PASS ** +Trial #021 OpenSSL: 90957.9us QAT: 61.0us Speed Up:1521.0x ** PASS ** +Trial #022 OpenSSL: 92337.8us QAT: 60.8us Speed Up:1549.9x ** PASS ** +Trial #023 OpenSSL: 90917.2us QAT: 60.9us Speed Up:1523.2x ** PASS ** +Trial #024 OpenSSL: 89605.8us QAT: 61.0us Speed Up:1499.7x ** PASS ** +Trial #025 OpenSSL: 89798.6us QAT: 61.0us Speed Up:1501.0x ** PASS ** +Trial #026 OpenSSL: 90038.0us QAT: 60.9us Speed Up:1506.9x ** PASS ** +Trial #027 OpenSSL: 88923.8us QAT: 61.0us Speed Up:1485.7x ** PASS ** +Trial #028 OpenSSL: 87863.9us QAT: 61.0us Speed Up:1466.9x ** PASS ** +Trial #029 OpenSSL: 86890.2us QAT: 61.1us Speed Up:1448.7x ** PASS ** +Trial #030 OpenSSL: 85988.6us QAT: 61.1us Speed Up:1433.1x ** PASS ** +Trial #031 OpenSSL: 85144.6us QAT: 61.2us Speed Up:1417.1x ** PASS ** +Trial #032 OpenSSL: 85497.5us QAT: 61.1us Speed Up:1425.9x ** PASS ** +Trial #033 OpenSSL: 84708.4us QAT: 61.1us Speed Up:1411.8x ** PASS ** +Trial #034 OpenSSL: 83965.9us QAT: 61.0us Speed Up:1399.6x ** PASS ** +Trial #035 OpenSSL: 83283.2us QAT: 61.3us Speed Up:1383.6x ** PASS ** +Trial #036 OpenSSL: 82636.1us QAT: 61.4us Speed Up:1371.5x ** PASS ** +Trial #037 OpenSSL: 82023.6us QAT: 61.5us Speed Up:1359.8x ** PASS ** +Trial #038 OpenSSL: 82417.9us QAT: 61.4us Speed Up:1367.3x ** PASS ** +Trial #039 OpenSSL: 82765.6us QAT: 61.4us Speed Up:1373.3x ** PASS ** +Trial #040 OpenSSL: 83024.8us QAT: 61.4us Speed Up:1376.8x ** PASS ** +Trial #041 OpenSSL: 83360.0us QAT: 61.4us Speed Up:1381.7x ** PASS ** +Trial #042 OpenSSL: 82792.2us QAT: 61.4us Speed Up:1370.8x ** PASS ** +Trial #043 OpenSSL: 82258.4us QAT: 61.6us Speed Up:1359.9x ** PASS ** +Trial #044 OpenSSL: 82516.1us QAT: 61.5us Speed Up:1365.5x ** PASS ** +Trial #045 OpenSSL: 83310.0us QAT: 61.5us Speed Up:1377.7x ** PASS ** +Trial #046 OpenSSL: 82796.1us QAT: 61.5us Speed Up:1368.5x ** PASS ** +Trial #047 OpenSSL: 82306.6us QAT: 61.6us Speed Up:1359.4x ** PASS ** +Trial #048 OpenSSL: 83089.2us QAT: 61.4us Speed Up:1375.6x ** PASS ** +Trial #049 OpenSSL: 83325.5us QAT: 61.4us Speed Up:1380.0x ** PASS ** +Trial #050 OpenSSL: 84037.0us QAT: 61.3us Speed Up:1394.3x ** PASS ** +Trial #051 OpenSSL: 84220.8us QAT: 61.2us Speed Up:1399.1x ** PASS ** +Trial #052 OpenSSL: 84431.7us QAT: 61.2us Speed Up:1403.8x ** PASS ** +Trial #053 OpenSSL: 83968.2us QAT: 61.2us Speed Up:1394.5x ** PASS ** +Trial #054 OpenSSL: 84627.4us QAT: 61.1us Speed Up:1408.1x ** PASS ** +Trial #055 OpenSSL: 84178.3us QAT: 61.2us Speed Up:1399.7x ** PASS ** +Trial #056 OpenSSL: 84762.3us QAT: 61.2us Speed Up:1409.5x ** PASS ** +Trial #057 OpenSSL: 84316.2us QAT: 61.2us Speed Up:1401.0x ** PASS ** +Trial #058 OpenSSL: 83892.7us QAT: 61.2us Speed Up:1393.5x ** PASS ** +Trial #059 OpenSSL: 84470.6us QAT: 61.2us Speed Up:1403.0x ** PASS ** +Trial #060 OpenSSL: 85004.8us QAT: 61.2us Speed Up:1413.1x ** PASS ** +Trial #061 OpenSSL: 85135.9us QAT: 61.2us Speed Up:1415.1x ** PASS ** +Trial #062 OpenSSL: 85315.8us QAT: 61.1us Speed Up:1418.5x ** PASS ** +Trial #063 OpenSSL: 85456.7us QAT: 61.1us Speed Up:1420.7x ** PASS ** +Trial #064 OpenSSL: 85957.1us QAT: 61.1us Speed Up:1430.1x ** PASS ** +Trial #065 OpenSSL: 86074.8us QAT: 61.1us Speed Up:1431.0x ** PASS ** +Trial #066 OpenSSL: 86224.6us QAT: 61.0us Speed Up:1434.4x ** PASS ** +Trial #067 OpenSSL: 85824.5us QAT: 61.1us Speed Up:1427.1x ** PASS ** +Trial #068 OpenSSL: 86291.3us QAT: 61.0us Speed Up:1436.1x ** PASS ** +Trial #069 OpenSSL: 86425.9us QAT: 61.0us Speed Up:1438.8x ** PASS ** +Trial #070 OpenSSL: 86039.3us QAT: 61.0us Speed Up:1431.9x ** PASS ** +Trial #071 OpenSSL: 86482.1us QAT: 61.0us Speed Up:1439.7x ** PASS ** +Trial #072 OpenSSL: 86113.8us QAT: 61.0us Speed Up:1433.1x ** PASS ** +Trial #073 OpenSSL: 85752.4us QAT: 61.1us Speed Up:1425.9x ** PASS ** +Trial #074 OpenSSL: 85405.3us QAT: 61.1us Speed Up:1418.8x ** PASS ** +Trial #075 OpenSSL: 85058.5us QAT: 61.2us Speed Up:1412.5x ** PASS ** +Trial #076 OpenSSL: 84723.6us QAT: 61.2us Speed Up:1406.5x ** PASS ** +Trial #077 OpenSSL: 84398.5us QAT: 61.2us Speed Up:1400.4x ** PASS ** +Trial #078 OpenSSL: 84081.7us QAT: 61.2us Speed Up:1394.7x ** PASS ** +Trial #079 OpenSSL: 83774.7us QAT: 61.3us Speed Up:1388.9x ** PASS ** +Trial #080 OpenSSL: 83913.3us QAT: 61.2us Speed Up:1392.0x ** PASS ** +Trial #081 OpenSSL: 84045.1us QAT: 61.2us Speed Up:1395.2x ** PASS ** +Trial #082 OpenSSL: 83749.8us QAT: 61.2us Speed Up:1390.1x ** PASS ** +Trial #083 OpenSSL: 83462.6us QAT: 61.2us Speed Up:1384.6x ** PASS ** +Trial #084 OpenSSL: 83181.6us QAT: 61.2us Speed Up:1379.3x ** PASS ** +Trial #085 OpenSSL: 82906.5us QAT: 61.2us Speed Up:1374.3x ** PASS ** +Trial #086 OpenSSL: 82640.0us QAT: 61.2us Speed Up:1369.7x ** PASS ** +Trial #087 OpenSSL: 83053.0us QAT: 61.2us Speed Up:1377.0x ** PASS ** +Trial #088 OpenSSL: 83189.2us QAT: 61.2us Speed Up:1379.3x ** PASS ** +Trial #089 OpenSSL: 82928.5us QAT: 61.3us Speed Up:1374.1x ** PASS ** +Trial #090 OpenSSL: 82670.5us QAT: 61.3us Speed Up:1369.1x ** PASS ** +Trial #091 OpenSSL: 82804.3us QAT: 61.3us Speed Up:1372.0x ** PASS ** +Trial #092 OpenSSL: 82554.4us QAT: 61.3us Speed Up:1367.3x ** PASS ** +Trial #093 OpenSSL: 82308.3us QAT: 61.3us Speed Up:1362.6x ** PASS ** +Trial #094 OpenSSL: 82687.5us QAT: 61.3us Speed Up:1369.5x ** PASS ** +Trial #095 OpenSSL: 82447.5us QAT: 61.3us Speed Up:1364.9x ** PASS ** +Trial #096 OpenSSL: 82805.9us QAT: 61.3us Speed Up:1372.1x ** PASS ** +Trial #097 OpenSSL: 82567.8us QAT: 61.3us Speed Up:1367.6x ** PASS ** +Trial #098 OpenSSL: 82930.6us QAT: 61.3us Speed Up:1375.1x ** PASS ** +Trial #099 OpenSSL: 82692.2us QAT: 61.3us Speed Up:1370.9x ** PASS ** +Trial #100 OpenSSL: 82456.7us QAT: 61.3us Speed Up:1366.9x ** PASS ** diff --git a/perf_data/bs8bit8192.txt b/perf_data/bs8bit8192.txt new file mode 100644 index 0000000..6e36531 --- /dev/null +++ b/perf_data/bs8bit8192.txt @@ -0,0 +1,101 @@ +Cpa CyInstance has successfully started. +Trial #001 OpenSSL: 244676.0us QAT: 130.2us Speed Up:1878.5x ** PASS ** +Trial #002 OpenSSL: 290090.0us QAT: 126.1us Speed Up:2315.7x ** PASS ** +Trial #003 OpenSSL: 304527.0us QAT: 126.3us Speed Up:2420.6x ** PASS ** +Trial #004 OpenSSL: 293434.0us QAT: 124.3us Speed Up:2364.3x ** PASS ** +Trial #005 OpenSSL: 287588.2us QAT: 124.5us Speed Up:2313.3x ** PASS ** +Trial #006 OpenSSL: 311858.8us QAT: 126.1us Speed Up:2465.6x ** PASS ** +Trial #007 OpenSSL: 304457.0us QAT: 127.2us Speed Up:2392.1x ** PASS ** +Trial #008 OpenSSL: 308027.1us QAT: 127.2us Speed Up:2419.6x ** PASS ** +Trial #009 OpenSSL: 302825.8us QAT: 128.1us Speed Up:2365.6x ** PASS ** +Trial #010 OpenSSL: 298619.1us QAT: 129.6us Speed Up:2311.0x ** PASS ** +Trial #011 OpenSSL: 310679.2us QAT: 130.1us Speed Up:2390.8x ** PASS ** +Trial #012 OpenSSL: 320779.9us QAT: 129.8us Speed Up:2476.7x ** PASS ** +Trial #013 OpenSSL: 316249.8us QAT: 129.9us Speed Up:2439.6x ** PASS ** +Trial #014 OpenSSL: 317377.6us QAT: 130.5us Speed Up:2436.6x ** PASS ** +Trial #015 OpenSSL: 313582.5us QAT: 130.8us Speed Up:2402.4x ** PASS ** +Trial #016 OpenSSL: 320854.8us QAT: 130.8us Speed Up:2457.8x ** PASS ** +Trial #017 OpenSSL: 321691.6us QAT: 131.1us Speed Up:2459.1x ** PASS ** +Trial #018 OpenSSL: 327720.1us QAT: 131.2us Speed Up:2501.3x ** PASS ** +Trial #019 OpenSSL: 324183.3us QAT: 131.1us Speed Up:2476.5x ** PASS ** +Trial #020 OpenSSL: 321087.0us QAT: 130.9us Speed Up:2455.5x ** PASS ** +Trial #021 OpenSSL: 321788.1us QAT: 130.2us Speed Up:2477.0x ** PASS ** +Trial #022 OpenSSL: 326841.4us QAT: 129.8us Speed Up:2527.1x ** PASS ** +Trial #023 OpenSSL: 324096.7us QAT: 129.2us Speed Up:2515.6x ** PASS ** +Trial #024 OpenSSL: 321539.2us QAT: 128.6us Speed Up:2505.6x ** PASS ** +Trial #025 OpenSSL: 319053.6us QAT: 128.1us Speed Up:2494.7x ** PASS ** +Trial #026 OpenSSL: 323513.8us QAT: 128.0us Speed Up:2532.4x ** PASS ** +Trial #027 OpenSSL: 323800.1us QAT: 127.5us Speed Up:2545.4x ** PASS ** +Trial #028 OpenSSL: 321647.9us QAT: 127.3us Speed Up:2532.2x ** PASS ** +Trial #029 OpenSSL: 325392.3us QAT: 127.2us Speed Up:2564.7x ** PASS ** +Trial #030 OpenSSL: 323317.6us QAT: 126.9us Speed Up:2552.8x ** PASS ** +Trial #031 OpenSSL: 326790.2us QAT: 126.7us Speed Up:2584.7x ** PASS ** +Trial #032 OpenSSL: 330115.9us QAT: 126.6us Speed Up:2613.7x ** PASS ** +Trial #033 OpenSSL: 333228.6us QAT: 126.3us Speed Up:2646.3x ** PASS ** +Trial #034 OpenSSL: 333248.1us QAT: 126.2us Speed Up:2650.0x ** PASS ** +Trial #035 OpenSSL: 331228.4us QAT: 125.9us Speed Up:2637.7x ** PASS ** +Trial #036 OpenSSL: 329369.8us QAT: 125.7us Speed Up:2627.5x ** PASS ** +Trial #037 OpenSSL: 329385.2us QAT: 125.5us Speed Up:2632.3x ** PASS ** +Trial #038 OpenSSL: 332027.5us QAT: 125.5us Speed Up:2653.3x ** PASS ** +Trial #039 OpenSSL: 330198.7us QAT: 125.4us Speed Up:2638.6x ** PASS ** +Trial #040 OpenSSL: 328434.7us QAT: 125.2us Speed Up:2628.1x ** PASS ** +Trial #041 OpenSSL: 326827.1us QAT: 125.1us Speed Up:2617.0x ** PASS ** +Trial #042 OpenSSL: 325289.2us QAT: 124.9us Speed Up:2608.5x ** PASS ** +Trial #043 OpenSSL: 323772.6us QAT: 124.6us Speed Up:2602.5x ** PASS ** +Trial #044 OpenSSL: 322315.8us QAT: 124.6us Speed Up:2590.5x ** PASS ** +Trial #045 OpenSSL: 324769.4us QAT: 124.6us Speed Up:2609.8x ** PASS ** +Trial #046 OpenSSL: 323430.9us QAT: 124.4us Speed Up:2602.2x ** PASS ** +Trial #047 OpenSSL: 325711.1us QAT: 124.4us Speed Up:2622.3x ** PASS ** +Trial #048 OpenSSL: 324337.5us QAT: 124.3us Speed Up:2613.2x ** PASS ** +Trial #049 OpenSSL: 322987.7us QAT: 124.1us Speed Up:2604.2x ** PASS ** +Trial #050 OpenSSL: 323219.7us QAT: 124.0us Speed Up:2609.8x ** PASS ** +Trial #051 OpenSSL: 321979.6us QAT: 124.0us Speed Up:2598.7x ** PASS ** +Trial #052 OpenSSL: 320798.7us QAT: 123.9us Speed Up:2592.3x ** PASS ** +Trial #053 OpenSSL: 320210.6us QAT: 123.6us Speed Up:2593.8x ** PASS ** +Trial #054 OpenSSL: 318710.6us QAT: 123.6us Speed Up:2581.4x ** PASS ** +Trial #055 OpenSSL: 318970.7us QAT: 123.6us Speed Up:2583.0x ** PASS ** +Trial #056 OpenSSL: 319263.5us QAT: 123.6us Speed Up:2585.5x ** PASS ** +Trial #057 OpenSSL: 319510.1us QAT: 123.6us Speed Up:2587.2x ** PASS ** +Trial #058 OpenSSL: 318460.1us QAT: 123.5us Speed Up:2580.5x ** PASS ** +Trial #059 OpenSSL: 317523.4us QAT: 123.4us Speed Up:2575.1x ** PASS ** +Trial #060 OpenSSL: 317776.0us QAT: 123.2us Speed Up:2580.7x ** PASS ** +Trial #061 OpenSSL: 318061.2us QAT: 123.2us Speed Up:2584.2x ** PASS ** +Trial #062 OpenSSL: 318327.0us QAT: 123.0us Speed Up:2589.7x ** PASS ** +Trial #063 OpenSSL: 318595.2us QAT: 123.0us Speed Up:2591.9x ** PASS ** +Trial #064 OpenSSL: 320337.0us QAT: 123.1us Speed Up:2604.8x ** PASS ** +Trial #065 OpenSSL: 320581.9us QAT: 123.0us Speed Up:2609.7x ** PASS ** +Trial #066 OpenSSL: 319664.2us QAT: 122.8us Speed Up:2604.9x ** PASS ** +Trial #067 OpenSSL: 319857.5us QAT: 122.8us Speed Up:2606.4x ** PASS ** +Trial #068 OpenSSL: 320087.8us QAT: 122.8us Speed Up:2608.2x ** PASS ** +Trial #069 OpenSSL: 320303.8us QAT: 122.7us Speed Up:2613.1x ** PASS ** +Trial #070 OpenSSL: 321912.4us QAT: 122.7us Speed Up:2625.8x ** PASS ** +Trial #071 OpenSSL: 321058.5us QAT: 122.6us Speed Up:2619.8x ** PASS ** +Trial #072 OpenSSL: 322237.3us QAT: 122.4us Speed Up:2635.9x ** PASS ** +Trial #073 OpenSSL: 322737.3us QAT: 122.2us Speed Up:2645.2x ** PASS ** +Trial #074 OpenSSL: 322869.1us QAT: 122.2us Speed Up:2647.7x ** PASS ** +Trial #075 OpenSSL: 322004.4us QAT: 122.1us Speed Up:2641.8x ** PASS ** +Trial #076 OpenSSL: 323436.0us QAT: 122.1us Speed Up:2654.2x ** PASS ** +Trial #077 OpenSSL: 324792.0us QAT: 122.1us Speed Up:2664.7x ** PASS ** +Trial #078 OpenSSL: 323988.2us QAT: 122.0us Speed Up:2660.8x ** PASS ** +Trial #079 OpenSSL: 325378.7us QAT: 121.9us Speed Up:2673.1x ** PASS ** +Trial #080 OpenSSL: 326689.1us QAT: 122.0us Speed Up:2682.6x ** PASS ** +Trial #081 OpenSSL: 326746.4us QAT: 121.8us Speed Up:2686.1x ** PASS ** +Trial #082 OpenSSL: 325923.8us QAT: 121.8us Speed Up:2679.8x ** PASS ** +Trial #083 OpenSSL: 327205.9us QAT: 121.8us Speed Up:2690.9x ** PASS ** +Trial #084 OpenSSL: 327270.5us QAT: 121.7us Speed Up:2693.9x ** PASS ** +Trial #085 OpenSSL: 326480.3us QAT: 121.7us Speed Up:2687.6x ** PASS ** +Trial #086 OpenSSL: 325697.7us QAT: 121.7us Speed Up:2681.5x ** PASS ** +Trial #087 OpenSSL: 326916.1us QAT: 121.6us Speed Up:2693.6x ** PASS ** +Trial #088 OpenSSL: 328123.7us QAT: 121.6us Speed Up:2704.4x ** PASS ** +Trial #089 OpenSSL: 327356.1us QAT: 121.6us Speed Up:2697.7x ** PASS ** +Trial #090 OpenSSL: 326631.5us QAT: 121.5us Speed Up:2692.9x ** PASS ** +Trial #091 OpenSSL: 325878.2us QAT: 121.4us Speed Up:2688.2x ** PASS ** +Trial #092 OpenSSL: 327034.9us QAT: 121.5us Speed Up:2696.8x ** PASS ** +Trial #093 OpenSSL: 326317.0us QAT: 121.5us Speed Up:2689.7x ** PASS ** +Trial #094 OpenSSL: 326410.7us QAT: 121.4us Speed Up:2692.3x ** PASS ** +Trial #095 OpenSSL: 325728.4us QAT: 121.4us Speed Up:2687.7x ** PASS ** +Trial #096 OpenSSL: 325807.1us QAT: 121.4us Speed Up:2688.7x ** PASS ** +Trial #097 OpenSSL: 325119.7us QAT: 121.3us Speed Up:2683.7x ** PASS ** +Trial #098 OpenSSL: 324464.4us QAT: 121.3us Speed Up:2679.1x ** PASS ** +Trial #099 OpenSSL: 323807.6us QAT: 121.2us Speed Up:2674.3x ** PASS ** +Trial #100 OpenSSL: 323174.3us QAT: 121.3us Speed Up:2668.9x ** PASS ** diff --git a/profiling/README.md b/profiling/README.md new file mode 100644 index 0000000..40313d0 --- /dev/null +++ b/profiling/README.md @@ -0,0 +1,2 @@ +sudo ./telemetry_helper.sh 1 +watch -n.2 cat /sys/devices/pci0000:6b/0000:6b:00.0/telemetry/device_data diff --git a/samples/test_bnModExpBatch.cpp b/samples/test_bnModExpBatch.cpp new file mode 100644 index 0000000..998c706 --- /dev/null +++ b/samples/test_bnModExpBatch.cpp @@ -0,0 +1,232 @@ + +#include "he_qat_misc.h" +#include "he_qat_utils.h" +#include "he_qat_bn_ops.h" +#include "he_qat_context.h" +#include "cpa_sample_utils.h" + +#include +#include +#include +#include + +#include +#include +#include + +#ifdef _DESTINY_DEBUG_VERBOSE +int gDebugParam = 1; +#endif + +const unsigned int BATCH_SIZE = 8; + +int main(int argc, const char** argv) { + const int bit_length = 2048; + const size_t num_trials = 32; + + double avg_speed_up = 0.0; + double ssl_avg_time = 0.0; + double qat_avg_time = 0.0; + + clock_t start = CLOCKS_PER_SEC; + clock_t ssl_elapsed = CLOCKS_PER_SEC; + clock_t qat_elapsed = CLOCKS_PER_SEC; + + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + // Set up QAT runtime context + acquire_qat_devices(); + + // Set up OpenSSL context (as baseline) + BN_CTX* ctx = BN_CTX_new(); + BN_CTX_start(ctx); + + for (unsigned int mod = 0; mod < num_trials; mod++) { + // Generate modulus number + BIGNUM* bn_mod = generateTestBNData(bit_length); + + if (!bn_mod) continue; + + char* bn_str = BN_bn2hex(bn_mod); +// printf("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, +// BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); + OPENSSL_free(bn_str); + + // Generate exponent in [0..bn_mod] + BIGNUM* bn_exponent = BN_new(); + if (!BN_rand_range(bn_exponent, bn_mod)) { + BN_free(bn_mod); + continue; + } + + // Generate base number + BIGNUM* bn_base = generateTestBNData(bit_length); + + // Perform OpenSSL ModExp Op + BIGNUM* ssl_res = BN_new(); + start = clock(); + BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); + ssl_elapsed = clock() - start; + + int len_ = (bit_length + 7) >> 3; + + // Start QAT timer (including data conversion overhead) + start = clock(); + + unsigned char* bn_base_data_ = + (unsigned char*)calloc(len_ * BATCH_SIZE, sizeof(unsigned char)); + if (NULL == bn_base_data_) exit(1); + for (unsigned int i = 0; i < BATCH_SIZE; i++) + BN_bn2binpad(bn_base, bn_base_data_+len_*i, len_); + unsigned char* bn_mod_data_ = + (unsigned char*)calloc(len_ * BATCH_SIZE, sizeof(unsigned char)); + if (NULL == bn_mod_data_) exit(1); + for (unsigned int i = 0; i < BATCH_SIZE; i++) + BN_bn2binpad(bn_mod, bn_mod_data_+len_*i, len_); + unsigned char* bn_exponent_data_ = + (unsigned char*)calloc(len_ * BATCH_SIZE, sizeof(unsigned char)); + if (NULL == bn_exponent_data_) exit(1); + for (unsigned int i = 0; i < BATCH_SIZE; i++) + BN_bn2binpad(bn_exponent, bn_exponent_data_+len_*i, len_); + unsigned char* bn_remainder_data_ = + (unsigned char*)calloc(len_ * BATCH_SIZE, sizeof(unsigned char)); + if (NULL == bn_remainder_data_) exit(1); + + clock_t cvt_elapsed = clock() - start; + + // Simulate input number in BigNumber representation + //BigNumber big_num_base((Ipp32u)0); + //BigNumber big_num_mod((Ipp32u)0); + //BigNumber big_num_exponent((Ipp32u)0); + std::vector big_num_base(BATCH_SIZE); + std::vector big_num_mod(BATCH_SIZE); + std::vector big_num_exponent(BATCH_SIZE); + + for (unsigned int i = 0; i < BATCH_SIZE; i++) { + status = binToBigNumber(big_num_base[i], bn_base_data_ + len_*i, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("Failed at binToBigNumber()\n"); + exit(1); + } + status = binToBigNumber(big_num_mod[i], bn_mod_data_ + len_*i, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("Failed at binToBigNumber()\n"); + exit(1); + } + status = binToBigNumber(big_num_exponent[i], bn_exponent_data_ + len_*i, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("Failed at binToBigNumber()\n"); + exit(1); + } + + // Reset numbers to 0 + memset(bn_base_data_ + len_*i, 0, len_); + memset(bn_mod_data_ + len_*i, 0, len_); + memset(bn_exponent_data_ + len_*i, 0, len_); + // Make sure variables are reset + if (memcmp(bn_base_data_ + len_*i, bn_mod_data_ + len_*i, len_) || + memcmp(bn_base_data_ + len_*i, bn_exponent_data_ + len_*i, len_)) { + PRINT_ERR("Pointers are not reset to zero!"); + exit(1); + } + + start = clock(); + status = bigNumberToBin(bn_base_data_ + len_*i, bit_length, big_num_base[i]); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("bn_base_data_: failed at bignumbertobin()\n"); + exit(1); + } + status = bigNumberToBin(bn_mod_data_ + len_*i, bit_length, big_num_mod[i]); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("bn_base_data_: failed at bignumbertobin()\n"); + exit(1); + } + status = bigNumberToBin(bn_exponent_data_ + len_*i, bit_length, big_num_exponent[i]); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("bn_base_data_: failed at bignumbertobin()\n"); + exit(1); + } + cvt_elapsed += (clock() - start); + } + + // Perform BigNumber modular exponentiation on QAT + start = clock(); + for (unsigned int i = 0; i < BATCH_SIZE; i++) + status = HE_QAT_bnModExp(bn_remainder_data_ + len_*i, bn_base_data_ + len_*i, + bn_exponent_data_ + len_*i, bn_mod_data_ + len_*i, bit_length); + getBnModExpRequest(BATCH_SIZE); + qat_elapsed = clock() - start; + + printf("BigNumber data conversion overhead: %.1lfus.\n", + (cvt_elapsed / (CLOCKS_PER_SEC / 1000000.0))); + printf("BigNumber modular exponentiation on QAT: %.1lfus.\n", + (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); + qat_elapsed += cvt_elapsed; + + BIGNUM* qat_res = BN_new(); + BN_bin2bn(bn_remainder_data_, len_, qat_res); + + if (HE_QAT_STATUS_SUCCESS != status) { + PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); + } +#ifdef _DESTINY_DEBUG_VERBOSE + else { + PRINT_DBG("\nQAT bnModExpOp finished\n"); + } +#endif + + start = clock(); + BigNumber big_num((Ipp32u)0); + status = binToBigNumber(big_num, bn_remainder_data_, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + printf("bn_remainder_data_: Failed at bigNumberToBin()\n"); + exit(1); + } + qat_elapsed += (clock() - start); + printf("BigNumber ModExp total time: %.1lfus.\n", + (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); + +#ifdef _DESTINY_DEBUG_VERBOSE + bn_str = BN_bn2hex(qat_res); + printf("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, + BN_num_bytes(qat_res), BN_num_bits(qat_res)); +#endif + +#ifdef _DESTINY_DEBUG_VERBOSE + int bit_len = 0; + ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); + std::string str; + big_num.num2hex(str); + printf("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, + bit_len); + printf("---------------------################-----------------------\n"); +#endif + + if (BN_cmp(qat_res, ssl_res) != 0) + printf("\t** FAIL **\n"); + else + printf("\t** PASS **\n"); + + BN_free(bn_mod); + BN_free(bn_base); + BN_free(bn_exponent); + BN_free(qat_res); + BN_free(ssl_res); + +// OPENSSL_free(bn_str); + + free(bn_mod_data_); + free(bn_base_data_); + free(bn_exponent_data_); + free(bn_remainder_data_); + + } + + // Tear down OpenSSL context + BN_CTX_end(ctx); + + // Tear down QAT runtime context + release_qat_devices(); + + return (int)status; +} diff --git a/signit.txt b/signit.txt new file mode 100644 index 0000000..023b5bf --- /dev/null +++ b/signit.txt @@ -0,0 +1,2 @@ +sudo chown fdiasmor $(tty) export GPG_TTY = + $(tty) git commit - S - m "Add initial 'code' to set up QAT context." diff --git a/start_qat_dev.sh b/start_qat_dev.sh new file mode 100755 index 0000000..429e54c --- /dev/null +++ b/start_qat_dev.sh @@ -0,0 +1,12 @@ +#!/bin/env bash + +start=$1 +stop=$2 +step=$3 +while [ $start -lt $stop ] +do + echo "start qat_dev$start" + sudo adf_ctl qat_dev$start up + start=`expr $start + $step` +done + diff --git a/stop_qat_dev.sh b/stop_qat_dev.sh new file mode 100755 index 0000000..cd990c4 --- /dev/null +++ b/stop_qat_dev.sh @@ -0,0 +1,12 @@ +#!/bin/env bash + +start=$1 +stop=$2 +step=$3 +while [ $start -lt $stop ] +do + echo "stop qat_dev$start" + sudo adf_ctl qat_dev$start down + start=`expr $start + $step` +done + diff --git a/telemetry_helper.sh b/telemetry_helper.sh new file mode 100755 index 0000000..b8678d6 --- /dev/null +++ b/telemetry_helper.sh @@ -0,0 +1,41 @@ +#! /bin/bash + +# Command Line Parameters +# - 1 => Enable Telemetry +# - 0 => Disable Telemetry +if [ $# == 0 ]; +then + echo "telemetry helper usage:" + echo " ./telemetry_helper.sh 1 <= Enables Telemetry service on all QAT end points" + echo " ./telemetry_helper.sh 0 <= Disables Telemetry service on all QAT end points" + exit +fi + +# ensure cr/lf are not removed from lspci command +IFS= + +# Capture all QuickAssist Device id info to logfile +echo "$(lspci -d 8086:4940)" > pci_ids.txt +control_file_names=() + +# Parse the logfile extracting just the pci device ids to array +while IFS= read -r line; do + bus_num=${line:0:2} + control_file_name="/sys/devices/pci0000:"$bus_num"/0000:"$bus_num":00.0/telemetry/control" + control_file_names+=($control_file_name) + done < pci_ids.txt + + for ((i=0; i<${#control_file_names[@]}; i++)) + do + if [ $1 = 0 ]; + then + echo "Disabling telemetry for " ${control_file_names[$i]} + else + echo "Enabling telemetry for " ${control_file_names[$i]} + fi + echo $1 > ${control_file_names[$i]} + done + +# Remove temporary file +rm pci_ids.txt + From aee4b381f5bfe71f291ddf2938d2cdeb1fa5d406 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Wed, 13 Jul 2022 15:16:47 -0700 Subject: [PATCH 197/364] Enable QAT static library building (#120) - Connect to static library enabled HE_QAT library - Fixed shared lib build to use IPP-Crypto shared library - Removed irrelavant cmake variables --- benchmark/CMakeLists.txt | 1 + cmake/heqat/heqat.cmake | 41 +++++++++++++++++++++++----------------- cmake/ippcrypto.cmake | 2 +- ipcl/CMakeLists.txt | 16 ++++++++++++---- test/CMakeLists.txt | 1 + 5 files changed, 39 insertions(+), 22 deletions(-) diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 56f25a2..1b843db 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -19,4 +19,5 @@ target_link_libraries(bench_ipcl PRIVATE # enable QAT unittests if(IPCL_ENABLE_QAT) target_link_libraries(bench_ipcl PRIVATE libhe_qat) + target_include_directories(bench_ipcl PRIVATE "$") endif() diff --git a/cmake/heqat/heqat.cmake b/cmake/heqat/heqat.cmake index c7c4286..cc324c4 100644 --- a/cmake/heqat/heqat.cmake +++ b/cmake/heqat/heqat.cmake @@ -5,9 +5,7 @@ include(ExternalProject) MESSAGE(STATUS "Configuring HE QAT") set(HEQAT_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_he_qat) set(HEQAT_GIT_REPO_URL git@github.com:intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.project-destiny.git) -#set(HEQAT_GIT_REPO_URL https://github.com/intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.project-destiny.git) -#set(HEQAT_GIT_LABEL development) -set(HEQAT_GIT_LABEL fdiasmor/modexp_latency) +set(HEQAT_GIT_LABEL development) set(HEQAT_SRC_DIR ${HEQAT_PREFIX}/src/ext_he_qat/) set(HEQAT_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS}") @@ -22,29 +20,38 @@ ExternalProject_Add( -DCMAKE_INSTALL_PREFIX=${HEQAT_PREFIX} -DHE_QAT_MISC=OFF -DIPPCP_PREFIX_PATH=${IPPCRYPTO_PREFIX}/lib/cmake - #-DARCH=${HEQAT_ARCH} - #-DCMAKE_ASM_NASM_COMPILER=nasm - #-DCMAKE_BUILD_TYPE=Release + -DHE_QAT_SHARED=OFF + -DCMAKE_BUILD_TYPE=Release UPDATE_COMMAND "" ) +add_dependencies(ext_he_qat ext_ipp-crypto) -add_dependencies(ext_he_qat libippcrypto) - -set(HEQAT_INC_DIR ${HEQAT_PREFIX}/include) #${HEQAT_SRC_DIR}/install/include) +set(HEQAT_INC_DIR ${HEQAT_PREFIX}/include) # Bring up CPA variables include(${CMAKE_CURRENT_LIST_DIR}/icp/CMakeLists.txt) list(APPEND HEQAT_INC_DIR ${ICP_INC_DIR}) -add_library(libhe_qat INTERFACE) -add_dependencies(libhe_qat ext_he_qat) +if(IPCL_SHARED) + add_library(libhe_qat INTERFACE) + add_dependencies(libhe_qat ext_he_qat) -ExternalProject_Get_Property(ext_he_qat SOURCE_DIR BINARY_DIR) + ExternalProject_Get_Property(ext_he_qat SOURCE_DIR BINARY_DIR) -target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libcpa_sample_utils.a) # ${HEQAT_PREFIX}/lib/libhe_qat_misc.a) -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat_debug.so) + target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libcpa_sample_utils.a) + if(CMAKE_BUILD_TYPE STREQUAL "Debug") + target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat_debug.a) + else() + target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat.a) + endif() + target_include_directories(libhe_qat SYSTEM INTERFACE ${HEQAT_INC_DIR}) else() - target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat.so) + add_library(libhe_qat STATIC IMPORTED GLOBAL) + add_dependencies(libhe_qat ext_he_qat) + + ExternalProject_Get_Property(ext_he_qat SOURCE_DIR BINARY_DIR) + + set_target_properties(libhe_qat PROPERTIES + IMPORTED_LOCATION ${HEQAT_PREFIX}/lib/libhe_qat.a + INCLUDE_DIRECTORIES ${HEQAT_INC_DIR}) endif() -target_include_directories(libhe_qat SYSTEM INTERFACE ${HEQAT_INC_DIR}) diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake index a12ad08..69b27de 100644 --- a/cmake/ippcrypto.cmake +++ b/cmake/ippcrypto.cmake @@ -40,7 +40,7 @@ if(IPCL_SHARED) ExternalProject_Get_Property(ext_ipp-crypto SOURCE_DIR BINARY_DIR) - target_link_libraries(libippcrypto INTERFACE ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libippcp.a ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libcrypto_mb.a) + target_link_libraries(libippcrypto INTERFACE ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libippcp.so ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libcrypto_mb.so) target_include_directories(libippcrypto SYSTEM INTERFACE ${IPPCRYPTO_PREFIX}/include) else() diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 5bfe2ec..d86653c 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -45,7 +45,7 @@ install(DIRECTORY ${IPPCRYPTO_INC_DIR}/ PATTERN "*.hpp" PATTERN "*.h") -target_link_libraries(ipcl PUBLIC OpenSSL::SSL OpenSSL::Crypto Threads::Threads -lnuma) +target_link_libraries(ipcl PUBLIC OpenSSL::SSL OpenSSL::Crypto Threads::Threads -lnuma udev z) if(IPCL_ENABLE_OMP) find_package(OpenMP REQUIRED) @@ -55,15 +55,23 @@ endif() if(IPCL_SHARED) target_link_libraries(ipcl PRIVATE libippcrypto) target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) + if(IPCL_ENABLE_QAT) + target_link_libraries(ipcl PRIVATE libhe_qat) + endif() + else() + ipcl_create_archive(ipcl libippcrypto::ippcp) ipcl_create_archive(ipcl libippcrypto::crypto_mb) + if(IPCL_ENABLE_QAT) + ipcl_create_archive(ipcl libhe_qat) + message(STATUS "HEQAT_PREFIX_INCLUDE : ${HEQAT_PREFIX}/include") + message(STATUS "HEQAT_INC_DIR : ${HEQAT_INC_DIR}") + target_include_directories(ipcl PRIVATE "$") + endif() target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) endif() -if(IPCL_ENABLE_QAT) - target_link_libraries(ipcl PRIVATE libhe_qat) -endif() # check whether cpu support avx512 flag set(CPU_AVX512_FLAG "avx512ifma") diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ac7389d..5794dff 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -19,4 +19,5 @@ target_link_libraries(unittest_ipcl PRIVATE # enable QAT unittests if(IPCL_ENABLE_QAT) target_link_libraries(unittest_ipcl PRIVATE libhe_qat) + target_include_directories(unittest_ipcl PRIVATE "$") endif() From a074de75febf11843acf23e7315361673d2df811 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Wed, 13 Jul 2022 16:55:18 -0700 Subject: [PATCH 198/364] Minor updates - Fix shared library build flags, use IPCL_SHARED value instead of OFF (heqat.cmake) - Remove udev/z linking issue when not using QAT library --- cmake/heqat/heqat.cmake | 8 ++++---- ipcl/CMakeLists.txt | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/cmake/heqat/heqat.cmake b/cmake/heqat/heqat.cmake index cc324c4..f59f028 100644 --- a/cmake/heqat/heqat.cmake +++ b/cmake/heqat/heqat.cmake @@ -20,7 +20,7 @@ ExternalProject_Add( -DCMAKE_INSTALL_PREFIX=${HEQAT_PREFIX} -DHE_QAT_MISC=OFF -DIPPCP_PREFIX_PATH=${IPPCRYPTO_PREFIX}/lib/cmake - -DHE_QAT_SHARED=OFF + -DHE_QAT_SHARED=${IPCL_SHARED} -DCMAKE_BUILD_TYPE=Release UPDATE_COMMAND "" ) @@ -38,11 +38,11 @@ if(IPCL_SHARED) ExternalProject_Get_Property(ext_he_qat SOURCE_DIR BINARY_DIR) - target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libcpa_sample_utils.a) + target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libcpa_sample_utils.so) if(CMAKE_BUILD_TYPE STREQUAL "Debug") - target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat_debug.a) + target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat_debug.so) else() - target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat.a) + target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat.so) endif() target_include_directories(libhe_qat SYSTEM INTERFACE ${HEQAT_INC_DIR}) else() diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index d86653c..3c931db 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -45,7 +45,7 @@ install(DIRECTORY ${IPPCRYPTO_INC_DIR}/ PATTERN "*.hpp" PATTERN "*.h") -target_link_libraries(ipcl PUBLIC OpenSSL::SSL OpenSSL::Crypto Threads::Threads -lnuma udev z) +target_link_libraries(ipcl PUBLIC OpenSSL::SSL OpenSSL::Crypto Threads::Threads -lnuma) if(IPCL_ENABLE_OMP) find_package(OpenMP REQUIRED) @@ -56,7 +56,7 @@ if(IPCL_SHARED) target_link_libraries(ipcl PRIVATE libippcrypto) target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) if(IPCL_ENABLE_QAT) - target_link_libraries(ipcl PRIVATE libhe_qat) + target_link_libraries(ipcl PRIVATE libhe_qat udev z) endif() else() @@ -65,9 +65,10 @@ else() ipcl_create_archive(ipcl libippcrypto::crypto_mb) if(IPCL_ENABLE_QAT) ipcl_create_archive(ipcl libhe_qat) - message(STATUS "HEQAT_PREFIX_INCLUDE : ${HEQAT_PREFIX}/include") + message(STATUS "HEQAT_PREFIX_INCLUDE : ${HEQAT_PREFIX}/include") message(STATUS "HEQAT_INC_DIR : ${HEQAT_INC_DIR}") target_include_directories(ipcl PRIVATE "$") + target_link_libraries(ipcl PRIVATE udev z) endif() target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) endif() From 811f9fd9380a3024e9eaa136affa5d62529802c1 Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Thu, 14 Jul 2022 08:03:41 +0800 Subject: [PATCH 199/364] benchmark with same inputs (#119) * Benchmark: update it to use same inputs * PubKey: Add support for fix hs & r in obfuscator when DJN is enabled * Minor typo fixes Co-authored-by: sejunkim --- benchmark/bench_cryptography.cpp | 88 +++++++++++++++++--- benchmark/bench_ops.cpp | 133 +++++++++++++++++++++++-------- ipcl/include/ipcl/pub_key.hpp | 6 ++ ipcl/pub_key.cpp | 43 +++++++--- 4 files changed, 212 insertions(+), 58 deletions(-) diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index c8b8165..84d45cd 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -3,7 +3,6 @@ #include -#include #include #include "ipcl/keygen.hpp" @@ -18,27 +17,81 @@ ->Args({1024}) \ ->Args({2048}) +constexpr bool Enable_DJN = true; + +// P_BN comes from ISO_IEC_18033_6_Compliance +const BigNumber P_BN = + "0xff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c" + "8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b4" + "0a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff76" + "4dd8b091f11a0943a2dd2b983b0df02f4c4d00b413"; + +// Q_BN comes from ISO_IEC_18033_6_Compliance +const BigNumber Q_BN = + "0xdacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d" + "9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de70" + "72a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49b" + "aa0f610bad100cdf47cc86e5034e2a0b2179e04ec7"; + +// R_BN comes from ISO_IEC_18033_6_Compliance +const BigNumber R_BN = + "0x57fb19590c31dc7c034b2a889cf4037ce3db799909c1eb0adb6199d8e96791daca9018" + "891f34309daff32dced4af7d793d16734d055e28023acab7295956bfbfdf62bf0ccb2ed3" + "1d5d176ca8b404e93007565fb6b72c33a512b4dc4f719231d62e27e34c3733929af32247" + "f88c20d1ee77096cc80d3d642464054c815b35878ba812349c8bdc3c6b645daf1a0de609" + "65f44dcf705681032480f1eeba82243196b96903becdc0df0801d4120cbd6db1c4b2841a" + "27991c44a43750c24ed0825718ad14cfb9c6b40b78ff3d25f71741f2def1c9d420d4b0fa" + "1e0a02e7851b5ec6a81133a368b80d1500b0f28fc653d2e6ff4366236dbf80ae3b4beae3" + "5e04579f2c"; + +const BigNumber HS_BN = + "0x7788f6e8f57d3488cf9e0c7f4c19521de9aa172bf35924c7827a1189d6c688ac078f77" + "7efcfc230e34f1fa5ae8d9d2ed5b062257618e0a0a485b0084b3fd39080031ea739bb48c" + "dcce4ad41704ed930d40f53a1cc5d7f70bcb379f17a912b0ad14fabe8fc10213dcd1eabd" + "9175ee9bf66c31e9af9703c9d92fa5c8d36279459631ba7e9d4571a10960f8e8d031b267" + "22f6ae6f618895b9ce4fce926c8f54169168f6bb3e033861e08c2eca2161198481bc7c52" + "3a38310be22f4dd7d028dc6b774e5cb8e6f33b24168697743b7deff411510e27694bf2e8" + "0258b325fd97370f5110f54d8d7580b45ae3db26da4e3b0409f0cfbc56d9d9856b66d8bf" + "46e727dc3148f70362d05faea743621e3841c94c78d53ee7e7fdef61022dd56922368991" + "f843ca0aebf8436e5ec7e737c7ce72ac58f138bb11a3035fe96cc5a7b1aa9d565cb8a317" + "f42564482dd3c842c5ee9fb523c165a8507ecee1ac4f185bdbcb7a51095c4c46bfe15aec" + "3dfd77e1fd2b0003596df83bbb0d5521f16e2301ec2d4aafe25e4479ee965d8bb30a689a" + "6f38ba710222fff7cf359d0f317b8e268f40f576c04262a595cdfc9a07b72978b9564ace" + "699208291da7024e86b6eeb1458658852f10794c677b53db8577af272233722ad4579d7a" + "074e57217e1c57d11862f74486c7f2987e4d09cd6fb2923569b577de50e89e6965a27e18" + "7a8a341a7282b385ef"; + static void BM_KeyGen(benchmark::State& state) { int64_t n_length = state.range(0); for (auto _ : state) { - ipcl::keyPair key = ipcl::generateKeypair(n_length, true); + ipcl::keyPair key = ipcl::generateKeypair(n_length, Enable_DJN); } } BENCHMARK(BM_KeyGen)->Unit(benchmark::kMicrosecond)->ADD_SAMPLE_KEY_LENGTH_ARGS; static void BM_Encrypt(benchmark::State& state) { size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector exp_value_v(dsize); + BigNumber n = P_BN * Q_BN; + int n_length = n.BitSize(); + ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); + ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + + std::vector r_bn_v(dsize, R_BN); + pub_key->setRandom(r_bn_v); + pub_key->setHS(HS_BN); + std::vector exp_bn_v(dsize); for (size_t i = 0; i < dsize; i++) - exp_value_v[i] = (unsigned int)(i * 1024) + 999; + exp_bn_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); - ipcl::PlainText pt(exp_value_v); + ipcl::PlainText pt(exp_bn_v); ipcl::CipherText ct; - for (auto _ : state) ct = key.pub_key->encrypt(pt); + for (auto _ : state) ct = pub_key->encrypt(pt); + + delete pub_key; + delete priv_key; } BENCHMARK(BM_Encrypt) ->Unit(benchmark::kMicrosecond) @@ -46,17 +99,26 @@ BENCHMARK(BM_Encrypt) static void BM_Decrypt(benchmark::State& state) { size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector exp_value_v(dsize); + BigNumber n = P_BN * Q_BN; + int n_length = n.BitSize(); + ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); + ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + + std::vector r_bn_v(dsize, R_BN); + pub_key->setRandom(r_bn_v); + pub_key->setHS(HS_BN); + std::vector exp_bn_v(dsize); for (size_t i = 0; i < dsize; i++) - exp_value_v[i] = (unsigned int)(i * 1024) + 999; + exp_bn_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); - ipcl::PlainText pt(exp_value_v), dt; - ipcl::CipherText ct = key.pub_key->encrypt(pt); + ipcl::PlainText pt(exp_bn_v), dt; + ipcl::CipherText ct = pub_key->encrypt(pt); + for (auto _ : state) dt = priv_key->decrypt(ct); - for (auto _ : state) dt = key.priv_key->decrypt(ct); + delete pub_key; + delete priv_key; } BENCHMARK(BM_Decrypt) diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index a8835f8..d57acd3 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -6,10 +6,9 @@ #include #include -#include "ipcl/ciphertext.hpp" #include "ipcl/keygen.hpp" -#include "ipcl/plaintext.hpp" +#define ADD_SAMPLE_KEY_LENGTH_ARGS Args({1024})->Args({2048}) #define ADD_SAMPLE_VECTOR_SIZE_ARGS \ Args({16}) \ ->Args({64}) \ @@ -19,75 +18,145 @@ ->Args({1024}) \ ->Args({2048}) +constexpr bool Enable_DJN = true; + +// P_BN comes from ISO_IEC_18033_6_Compliance +const BigNumber P_BN = + "0xff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c" + "8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b4" + "0a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff76" + "4dd8b091f11a0943a2dd2b983b0df02f4c4d00b413"; + +// Q_BN comes from ISO_IEC_18033_6_Compliance +const BigNumber Q_BN = + "0xdacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d" + "9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de70" + "72a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49b" + "aa0f610bad100cdf47cc86e5034e2a0b2179e04ec7"; + +// R_BN comes from ISO_IEC_18033_6_Compliance +const BigNumber R_BN = + "0x57fb19590c31dc7c034b2a889cf4037ce3db799909c1eb0adb6199d8e96791daca9018" + "891f34309daff32dced4af7d793d16734d055e28023acab7295956bfbfdf62bf0ccb2ed3" + "1d5d176ca8b404e93007565fb6b72c33a512b4dc4f719231d62e27e34c3733929af32247" + "f88c20d1ee77096cc80d3d642464054c815b35878ba812349c8bdc3c6b645daf1a0de609" + "65f44dcf705681032480f1eeba82243196b96903becdc0df0801d4120cbd6db1c4b2841a" + "27991c44a43750c24ed0825718ad14cfb9c6b40b78ff3d25f71741f2def1c9d420d4b0fa" + "1e0a02e7851b5ec6a81133a368b80d1500b0f28fc653d2e6ff4366236dbf80ae3b4beae3" + "5e04579f2c"; + +const BigNumber HS_BN = + "0x7788f6e8f57d3488cf9e0c7f4c19521de9aa172bf35924c7827a1189d6c688ac078f77" + "7efcfc230e34f1fa5ae8d9d2ed5b062257618e0a0a485b0084b3fd39080031ea739bb48c" + "dcce4ad41704ed930d40f53a1cc5d7f70bcb379f17a912b0ad14fabe8fc10213dcd1eabd" + "9175ee9bf66c31e9af9703c9d92fa5c8d36279459631ba7e9d4571a10960f8e8d031b267" + "22f6ae6f618895b9ce4fce926c8f54169168f6bb3e033861e08c2eca2161198481bc7c52" + "3a38310be22f4dd7d028dc6b774e5cb8e6f33b24168697743b7deff411510e27694bf2e8" + "0258b325fd97370f5110f54d8d7580b45ae3db26da4e3b0409f0cfbc56d9d9856b66d8bf" + "46e727dc3148f70362d05faea743621e3841c94c78d53ee7e7fdef61022dd56922368991" + "f843ca0aebf8436e5ec7e737c7ce72ac58f138bb11a3035fe96cc5a7b1aa9d565cb8a317" + "f42564482dd3c842c5ee9fb523c165a8507ecee1ac4f185bdbcb7a51095c4c46bfe15aec" + "3dfd77e1fd2b0003596df83bbb0d5521f16e2301ec2d4aafe25e4479ee965d8bb30a689a" + "6f38ba710222fff7cf359d0f317b8e268f40f576c04262a595cdfc9a07b72978b9564ace" + "699208291da7024e86b6eeb1458658852f10794c677b53db8577af272233722ad4579d7a" + "074e57217e1c57d11862f74486c7f2987e4d09cd6fb2923569b577de50e89e6965a27e18" + "7a8a341a7282b385ef"; + static void BM_Add_CTCT(benchmark::State& state) { size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector exp_value1_v(dsize, 65535), exp_value2_v(dsize, 65535); + BigNumber n = P_BN * Q_BN; + int n_length = n.BitSize(); + ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); + ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + + std::vector r_bn_v(dsize, R_BN); + pub_key->setRandom(r_bn_v); + pub_key->setHS(HS_BN); - ipcl::PlainText pt1, pt2; + std::vector exp_bn1_v(dsize), exp_bn2_v(dsize); for (int i = 0; i < dsize; i++) { - exp_value1_v[i] += (unsigned int)(i * 1024); - exp_value2_v[i] += (unsigned int)(i * 1024); + exp_bn1_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); + exp_bn2_v[i] = Q_BN + BigNumber((unsigned int)(i * 1024)); } - pt1 = ipcl::PlainText(exp_value1_v); - pt2 = ipcl::PlainText(exp_value2_v); - ipcl::CipherText ct1 = key.pub_key->encrypt(pt1); - ipcl::CipherText ct2 = key.pub_key->encrypt(pt2); + ipcl::PlainText pt1(exp_bn1_v); + ipcl::PlainText pt2(exp_bn2_v); + + ipcl::CipherText ct1 = pub_key->encrypt(pt1); + ipcl::CipherText ct2 = pub_key->encrypt(pt2); ipcl::CipherText sum; for (auto _ : state) sum = ct1 + ct2; -} + delete pub_key; + delete priv_key; +} BENCHMARK(BM_Add_CTCT) ->Unit(benchmark::kMicrosecond) ->ADD_SAMPLE_VECTOR_SIZE_ARGS; static void BM_Add_CTPT(benchmark::State& state) { size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector exp_value1_v(dsize, 65535), exp_value2_v(dsize, 65535); + BigNumber n = P_BN * Q_BN; + int n_length = n.BitSize(); + ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); + ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + + std::vector r_bn_v(dsize, R_BN); + pub_key->setRandom(r_bn_v); + pub_key->setHS(HS_BN); - ipcl::PlainText pt1, pt2; + std::vector exp_bn1_v(dsize), exp_bn2_v(dsize); for (int i = 0; i < dsize; i++) { - exp_value1_v[i] += (unsigned int)(i * 1024); - exp_value2_v[i] += (unsigned int)(i * 1024); + exp_bn1_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); + exp_bn2_v[i] = Q_BN + BigNumber((unsigned int)(i * 1024)); } - pt1 = ipcl::PlainText(exp_value1_v); - pt2 = ipcl::PlainText(exp_value2_v); - ipcl::CipherText ct1 = key.pub_key->encrypt(pt1); - ipcl::CipherText sum; + ipcl::PlainText pt1(exp_bn1_v); + ipcl::PlainText pt2(exp_bn2_v); + + ipcl::CipherText ct1 = pub_key->encrypt(pt1); + ipcl::CipherText sum; for (auto _ : state) sum = ct1 + pt2; -} + delete pub_key; + delete priv_key; +} BENCHMARK(BM_Add_CTPT) ->Unit(benchmark::kMicrosecond) ->ADD_SAMPLE_VECTOR_SIZE_ARGS; static void BM_Mul_CTPT(benchmark::State& state) { size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); + BigNumber n = P_BN * Q_BN; + int n_length = n.BitSize(); + ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); + ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); - std::vector exp_value1_v(dsize, 65535), exp_value2_v(dsize, 65535); + std::vector r_bn_v(dsize, R_BN); + pub_key->setRandom(r_bn_v); + pub_key->setHS(HS_BN); - ipcl::PlainText pt1, pt2; + std::vector exp_bn1_v(dsize), exp_bn2_v(dsize); for (int i = 0; i < dsize; i++) { - exp_value1_v[i] += (unsigned int)(i * 1024); - exp_value2_v[i] += (unsigned int)(i * 1024); + exp_bn1_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); + exp_bn2_v[i] = Q_BN + BigNumber((unsigned int)(i * 1024)); } - pt1 = ipcl::PlainText(exp_value1_v); - pt2 = ipcl::PlainText(exp_value2_v); - ipcl::CipherText ct1 = key.pub_key->encrypt(pt1); - ipcl::CipherText product; + ipcl::PlainText pt1(exp_bn1_v); + ipcl::PlainText pt2(exp_bn2_v); + ipcl::CipherText ct1 = pub_key->encrypt(pt1); + + ipcl::CipherText product; for (auto _ : state) product = ct1 * pt2; -} + delete pub_key; + delete priv_key; +} BENCHMARK(BM_Mul_CTPT) ->Unit(benchmark::kMicrosecond) ->ADD_SAMPLE_VECTOR_SIZE_ARGS; diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp index b40b7fd..6938e40 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -90,6 +90,8 @@ class PublicKey { */ void setRandom(const std::vector& r); + void setHS(const BigNumber& hs); + /** * Check if using DJN scheme */ @@ -148,6 +150,10 @@ class PublicKey { * @return the random value of type BigNumber */ BigNumber getRandom(int length) const; + + void applyDjnObfuscator(std::vector& obfuscator) const; + + void applyNormalObfuscator(std::vector& obfuscator) const; }; } // namespace ipcl diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index b4fe94f..d19c915 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -86,30 +86,45 @@ void PublicKey::enableDJN() { m_enable_DJN = true; } -void PublicKey::applyObfuscator(std::vector& obfuscator) const { +void PublicKey::applyDjnObfuscator(std::vector& obfuscator) const { std::size_t obf_size = obfuscator.size(); std::vector r(obf_size); - std::vector pown(obf_size, m_n); std::vector base(obf_size, m_hs); std::vector sq(obf_size, m_nsquare); - if (m_enable_DJN) { + if (m_testv) { + r = m_r; + } else { for (auto& r_ : r) { r_ = getRandom(m_randbits); } - obfuscator = ipcl::ippModExp(base, r, sq); + } + obfuscator = ipcl::ippModExp(base, r, sq); +} + +void PublicKey::applyNormalObfuscator( + std::vector& obfuscator) const { + std::size_t obf_size = obfuscator.size(); + std::vector r(obf_size); + std::vector sq(obf_size, m_nsquare); + std::vector pown(obf_size, m_n); + + if (m_testv) { + r = m_r; } else { for (int i = 0; i < obf_size; i++) { - if (m_testv) { - r[i] = m_r[i]; - } else { - r[i] = getRandom(m_bits); - r[i] = r[i] % (m_n - 1) + 1; - } - pown[i] = m_n; - sq[i] = m_nsquare; + r[i] = getRandom(m_bits); + r[i] = r[i] % (m_n - 1) + 1; } - obfuscator = ipcl::ippModExp(r, pown, sq); + } + obfuscator = ipcl::ippModExp(r, pown, sq); +} + +void PublicKey::applyObfuscator(std::vector& obfuscator) const { + if (m_enable_DJN) { + applyDjnObfuscator(obfuscator); + } else { + applyNormalObfuscator(obfuscator); } } @@ -118,6 +133,8 @@ void PublicKey::setRandom(const std::vector& r) { m_testv = true; } +void PublicKey::setHS(const BigNumber& hs) { m_hs = hs; } + std::vector PublicKey::raw_encrypt(const std::vector& pt, bool make_secure) const { std::size_t pt_size = pt.size(); From 8e97cb3aee62b0175581cb99205d9cf2ce25ed28 Mon Sep 17 00:00:00 2001 From: Fillipe Souza Date: Thu, 14 Jul 2022 18:07:08 -0700 Subject: [PATCH 200/364] Handling throttling at runtime. Signed-off-by: Fillipe Souza --- he_qat/he_qat_bn_ops.c | 120 ++++++++++++++++++++++++++++++++------ he_qat/he_qat_context.c | 2 +- samples/test_bnModExp.cpp | 2 +- 3 files changed, 104 insertions(+), 20 deletions(-) diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index 49c8cb0..e150487 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -29,6 +29,19 @@ HE_QAT_RequestBuffer he_qat_buffer; HE_QAT_RequestBufferList outstanding_buffer; HE_QAT_OutstandingBuffer outstanding; +volatile unsigned long request_count = 0; +volatile unsigned long response_count = 0; +pthread_mutex_t response_mutex; + +unsigned long request_latency = 0; // unused +unsigned long restart_threshold = 12; +unsigned long max_pending = 24; // each QAT endpoint has 6 PKE slices + // single socket has 4 QAT endpoints (24 simultaneous requests) + // dual-socket has 8 QAT endpoints (48 simultaneous requests) + // max_pending = (num_sockets * num_qat_devices * num_pke_slices) / k + // k (default: 1) can be adjusted dynamically as the measured request_latency deviate from the hardware latency + + /// @brief /// @function /// Callback function for lnModExpPerformOp. It performs any data processing @@ -240,10 +253,11 @@ static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) { /// Read requests from a buffer to finally offload the work to QAT devices. /// @future: Meant for multi-threaded mode. static void read_request_list(HE_QAT_TaskRequestList* _requests, - HE_QAT_RequestBuffer* _buffer) { + HE_QAT_RequestBuffer* _buffer, unsigned int max_requests) { if (NULL == _requests) return; pthread_mutex_lock(&_buffer->mutex); + // Wait while buffer is empty while (_buffer->count <= 0) pthread_cond_wait(&_buffer->any_more_data, &_buffer->mutex); @@ -251,12 +265,17 @@ static void read_request_list(HE_QAT_TaskRequestList* _requests, assert(_buffer->count > 0); // assert(_buffer->count <= HE_QAT_BUFFER_SIZE); - for (unsigned int i = 0; i < _buffer->count; i++) { + unsigned int count = (_buffer->count < max_requests) ? _buffer->count : max_requests; + + //for (unsigned int i = 0; i < _buffer->count; i++) { + for (unsigned int i = 0; i < count; i++) { _requests->request[i] = _buffer->data[_buffer->next_data_slot++]; _buffer->next_data_slot %= HE_QAT_BUFFER_SIZE; } - _requests->count = _buffer->count; - _buffer->count = 0; + //_requests->count = _buffer->count; + //_buffer->count = 0; + _requests->count = count; + _buffer->count -= count; pthread_cond_signal(&_buffer->any_free_slot); pthread_mutex_unlock(&_buffer->mutex); @@ -494,7 +513,7 @@ static void* start_inst_polling(void* _inst_config) { /// @param[in] HE_QAT_InstConfig *: contains the handle to CPA instance, pointer /// the global buffer of requests. void* start_perform_op(void* _inst_config) { - static unsigned int request_count = 0; +// static unsigned int request_count = 0; if (NULL == _inst_config) { printf("Failed in start_perform_op: _inst_config is NULL.\n"); pthread_exit(NULL); @@ -536,6 +555,14 @@ void* start_perform_op(void* _inst_config) { printf("Failed at detaching polling thread.\n"); pthread_exit(NULL); } + + /* NEW CODE */ + HE_QAT_TaskRequestList outstanding_requests; + for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { + outstanding_requests.request[i] = NULL; + } + outstanding_requests.count = 0; + /* END NEW CODE */ config->running = 1; config->active = 1; @@ -543,15 +570,44 @@ void* start_perform_op(void* _inst_config) { #ifdef HE_QAT_DEBUG printf("Try reading request from buffer. Inst #%d\n", config->inst_id); #endif - // Try consume data from butter to perform requested operation - HE_QAT_TaskRequest* request = - (HE_QAT_TaskRequest*)read_request(&he_qat_buffer); - - if (NULL == request) { - pthread_cond_signal(&config->ready); - continue; - } -// printf("Try process request #%u\n", request_count++); + /* NEW CODE */ + unsigned long pending = request_count - response_count; + unsigned long available = max_pending - ((pending < max_pending)?pending:max_pending); +#ifdef HE_QAT_DEBUG + printf("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", + request_count,response_count,pending,available); +#endif + while (available < restart_threshold) { +#ifdef HE_QAT_DEBUG + printf("[WAIT]\n"); +#endif + // argument passed in microseconds + OS_SLEEP(650); + pending = request_count - response_count; + available = max_pending - ((pending < max_pending)?pending:max_pending); + } +#ifdef HE_QAT_DEBUG + printf("[SUBMIT] request_count: %lu response_count: %lu pending: %lu available: %lu\n", + request_count,response_count,pending,available); +#endif + unsigned int max_requests = available; + // Try consume maximum amount of data from butter to perform requested operation + read_request_list(&outstanding_requests, &he_qat_buffer, max_requests); + /* END NEW CODE */ + +// // Try consume data from butter to perform requested operation +// HE_QAT_TaskRequest* request = +// (HE_QAT_TaskRequest*)read_request(&he_qat_buffer); +// +// if (NULL == request) { +// pthread_cond_signal(&config->ready); +// continue; +// } +#ifdef HE_QAT_DEBUG + printf("Offloading %u requests to the accelerator.\n", outstanding_requests.count); +#endif + for (unsigned int i = 0; i < outstanding_requests.count; i++) { + HE_QAT_TaskRequest* request = outstanding_requests.request[i]; #ifdef HE_QAT_SYNC_MODE COMPLETION_INIT(&request->callback); #endif @@ -583,10 +639,18 @@ void* start_perform_op(void* _inst_config) { retry = HE_QAT_MAX_RETRY; break; } + + if (CPA_STATUS_RETRY == status) { + printf("CPA requested RETRY\n"); + } + } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); // Ensure every call to perform operation is blocking for each endpoint if (CPA_STATUS_SUCCESS == status) { + // Global tracking of number of requests + request_count += 1; + // printf("retry_count = %d\n",retry_count); #ifdef HE_QAT_SYNC_MODE // Wait until the callback function has been called @@ -604,7 +668,14 @@ void* start_perform_op(void* _inst_config) { request->request_status = HE_QAT_STATUS_FAIL; // Review it } - // Wake up any blocked call to stop_perform_op, signaling that now it is + // Reset pointer + outstanding_requests.request[i] = NULL; + request = NULL; + + }// for loop over batch of requests + outstanding_requests.count = 0; + + // Wake up any blocked call to stop_perform_op, signaling that now it is // safe to terminate running instances. Check if this detereorate // performance. pthread_cond_signal( @@ -897,14 +968,18 @@ void getBnModExpRequest(unsigned int batch_size) { #ifdef HE_QAT_PERF gettimeofday(&start_time, NULL); #endif +//printf("batch_size=%u ",batch_size); +// while (j < batch_size) { do { // Buffer read may be safe for single-threaded blocking calls only. // Note: Not tested on multithreaded environment. HE_QAT_TaskRequest* task = (HE_QAT_TaskRequest*)he_qat_buffer.data[block_at_index]; - // if (NULL == task) - // continue; + if (NULL == task) + continue; + +//printf("j=%u ",j); // Block and synchronize: Wait for the most recently offloaded request // to complete processing @@ -941,7 +1016,9 @@ void getBnModExpRequest(unsigned int batch_size) { he_qat_buffer.data[block_at_index] = NULL; block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; - } while (++j < batch_size); +// j++; +// } + } while (++j < batch_size); // number of null pointers equal batch size ? #ifdef HE_QAT_PERF gettimeofday(&end_time, NULL); @@ -951,6 +1028,8 @@ void getBnModExpRequest(unsigned int batch_size) { printf("Batch Wall Time: %.1lfus\n", time_taken); #endif + printf("\n"); + return; } @@ -965,6 +1044,11 @@ static void HE_QAT_bnModExpCallback( CpaFlatBuffer* pOut) { HE_QAT_TaskRequest* request = NULL; +// pthread_mutex_lock(&response_mutex); + // Global track of reponses by accelerator + response_count += 1; +// pthread_mutex_unlock(&response_mutex); + // Check if input data for the op is available and do something if (NULL != pCallbackTag) { // Read request data diff --git a/he_qat/he_qat_context.c b/he_qat/he_qat_context.c index 5269781..40c172f 100644 --- a/he_qat/he_qat_context.c +++ b/he_qat/he_qat_context.c @@ -24,7 +24,7 @@ #define MAX_INSTANCES 1 #endif -#define NUM_ACTIVE_INSTANCES 8 +#define NUM_ACTIVE_INSTANCES 1 volatile int context_state = 0; diff --git a/samples/test_bnModExp.cpp b/samples/test_bnModExp.cpp index 4ef256a..746ffee 100644 --- a/samples/test_bnModExp.cpp +++ b/samples/test_bnModExp.cpp @@ -18,7 +18,7 @@ int gDebugParam = 1; #endif -const unsigned int BATCH_SIZE = 1024; +const unsigned int BATCH_SIZE = 512; using namespace std::chrono; From 791ea9ebfd084e7e2cd902141405b1d342c74552 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 15 Jul 2022 18:12:06 -0700 Subject: [PATCH 201/364] WIP: multiple instances handled from a single thread. Signed-off-by: Souza, Fillipe --- he_qat/he_qat_bn_ops.c | 197 ++++++++++++++++++++++++++++++++++ he_qat/he_qat_context.c | 66 ++++++++---- he_qat/include/he_qat_types.h | 10 +- setup_devices.sh | 62 +++++++++++ 4 files changed, 316 insertions(+), 19 deletions(-) create mode 100755 setup_devices.sh diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index e150487..cb87109 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -506,6 +506,195 @@ static void* start_inst_polling(void* _inst_config) { pthread_exit(NULL); } + + +void* start_instances(void* _config) { +// static unsigned int request_count = 0; + static unsigned int instance_count = 0; + static unsigned int next_instance = 0; + + if (NULL == _config) { + printf("Failed in start_instances: _config is NULL.\n"); + pthread_exit(NULL); + } + + HE_QAT_Config* config = (HE_QAT_Config*)_config; + instance_count = config->count; + + CpaStatus status = CPA_STATUS_FAIL; + + for (unsigned int j = 0; j < config->count; j++) { + // Start from zero or restart after stop_perform_op + pthread_mutex_lock(&config->inst_config[j].mutex); + while (config->inst_config[j].active) + pthread_cond_wait(&config->inst_config[j].ready, + &config->inst_config[j].mutex); + + // assert(0 == config->active); + // assert(NULL == config->inst_handle); + + status = cpaCyStartInstance(config->inst_config[j].inst_handle); + config->inst_config[j].status = status; + if (CPA_STATUS_SUCCESS == status) { + printf("Cpa CyInstance has successfully started.\n"); + status = + cpaCySetAddressTranslation(config->inst_config[j].inst_handle, + sampleVirtToPhys); + } + + pthread_cond_signal(&config->inst_config[j].ready); + pthread_mutex_unlock(&config->inst_config[j].mutex); + + if (CPA_STATUS_SUCCESS != status) pthread_exit(NULL); + + // Start QAT instance and start polling + pthread_t polling_thread; + if (pthread_create(&polling_thread, config->inst_config[j].attr, start_inst_polling, + (void*)&(config->inst_config[j])) != 0) { + printf("Failed at creating and starting polling thread.\n"); + pthread_exit(NULL); + } + + if (pthread_detach(polling_thread) != 0) { + printf("Failed at detaching polling thread.\n"); + pthread_exit(NULL); + } + + } // for loop + + /* NEW CODE */ + HE_QAT_TaskRequestList outstanding_requests; + for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { + outstanding_requests.request[i] = NULL; + } + outstanding_requests.count = 0; + /* END NEW CODE */ + + config->running = 1; + config->active = 1; + while (config->running) { +#ifdef HE_QAT_DEBUG + printf("Try reading request from buffer. Inst #%d\n", config->inst_id); +#endif + /* NEW CODE */ + unsigned long pending = request_count - response_count; + unsigned long available = max_pending - ((pending < max_pending)?pending:max_pending); +#ifdef HE_QAT_DEBUG + printf("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", + request_count,response_count,pending,available); +#endif + while (available < restart_threshold) { +#ifdef HE_QAT_DEBUG + printf("[WAIT]\n"); +#endif + // argument passed in microseconds + OS_SLEEP(650); + pending = request_count - response_count; + available = max_pending - ((pending < max_pending)?pending:max_pending); + } +#ifdef HE_QAT_DEBUG + printf("[SUBMIT] request_count: %lu response_count: %lu pending: %lu available: %lu\n", + request_count,response_count,pending,available); +#endif + unsigned int max_requests = available; + // Try consume maximum amount of data from butter to perform requested operation + read_request_list(&outstanding_requests, &he_qat_buffer, max_requests); + /* END NEW CODE */ + +// // Try consume data from butter to perform requested operation +// HE_QAT_TaskRequest* request = +// (HE_QAT_TaskRequest*)read_request(&he_qat_buffer); +// +// if (NULL == request) { +// pthread_cond_signal(&config->ready); +// continue; +// } +#ifdef HE_QAT_DEBUG + printf("Offloading %u requests to the accelerator.\n", outstanding_requests.count); +#endif + for (unsigned int i = 0; i < outstanding_requests.count; i++) { + HE_QAT_TaskRequest* request = outstanding_requests.request[i]; +#ifdef HE_QAT_SYNC_MODE + COMPLETION_INIT(&request->callback); +#endif + + unsigned retry = 0; + do { + // Realize the type of operation from data + switch (request->op_type) { + // Select appropriate action + case HE_QAT_OP_MODEXP: +#ifdef HE_QAT_DEBUG + printf("Offload request using instance #%d\n", next_instance); +#endif +#ifdef HE_QAT_PERF + gettimeofday(&request->start, NULL); +#endif + status = cpaCyLnModExp( + config->inst_config[next_instance].inst_handle, + (CpaCyGenFlatBufCbFunc) + request->callback_func, // lnModExpCallback, + (void*)request, (CpaCyLnModExpOpData*)request->op_data, + &request->op_result); + retry++; + break; + case HE_QAT_OP_NONE: + default: +#ifdef HE_QAT_DEBUG + printf("HE_QAT_OP_NONE to instance #%d\n", next_instance); +#endif + retry = HE_QAT_MAX_RETRY; + break; + } + + if (CPA_STATUS_RETRY == status) { + printf("CPA requested RETRY\n"); + } + + } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); + + // Ensure every call to perform operation is blocking for each endpoint + if (CPA_STATUS_SUCCESS == status) { + // Global tracking of number of requests + request_count += 1; + next_instance = (next_instance + 1) % instance_count; +// printf("retry_count = %d\n",retry_count); +#ifdef HE_QAT_SYNC_MODE + // Wait until the callback function has been called + if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { + request->op_status = CPA_STATUS_FAIL; + request->request_status = HE_QAT_STATUS_FAIL; // Review it + printf("Failed in COMPLETION WAIT\n"); + } + + // Destroy synchronization object + COMPLETION_DESTROY(&request->callback); +#endif + } else { + request->op_status = CPA_STATUS_FAIL; + request->request_status = HE_QAT_STATUS_FAIL; // Review it + } + +#ifdef HE_QAT_DEBUG + printf("Offloading completed by instance #%d\n", next_instance-1); +#endif + + // Reset pointer + outstanding_requests.request[i] = NULL; + request = NULL; + + }// for loop over batch of requests + outstanding_requests.count = 0; + + // Wake up any blocked call to stop_perform_op, signaling that now it is + // safe to terminate running instances. Check if this detereorate + // performance. + // pthread_cond_signal( + // &config->ready); // Prone to the lost wake-up problem + } + pthread_exit(NULL); +} + /// @brief /// @function perform_op /// Offload operation to QAT endpoints; for example, large number modular @@ -737,6 +926,14 @@ void stop_perform_op(HE_QAT_InstConfig* config, unsigned num_inst) { return; } +void stop_instances(HE_QAT_Config* _config) { + if (NULL == _config) return; + if (_config->active) _config->active = 0; + if (_config->running) _config->running = 0; + stop_perform_op(_config->inst_config, _config->count); + return ; +} + HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int nbits) { // Unpack data and copy to QAT friendly memory space diff --git a/he_qat/he_qat_context.c b/he_qat/he_qat_context.c index 40c172f..50542b0 100644 --- a/he_qat/he_qat_context.c +++ b/he_qat/he_qat_context.c @@ -24,21 +24,22 @@ #define MAX_INSTANCES 1 #endif -#define NUM_ACTIVE_INSTANCES 1 - volatile int context_state = 0; // Global variable declarations -pthread_t buffer_manager; -HE_QAT_Inst he_qat_instances[NUM_ACTIVE_INSTANCES]; -pthread_attr_t he_qat_inst_attr[NUM_ACTIVE_INSTANCES]; -HE_QAT_InstConfig he_qat_inst_config[NUM_ACTIVE_INSTANCES]; +pthread_t buffer_manager; +HE_QAT_Inst he_qat_instances[HE_QAT_NUM_ACTIVE_INSTANCES]; +pthread_attr_t he_qat_inst_attr[HE_QAT_NUM_ACTIVE_INSTANCES]; +HE_QAT_InstConfig he_qat_inst_config[HE_QAT_NUM_ACTIVE_INSTANCES]; +HE_QAT_Config* he_qat_config = NULL; extern HE_QAT_RequestBuffer he_qat_buffer; extern HE_QAT_RequestBufferList outstanding_buffer; extern HE_QAT_OutstandingBuffer outstanding; extern void* schedule_requests(void* state); extern void* start_perform_op(void* _inst_config); +extern void* start_instances(void* _inst_config); +extern void stop_instances(HE_QAT_Config* _config); extern void stop_perform_op(void* _inst_config, unsigned num_inst); CpaInstanceHandle handle = NULL; @@ -48,6 +49,7 @@ static CpaInstanceHandle get_qat_instance() { static Cpa16U numInstances = 0; static Cpa16U nextInstance = 0; CpaStatus status = CPA_STATUS_SUCCESS; + CpaInstanceInfo2 info = {0}; if (0 == numInstances) { //*pCyInstHandle = NULL; @@ -55,15 +57,32 @@ static CpaInstanceHandle get_qat_instance() { if (numInstances >= MAX_INSTANCES) { numInstances = MAX_INSTANCES; } - if (numInstances >= NUM_ACTIVE_INSTANCES) { - numInstances = NUM_ACTIVE_INSTANCES; + if (numInstances >= HE_QAT_NUM_ACTIVE_INSTANCES) { + numInstances = HE_QAT_NUM_ACTIVE_INSTANCES; } printf("Found %d CyInstances.\n", numInstances); - printf("Next Instance: %d.\n", nextInstance); if ((status == CPA_STATUS_SUCCESS) && (numInstances > 0)) { status = cpaCyGetInstances(numInstances, cyInstHandles); + // List instances and their characteristics + for (unsigned int i = 0; i < numInstances; i++) { + status = cpaCyInstanceGetInfo2(cyInstHandles[i],&info); + if (CPA_STATUS_SUCCESS == status) { + printf("Vendor Name: %s\n",info.vendorName); + printf("Part Name: %s\n",info.partName); + printf("Inst Name: %s\n",info.instName); + printf("Inst ID: %s\n",info.instID); + printf("Node Affinity: %u\n",info.nodeAffinity); + printf("Physical Instance:\n"); + printf("\tpackageId: %d\n",info.physInstId.packageId); + printf("\tacceleratorId: %d\n",info.physInstId.acceleratorId); + printf("\texecutionEngineId: %d\n",info.physInstId.executionEngineId); + printf("\tbusAddress: %d\n",info.physInstId.busAddress); + printf("\tkptAcHandle: %d\n",info.physInstId.kptAcHandle); + } + } + printf("Next Instance: %d.\n", nextInstance); if (status == CPA_STATUS_SUCCESS) return cyInstHandles[nextInstance]; //*pCyInstHandle = cyInstHandles[0]; @@ -113,10 +132,10 @@ HE_QAT_STATUS acquire_qat_devices() { #endif // Potential out-of-scope hazard for segmentation fault - CpaInstanceHandle _inst_handle[NUM_ACTIVE_INSTANCES]; // = NULL; + CpaInstanceHandle _inst_handle[HE_QAT_NUM_ACTIVE_INSTANCES]; // = NULL; // TODO: @fdiasmor Create a CyGetInstance that retrieves more than one. // sampleCyGetInstance(&_inst_handle); - for (unsigned int i = 0; i < NUM_ACTIVE_INSTANCES; i++) { + for (unsigned int i = 0; i < HE_QAT_NUM_ACTIVE_INSTANCES; i++) { _inst_handle[i] = get_qat_instance(); if (_inst_handle[i] == NULL) { printf("Failed to find QAT endpoints.\n"); @@ -169,7 +188,7 @@ HE_QAT_STATUS acquire_qat_devices() { pthread_attr_t attr; cpu_set_t cpus; // for (int i = 0; i < HE_QAT_SYNC; i++) { - for (int i = 0; i < NUM_ACTIVE_INSTANCES; i++) { + for (int i = 0; i < HE_QAT_NUM_ACTIVE_INSTANCES; i++) { CPU_ZERO(&cpus); CPU_SET(i, &cpus); pthread_attr_init(&he_qat_inst_attr[i]); @@ -191,18 +210,28 @@ HE_QAT_STATUS acquire_qat_devices() { he_qat_inst_config[i].inst_handle = _inst_handle[i]; he_qat_inst_config[i].inst_id = i; he_qat_inst_config[i].attr = &he_qat_inst_attr[i]; - pthread_create(&he_qat_instances[i], he_qat_inst_config[i].attr, - start_perform_op, (void*)&he_qat_inst_config[i]); +// pthread_create(&he_qat_instances[i], he_qat_inst_config[i].attr, +// start_perform_op, (void*)&he_qat_inst_config[i]); } + + he_qat_config = (HE_QAT_Config *) malloc(sizeof(HE_QAT_Config)); + he_qat_config->inst_config = he_qat_inst_config; + he_qat_config->count = HE_QAT_NUM_ACTIVE_INSTANCES; + he_qat_config->running = 0; + he_qat_config->active = 0; + + // Work on this + pthread_create(&he_qat_instances[0], NULL, start_instances, (void*)he_qat_config); #ifdef _DESTINY_DEBUG_VERBOSE printf("Created processing threads.\n"); #endif // Dispatch the qat instances to run independently in the background // for (int i = 0; i < HE_QAT_SYNC; i++) { - for (int i = 0; i < NUM_ACTIVE_INSTANCES; i++) { - pthread_detach(he_qat_instances[i]); - } + pthread_detach(he_qat_instances[0]); +// for (int i = 0; i < HE_QAT_NUM_ACTIVE_INSTANCES; i++) { +// pthread_detach(he_qat_instances[i]); +// } #ifdef _DESTINY_DEBUG_VERBOSE printf("Detached processing threads.\n"); #endif @@ -239,7 +268,8 @@ HE_QAT_STATUS release_qat_devices() { if (0 == context_state) return HE_QAT_STATUS_SUCCESS; - stop_perform_op(he_qat_inst_config, NUM_ACTIVE_INSTANCES); + stop_instances(he_qat_config); + //stop_perform_op(he_qat_inst_config, HE_QAT_NUM_ACTIVE_INSTANCES); #ifdef _DESTINY_DEBUG_VERBOSE printf("Stopped polling and processing threads.\n"); #endif diff --git a/he_qat/include/he_qat_types.h b/he_qat/include/he_qat_types.h index dfc5b8a..02f49ca 100644 --- a/he_qat/include/he_qat_types.h +++ b/he_qat/include/he_qat_types.h @@ -13,8 +13,9 @@ extern "C" { #include +#define HE_QAT_NUM_ACTIVE_INSTANCES 8 #define HE_QAT_BUFFER_SIZE 1024 -#define HE_QAT_BUFFER_COUNT 8 +#define HE_QAT_BUFFER_COUNT HE_QAT_NUM_ACTIVE_INSTANCES // Type definitions typedef enum { HE_QAT_SYNC = 1, HE_QAT_ASYNC = 2 } HE_QAT_EXEC_MODE; @@ -85,6 +86,13 @@ typedef struct { CpaStatus status; } HE_QAT_InstConfig; +typedef struct { + HE_QAT_InstConfig *inst_config; + volatile int active; + volatile int running; + unsigned int count; +} HE_QAT_Config; + #ifdef __cplusplus } // close the extern "C" { #endif diff --git a/setup_devices.sh b/setup_devices.sh new file mode 100755 index 0000000..25d272f --- /dev/null +++ b/setup_devices.sh @@ -0,0 +1,62 @@ +#!/bin/env bash + +num_phys_dev=8 # num_dev=$(lspci -d 8086:4940 | wc -l) +conf_virt_func=0 # total_virt_func=$(lspci -d 8086:4941 | wc -l) +num_virt_func=0 # conf_virt_func=`expr $total_virt_func / $num_dev` +dev_step=1 + +if [ $# -eq 0 ]; then + echo "Parameters:" + echo "-- num_phys_dev: Number of physical devices to be active. (default: 8)" + echo "-- conf_virt_func: Number of configured virtual functions per device. (default: 0)" + echo "-- num_virt_func: Number of virtual functions to be active per device. (default: 0)" + echo "./setup_devices " +fi + +if [ -n "$1" ]; then + num_phys_dev=$1 +fi + +if [ -n "$2" ]; then + conf_virt_func=$2 +fi + +if [ -n "$3" ]; then + num_virt_func=$3 +fi + +if [ $conf_virt_func -gt 0 ]; then + dev_step=$conf_virt_func +fi + +start=$num_phys_dev +stop=`expr $num_phy_dev \\* $conf_virt_func` +stop=`expr $start + $stop` +step=$dev_step + +i=$start; +n=`expr $start \\* $conf_virt_func`; +n=`expr $i + $n`; +while [ $i -lt $n ]; +do + echo "sudo adf_ctl qat_dev$i down"; + sudo adf_ctl qat_dev$i down; + i=`expr $i + 1`; +done + +while [ $start -lt $stop ]; +do + echo "adf_ctl qat_dev$start up" + sudo adf_ctl qat_dev$start up; + # start up additional instances mapped to the same physical device + j=1; + while [ $j -lt $num_virt_func ]; + do + dev_id=`expr $j + $start`; + sudo adf_ctl qat_dev$dev_id up; + j=`expr $j + 1`; + done + start=`expr $start + $dev_step` +done + + From f4a0f8f12bd00312c6bb236183db33ba8e2f37fe Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 19 Jul 2022 18:39:03 -0700 Subject: [PATCH 202/364] Round-robin instance scheduling. Signed-off-by: Souza, Fillipe --- he_qat/he_qat_bn_ops.c | 82 +++++++++++++++++++++++----------- he_qat/include/he_qat_bn_ops.h | 1 + samples/test_bnModExp.cpp | 2 +- 3 files changed, 59 insertions(+), 26 deletions(-) diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index cb87109..7eb58df 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -24,6 +24,8 @@ double time_taken = 0.0; #pragma message "Asynchronous execution mode." #endif +#define RESTART_LATENCY_MICROSEC 620 + // Global buffer for the runtime environment HE_QAT_RequestBuffer he_qat_buffer; HE_QAT_RequestBufferList outstanding_buffer; @@ -34,8 +36,8 @@ volatile unsigned long response_count = 0; pthread_mutex_t response_mutex; unsigned long request_latency = 0; // unused -unsigned long restart_threshold = 12; -unsigned long max_pending = 24; // each QAT endpoint has 6 PKE slices +unsigned long restart_threshold = 6; +unsigned long max_pending = 64; // each QAT endpoint has 6 PKE slices // single socket has 4 QAT endpoints (24 simultaneous requests) // dual-socket has 8 QAT endpoints (48 simultaneous requests) // max_pending = (num_sockets * num_qat_devices * num_pke_slices) / k @@ -496,6 +498,10 @@ static void* start_inst_polling(void* _inst_config) { if (NULL == config->inst_handle) return NULL; +#ifdef HE_QAT_DEBUG + printf("Instance ID %d Polling\n",config->inst_id); +#endif + // What is harmful for polling without performing any operation? config->polling = 1; while (config->polling) { @@ -521,6 +527,21 @@ void* start_instances(void* _config) { HE_QAT_Config* config = (HE_QAT_Config*)_config; instance_count = config->count; + printf("Instance Count: %d\n",instance_count); + pthread_t* polling_thread = (pthread_t *) malloc(sizeof(pthread_t)*instance_count); + if (NULL == polling_thread) { + printf("Failed in start_instances: polling_thread is NULL.\n"); + pthread_exit(NULL); + } + unsigned* request_count_per_instance = (unsigned *) malloc(sizeof(unsigned)*instance_count); + if (NULL == request_count_per_instance) { + printf("Failed in start_instances: polling_thread is NULL.\n"); + pthread_exit(NULL); + } + for (unsigned i = 0; i < instance_count; i++) { + request_count_per_instance[i] = 0; + } + CpaStatus status = CPA_STATUS_FAIL; for (unsigned int j = 0; j < config->count; j++) { @@ -547,18 +568,23 @@ void* start_instances(void* _config) { if (CPA_STATUS_SUCCESS != status) pthread_exit(NULL); + printf("Instance ID: %d\n",config->inst_config[j].inst_id); + // Start QAT instance and start polling - pthread_t polling_thread; - if (pthread_create(&polling_thread, config->inst_config[j].attr, start_inst_polling, + //pthread_t polling_thread; + if (pthread_create(&polling_thread[j], config->inst_config[j].attr, start_inst_polling, (void*)&(config->inst_config[j])) != 0) { printf("Failed at creating and starting polling thread.\n"); pthread_exit(NULL); } - if (pthread_detach(polling_thread) != 0) { + if (pthread_detach(polling_thread[j]) != 0) { printf("Failed at detaching polling thread.\n"); pthread_exit(NULL); } + + config->inst_config[j].active = 1; + config->inst_config[j].running = 1; } // for loop @@ -588,9 +614,11 @@ void* start_instances(void* _config) { printf("[WAIT]\n"); #endif // argument passed in microseconds - OS_SLEEP(650); + OS_SLEEP(RESTART_LATENCY_MICROSEC); pending = request_count - response_count; available = max_pending - ((pending < max_pending)?pending:max_pending); +// printf("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", +// request_count,response_count,pending,available); } #ifdef HE_QAT_DEBUG printf("[SUBMIT] request_count: %lu response_count: %lu pending: %lu available: %lu\n", @@ -649,6 +677,7 @@ void* start_instances(void* _config) { if (CPA_STATUS_RETRY == status) { printf("CPA requested RETRY\n"); + pthread_exit(NULL); } } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); @@ -657,8 +686,15 @@ void* start_instances(void* _config) { if (CPA_STATUS_SUCCESS == status) { // Global tracking of number of requests request_count += 1; + request_count_per_instance[next_instance] += 1; +// printf("Instance %d Count %u\n",next_instance,request_count_per_instance[next_instance]); next_instance = (next_instance + 1) % instance_count; // printf("retry_count = %d\n",retry_count); +// printf("SUCCESS Next Instance = %d\n",next_instance); + // Wake up any blocked call to stop_perform_op, signaling that now it is + // safe to terminate running instances. Check if this detereorate + // performance. + pthread_cond_signal(&config->inst_config[next_instance].ready); // Prone to the lost wake-up problem #ifdef HE_QAT_SYNC_MODE // Wait until the callback function has been called if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { @@ -673,6 +709,7 @@ void* start_instances(void* _config) { } else { request->op_status = CPA_STATUS_FAIL; request->request_status = HE_QAT_STATUS_FAIL; // Review it + printf("Request Submission FAILED\n"); } #ifdef HE_QAT_DEBUG @@ -682,15 +719,9 @@ void* start_instances(void* _config) { // Reset pointer outstanding_requests.request[i] = NULL; request = NULL; - + }// for loop over batch of requests outstanding_requests.count = 0; - - // Wake up any blocked call to stop_perform_op, signaling that now it is - // safe to terminate running instances. Check if this detereorate - // performance. - // pthread_cond_signal( - // &config->ready); // Prone to the lost wake-up problem } pthread_exit(NULL); } @@ -1165,7 +1196,7 @@ void getBnModExpRequest(unsigned int batch_size) { #ifdef HE_QAT_PERF gettimeofday(&start_time, NULL); #endif -//printf("batch_size=%u ",batch_size); +//printf("batch_size=%u \n",batch_size); // while (j < batch_size) { do { // Buffer read may be safe for single-threaded blocking calls only. @@ -1225,7 +1256,7 @@ void getBnModExpRequest(unsigned int batch_size) { printf("Batch Wall Time: %.1lfus\n", time_taken); #endif - printf("\n"); +// printf("\n"); return; } @@ -1240,16 +1271,16 @@ static void HE_QAT_bnModExpCallback( void* pOpData, // This is fixed -- please swap it CpaFlatBuffer* pOut) { HE_QAT_TaskRequest* request = NULL; - -// pthread_mutex_lock(&response_mutex); - // Global track of reponses by accelerator - response_count += 1; -// pthread_mutex_unlock(&response_mutex); - + // Check if input data for the op is available and do something if (NULL != pCallbackTag) { // Read request data request = (HE_QAT_TaskRequest*)pCallbackTag; + + pthread_mutex_lock(&response_mutex); + // Global track of reponses by accelerator + response_count += 1; + pthread_mutex_unlock(&response_mutex); pthread_mutex_lock(&request->mutex); // Collect the device output in pOut @@ -1261,6 +1292,7 @@ static void HE_QAT_bnModExpCallback( // Copy compute results to output destination memcpy(request->op_output, request->op_result.pData, request->op_result.dataLenInBytes); +// printf("Request ID %llu Completed.\n",request->id); #ifdef HE_QAT_PERF gettimeofday(&request->end, NULL); #endif @@ -1281,10 +1313,9 @@ static void HE_QAT_bnModExpCallback( HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, unsigned char* e, unsigned char* m, int nbits) { -#ifdef HE_QAT_DEBUG +//#ifdef HE_QAT_DEBUG static unsigned long long req_count = 0; - // printf("Wait lock write request. [buffer size: %d]\n",_buffer->count); -#endif +//#endif // Unpack data and copy to QAT friendly memory space int len = nbits / 8; @@ -1367,11 +1398,12 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, request->callback_func = (void*)HE_QAT_bnModExpCallback; request->op_status = status; request->op_output = (void*)r; - + // Ensure calls are synchronized at exit (blocking) pthread_mutex_init(&request->mutex, NULL); pthread_cond_init(&request->ready, NULL); + request->id = req_count; #ifdef HE_QAT_DEBUG printf("BN ModExp interface call for request #%llu\n", ++req_count); #endif diff --git a/he_qat/include/he_qat_bn_ops.h b/he_qat/include/he_qat_bn_ops.h index bf51313..2ebda91 100644 --- a/he_qat/include/he_qat_bn_ops.h +++ b/he_qat/include/he_qat_bn_ops.h @@ -29,6 +29,7 @@ extern "C" { // One for each consumer typedef struct { + unsigned long long id; // sem_t callback; struct COMPLETION_STRUCT callback; HE_QAT_OP op_type; diff --git a/samples/test_bnModExp.cpp b/samples/test_bnModExp.cpp index 746ffee..4ef256a 100644 --- a/samples/test_bnModExp.cpp +++ b/samples/test_bnModExp.cpp @@ -18,7 +18,7 @@ int gDebugParam = 1; #endif -const unsigned int BATCH_SIZE = 512; +const unsigned int BATCH_SIZE = 1024; using namespace std::chrono; From 5cfec248c9122f25dabb434a9bc3bce457fe3676 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 25 Jul 2022 14:09:48 -0700 Subject: [PATCH 203/364] Some code refactoring. Signed-off-by: Souza, Fillipe --- he_qat/he_qat_bn_ops.c | 16 ++++++++++------ he_qat/he_qat_context.c | 20 ++++++++++++++++---- samples/test_bnModExp.cpp | 2 +- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index 7eb58df..f89ac90 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -24,7 +24,8 @@ double time_taken = 0.0; #pragma message "Asynchronous execution mode." #endif -#define RESTART_LATENCY_MICROSEC 620 +#define RESTART_LATENCY_MICROSEC 600 +#define NUM_PKE_SLICES 6 // Global buffer for the runtime environment HE_QAT_RequestBuffer he_qat_buffer; @@ -36,8 +37,8 @@ volatile unsigned long response_count = 0; pthread_mutex_t response_mutex; unsigned long request_latency = 0; // unused -unsigned long restart_threshold = 6; -unsigned long max_pending = 64; // each QAT endpoint has 6 PKE slices +unsigned long restart_threshold = NUM_PKE_SLICES;//48; +unsigned long max_pending = (NUM_PKE_SLICES * 8 * HE_QAT_NUM_ACTIVE_INSTANCES); // each QAT endpoint has 6 PKE slices // single socket has 4 QAT endpoints (24 simultaneous requests) // dual-socket has 8 QAT endpoints (48 simultaneous requests) // max_pending = (num_sockets * num_qat_devices * num_pke_slices) / k @@ -677,7 +678,8 @@ void* start_instances(void* _config) { if (CPA_STATUS_RETRY == status) { printf("CPA requested RETRY\n"); - pthread_exit(NULL); + printf("RETRY count = %u\n",retry); + pthread_exit(NULL); // halt the whole system } } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); @@ -837,6 +839,7 @@ void* start_perform_op(void* _inst_config) { switch (request->op_type) { // Select appropriate action case HE_QAT_OP_MODEXP: + //if (retry > 0) printf("Try offloading again last request\n"); #ifdef HE_QAT_DEBUG printf("Offload request using instance #%d\n", config->inst_id); #endif @@ -862,6 +865,8 @@ void* start_perform_op(void* _inst_config) { if (CPA_STATUS_RETRY == status) { printf("CPA requested RETRY\n"); + printf("RETRY count: %u\n",retry); + OS_SLEEP(600); } } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); @@ -870,8 +875,7 @@ void* start_perform_op(void* _inst_config) { if (CPA_STATUS_SUCCESS == status) { // Global tracking of number of requests request_count += 1; - -// printf("retry_count = %d\n",retry_count); + //printf("retry_count = %d\n",retry_count); #ifdef HE_QAT_SYNC_MODE // Wait until the callback function has been called if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { diff --git a/he_qat/he_qat_context.c b/he_qat/he_qat_context.c index 50542b0..e15dab4 100644 --- a/he_qat/he_qat_context.c +++ b/he_qat/he_qat_context.c @@ -28,6 +28,7 @@ volatile int context_state = 0; // Global variable declarations pthread_t buffer_manager; +pthread_t he_qat_runner; HE_QAT_Inst he_qat_instances[HE_QAT_NUM_ACTIVE_INSTANCES]; pthread_attr_t he_qat_inst_attr[HE_QAT_NUM_ACTIVE_INSTANCES]; HE_QAT_InstConfig he_qat_inst_config[HE_QAT_NUM_ACTIVE_INSTANCES]; @@ -36,11 +37,20 @@ HE_QAT_Config* he_qat_config = NULL; extern HE_QAT_RequestBuffer he_qat_buffer; extern HE_QAT_RequestBufferList outstanding_buffer; extern HE_QAT_OutstandingBuffer outstanding; + + +/*********** Internal Services ***********/ +// Start scheduler of work requests (consumer) extern void* schedule_requests(void* state); -extern void* start_perform_op(void* _inst_config); +// Activate cpaCyInstances to run on background and poll responses from QAT accelerator extern void* start_instances(void* _inst_config); +// Stop a running group of cpaCyInstances started with the "start_instances" service extern void stop_instances(HE_QAT_Config* _config); +// Stop running individual QAT instances from a list of cpaCyInstances (called by "stop_instances") extern void stop_perform_op(void* _inst_config, unsigned num_inst); +// Activate a cpaCyInstance to run on background and poll responses from QAT accelerator +// WARNING: Deprecated when "start_instances" becomes default. +extern void* start_perform_op(void* _inst_config); CpaInstanceHandle handle = NULL; @@ -221,17 +231,19 @@ HE_QAT_STATUS acquire_qat_devices() { he_qat_config->active = 0; // Work on this - pthread_create(&he_qat_instances[0], NULL, start_instances, (void*)he_qat_config); + // pthread_create(&he_qat_instances[0], NULL, start_instances, (void*)he_qat_config); + pthread_create(&he_qat_runner, NULL, start_instances, (void*)he_qat_config); #ifdef _DESTINY_DEBUG_VERBOSE printf("Created processing threads.\n"); #endif // Dispatch the qat instances to run independently in the background - // for (int i = 0; i < HE_QAT_SYNC; i++) { - pthread_detach(he_qat_instances[0]); // for (int i = 0; i < HE_QAT_NUM_ACTIVE_INSTANCES; i++) { // pthread_detach(he_qat_instances[i]); // } + // Dispatch all QAT instances in a single thread +// pthread_detach(he_qat_instances[0]); + pthread_detach(he_qat_runner); #ifdef _DESTINY_DEBUG_VERBOSE printf("Detached processing threads.\n"); #endif diff --git a/samples/test_bnModExp.cpp b/samples/test_bnModExp.cpp index 4ef256a..27003a0 100644 --- a/samples/test_bnModExp.cpp +++ b/samples/test_bnModExp.cpp @@ -18,7 +18,7 @@ int gDebugParam = 1; #endif -const unsigned int BATCH_SIZE = 1024; +const unsigned int BATCH_SIZE = 48; using namespace std::chrono; From 5891a28435f556aacf39e7433e65bf1261596bd6 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 3 Aug 2022 15:47:42 -0700 Subject: [PATCH 204/364] Minor fix. --- cmake/heqat/heqat.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/heqat/heqat.cmake b/cmake/heqat/heqat.cmake index f59f028..97f83d5 100644 --- a/cmake/heqat/heqat.cmake +++ b/cmake/heqat/heqat.cmake @@ -38,7 +38,7 @@ if(IPCL_SHARED) ExternalProject_Get_Property(ext_he_qat SOURCE_DIR BINARY_DIR) - target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libcpa_sample_utils.so) + target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libcpa_sample_utils.a) if(CMAKE_BUILD_TYPE STREQUAL "Debug") target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat_debug.so) else() From 3f92e85f39b1a7b5d5e078fccb9515eedbb9ff90 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 4 Aug 2022 19:59:13 -0700 Subject: [PATCH 205/364] Minor tweak for robust performance. --- he_qat/he_qat_bn_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index f89ac90..2985413 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -38,7 +38,7 @@ pthread_mutex_t response_mutex; unsigned long request_latency = 0; // unused unsigned long restart_threshold = NUM_PKE_SLICES;//48; -unsigned long max_pending = (NUM_PKE_SLICES * 8 * HE_QAT_NUM_ACTIVE_INSTANCES); // each QAT endpoint has 6 PKE slices +unsigned long max_pending = (NUM_PKE_SLICES * 2 * HE_QAT_NUM_ACTIVE_INSTANCES); // each QAT endpoint has 6 PKE slices // single socket has 4 QAT endpoints (24 simultaneous requests) // dual-socket has 8 QAT endpoints (48 simultaneous requests) // max_pending = (num_sockets * num_qat_devices * num_pke_slices) / k From 99bdbfd0c60d9e6aa283dca352a49b0dbbfb2e1c Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 5 Aug 2022 12:13:54 -0700 Subject: [PATCH 206/364] Update multithreaded sample (functional). --- samples/test_bnModExp_MT.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/test_bnModExp_MT.cpp b/samples/test_bnModExp_MT.cpp index 115eac2..e3ef33c 100644 --- a/samples/test_bnModExp_MT.cpp +++ b/samples/test_bnModExp_MT.cpp @@ -19,7 +19,7 @@ int gDebugParam = 1; #endif -const unsigned int BATCH_SIZE = 2048; +const unsigned int BATCH_SIZE = 4096; using namespace std::chrono; @@ -44,7 +44,7 @@ int main(int argc, const char** argv) { BN_CTX* ctx = BN_CTX_new(); BN_CTX_start(ctx); - int nthreads = 2; + int nthreads = 4; for (unsigned int mod = 0; mod < num_trials; mod++) { // Generate modulus number BIGNUM* bn_mod = generateTestBNData(bit_length); From a0d659766c6121f66c03a00b8fda3becbcc37ab9 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 5 Aug 2022 12:15:42 -0700 Subject: [PATCH 207/364] Remove unused variable. --- he_qat/he_qat_context.c | 1 - 1 file changed, 1 deletion(-) diff --git a/he_qat/he_qat_context.c b/he_qat/he_qat_context.c index e15dab4..85e9da5 100644 --- a/he_qat/he_qat_context.c +++ b/he_qat/he_qat_context.c @@ -35,7 +35,6 @@ HE_QAT_InstConfig he_qat_inst_config[HE_QAT_NUM_ACTIVE_INSTANCES]; HE_QAT_Config* he_qat_config = NULL; extern HE_QAT_RequestBuffer he_qat_buffer; -extern HE_QAT_RequestBufferList outstanding_buffer; extern HE_QAT_OutstandingBuffer outstanding; From 9086e4dde5a733dcfb6e12e8c16585e52cc53bbe Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 5 Aug 2022 12:20:34 -0700 Subject: [PATCH 208/364] Minor fix in callback. --- he_qat/he_qat_bn_ops.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index 2985413..0d276a0 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -15,6 +15,7 @@ struct timeval start_time, end_time; double time_taken = 0.0; #endif +#include #include #include @@ -29,7 +30,6 @@ double time_taken = 0.0; // Global buffer for the runtime environment HE_QAT_RequestBuffer he_qat_buffer; -HE_QAT_RequestBufferList outstanding_buffer; HE_QAT_OutstandingBuffer outstanding; volatile unsigned long request_count = 0; @@ -71,6 +71,9 @@ static void lnModExpCallback(void* pCallbackTag, // This type can be variable BIGNUM* r = BN_bin2bn(request->op_result.pData, request->op_result.dataLenInBytes, (BIGNUM*)request->op_output); + if (NULL == r) + request->request_status = HE_QAT_STATUS_FAIL; + } else { request->request_status = HE_QAT_STATUS_FAIL; } @@ -291,6 +294,7 @@ static void read_request_list(HE_QAT_TaskRequestList* _requests, /// Thread-safe consumer implementation for the shared request buffer. /// Read requests from a buffer to finally offload the work to QAT devices. /// @deprecated +//[[deprecated("Replaced by pull_outstanding_requests() in schedule_requests().")]] static void pull_request(HE_QAT_TaskRequestList* _requests, // HE_QAT_OutstandingBuffer *_outstanding_buffer, HE_QAT_RequestBufferList* _outstanding_buffer, From 1d0ba4a8d393f341afd6aef1461f70a6ea9a66b0 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 5 Aug 2022 12:21:10 -0700 Subject: [PATCH 209/364] Remove unused variables. --- samples/test_bnConversion.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/samples/test_bnConversion.cpp b/samples/test_bnConversion.cpp index 892662d..4f6fd3e 100644 --- a/samples/test_bnConversion.cpp +++ b/samples/test_bnConversion.cpp @@ -5,32 +5,19 @@ #include "he_qat_context.h" #include "cpa_sample_utils.h" -//#ifdef __cplusplus -// extern "C" { -//#endif - #include #include #include #include -//#ifdef __cplusplus -//} -//#endif - #include -//#include "ippcp.h" #include int main(int argc, const char** argv) { const int bit_length = 1024; const size_t num_trials = 4; - double avg_speed_up = 0.0; - double ssl_avg_time = 0.0; - double qat_avg_time = 0.0; - clock_t start = CLOCKS_PER_SEC; clock_t ssl_elapsed = CLOCKS_PER_SEC; clock_t qat_elapsed = CLOCKS_PER_SEC; From 02349c744ca613a8c37b522e0d9bc1c05b906085 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 5 Aug 2022 12:21:51 -0700 Subject: [PATCH 210/364] Enable warnings for unused variables and functions. --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 54ef689..2898faf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,8 +30,8 @@ set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_C_FLAGS "-O2") -set(CMAKE_CXX_FLAGS "-O2 -fpermissive") +set(CMAKE_C_FLAGS "-O2 -Wunused-variable -Wunused-function") +set(CMAKE_CXX_FLAGS "-O2 -Wunused-variable -Wunused-function -fpermissive") # What does it do? set(CMAKE_EXPORT_COMPILE_COMMANDS ON) From 453fc58757e02af2ad67c9a61835675aab8006a0 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 5 Aug 2022 15:08:07 -0700 Subject: [PATCH 211/364] Code clean up. --- add_pci_vf.xml | 6 - cmake/he_qat-0.1.0/HE_QATConfig.cmake | 45 ----- cmake/he_qat/he_qatConfig.cmake | 1 - cmake/he_qat/heqat-util.cmake | 31 ---- cmake/heqat-0.1.0/HEQATConfig.cmake | 45 ----- cmake/ippcrypto.cmake | 65 -------- extract/qae_mem_hugepage_utils.o | Bin 8688 -> 0 bytes extract/qae_mem_utils.o | Bin 32216 -> 0 bytes perf_data/bs1bit1024.txt | 101 ----------- perf_data/bs1bit8192.txt | 101 ----------- perf_data/bs8bit1024.txt | 101 ----------- perf_data/bs8bit4096.txt | 101 ----------- perf_data/bs8bit8192.txt | 101 ----------- profiling/README.md | 2 - samples/test_bnModExpBatch.cpp | 232 -------------------------- signit.txt | 2 - start_qat_dev.sh | 12 -- stop_qat_dev.sh | 12 -- telemetry_helper.sh | 41 ----- 19 files changed, 999 deletions(-) delete mode 100644 add_pci_vf.xml delete mode 100644 cmake/he_qat-0.1.0/HE_QATConfig.cmake delete mode 100644 cmake/he_qat/he_qatConfig.cmake delete mode 100644 cmake/he_qat/heqat-util.cmake delete mode 100644 cmake/heqat-0.1.0/HEQATConfig.cmake delete mode 100644 cmake/ippcrypto.cmake delete mode 100644 extract/qae_mem_hugepage_utils.o delete mode 100644 extract/qae_mem_utils.o delete mode 100644 perf_data/bs1bit1024.txt delete mode 100644 perf_data/bs1bit8192.txt delete mode 100644 perf_data/bs8bit1024.txt delete mode 100644 perf_data/bs8bit4096.txt delete mode 100644 perf_data/bs8bit8192.txt delete mode 100644 profiling/README.md delete mode 100644 samples/test_bnModExpBatch.cpp delete mode 100644 signit.txt delete mode 100755 start_qat_dev.sh delete mode 100755 stop_qat_dev.sh delete mode 100755 telemetry_helper.sh diff --git a/add_pci_vf.xml b/add_pci_vf.xml deleted file mode 100644 index a55b6ac..0000000 --- a/add_pci_vf.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - -
- - diff --git a/cmake/he_qat-0.1.0/HE_QATConfig.cmake b/cmake/he_qat-0.1.0/HE_QATConfig.cmake deleted file mode 100644 index 6f9b195..0000000 --- a/cmake/he_qat-0.1.0/HE_QATConfig.cmake +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright (C) 2021 Intel Corporation - - -####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() ####### -####### Any changes to this file will be overwritten by the next CMake run #### -####### The input file was HE_QATConfig.cmake.in ######## - -get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE) - -macro(set_and_check _var _file) - set(${_var} "${_file}") - if(NOT EXISTS "${_file}") - message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !") - endif() -endmacro() - -macro(check_required_components _NAME) - foreach(comp ${${_NAME}_FIND_COMPONENTS}) - if(NOT ${_NAME}_${comp}_FOUND) - if(${_NAME}_FIND_REQUIRED_${comp}) - set(${_NAME}_FOUND FALSE) - endif() - endif() - endforeach() -endmacro() - -#################################################################################### - -include(CMakeFindDependencyMacro) - -include(${CMAKE_CURRENT_LIST_DIR}/he_qatTargets.cmake) - -if(TARGET HE_QAT::he_qat) - set(HE_QAT_FOUND TRUE) - message(STATUS "Intel Homomorphic Encryption Acceleration Library for QAT found") -else() - message(STATUS "Intel Homomorphic Encryption Acceleraiton Library for QAT not found") -endif() - -set(HE_QAT_VERSION "@HE_QAT_VERSION") -set(HE_QAT_VERSION_MAJOR "@HE_QAT_VERSION_MAJOR") -set(HE_QAT_VERSION_MINOR "@HE_QAT_VERSION") -set(HE_QAT_VERSION_PATCH "@HE_QAT_VERSION") - -set(HE_QAT_DEBUG "@HE_QAT_DEBUG") diff --git a/cmake/he_qat/he_qatConfig.cmake b/cmake/he_qat/he_qatConfig.cmake deleted file mode 100644 index eed8897..0000000 --- a/cmake/he_qat/he_qatConfig.cmake +++ /dev/null @@ -1 +0,0 @@ -include("${CMAKE_CURRENT_LIST_DIR}/he_qatTargets.cmake") diff --git a/cmake/he_qat/heqat-util.cmake b/cmake/he_qat/heqat-util.cmake deleted file mode 100644 index 0b5ca8a..0000000 --- a/cmake/he_qat/heqat-util.cmake +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (C) 2021 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -# Add dependency to the target archive -function(heqat_create_archive target dependency) - # For proper export of IPCLConfig.cmake / IPCLTargets.cmake, - # we avoid explicitly linking dependencies via target_link_libraries, since - # this would add dependencies to the exported ipcl target. - add_dependencies(${target} ${dependency}) - - if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - add_custom_command(TARGET ${target} POST_BUILD - COMMAND ar -x $ - COMMAND ar -x $ - COMMAND ar -qcs $ *.o - COMMAND rm -f *.o - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS ${target} ${dependency} - ) - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - add_custom_command(TARGET ${target} POST_BUILD - COMMAND lib.exe /OUT:$ - $ - $ - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS ${target} ${dependency} - ) - else() - message(WARNING "Unsupported compiler ${CMAKE_CXX_COMPILER_ID}") - endif() -endfunction() diff --git a/cmake/heqat-0.1.0/HEQATConfig.cmake b/cmake/heqat-0.1.0/HEQATConfig.cmake deleted file mode 100644 index 6f9b195..0000000 --- a/cmake/heqat-0.1.0/HEQATConfig.cmake +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright (C) 2021 Intel Corporation - - -####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() ####### -####### Any changes to this file will be overwritten by the next CMake run #### -####### The input file was HE_QATConfig.cmake.in ######## - -get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE) - -macro(set_and_check _var _file) - set(${_var} "${_file}") - if(NOT EXISTS "${_file}") - message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !") - endif() -endmacro() - -macro(check_required_components _NAME) - foreach(comp ${${_NAME}_FIND_COMPONENTS}) - if(NOT ${_NAME}_${comp}_FOUND) - if(${_NAME}_FIND_REQUIRED_${comp}) - set(${_NAME}_FOUND FALSE) - endif() - endif() - endforeach() -endmacro() - -#################################################################################### - -include(CMakeFindDependencyMacro) - -include(${CMAKE_CURRENT_LIST_DIR}/he_qatTargets.cmake) - -if(TARGET HE_QAT::he_qat) - set(HE_QAT_FOUND TRUE) - message(STATUS "Intel Homomorphic Encryption Acceleration Library for QAT found") -else() - message(STATUS "Intel Homomorphic Encryption Acceleraiton Library for QAT not found") -endif() - -set(HE_QAT_VERSION "@HE_QAT_VERSION") -set(HE_QAT_VERSION_MAJOR "@HE_QAT_VERSION_MAJOR") -set(HE_QAT_VERSION_MINOR "@HE_QAT_VERSION") -set(HE_QAT_VERSION_PATCH "@HE_QAT_VERSION") - -set(HE_QAT_DEBUG "@HE_QAT_DEBUG") diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake deleted file mode 100644 index a12ad08..0000000 --- a/cmake/ippcrypto.cmake +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright (C) 2021 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -include(ExternalProject) -MESSAGE(STATUS "Configuring ipp-crypto") -set(IPPCRYPTO_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_ipp-crypto) -set(IPPCRYPTO_GIT_REPO_URL https://github.com/intel/ipp-crypto.git) -set(IPPCRYPTO_GIT_LABEL ipp-crypto_2021_4) -set(IPPCRYPTO_SRC_DIR ${IPPCRYPTO_PREFIX}/src/ext_ipp-crypto/) - -set(IPPCRYPTO_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS} -DNONPIC_LIB:BOOL=off -DMERGED_BLD:BOOL=on") - -set(IPPCRYPTO_ARCH intel64) -set(BUILD_x64 ON) -if(BUILD_x64) - if(NOT ${BUILD_x64}) - set(IPPCRYPTO_ARCH ia32) - endif() -endif() - -ExternalProject_Add( - ext_ipp-crypto - GIT_REPOSITORY ${IPPCRYPTO_GIT_REPO_URL} - GIT_TAG ${IPPCRYPTO_GIT_LABEL} - PREFIX ${IPPCRYPTO_PREFIX} - INSTALL_DIR ${IPPCRYPTO_PREFIX} - CMAKE_ARGS ${IPPCRYPTO_CXX_FLAGS} - -DCMAKE_INSTALL_PREFIX=${IPPCRYPTO_PREFIX} - -DARCH=${IPPCRYPTO_ARCH} - -DCMAKE_ASM_NASM_COMPILER=nasm - -DCMAKE_BUILD_TYPE=Release - UPDATE_COMMAND "" -) - -set(IPPCRYPTO_INC_DIR ${IPPCRYPTO_PREFIX}/include) - -if(IPCL_SHARED) - add_library(libippcrypto INTERFACE) - add_dependencies(libippcrypto ext_ipp-crypto) - - ExternalProject_Get_Property(ext_ipp-crypto SOURCE_DIR BINARY_DIR) - - target_link_libraries(libippcrypto INTERFACE ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libippcp.a ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libcrypto_mb.a) - target_include_directories(libippcrypto SYSTEM INTERFACE ${IPPCRYPTO_PREFIX}/include) - -else() - - add_library(libippcrypto::ippcp STATIC IMPORTED GLOBAL) - add_library(libippcrypto::crypto_mb STATIC IMPORTED GLOBAL) - - add_dependencies(libippcrypto::ippcp ext_ipp-crypto) - add_dependencies(libippcrypto::crypto_mb ext_ipp-crypto) - - find_package(OpenSSL REQUIRED) - - set_target_properties(libippcrypto::ippcp PROPERTIES - IMPORTED_LOCATION ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libippcp.a - INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} - ) - - set_target_properties(libippcrypto::crypto_mb PROPERTIES - IMPORTED_LOCATION ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libcrypto_mb.a - INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} - ) -endif() diff --git a/extract/qae_mem_hugepage_utils.o b/extract/qae_mem_hugepage_utils.o deleted file mode 100644 index 5c82e82b428039bbc6eb714266c55f7069d4e61d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8688 zcmcIoeQ+Da6<^zO5ZIN>M_Nxpk}H)#2BJubLlRS3%aQHPRFKrzG#wxpMLOB4^%d!q zCQwR1G37>aN&o8yf20i4P78(nK_R$|M-Vv4AL$@&@_~E#C)Aju zM=JiVDlpR0WwUhh6@APEuM*(12o9Uz@_FD5Cb)PW=mqeex2tXtc%;(KryS4HE;3iG z(hKK~x>xLDRs_mN<8hxD#Sb*HXLCJ!dh6NKWvZ^OK-I!3rkWh*szZc;UiS)U8|nLA zJ$?Q4^sO{ONz-Im@1#dgw}S(iM;&ur=m}8RhkC!zdWY)iUp-$xEDBUD167Ods^Y?< zc761ocV7d?Z!%!lbq{RQh{sQjuxEYP2zmO#(4+gx`Z{-a$g{=W9rkQ@caM0o?(PRY zdx6c}{jlc%YajI-WbG54L#%zqQ-(H1OO7rtbSOyc43z2AKF@JBd?ReUf}oR5g*?g( zhA0j@XsH#tWY*zvB2-#G8}c~((5)a$OCTmj*O)>JPI}KVwEifYWcwE!4Ns-3!IALP zZy}z^=*`sllosE0iuKddHFWZnzU)S*+QPyuXn@hk)d7FvAgEbabus)Ra@oM`!gJ|Y<+g^PQ|m#_!*pb4*k z##j4)vj_a`U9j^;k7uTJXJ;8Btb-c=rm(S2TrKm-WVx`6mcndv+s%l9t#%f!goS&- z_ry3dy%SwCwHA3Wl5W6G<(ucL)sxRL8P@p?-Vz+$WSqy{DZaZt?#{4~nrD$WP~K#` z4JLGMg+dQU^i_p?EahV{7&guv-nx~LI0WS7&xbtAA@Q-I>@x?-_wCAo7rR>qs6mT_r5=YmD3kN#e!{?O~Pu`O-9nwiSZ1s;_>XBd<^Jd z#c=qJv#1Mh6LH7*!p8g44*jI7kv=acgc|~Hw(rp5N+2dpw=VP# zTgLQk%}5a-OJQYo=%@d=kaX^oYBgB;k*AX{`W{Z#xPGyYYQzJF>xNU`MKzBJj{zMvSUKVgPUO=1 zPY6wxbOO?)``G;?6LS>hbme=yVoD+t)sspzl1wV`OimfobR|2!C!YXBiNs<#B_2s6 zwb->v4rXppx?*@hSuy!j6M0=rWxZYbZYE$nJEq2CoJ;v(LLXPOTrQpIwOCEQoe@n< zr6ON|QK*#oBC%bGy!QDz87sFFboDCQ?x?24w3w2L>{iALW15nUjA?lVmY<16^h73| zXRFZ16L}?@%S5$&-p5y5lcQwPHD)EHr82oak_f(d;V6@DS0bmc2G4$RUX#zZKZ#5# zRZt3PSk0H)C!3t;xE7sAq{ozWA+|CnG!L>DoMofeNlsG2Ut<7Qb*^ZHo0)#k5_k1W|s~PBOG{W3S>J-BC#E1!aS; z$LC)eD6moB$E*E5e~&NFZQ_jI0X1X|1W&}!O``;|kTPN{%YgPWc(63xF-)3vcQh?+ zzrc9_PAT$S&SnTH@)j{a?@ve=yk1zzOBlQ^S&8zt6WS#2{~6mM*YT$2nTuS`U|SCi z@8@&h$F|?qG1WZi>fGN#UCMoqpvzlq9dh~aaCw6+CFtse`F@v^AYU2jq1=nrAo6WO zKA^kL5#oH!+vhVP-&v%G@@4pN4Svi_q1=fTb@`jau!K+>Sr5Z7pDSPsw*0iY-_<$Q zGT>77;~MU34Y{^AKXH-E8*(WyW3Ga>kuZ?o&v~oRCpTHV{T6S~~i z&eym+wm!7;yUf*WUq9q??2ZRo1s*2^29~F>0^9dDH;*um=G(#3W}IBhY1)zIa|)_( zkoVbg?4&Jqzd$i2MO4n`XaPy~vIKx;Nsfq7562I11`(&L1wCK8h}G*kzL(=7UMa`t zIL=}guwjmuxi46}0+!&o!k57O4%l5BKV-uJhSgfHI~=ky1$7fyM6!H*32%SJ@hyD( zHQxS?;Whu@USYv~L^ zTgV0S(CW943$4D~X(8e*BBLm$Z9V{_GYnbiw{r|%sMq}U(MtN*e63o<7T8J-)gabu zKgsFKoSxl{K>uI^`iC3fk2Js!HNX!yz+Y^D zzXUj27Y}uDalI*U9$MmDpXK<=92e)P4ekY$GskgupTc^V0A6pu)-=Ee8sN8Z`G@#H zweDh;YHBGfcTo#^BANF^Niq|OnMsG$Qz3sf@d<5@)nVwy8$;^A@bKng63=Oxidm4F z)OKk}UpA7{eSQhnBRi5BW2%udjHqh7kdCUVuV?Ls4btd3|2i_JLNaDqnU`k+Yvs}E z)j(@yKB|^RbupP@ji30!8(GzZy#Q8guv(4PTCCP#bsbjgu>xy`!khbpVRiH1;LQUg z>PWCZJfM=i9)koPgzt)HbBVMbSEJ(-FwERT{s+F{{#IsSd$G;v( zA)QR5CkSSOBxPpzpn`oks3J2b(PSpC)g(!2rKMF)MJB9S@2=RyIYIv@M2YxZI@=K26F~3T}pOSE|gg5c`A<}nCxY_`J zuK}Lt_X;-GNOB(HII739DRR$8Bph=HVgFN-9NEslOY}=6`lb98gwyyFLddyV!hI4R zlJHd$9+7arg#SXq0}}oi$HlrZcf|5X3CFx$*z=MkNA~lp5-!VsQ<8&z6Y@_<_%ccU zXObMuv4q}>`8|sMk>x8Kx7&ZUgfExm1SC1~z6?q9s005YV2Mlg*Gh68kZ_D$VdudH za-NfL^aIMm@)rqT0b?O&PQqpSGZL;y^o#iW0d1H4cA13B`{m`h@SCt_m4ts?l7E*Z zM?M$7k?7IRc6hM-LBg+qu~^rPBuDoDKO}nD{~z0MA*a>J)UZrmw&zlgzG9Nx<-^$n*_yImac`I;8_F1{jhVSKg)`pAk zqy08qd>+weYq-u`9BxxX-P!y@F1{H+}U z2^aaB--e64i}><;QjqOHtLMyiT=a5UGUC&<-8%8bB6@`QcI5NKm&@P)$pb#fMa-dS zebKxgfHWlvf4;OdFs3uQ=7S$LD_I7@$7AV&5B}F>wVb{OI8lu@4lnmeN;9qh-)jX# zpo_R0ErET!_Y99mF=5YX@g0dV+9wEjyXC89=OBMydo86&hNMJzs&i?dqYeMyG5&VelaiFbDUp{MJxEkI0GF# zYWDSu7mXqac`N)U;GaMTW!m`_{-Wx$P1yO-zxCp84g(X4_)f?8!zBrR5r6e`Bj0ux v*6^Q>$1e`M;IZ>#m@J4rz$%wQ1!c@;zukWq15G{tt(bH{`I*^RwVnUJ=tn9T diff --git a/extract/qae_mem_utils.o b/extract/qae_mem_utils.o deleted file mode 100644 index 7c4fb5af9db4e823df554901e0b876b9f9bed0b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32216 zcmcJ13w)Ht)%UXrmvAu~1>1OK)ubj0F^MRNSlNYKp2ZDBNQ4R+Lb8F>+)Q>66qT5) z@^p!&ciZ~*wbj4_s);q z=b8VUIdkUBnKNf*Hr!C|t4MP=44oXtMMgZQQNviiA^z?buWsWw<5=SZ=c%8V)~Go& zQkWY>MKe5o*bMCstdZcE8hnJnB@#R}0sN)}k52&e0Cv9>b%Np0$W&D{?h!NB7>!2F zNu%4HGkS#-MT6U$nhJETsXvuG%aX}6KbbtU66Haop}|15IrQFC2qbzqZZwx9gA8uN z-o6?7II!4L>+5TadTM-qcNpjytJo0oj8hw~( zC_^1Gd$wozO5X@RZ}#lSSaG>$rRVbPyoYA@p?x6pTF`nR2WqOxDKsr#PKnPd%W?bg zX7&yS<~Z}qa;lyAzMNIg{F--_B`T-bnDJFdmeQwrt9vZ0WUAwy~1bhqG7)R<^}yglA_%QLrvPk ztE|^A?i)AGJM{Wwuj3Q*n+DYGym=2q@L6y9`c5HXnkuZ`HOonXL+?StlRqNR+c*6L zPtSpQ!CIe1qC$}q0<*l1QL}H{k%fKJMK?^x^UfKYh};}@S3^|DI+$UW4hIkW98aK= zPnwg`NKgnVjFY4k^jqDiRA#;A%ir%S9rQXY2hll4Re1JxZ~mZn&s)Ap#ooS}6EY5V zqbs6cP~pD@Zh@3!X6K={VfKBK9wXVGL5Jw|k38F`dp_&6fd`V&js9EEMXrRLT0b=Z zY5LtqlM1F~TA#&dAKLYW{YF*jK;XoOVNziI_Q*nT5mS&d)V|rX6I1Zr;B#i*wHf9x z(UFY9Jx4L=DVaTQA2sto?F&;ILy`0kOfh(Bwla5w`7Y)0TL19WU?^+7Lx*N9^>iN~ zR;KlV*YR&MeQ$VX4tWLm$9=G>oLo`t*r|kd_TEITin5bLnb)yH)p7O?P}$JIiMkwqo(tL>x|%ax+kIY{~!6~Q#~zX@Hj1B@3FumpM9=|Q1t2G z>+$|Y&P6%P29RX~B-aa1t=IYp<1_T`EU)!kt*84<(*IJg<1-AA9G_NrrFR3JW5%Zy z#`LbU_t!KA3FEWV8y0n(y|2g0j*E}0s`oW9Ne@nyV^?K0CXAg}U%uM-J+5?fo#6}- zQ{8%KA?Yn{4qtivf~e<%zQy=CL(ifUKJN4nfXs3eXa z5BA82N6}!>$ENlCHUs6D;SPhGjPj2}78b7397e-3ed%i`di{7I%)?-*+bkLskR{ky zJ0a)hAuMse@GRmgZ2Jj#3`um@W0lKS>d!p#Hi%}VP(JCx5!R?~4DBC>Njd@3CYT** z1ApoF&2Xy;%-OpF5C+aXyFAaFTb|MN){*io_q((jbqPQM z0vRYl&{GYHau?p+W#L>B*9=#gaG%pfbcV&-+50t7bD;?$vSrXYO|q`DQzw>}nxIYU320Pfv8HbY}_$?{y`snhFtSy+S+<)N3H)~Pgy z>M$r+$9&-_RiVe7y-%TMKI`uYh4JDHRiVc|>j^Xe9n*T&9Ewaf`!-e?WzIj}O!0@$ z8Z1YbdnbYx3wl$T^<#n;_Fd>OyQ8$WJ8ymiW#-U3S!UmL)jnzaUTcrpH~k-CND<#= z`1)pk9T7{Q*z-3xKyUstRi(pK&dQ_Sp6!l{!_zL!sNX>dAaHh}k;=;Z%IN71s(|vs_k2m@$&JhhE&heIRN1TJk5a>LCK+$_zxl!JG zAdo|0b+%_{|Kz5AlOkFZQ4^w@Mse5cLZKi-iP5QD4JoJTCBAAB%F;y4Tt%S}edI4;+W~QEn>3BT3%+G#VW!CTSCF z742P$_Dt!bG|w>(OSB~Y7p8qQau{(~Q~$u!G4hXOko4zEJ2d-Ra$K>^lJ%aRS&`qO zI_%UM8t5klNr`9<3P(AzMTXo1IV@}XgvgudReVQDdw`S7 z;rUYkJ`~Xt z<5x6T4kcNUfl>0h3FA1@4^ooqETQ^dVha<57u`iKNpy0KAlxMAhRaLn8TpnRH}w0| zvHdPkEj&hJFXMe+YJ{c?0XW0IeNIw=M34LO`Z;SJdkN0yRjJ%C$sNxCG z{U%PQ^bSkCm*`qQA!jKjqL6tFxMTXdu%N`(7BZ38+5%7b5=c$!lK9$EMB>KRmR77S zuvM%XLA|yF#M*Kl)|QQ8ZE4kOON&@rf>>JuYHhKGLW9A&*vhg6jfs`z-y|AeSI`HN zndqIpcl`^!nTFY9_8mj$!1Va+jO%9WVNh)XDW58FmHY(72Sa4|8!*Uj;v?2iJwYf| zvYVk0*Ds8)7R3Yk@pj{k-C!);fT$k%>?o<3+xbomm}E_jjh#lnLOCDrIPU}Rp-&sp zG>h&jewOD!!Uu@+ny-=9I~DjHm& z1dCKbEGCiOZ>VB@^db0ptQ|C&9~4$3Y!S{EVPY0$T!#&tBUP6Og;a#F-&hq_AVg)-x6R09KBW2cpwOQ_$0dZ(>!=A{=s3q5@ z$h9<(aetSvUXAee>OH|*`DD}DF4n70AedUOaL6WODw-WN;L6vlqCw9?9|F^2-f@WR zQP>LNSi$*ASFICJpX|&U_B=%07PSTzjWK^2z+HqEBA>vB6Ui@2LGC2-Cqe#2)7kS7 z2%;lz90YBc<_DX5_8vYAB0d9GfS#GBKCie`+o#<4^c-51uG864s||qKUg##oV;s@b!uCMOn1uqGNg59PPzGMoM5bY&}jMM9F=?*bTt%NwXH) z0PG+j?xbtsq^D7opXJP7kwx)6oO1&??bbqP{*|;9Ag|ozrriPd9UF74uRtQgLfz`s(qYL^?5X3v7-x~6FGo4z0Xc6?$6P>*!(>RN}u&^Rk)RQUoPRT z$LzB9k?Z41K1@Jd$+XK#hbF6_OQUO`HxZB>IiiIQi6RZPhyGPDYY zDo9OZH6TtWs!*2LebJLq^dzo_gJ*qV|JPwOzk2`I+WUWXV*e=;I2)Y|qW@jge~JLE zrT&+r{|l)9Rp|f4$@>2gtUuQOeaQUZ^q)^UHvi(U<)H)4TmMDUvZDpE?N`J!Da%>T z_Koil*0W=k-ZYB!RK?pATnGcxjB4J7r%{t5^ag^KWRBrJv`j>iM?fI`y-AzQN|I10-7 zJsufHbj?C4&5y;*R z%gKU{L?h3m`BeRAq;?C1R=!Za3yJQZh`r$LW5TjPB4IF>e>~ zLP*Fb&JXPTc7QH&R)YTil#Ji)M3)9Sp$rwT@-xuepc@tq^yX{^0R7W3=&djwv+uH~ z*V=1#V+`iuG~-&D%ct$Zxfi`ypQ!=$HM|v5_vj=nGJSug6QwHaBk$1R$vBFi?Cq-@ zFK-H(Id8rPzQ>CT#^?-WevXU^vV1aLLmNLFbpC13F^F5&nNlNk z|5}Cph|k-wqnwV5%W^Wp$747Q?A<2QsT7X1CI)eQh10qBd{%Vime->goFR&mL%Tue z#VMAz=krNdPpS&vPy$}Tzp3`{?(FTwA%-_xSt6Nw8=ms?{5u*r2HYok=Q^FCHIUpJ zUR>x6FGDmVS{D9$1_so$JS9|DMCAVg07T-@RuJRB&pTXMJp(dG(Y(WD&x;F32s`rj zYcVlqCTEO#@3|r7zr=Q&MHUUv3@U=5S#<1ThSp_E~b) zd96q3+Rxeh7)E#innWMpVq2xquYgz4J^bDDVy(;bhAUiZ7lK1AH)`MzRUd~~kKjOc zoauPN3{MsYFo6umT4egHtHddms_Bz+)@RLjDE)cE>+*2pv6t*JyvP+A^oFm;p=|&^ zEa*FL6?`DB=l3GOHZ4pP(u>PHVR!fI#wbqSy5BJj7vdolK2~+Y0TRbN?Fn)C@9jQd zWbKcdlXiK#cMugRKb!XMv-G+EmElJi*jY_ar&+$fdmsz?pC*$fDdp2TB zoxM?*4#dmz3|CC2AwDuhzyENC{)Trb2DjmIf*pZsq)iWvz`n~K6&5{`{XcPYei@pH znR7+lobSS*d94bVa|g_s+bDUF3^DxVMKUnLy;WFe^aa4*AzPwR%dO^~SA=CpP7`aA zAzc%KD{C_xbL3&Y{tbKw^|4LdChp6((sffJw~_CF5skh#e5qUQU}6JLJCz@hm*m7~fLisiX#VySA zCxI!3$}KirEy#!yvFAkxnbLHpif-r(I#3zEPZdVfGO(|T2$JYX&nWj5IzTLOGxU^IfS(dipI zI;WWri__80*B~I#V#g^w8`ug9kU1912^8Y8C}k%Ge1IHa(V*8F@mc?}jpx8iG@g|h z&t;gKdJ5A>u0sdl&ecdRlOwrZfR$n-ak-OIxNSOm>$5%=Q}Tmf(Vh)^!;Lx1g)HJ6 zGIR_oVeYswcNVHw+={&*Y#+W2)LCMSth@kK3Y^HtN+|;6Qy?x)!!+erouOv*Z5uua z(Qwm`$qi>J+9t0?4zQXm{0uRu#=!5#%#V?+FUqMg0h2&fWRB9;us@Zryd6_NnXlXc zT=>ds@gmeg6SW#Q*xdOFrzTp1ZAj+WoA0WEw~Wk1RiD+F0b&y*M&x~1y^d#xg%ksijA>iCuj#7!)glCT z%d0QC!SX_TVRuR7>LWrf)=OM5q>bS=^5i}&B4PBuh!)*=|7jLRAs~E225LnqVz^*X{Nia7IFmz;bb&zaPvP(~;CC<> zKY>~ic-h>~T*#NWoQP#D(G%SY#$(o$e+e+YrkpQUM!GU7q}Aejy|B>T3i9i)uplB5 zMS5Y`n6pY0VPOfVg+(u_p^u=R*y_@Vwgh{z#B4(mg^m=fu_Z=V?Og)%NVV2nyq8=# z7VgMQQ1v5*mG)xdf?nt}W^qLnB*tU9$n!Xx=0o9l%)X2LrEE9p27J#yUOrimC;9bLDfrS z^(>TL{C1RZQR6KEp}j58+1}z>-O}E0rK`Qu)zy5B-__CCzOK2^-zed_hCpYF>zl6J z4p)6!qohFYnxG3CP07yFg8KD==Jqz1zq1o;X1SL5uL?GIY93uK|M~{Mzp=};x;fBV z-{HEtxvjDN>H^n%(J(Up_0+^Q!I={3a&>A3vMp+QKCesUjU<9dQVwrhM=;>(sPC+A z^#}Z&u7>)yw)TK)wcoX<*5_mLHa2$pySiL~b}DP?gk(u*iLvBcE;@zY1=e=@>l+ z(*}`LO=`eS7wl-P4`8I~*NEZj@OK89{SZacEpGF>+M6IPQ7C0}xthC#8Vbe?s~mmk zvqP&>@sXobFSV7I+mVl+cL{yA23rEn9q0<0sYPFfS>)w5<|__T4zDsZ*?{5`H?LV^ zhrhs8-QLyJyt-wBtFb*u%B0aLu*vnMd}V_z{L-tuge8i-vZf|bGTuJDskc&o>IFGgYSbvp1 zVjXU%Z-B`qQBP|9boyKT^*(2DK~L(b3)+fPQs14JpwQl8)TFaaFzF6R2qKyi(*0DzBqCrm_aT z*U{XHm($c)R9oc{h#0Usp|HBHmipDY9`O;V0-E4wIDxFe7%Mu+Q{`{;~X@V8YoCe-)BBTGQilgNrdJt#(?MCZtqaH=B`&Ot?@lYC0^Hm26zey@DvR26cXSm7~m-+z%wfO#p5JmKsYg=Co!NWF`y?gpeHe)CovFDNFbhI zAf8|#o?sxJU?84gAf8|#o?sxK4)sh|&xz{kRL>deIZr)rP|v7-IwYScomNnqC?8R$ zdd^VKdFpwCdP0H}sdB-B3tV}%tAlNUpsTcCc0u8+qM*nXU0+;SP&m7wC|}}&0nP;I zq}f1}Yg8_(rSs-N!sMtL1|2R^a$K{-aIDXAoHTV}2Az{pos&fgP8QXZutN3TrJl68 zE>rKd^sLOx>PxH0%-)i2X1Z<~=gG|L8DE)M*pZp%$#i)#v*%}K&Cks6Y=88rr?Wx6 ziRvIdNne$j`yFWyPe$<+AF{U-hD1L@F;MT8wE4srd=%fZ%)<0>j>(yMWtpxr&AMVr z+K(j^Yt5Wu%m#}?#0=?1`l=u~y)k}eO3t)ZiGr>IX^xtV->0XjS5EcN=uP9wsoo`- zg=sZtGogo5(o7pPKN$p;)W&Aj#@DH@@iv4GO=@Ey+UT$`EKkNT&1a*kz|ERL`aGoC zcmTJ9q|aMPpSPsX&vf;To1dAtWxOY|@TLi#%#xmom6?N%^rzD%XO;lN7=i}0a_pc@ zX&)DotVmPkL)c7p609)^wq9YGsxH|Y{cR4V1@u*(nbnhaIc%X~%HqrngY4{HRsKDC z+Qv`V8SEi#6urmD#KwO96k(quy1fip_ZAxaKI;1xveBEU?>!UBGW#9rQ^!pfea2|U z`dqGcSg0mWI!y-1@P#_uXq~^n9f`_mIMV zpzLx>nwgn>6U~pFacL_jXJ&iET$?||gZBlQS<5mrU@=!A1HqSMW(Xmufh37ojx*j* z>W9(|Wk|Mq=`pX8SddOXFt?>+kxyfMdQ|yI3h!5W?Pqcno~4==z6Kc0YvR+P@F!J0 zdZY`l#{j%ugb&fXl|2aG0?fq6L949dlcCC&D10rRlyso73h%_HUv=$9Dn#nQhj14; zTqNN$@Wj$0@Il0*T! z%4}@hza?<-8xm2X-i2ve}|&aQqTWV z_-2*Y?b7cU$)49MT5esUy*AzMB3mg-fcqucv%^EGpHd@|n)YiQQ#0sIj1$Y>@3Ht4c~aNRFm`nkZz&aZSazsDP!Bp(Zr8$f{=_1oTR?O5s@w*YR_w z!V48HVrZ(01DQHH90~@STe=DwjF$HLMtQ&_-mdg-kY`SGvR~KYU*~Tz7F3nhl`mPc zc!@ZjlBY^_b>bqW>q?`pt|{2oP*+!Q-kjo6RyROb5k^-42b+R_-P(>dEK9s%Ct2b? z!w{#pbsf!(#+o|OykxOPoLkkkGz>)OPth7tpD%iF*;5#rc&Fv~j>k zrseomnWFzW{vN@tmeha!{Ng??OCdGnbv7kY3sU5+qSTHCSf)q&_-MXfZPTU_f)itaoQ|t=VH(W{Y zb#z*7(7CnIAukZ>gpt*?;G&Uiugf1W8d}=B{6;&@FO4<+02v-#o7JriuJM!obs6Gx z)y6=c_(OtDNYLIXY7#M-V{3imx@NG{9K=zsJa&yi&F!tN!8&n~V?YQ=5;u2gK2$(f zN(Z!w2qvfmV86+K_X}nRw#$sZOM0hbintunwiI1kgn&Ia%`ezhQ z58ki8s5pu6<&1uciihm@iWK;*4CnmmKi{BaZ})d8@N2~>wWR0rJedMNL#=OiIlEHe zcQc&J`CtnCkreo|Dex232A0N)WYTB2rz@PWZ{efIvB*Z>sP^%dHhd*w14>m4r=?TJ zCp8SGHZ*cjrPHkvCzs>ku&iMS3;a4zxoZ6V{@zr{s zG6qK_r0EQ&@zVX;%y2H}QH7I?+&<4z0TtnOjE`I4S{`k0;=mMiM8AsBS2I5K3}4Ck zkUzN)A4&}jKM#2=|FtRj+|1}XpIaDyKI5~8;am^Z%CMD1Umk|f z1+MvArEucS?O`Lsx&H5De2D){d??+^aMGFPzl-5qp63}(KP%Mq8ESK<`$ck5DrPw6 zQ_65UtJi!Q7|!Xx&G31Q{yPjOdOa@RXE-01|7JL+-^Oq^*3c7Cpqu!b@K%S}iQ2MhC*JC+s!?pfD zRyfhM;G^*@bq=ESaEO>AoyhP7$ZPsih7&J6uPYQz7?0DI+vv65ZnNP!9tbd;_xD2Vvb{oyMN=kwx# z!eyW0a=ydpxtyOeoa$(Oj-M{uCyd8qnGEOgm`mX_?o>yQV=kj#1zhWGKBMRIT*BzN z{ns;mHRIFGaK658X8d`-?qc)}jL%j^&*$$j!}R!*TWG;PkgjKk5%W4#Dm9^rzl*{$Cpt~DTm=a4s@sB<74!sAI)be!_Nb*mf!@1x7DZ@GaZy7$H@&5zExt_Nvob`2wS-GHtg<89nzu6Tb!`ByHz< zz8tG?;=%3nWQNzEOzY=t8y`LH=i6}Ym)v7;k^(=yU^w@0RSYMYw4bkGIM>ey3MX1F z=ZvpYD{@Zrb-6&{S`V84MK)aT3$C=`ntmhW--vd!er{$sk27yc!RMz8=l%Kx!>Mod zp>&T8UnybZ?+Pb6-rwcfl7MiopX(Xkh%zm|#c(eFPZUmi<8t1?aB4&IdC-Q(WWYD2GI_t?^XC{Jxo0j z86=X2{J_1GL7K*J9_O5;aN@HXAI;}HhVyZ}o$=xP?_~G|jL!h$!};%IIOjj}BveMS z%YQDzIsb(Ux65D4aL)f8#)pr~WTjYpyVDrX+bw1|*TYSB zrw=on(?6|n>Jzu~R~Wv6@qdHyq4}lT{ehQKscQ!su5r{4+++<;S1i ziKNFx>-ltrQ@fWlKE({bg5j4lyo2G5HvYtq(t3t-dA?`Eb-$itIPuW&z}pNbKAL{2 z3mGKcFCAB`bqP3zYk4-Oz#n8d+5hdbx-r0T6PRxIQ-u>>u7~4K1As*G@cuR{oapQD z(R{AA(QAA7Z$`hI(LclR28JJIe5ehw2}=2=%V$hKGHVo$!5yMxuEOp8nsY`XA1bG` zECqgr4cC5Pt-`7PDtxpaHZr`P;hPyBJ}$R1{5(egJBFtN*J&@qiBGR8c!l9!U|OD0 zhI2lRIkFGMta^-3llDQ@c7oxu4-~;JV#s8K2b*|Cr(29>(W_2#NTQ!$;5S zT!jV>pZX0^JSOh-Fr1IqQia>c>oSJB8UI#>^ZssT{I6p4zhU$w zzxFftG5lgiKg9TOdw7-M+#Wt<4b zKHMJu$Z)RbCmA2ogXX`R;cmwNAj7E-y4`7c$RKI^*Z5q86D{{Am5iS2e-XpaM;*=Q zX2ys2>xYb<%YQq=s~Dd@GCo`nC+33)$*$)!7`_PQTAmt)Q{SdiWuzvB6V`~2rte_5 zpW!`>56OQoK9sgFoX5Qb45v2q`tni={2hf8Ew|f`7|!*Xdlt1G*F&$&8Z#Nr=k+{> z^Lh7Ig;Tqn|51i>{ZBhvHl+2h^>8x7-5}BWyh!18{!17=m1Rh_Mw1QKdJ8k0>;DG~ z=lZ`#;l#U<$@52s^YML}@!|aUGMw|DG*b$!=aH841cuLM?dCF^_&+798wCvaF#2+Z zllsXMyv6u%J^z#8 zT+hc55fbrl#7EoJsSM}ic#gvD_IW|}u&hFjr;@qOhY8~qeTe}xU#W8Y@O z=|3i+w9$s^cDof$?XJQ{kK?_Jp1M92A4(50yaIVmzn$^n>(n!hp7Ytua31#_WjLpg zGJG*>H~SotD(-K!oHH2C=`UnB=f8mA)!?W5wVdHZukj{^U&8QB4CnN>GMv-@hT)w4 zPYmbuFS2{dZ?kssDiT>A*ARq<9ytzkx?72<;hd^G#}S^Nw~#^4^EKys14t*7BJn8=5vSAV~uKG zmb9(1z>Z#Tx}(8(Q%@b36l`^0`*O;lBo{FTj7a6EF(!pWW0O1*^Nd zjDpT~$`E-`0e;WSv-s(<%;HIP1tH!F@Z;S27Nej6KmEmj3St!CKZo!a;Lp`(iQg-$ z{F=640si9@`mc00CH;Yq&I zt@8TeS|s19RebD3mfF$rQ???cZ4KdS7!(Sgh4NL?>jG+vCt8k)#$Mm0>UZb~s4BVC zQ$LFELhTo8Ks|N+Z8pVdd8iI0H$KVgzd)M}B)9mEf9ZPqxfn(CuFOA1=$a#6Gi)7m z#VF(p#ZOeEOT-F>paCg$;Pi^oun`oA&npPUH4z}Z2?B@D|O>dCbw#z z#)l`}Z~Y9SP``7!7FC~P^lqmO0h@@AU4I>_z6)hMY56twA9x|2_WJ$0eVf7A>)(dD z$@I5X>F=l#nDloHKDxfvU$VAAX7pb~-}oCL72wdkTZ)gp{v=@bu?J+_;iYfG*l3gA XuD@eJldS&z>qT|rZuy9P+w1=y--g9V diff --git a/perf_data/bs1bit1024.txt b/perf_data/bs1bit1024.txt deleted file mode 100644 index adc583f..0000000 --- a/perf_data/bs1bit1024.txt +++ /dev/null @@ -1,101 +0,0 @@ -Cpa CyInstance has successfully started. -Trial #001 OpenSSL: 3115.0us QAT: 170.0us Speed Up:18.3x ** PASS ** -Trial #002 OpenSSL: 3705.0us QAT: 124.5us Speed Up:36.3x ** PASS ** -Trial #003 OpenSSL: 2840.7us QAT: 106.0us Speed Up:29.6x ** PASS ** -Trial #004 OpenSSL: 2404.2us QAT: 96.8us Speed Up:26.2x ** PASS ** -Trial #005 OpenSSL: 2772.6us QAT: 91.4us Speed Up:33.1x ** PASS ** -Trial #006 OpenSSL: 3013.0us QAT: 88.8us Speed Up:36.8x ** PASS ** -Trial #007 OpenSSL: 3009.3us QAT: 85.9us Speed Up:37.8x ** PASS ** -Trial #008 OpenSSL: 2771.0us QAT: 83.8us Speed Up:35.1x ** PASS ** -Trial #009 OpenSSL: 2936.2us QAT: 82.0us Speed Up:38.1x ** PASS ** -Trial #010 OpenSSL: 3061.3us QAT: 80.7us Speed Up:40.4x ** PASS ** -Trial #011 OpenSSL: 3058.7us QAT: 79.7us Speed Up:40.7x ** PASS ** -Trial #012 OpenSSL: 2896.5us QAT: 78.6us Speed Up:38.7x ** PASS ** -Trial #013 OpenSSL: 2757.8us QAT: 77.7us Speed Up:37.0x ** PASS ** -Trial #014 OpenSSL: 2779.4us QAT: 76.9us Speed Up:37.6x ** PASS ** -Trial #015 OpenSSL: 2876.7us QAT: 76.1us Speed Up:39.5x ** PASS ** -Trial #016 OpenSSL: 2963.4us QAT: 75.6us Speed Up:40.9x ** PASS ** -Trial #017 OpenSSL: 2853.6us QAT: 75.1us Speed Up:39.4x ** PASS ** -Trial #018 OpenSSL: 2932.4us QAT: 74.5us Speed Up:40.9x ** PASS ** -Trial #019 OpenSSL: 2835.7us QAT: 74.0us Speed Up:39.6x ** PASS ** -Trial #020 OpenSSL: 2846.8us QAT: 73.9us Speed Up:39.8x ** PASS ** -Trial #021 OpenSSL: 2912.5us QAT: 73.5us Speed Up:40.9x ** PASS ** -Trial #022 OpenSSL: 2830.3us QAT: 73.2us Speed Up:39.8x ** PASS ** -Trial #023 OpenSSL: 2754.8us QAT: 72.9us Speed Up:38.8x ** PASS ** -Trial #024 OpenSSL: 2816.4us QAT: 72.6us Speed Up:39.9x ** PASS ** -Trial #025 OpenSSL: 2747.4us QAT: 72.4us Speed Up:38.9x ** PASS ** -Trial #026 OpenSSL: 2683.8us QAT: 72.1us Speed Up:38.1x ** PASS ** -Trial #027 OpenSSL: 2625.1us QAT: 71.9us Speed Up:37.3x ** PASS ** -Trial #028 OpenSSL: 2570.3us QAT: 71.6us Speed Up:36.5x ** PASS ** -Trial #029 OpenSSL: 2587.1us QAT: 71.4us Speed Up:36.9x ** PASS ** -Trial #030 OpenSSL: 2537.5us QAT: 71.2us Speed Up:36.2x ** PASS ** -Trial #031 OpenSSL: 2592.1us QAT: 71.0us Speed Up:37.2x ** PASS ** -Trial #032 OpenSSL: 2545.3us QAT: 70.8us Speed Up:36.5x ** PASS ** -Trial #033 OpenSSL: 2560.2us QAT: 70.7us Speed Up:36.8x ** PASS ** -Trial #034 OpenSSL: 2516.9us QAT: 70.6us Speed Up:36.2x ** PASS ** -Trial #035 OpenSSL: 2476.4us QAT: 70.3us Speed Up:35.7x ** PASS ** -Trial #036 OpenSSL: 2438.2us QAT: 70.2us Speed Up:35.2x ** PASS ** -Trial #037 OpenSSL: 2454.9us QAT: 70.1us Speed Up:35.5x ** PASS ** -Trial #038 OpenSSL: 2469.8us QAT: 69.9us Speed Up:35.8x ** PASS ** -Trial #039 OpenSSL: 2515.1us QAT: 69.8us Speed Up:36.6x ** PASS ** -Trial #040 OpenSSL: 2528.3us QAT: 69.7us Speed Up:36.8x ** PASS ** -Trial #041 OpenSSL: 2569.2us QAT: 69.6us Speed Up:37.4x ** PASS ** -Trial #042 OpenSSL: 2534.0us QAT: 69.5us Speed Up:37.0x ** PASS ** -Trial #043 OpenSSL: 2500.8us QAT: 69.4us Speed Up:36.5x ** PASS ** -Trial #044 OpenSSL: 2513.5us QAT: 69.3us Speed Up:36.7x ** PASS ** -Trial #045 OpenSSL: 2524.2us QAT: 69.3us Speed Up:36.9x ** PASS ** -Trial #046 OpenSSL: 2535.2us QAT: 69.2us Speed Up:37.1x ** PASS ** -Trial #047 OpenSSL: 2504.5us QAT: 69.2us Speed Up:36.6x ** PASS ** -Trial #048 OpenSSL: 2475.2us QAT: 69.1us Speed Up:36.2x ** PASS ** -Trial #049 OpenSSL: 2484.9us QAT: 69.0us Speed Up:36.4x ** PASS ** -Trial #050 OpenSSL: 2457.2us QAT: 68.9us Speed Up:36.0x ** PASS ** -Trial #051 OpenSSL: 2430.6us QAT: 68.9us Speed Up:35.6x ** PASS ** -Trial #052 OpenSSL: 2465.8us QAT: 68.8us Speed Up:36.2x ** PASS ** -Trial #053 OpenSSL: 2440.1us QAT: 68.8us Speed Up:35.8x ** PASS ** -Trial #054 OpenSSL: 2473.1us QAT: 68.8us Speed Up:36.3x ** PASS ** -Trial #055 OpenSSL: 2448.1us QAT: 68.7us Speed Up:36.0x ** PASS ** -Trial #056 OpenSSL: 2459.4us QAT: 68.7us Speed Up:36.2x ** PASS ** -Trial #057 OpenSSL: 2469.6us QAT: 68.5us Speed Up:36.4x ** PASS ** -Trial #058 OpenSSL: 2479.6us QAT: 68.5us Speed Up:36.5x ** PASS ** -Trial #059 OpenSSL: 2509.4us QAT: 68.5us Speed Up:37.0x ** PASS ** -Trial #060 OpenSSL: 2485.9us QAT: 68.5us Speed Up:36.7x ** PASS ** -Trial #061 OpenSSL: 2494.6us QAT: 68.4us Speed Up:36.8x ** PASS ** -Trial #062 OpenSSL: 2523.0us QAT: 68.4us Speed Up:37.2x ** PASS ** -Trial #063 OpenSSL: 2530.2us QAT: 68.4us Speed Up:37.4x ** PASS ** -Trial #064 OpenSSL: 2557.0us QAT: 68.3us Speed Up:37.8x ** PASS ** -Trial #065 OpenSSL: 2563.8us QAT: 68.4us Speed Up:37.9x ** PASS ** -Trial #066 OpenSSL: 2571.3us QAT: 68.4us Speed Up:38.0x ** PASS ** -Trial #067 OpenSSL: 2549.3us QAT: 68.3us Speed Up:37.7x ** PASS ** -Trial #068 OpenSSL: 2528.1us QAT: 68.3us Speed Up:37.4x ** PASS ** -Trial #069 OpenSSL: 2507.3us QAT: 68.3us Speed Up:37.1x ** PASS ** -Trial #070 OpenSSL: 2532.5us QAT: 68.3us Speed Up:37.4x ** PASS ** -Trial #071 OpenSSL: 2539.5us QAT: 68.2us Speed Up:37.6x ** PASS ** -Trial #072 OpenSSL: 2519.6us QAT: 68.2us Speed Up:37.3x ** PASS ** -Trial #073 OpenSSL: 2500.1us QAT: 68.1us Speed Up:37.0x ** PASS ** -Trial #074 OpenSSL: 2481.1us QAT: 68.1us Speed Up:36.7x ** PASS ** -Trial #075 OpenSSL: 2487.6us QAT: 68.1us Speed Up:36.8x ** PASS ** -Trial #076 OpenSSL: 2510.9us QAT: 68.1us Speed Up:37.2x ** PASS ** -Trial #077 OpenSSL: 2492.5us QAT: 68.1us Speed Up:36.9x ** PASS ** -Trial #078 OpenSSL: 2499.6us QAT: 68.1us Speed Up:37.0x ** PASS ** -Trial #079 OpenSSL: 2481.9us QAT: 68.0us Speed Up:36.8x ** PASS ** -Trial #080 OpenSSL: 2464.6us QAT: 68.0us Speed Up:36.5x ** PASS ** -Trial #081 OpenSSL: 2472.1us QAT: 67.9us Speed Up:36.6x ** PASS ** -Trial #082 OpenSSL: 2479.5us QAT: 67.9us Speed Up:36.8x ** PASS ** -Trial #083 OpenSSL: 2462.7us QAT: 67.9us Speed Up:36.5x ** PASS ** -Trial #084 OpenSSL: 2484.3us QAT: 67.9us Speed Up:36.9x ** PASS ** -Trial #085 OpenSSL: 2505.3us QAT: 67.9us Speed Up:37.1x ** PASS ** -Trial #086 OpenSSL: 2488.8us QAT: 67.9us Speed Up:36.9x ** PASS ** -Trial #087 OpenSSL: 2508.5us QAT: 67.8us Speed Up:37.2x ** PASS ** -Trial #088 OpenSSL: 2492.5us QAT: 67.8us Speed Up:37.0x ** PASS ** -Trial #089 OpenSSL: 2498.1us QAT: 67.8us Speed Up:37.1x ** PASS ** -Trial #090 OpenSSL: 2517.3us QAT: 67.8us Speed Up:37.4x ** PASS ** -Trial #091 OpenSSL: 2501.6us QAT: 67.7us Speed Up:37.1x ** PASS ** -Trial #092 OpenSSL: 2486.3us QAT: 67.7us Speed Up:36.9x ** PASS ** -Trial #093 OpenSSL: 2471.3us QAT: 67.7us Speed Up:36.7x ** PASS ** -Trial #094 OpenSSL: 2456.7us QAT: 67.6us Speed Up:36.5x ** PASS ** -Trial #095 OpenSSL: 2442.4us QAT: 67.6us Speed Up:36.3x ** PASS ** -Trial #096 OpenSSL: 2428.4us QAT: 67.6us Speed Up:36.1x ** PASS ** -Trial #097 OpenSSL: 2414.7us QAT: 67.6us Speed Up:35.9x ** PASS ** -Trial #098 OpenSSL: 2421.2us QAT: 67.6us Speed Up:36.0x ** PASS ** -Trial #099 OpenSSL: 2407.9us QAT: 67.5us Speed Up:35.8x ** PASS ** -Trial #100 OpenSSL: 2394.7us QAT: 67.5us Speed Up:35.6x ** PASS ** diff --git a/perf_data/bs1bit8192.txt b/perf_data/bs1bit8192.txt deleted file mode 100644 index 07d8f57..0000000 --- a/perf_data/bs1bit8192.txt +++ /dev/null @@ -1,101 +0,0 @@ -Cpa CyInstance has successfully started. -Trial #001 OpenSSL: 416765.0us QAT: 242.0us Speed Up:1722.2x ** PASS ** -Trial #002 OpenSSL: 371030.0us QAT: 197.0us Speed Up:1931.1x ** PASS ** -Trial #003 OpenSSL: 384466.7us QAT: 183.7us Speed Up:2160.8x ** PASS ** -Trial #004 OpenSSL: 375548.2us QAT: 166.5us Speed Up:2378.8x ** PASS ** -Trial #005 OpenSSL: 343536.6us QAT: 157.0us Speed Up:2265.2x ** PASS ** -Trial #006 OpenSSL: 322819.8us QAT: 151.3us Speed Up:2184.7x ** PASS ** -Trial #007 OpenSSL: 312659.3us QAT: 151.0us Speed Up:2114.0x ** PASS ** -Trial #008 OpenSSL: 326272.0us QAT: 150.6us Speed Up:2205.8x ** PASS ** -Trial #009 OpenSSL: 326400.8us QAT: 153.2us Speed Up:2169.8x ** PASS ** -Trial #010 OpenSSL: 318748.4us QAT: 152.1us Speed Up:2128.8x ** PASS ** -Trial #011 OpenSSL: 319286.8us QAT: 150.4us Speed Up:2157.2x ** PASS ** -Trial #012 OpenSSL: 319728.6us QAT: 148.7us Speed Up:2185.5x ** PASS ** -Trial #013 OpenSSL: 322086.2us QAT: 145.6us Speed Up:2264.6x ** PASS ** -Trial #014 OpenSSL: 323654.2us QAT: 143.0us Speed Up:2328.3x ** PASS ** -Trial #015 OpenSSL: 316293.1us QAT: 140.6us Speed Up:2305.9x ** PASS ** -Trial #016 OpenSSL: 309997.5us QAT: 138.9us Speed Up:2281.1x ** PASS ** -Trial #017 OpenSSL: 304461.3us QAT: 137.9us Speed Up:2251.0x ** PASS ** -Trial #018 OpenSSL: 309513.6us QAT: 140.1us Speed Up:2250.0x ** PASS ** -Trial #019 OpenSSL: 315520.6us QAT: 140.2us Speed Up:2287.5x ** PASS ** -Trial #020 OpenSSL: 316112.0us QAT: 140.1us Speed Up:2292.6x ** PASS ** -Trial #021 OpenSSL: 321244.4us QAT: 139.8us Speed Up:2333.0x ** PASS ** -Trial #022 OpenSSL: 323171.5us QAT: 138.5us Speed Up:2377.2x ** PASS ** -Trial #023 OpenSSL: 318626.0us QAT: 137.7us Speed Up:2351.7x ** PASS ** -Trial #024 OpenSSL: 316617.0us QAT: 136.8us Speed Up:2351.7x ** PASS ** -Trial #025 OpenSSL: 318861.8us QAT: 136.3us Speed Up:2377.9x ** PASS ** -Trial #026 OpenSSL: 322852.6us QAT: 136.5us Speed Up:2401.7x ** PASS ** -Trial #027 OpenSSL: 326495.4us QAT: 136.9us Speed Up:2418.9x ** PASS ** -Trial #028 OpenSSL: 329951.8us QAT: 137.9us Speed Up:2423.0x ** PASS ** -Trial #029 OpenSSL: 327162.7us QAT: 138.1us Speed Up:2400.0x ** PASS ** -Trial #030 OpenSSL: 330461.2us QAT: 138.1us Speed Up:2421.4x ** PASS ** -Trial #031 OpenSSL: 327979.4us QAT: 137.9us Speed Up:2405.3x ** PASS ** -Trial #032 OpenSSL: 330974.3us QAT: 138.1us Speed Up:2422.7x ** PASS ** -Trial #033 OpenSSL: 330758.0us QAT: 138.2us Speed Up:2417.9x ** PASS ** -Trial #034 OpenSSL: 333490.8us QAT: 138.1us Speed Up:2439.1x ** PASS ** -Trial #035 OpenSSL: 331162.5us QAT: 137.8us Speed Up:2426.6x ** PASS ** -Trial #036 OpenSSL: 330943.2us QAT: 137.9us Speed Up:2422.4x ** PASS ** -Trial #037 OpenSSL: 328889.9us QAT: 137.8us Speed Up:2408.4x ** PASS ** -Trial #038 OpenSSL: 331389.9us QAT: 137.8us Speed Up:2427.0x ** PASS ** -Trial #039 OpenSSL: 331224.0us QAT: 137.5us Speed Up:2430.4x ** PASS ** -Trial #040 OpenSSL: 333505.7us QAT: 138.3us Speed Up:2431.7x ** PASS ** -Trial #041 OpenSSL: 333300.1us QAT: 138.2us Speed Up:2431.2x ** PASS ** -Trial #042 OpenSSL: 333182.5us QAT: 138.1us Speed Up:2431.6x ** PASS ** -Trial #043 OpenSSL: 332990.2us QAT: 138.2us Speed Up:2427.9x ** PASS ** -Trial #044 OpenSSL: 332832.3us QAT: 138.4us Speed Up:2423.8x ** PASS ** -Trial #045 OpenSSL: 332669.9us QAT: 138.2us Speed Up:2424.8x ** PASS ** -Trial #046 OpenSSL: 332447.8us QAT: 138.0us Speed Up:2426.4x ** PASS ** -Trial #047 OpenSSL: 330764.3us QAT: 138.0us Speed Up:2413.8x ** PASS ** -Trial #048 OpenSSL: 332568.4us QAT: 137.7us Speed Up:2435.4x ** PASS ** -Trial #049 OpenSSL: 331273.7us QAT: 137.2us Speed Up:2433.0x ** PASS ** -Trial #050 OpenSSL: 329913.4us QAT: 136.7us Speed Up:2433.1x ** PASS ** -Trial #051 OpenSSL: 330081.1us QAT: 136.3us Speed Up:2441.7x ** PASS ** -Trial #052 OpenSSL: 328792.5us QAT: 135.8us Speed Up:2441.1x ** PASS ** -Trial #053 OpenSSL: 326560.7us QAT: 135.4us Speed Up:2429.0x ** PASS ** -Trial #054 OpenSSL: 326427.3us QAT: 135.5us Speed Up:2426.9x ** PASS ** -Trial #055 OpenSSL: 325038.8us QAT: 135.7us Speed Up:2413.1x ** PASS ** -Trial #056 OpenSSL: 323779.7us QAT: 135.7us Speed Up:2403.4x ** PASS ** -Trial #057 OpenSSL: 325537.8us QAT: 135.6us Speed Up:2419.8x ** PASS ** -Trial #058 OpenSSL: 324271.7us QAT: 135.3us Speed Up:2413.7x ** PASS ** -Trial #059 OpenSSL: 323053.5us QAT: 136.0us Speed Up:2397.4x ** PASS ** -Trial #060 OpenSSL: 323080.6us QAT: 136.0us Speed Up:2397.2x ** PASS ** -Trial #061 OpenSSL: 321949.5us QAT: 136.1us Speed Up:2387.5x ** PASS ** -Trial #062 OpenSSL: 323559.7us QAT: 136.1us Speed Up:2398.6x ** PASS ** -Trial #063 OpenSSL: 323559.6us QAT: 136.0us Speed Up:2399.5x ** PASS ** -Trial #064 OpenSSL: 322406.5us QAT: 136.2us Speed Up:2388.0x ** PASS ** -Trial #065 OpenSSL: 323951.9us QAT: 136.2us Speed Up:2400.2x ** PASS ** -Trial #066 OpenSSL: 325425.0us QAT: 136.2us Speed Up:2411.1x ** PASS ** -Trial #067 OpenSSL: 324327.9us QAT: 136.1us Speed Up:2404.2x ** PASS ** -Trial #068 OpenSSL: 325751.3us QAT: 136.1us Speed Up:2413.1x ** PASS ** -Trial #069 OpenSSL: 324638.5us QAT: 136.1us Speed Up:2404.9x ** PASS ** -Trial #070 OpenSSL: 323598.7us QAT: 136.0us Speed Up:2398.0x ** PASS ** -Trial #071 OpenSSL: 322600.1us QAT: 136.1us Speed Up:2389.6x ** PASS ** -Trial #072 OpenSSL: 321604.8us QAT: 136.2us Speed Up:2381.3x ** PASS ** -Trial #073 OpenSSL: 320660.3us QAT: 136.1us Speed Up:2374.3x ** PASS ** -Trial #074 OpenSSL: 320675.5us QAT: 136.2us Speed Up:2373.1x ** PASS ** -Trial #075 OpenSSL: 319747.0us QAT: 136.3us Speed Up:2365.4x ** PASS ** -Trial #076 OpenSSL: 318875.2us QAT: 136.3us Speed Up:2358.4x ** PASS ** -Trial #077 OpenSSL: 320238.9us QAT: 136.1us Speed Up:2371.8x ** PASS ** -Trial #078 OpenSSL: 319009.6us QAT: 135.8us Speed Up:2366.6x ** PASS ** -Trial #079 OpenSSL: 319321.7us QAT: 135.5us Speed Up:2377.0x ** PASS ** -Trial #080 OpenSSL: 317989.7us QAT: 135.2us Speed Up:2370.4x ** PASS ** -Trial #081 OpenSSL: 319249.5us QAT: 135.3us Speed Up:2379.0x ** PASS ** -Trial #082 OpenSSL: 319313.4us QAT: 135.4us Speed Up:2376.5x ** PASS ** -Trial #083 OpenSSL: 318499.8us QAT: 135.5us Speed Up:2369.4x ** PASS ** -Trial #084 OpenSSL: 317718.5us QAT: 135.9us Speed Up:2358.9x ** PASS ** -Trial #085 OpenSSL: 316934.0us QAT: 136.0us Speed Up:2351.8x ** PASS ** -Trial #086 OpenSSL: 318171.3us QAT: 136.0us Speed Up:2360.9x ** PASS ** -Trial #087 OpenSSL: 317438.2us QAT: 135.8us Speed Up:2357.4x ** PASS ** -Trial #088 OpenSSL: 317528.7us QAT: 135.8us Speed Up:2357.8x ** PASS ** -Trial #089 OpenSSL: 316834.8us QAT: 135.9us Speed Up:2352.1x ** PASS ** -Trial #090 OpenSSL: 316135.5us QAT: 135.9us Speed Up:2345.8x ** PASS ** -Trial #091 OpenSSL: 315430.1us QAT: 135.8us Speed Up:2341.7x ** PASS ** -Trial #092 OpenSSL: 314767.1us QAT: 135.8us Speed Up:2337.0x ** PASS ** -Trial #093 OpenSSL: 314077.4us QAT: 135.9us Speed Up:2330.7x ** PASS ** -Trial #094 OpenSSL: 315281.7us QAT: 136.0us Speed Up:2337.3x ** PASS ** -Trial #095 OpenSSL: 316394.6us QAT: 136.0us Speed Up:2345.3x ** PASS ** -Trial #096 OpenSSL: 316501.2us QAT: 136.0us Speed Up:2346.0x ** PASS ** -Trial #097 OpenSSL: 316606.8us QAT: 136.0us Speed Up:2346.3x ** PASS ** -Trial #098 OpenSSL: 315942.8us QAT: 136.0us Speed Up:2341.6x ** PASS ** -Trial #099 OpenSSL: 316011.4us QAT: 136.0us Speed Up:2341.9x ** PASS ** -Trial #100 OpenSSL: 316066.4us QAT: 135.9us Speed Up:2342.9x ** PASS ** diff --git a/perf_data/bs8bit1024.txt b/perf_data/bs8bit1024.txt deleted file mode 100644 index d4250f8..0000000 --- a/perf_data/bs8bit1024.txt +++ /dev/null @@ -1,101 +0,0 @@ -Cpa CyInstance has successfully started. -Trial #001 OpenSSL: 4340.0us QAT: 67.0us Speed Up:64.8x ** PASS ** -Trial #002 OpenSSL: 2726.5us QAT: 59.5us Speed Up:43.1x ** PASS ** -Trial #003 OpenSSL: 2803.0us QAT: 56.3us Speed Up:48.5x ** PASS ** -Trial #004 OpenSSL: 2377.8us QAT: 54.5us Speed Up:42.0x ** PASS ** -Trial #005 OpenSSL: 2509.8us QAT: 53.4us Speed Up:46.0x ** PASS ** -Trial #006 OpenSSL: 2273.3us QAT: 52.9us Speed Up:41.9x ** PASS ** -Trial #007 OpenSSL: 2551.3us QAT: 52.3us Speed Up:48.4x ** PASS ** -Trial #008 OpenSSL: 2611.6us QAT: 52.1us Speed Up:49.8x ** PASS ** -Trial #009 OpenSSL: 2444.0us QAT: 52.0us Speed Up:46.6x ** PASS ** -Trial #010 OpenSSL: 2502.6us QAT: 51.8us Speed Up:48.1x ** PASS ** -Trial #011 OpenSSL: 2374.5us QAT: 51.9us Speed Up:45.6x ** PASS ** -Trial #012 OpenSSL: 2268.1us QAT: 51.8us Speed Up:43.6x ** PASS ** -Trial #013 OpenSSL: 2177.6us QAT: 51.6us Speed Up:42.0x ** PASS ** -Trial #014 OpenSSL: 2323.6us QAT: 51.5us Speed Up:45.0x ** PASS ** -Trial #015 OpenSSL: 2452.6us QAT: 51.4us Speed Up:47.7x ** PASS ** -Trial #016 OpenSSL: 2367.5us QAT: 51.2us Speed Up:46.1x ** PASS ** -Trial #017 OpenSSL: 2404.4us QAT: 51.2us Speed Up:46.9x ** PASS ** -Trial #018 OpenSSL: 2331.1us QAT: 51.1us Speed Up:45.5x ** PASS ** -Trial #019 OpenSSL: 2265.7us QAT: 51.0us Speed Up:44.3x ** PASS ** -Trial #020 OpenSSL: 2207.2us QAT: 50.9us Speed Up:43.2x ** PASS ** -Trial #021 OpenSSL: 2247.6us QAT: 50.8us Speed Up:44.1x ** PASS ** -Trial #022 OpenSSL: 2336.4us QAT: 50.7us Speed Up:45.9x ** PASS ** -Trial #023 OpenSSL: 2418.3us QAT: 50.7us Speed Up:47.6x ** PASS ** -Trial #024 OpenSSL: 2363.3us QAT: 50.7us Speed Up:46.6x ** PASS ** -Trial #025 OpenSSL: 2390.2us QAT: 50.6us Speed Up:47.2x ** PASS ** -Trial #026 OpenSSL: 2412.6us QAT: 50.5us Speed Up:47.7x ** PASS ** -Trial #027 OpenSSL: 2433.8us QAT: 50.4us Speed Up:48.2x ** PASS ** -Trial #028 OpenSSL: 2454.4us QAT: 50.4us Speed Up:48.7x ** PASS ** -Trial #029 OpenSSL: 2407.2us QAT: 50.3us Speed Up:47.8x ** PASS ** -Trial #030 OpenSSL: 2425.3us QAT: 50.3us Speed Up:48.2x ** PASS ** -Trial #031 OpenSSL: 2483.7us QAT: 50.2us Speed Up:49.5x ** PASS ** -Trial #032 OpenSSL: 2440.2us QAT: 50.2us Speed Up:48.7x ** PASS ** -Trial #033 OpenSSL: 2399.4us QAT: 50.1us Speed Up:47.9x ** PASS ** -Trial #034 OpenSSL: 2361.4us QAT: 50.1us Speed Up:47.1x ** PASS ** -Trial #035 OpenSSL: 2325.3us QAT: 50.0us Speed Up:46.4x ** PASS ** -Trial #036 OpenSSL: 2291.2us QAT: 50.0us Speed Up:45.8x ** PASS ** -Trial #037 OpenSSL: 2342.9us QAT: 50.0us Speed Up:46.8x ** PASS ** -Trial #038 OpenSSL: 2309.8us QAT: 50.0us Speed Up:46.1x ** PASS ** -Trial #039 OpenSSL: 2358.2us QAT: 50.0us Speed Up:47.1x ** PASS ** -Trial #040 OpenSSL: 2373.8us QAT: 50.0us Speed Up:47.4x ** PASS ** -Trial #041 OpenSSL: 2389.0us QAT: 49.9us Speed Up:47.7x ** PASS ** -Trial #042 OpenSSL: 2358.2us QAT: 49.9us Speed Up:47.1x ** PASS ** -Trial #043 OpenSSL: 2401.2us QAT: 49.9us Speed Up:48.0x ** PASS ** -Trial #044 OpenSSL: 2371.4us QAT: 49.9us Speed Up:47.4x ** PASS ** -Trial #045 OpenSSL: 2412.4us QAT: 49.9us Speed Up:48.3x ** PASS ** -Trial #046 OpenSSL: 2383.9us QAT: 49.9us Speed Up:47.7x ** PASS ** -Trial #047 OpenSSL: 2356.7us QAT: 49.9us Speed Up:47.2x ** PASS ** -Trial #048 OpenSSL: 2395.2us QAT: 49.9us Speed Up:47.9x ** PASS ** -Trial #049 OpenSSL: 2368.6us QAT: 49.9us Speed Up:47.4x ** PASS ** -Trial #050 OpenSSL: 2343.2us QAT: 49.9us Speed Up:46.9x ** PASS ** -Trial #051 OpenSSL: 2380.8us QAT: 49.9us Speed Up:47.7x ** PASS ** -Trial #052 OpenSSL: 2393.9us QAT: 49.9us Speed Up:48.0x ** PASS ** -Trial #053 OpenSSL: 2369.3us QAT: 49.9us Speed Up:47.5x ** PASS ** -Trial #054 OpenSSL: 2380.7us QAT: 49.9us Speed Up:47.7x ** PASS ** -Trial #055 OpenSSL: 2414.3us QAT: 49.9us Speed Up:48.3x ** PASS ** -Trial #056 OpenSSL: 2423.9us QAT: 49.9us Speed Up:48.5x ** PASS ** -Trial #057 OpenSSL: 2400.6us QAT: 49.9us Speed Up:48.1x ** PASS ** -Trial #058 OpenSSL: 2431.7us QAT: 49.9us Speed Up:48.7x ** PASS ** -Trial #059 OpenSSL: 2440.9us QAT: 49.9us Speed Up:48.8x ** PASS ** -Trial #060 OpenSSL: 2418.4us QAT: 50.0us Speed Up:48.4x ** PASS ** -Trial #061 OpenSSL: 2396.9us QAT: 50.0us Speed Up:47.9x ** PASS ** -Trial #062 OpenSSL: 2376.0us QAT: 50.0us Speed Up:47.5x ** PASS ** -Trial #063 OpenSSL: 2355.7us QAT: 50.0us Speed Up:47.1x ** PASS ** -Trial #064 OpenSSL: 2366.4us QAT: 50.0us Speed Up:47.3x ** PASS ** -Trial #065 OpenSSL: 2376.3us QAT: 49.9us Speed Up:47.5x ** PASS ** -Trial #066 OpenSSL: 2357.0us QAT: 50.0us Speed Up:47.2x ** PASS ** -Trial #067 OpenSSL: 2365.9us QAT: 50.0us Speed Up:47.3x ** PASS ** -Trial #068 OpenSSL: 2347.4us QAT: 50.0us Speed Up:47.0x ** PASS ** -Trial #069 OpenSSL: 2374.6us QAT: 49.9us Speed Up:47.5x ** PASS ** -Trial #070 OpenSSL: 2400.8us QAT: 49.9us Speed Up:48.1x ** PASS ** -Trial #071 OpenSSL: 2408.6us QAT: 49.9us Speed Up:48.2x ** PASS ** -Trial #072 OpenSSL: 2390.4us QAT: 49.9us Speed Up:47.8x ** PASS ** -Trial #073 OpenSSL: 2372.6us QAT: 49.9us Speed Up:47.5x ** PASS ** -Trial #074 OpenSSL: 2397.2us QAT: 49.9us Speed Up:48.0x ** PASS ** -Trial #075 OpenSSL: 2380.0us QAT: 49.9us Speed Up:47.7x ** PASS ** -Trial #076 OpenSSL: 2388.5us QAT: 49.9us Speed Up:47.9x ** PASS ** -Trial #077 OpenSSL: 2371.8us QAT: 49.9us Speed Up:47.5x ** PASS ** -Trial #078 OpenSSL: 2380.6us QAT: 49.9us Speed Up:47.7x ** PASS ** -Trial #079 OpenSSL: 2364.3us QAT: 49.8us Speed Up:47.4x ** PASS ** -Trial #080 OpenSSL: 2348.4us QAT: 49.8us Speed Up:47.1x ** PASS ** -Trial #081 OpenSSL: 2371.8us QAT: 49.8us Speed Up:47.6x ** PASS ** -Trial #082 OpenSSL: 2394.2us QAT: 49.8us Speed Up:48.1x ** PASS ** -Trial #083 OpenSSL: 2378.6us QAT: 49.8us Speed Up:47.8x ** PASS ** -Trial #084 OpenSSL: 2386.3us QAT: 49.8us Speed Up:47.9x ** PASS ** -Trial #085 OpenSSL: 2371.1us QAT: 49.8us Speed Up:47.6x ** PASS ** -Trial #086 OpenSSL: 2392.3us QAT: 49.8us Speed Up:48.1x ** PASS ** -Trial #087 OpenSSL: 2377.4us QAT: 49.8us Speed Up:47.8x ** PASS ** -Trial #088 OpenSSL: 2385.5us QAT: 49.7us Speed Up:47.9x ** PASS ** -Trial #089 OpenSSL: 2405.8us QAT: 49.7us Speed Up:48.4x ** PASS ** -Trial #090 OpenSSL: 2391.2us QAT: 49.7us Speed Up:48.1x ** PASS ** -Trial #091 OpenSSL: 2376.9us QAT: 49.7us Speed Up:47.8x ** PASS ** -Trial #092 OpenSSL: 2396.9us QAT: 49.7us Speed Up:48.2x ** PASS ** -Trial #093 OpenSSL: 2382.8us QAT: 49.7us Speed Up:47.9x ** PASS ** -Trial #094 OpenSSL: 2369.2us QAT: 49.7us Speed Up:47.6x ** PASS ** -Trial #095 OpenSSL: 2355.8us QAT: 49.7us Speed Up:47.4x ** PASS ** -Trial #096 OpenSSL: 2342.7us QAT: 49.7us Speed Up:47.1x ** PASS ** -Trial #097 OpenSSL: 2329.8us QAT: 49.7us Speed Up:46.9x ** PASS ** -Trial #098 OpenSSL: 2317.2us QAT: 49.7us Speed Up:46.6x ** PASS ** -Trial #099 OpenSSL: 2336.4us QAT: 49.7us Speed Up:47.0x ** PASS ** -Trial #100 OpenSSL: 2324.0us QAT: 49.7us Speed Up:46.7x ** PASS ** diff --git a/perf_data/bs8bit4096.txt b/perf_data/bs8bit4096.txt deleted file mode 100644 index 0a5c8f9..0000000 --- a/perf_data/bs8bit4096.txt +++ /dev/null @@ -1,101 +0,0 @@ -Cpa CyInstance has successfully started. -Trial #001 OpenSSL: 55741.0us QAT: 75.5us Speed Up:738.3x ** PASS ** -Trial #002 OpenSSL: 75929.0us QAT: 67.7us Speed Up:1171.8x ** PASS ** -Trial #003 OpenSSL: 81653.0us QAT: 64.9us Speed Up:1305.0x ** PASS ** -Trial #004 OpenSSL: 90997.5us QAT: 63.0us Speed Up:1497.4x ** PASS ** -Trial #005 OpenSSL: 91945.4us QAT: 62.0us Speed Up:1528.0x ** PASS ** -Trial #006 OpenSSL: 86562.3us QAT: 62.1us Speed Up:1431.5x ** PASS ** -Trial #007 OpenSSL: 82684.9us QAT: 62.3us Speed Up:1361.7x ** PASS ** -Trial #008 OpenSSL: 79768.5us QAT: 62.3us Speed Up:1309.7x ** PASS ** -Trial #009 OpenSSL: 81429.0us QAT: 62.2us Speed Up:1335.3x ** PASS ** -Trial #010 OpenSSL: 85043.1us QAT: 62.1us Speed Up:1394.9x ** PASS ** -Trial #011 OpenSSL: 82742.4us QAT: 63.0us Speed Up:1343.3x ** PASS ** -Trial #012 OpenSSL: 85945.3us QAT: 62.6us Speed Up:1407.0x ** PASS ** -Trial #013 OpenSSL: 88348.0us QAT: 62.2us Speed Up:1453.8x ** PASS ** -Trial #014 OpenSSL: 86296.7us QAT: 62.2us Speed Up:1418.0x ** PASS ** -Trial #015 OpenSSL: 88532.7us QAT: 61.9us Speed Up:1462.4x ** PASS ** -Trial #016 OpenSSL: 90321.9us QAT: 61.5us Speed Up:1504.4x ** PASS ** -Trial #017 OpenSSL: 92032.1us QAT: 61.4us Speed Up:1534.5x ** PASS ** -Trial #018 OpenSSL: 92206.6us QAT: 61.2us Speed Up:1539.4x ** PASS ** -Trial #019 OpenSSL: 92367.7us QAT: 61.0us Speed Up:1545.2x ** PASS ** -Trial #020 OpenSSL: 92508.2us QAT: 60.9us Speed Up:1550.2x ** PASS ** -Trial #021 OpenSSL: 90957.9us QAT: 61.0us Speed Up:1521.0x ** PASS ** -Trial #022 OpenSSL: 92337.8us QAT: 60.8us Speed Up:1549.9x ** PASS ** -Trial #023 OpenSSL: 90917.2us QAT: 60.9us Speed Up:1523.2x ** PASS ** -Trial #024 OpenSSL: 89605.8us QAT: 61.0us Speed Up:1499.7x ** PASS ** -Trial #025 OpenSSL: 89798.6us QAT: 61.0us Speed Up:1501.0x ** PASS ** -Trial #026 OpenSSL: 90038.0us QAT: 60.9us Speed Up:1506.9x ** PASS ** -Trial #027 OpenSSL: 88923.8us QAT: 61.0us Speed Up:1485.7x ** PASS ** -Trial #028 OpenSSL: 87863.9us QAT: 61.0us Speed Up:1466.9x ** PASS ** -Trial #029 OpenSSL: 86890.2us QAT: 61.1us Speed Up:1448.7x ** PASS ** -Trial #030 OpenSSL: 85988.6us QAT: 61.1us Speed Up:1433.1x ** PASS ** -Trial #031 OpenSSL: 85144.6us QAT: 61.2us Speed Up:1417.1x ** PASS ** -Trial #032 OpenSSL: 85497.5us QAT: 61.1us Speed Up:1425.9x ** PASS ** -Trial #033 OpenSSL: 84708.4us QAT: 61.1us Speed Up:1411.8x ** PASS ** -Trial #034 OpenSSL: 83965.9us QAT: 61.0us Speed Up:1399.6x ** PASS ** -Trial #035 OpenSSL: 83283.2us QAT: 61.3us Speed Up:1383.6x ** PASS ** -Trial #036 OpenSSL: 82636.1us QAT: 61.4us Speed Up:1371.5x ** PASS ** -Trial #037 OpenSSL: 82023.6us QAT: 61.5us Speed Up:1359.8x ** PASS ** -Trial #038 OpenSSL: 82417.9us QAT: 61.4us Speed Up:1367.3x ** PASS ** -Trial #039 OpenSSL: 82765.6us QAT: 61.4us Speed Up:1373.3x ** PASS ** -Trial #040 OpenSSL: 83024.8us QAT: 61.4us Speed Up:1376.8x ** PASS ** -Trial #041 OpenSSL: 83360.0us QAT: 61.4us Speed Up:1381.7x ** PASS ** -Trial #042 OpenSSL: 82792.2us QAT: 61.4us Speed Up:1370.8x ** PASS ** -Trial #043 OpenSSL: 82258.4us QAT: 61.6us Speed Up:1359.9x ** PASS ** -Trial #044 OpenSSL: 82516.1us QAT: 61.5us Speed Up:1365.5x ** PASS ** -Trial #045 OpenSSL: 83310.0us QAT: 61.5us Speed Up:1377.7x ** PASS ** -Trial #046 OpenSSL: 82796.1us QAT: 61.5us Speed Up:1368.5x ** PASS ** -Trial #047 OpenSSL: 82306.6us QAT: 61.6us Speed Up:1359.4x ** PASS ** -Trial #048 OpenSSL: 83089.2us QAT: 61.4us Speed Up:1375.6x ** PASS ** -Trial #049 OpenSSL: 83325.5us QAT: 61.4us Speed Up:1380.0x ** PASS ** -Trial #050 OpenSSL: 84037.0us QAT: 61.3us Speed Up:1394.3x ** PASS ** -Trial #051 OpenSSL: 84220.8us QAT: 61.2us Speed Up:1399.1x ** PASS ** -Trial #052 OpenSSL: 84431.7us QAT: 61.2us Speed Up:1403.8x ** PASS ** -Trial #053 OpenSSL: 83968.2us QAT: 61.2us Speed Up:1394.5x ** PASS ** -Trial #054 OpenSSL: 84627.4us QAT: 61.1us Speed Up:1408.1x ** PASS ** -Trial #055 OpenSSL: 84178.3us QAT: 61.2us Speed Up:1399.7x ** PASS ** -Trial #056 OpenSSL: 84762.3us QAT: 61.2us Speed Up:1409.5x ** PASS ** -Trial #057 OpenSSL: 84316.2us QAT: 61.2us Speed Up:1401.0x ** PASS ** -Trial #058 OpenSSL: 83892.7us QAT: 61.2us Speed Up:1393.5x ** PASS ** -Trial #059 OpenSSL: 84470.6us QAT: 61.2us Speed Up:1403.0x ** PASS ** -Trial #060 OpenSSL: 85004.8us QAT: 61.2us Speed Up:1413.1x ** PASS ** -Trial #061 OpenSSL: 85135.9us QAT: 61.2us Speed Up:1415.1x ** PASS ** -Trial #062 OpenSSL: 85315.8us QAT: 61.1us Speed Up:1418.5x ** PASS ** -Trial #063 OpenSSL: 85456.7us QAT: 61.1us Speed Up:1420.7x ** PASS ** -Trial #064 OpenSSL: 85957.1us QAT: 61.1us Speed Up:1430.1x ** PASS ** -Trial #065 OpenSSL: 86074.8us QAT: 61.1us Speed Up:1431.0x ** PASS ** -Trial #066 OpenSSL: 86224.6us QAT: 61.0us Speed Up:1434.4x ** PASS ** -Trial #067 OpenSSL: 85824.5us QAT: 61.1us Speed Up:1427.1x ** PASS ** -Trial #068 OpenSSL: 86291.3us QAT: 61.0us Speed Up:1436.1x ** PASS ** -Trial #069 OpenSSL: 86425.9us QAT: 61.0us Speed Up:1438.8x ** PASS ** -Trial #070 OpenSSL: 86039.3us QAT: 61.0us Speed Up:1431.9x ** PASS ** -Trial #071 OpenSSL: 86482.1us QAT: 61.0us Speed Up:1439.7x ** PASS ** -Trial #072 OpenSSL: 86113.8us QAT: 61.0us Speed Up:1433.1x ** PASS ** -Trial #073 OpenSSL: 85752.4us QAT: 61.1us Speed Up:1425.9x ** PASS ** -Trial #074 OpenSSL: 85405.3us QAT: 61.1us Speed Up:1418.8x ** PASS ** -Trial #075 OpenSSL: 85058.5us QAT: 61.2us Speed Up:1412.5x ** PASS ** -Trial #076 OpenSSL: 84723.6us QAT: 61.2us Speed Up:1406.5x ** PASS ** -Trial #077 OpenSSL: 84398.5us QAT: 61.2us Speed Up:1400.4x ** PASS ** -Trial #078 OpenSSL: 84081.7us QAT: 61.2us Speed Up:1394.7x ** PASS ** -Trial #079 OpenSSL: 83774.7us QAT: 61.3us Speed Up:1388.9x ** PASS ** -Trial #080 OpenSSL: 83913.3us QAT: 61.2us Speed Up:1392.0x ** PASS ** -Trial #081 OpenSSL: 84045.1us QAT: 61.2us Speed Up:1395.2x ** PASS ** -Trial #082 OpenSSL: 83749.8us QAT: 61.2us Speed Up:1390.1x ** PASS ** -Trial #083 OpenSSL: 83462.6us QAT: 61.2us Speed Up:1384.6x ** PASS ** -Trial #084 OpenSSL: 83181.6us QAT: 61.2us Speed Up:1379.3x ** PASS ** -Trial #085 OpenSSL: 82906.5us QAT: 61.2us Speed Up:1374.3x ** PASS ** -Trial #086 OpenSSL: 82640.0us QAT: 61.2us Speed Up:1369.7x ** PASS ** -Trial #087 OpenSSL: 83053.0us QAT: 61.2us Speed Up:1377.0x ** PASS ** -Trial #088 OpenSSL: 83189.2us QAT: 61.2us Speed Up:1379.3x ** PASS ** -Trial #089 OpenSSL: 82928.5us QAT: 61.3us Speed Up:1374.1x ** PASS ** -Trial #090 OpenSSL: 82670.5us QAT: 61.3us Speed Up:1369.1x ** PASS ** -Trial #091 OpenSSL: 82804.3us QAT: 61.3us Speed Up:1372.0x ** PASS ** -Trial #092 OpenSSL: 82554.4us QAT: 61.3us Speed Up:1367.3x ** PASS ** -Trial #093 OpenSSL: 82308.3us QAT: 61.3us Speed Up:1362.6x ** PASS ** -Trial #094 OpenSSL: 82687.5us QAT: 61.3us Speed Up:1369.5x ** PASS ** -Trial #095 OpenSSL: 82447.5us QAT: 61.3us Speed Up:1364.9x ** PASS ** -Trial #096 OpenSSL: 82805.9us QAT: 61.3us Speed Up:1372.1x ** PASS ** -Trial #097 OpenSSL: 82567.8us QAT: 61.3us Speed Up:1367.6x ** PASS ** -Trial #098 OpenSSL: 82930.6us QAT: 61.3us Speed Up:1375.1x ** PASS ** -Trial #099 OpenSSL: 82692.2us QAT: 61.3us Speed Up:1370.9x ** PASS ** -Trial #100 OpenSSL: 82456.7us QAT: 61.3us Speed Up:1366.9x ** PASS ** diff --git a/perf_data/bs8bit8192.txt b/perf_data/bs8bit8192.txt deleted file mode 100644 index 6e36531..0000000 --- a/perf_data/bs8bit8192.txt +++ /dev/null @@ -1,101 +0,0 @@ -Cpa CyInstance has successfully started. -Trial #001 OpenSSL: 244676.0us QAT: 130.2us Speed Up:1878.5x ** PASS ** -Trial #002 OpenSSL: 290090.0us QAT: 126.1us Speed Up:2315.7x ** PASS ** -Trial #003 OpenSSL: 304527.0us QAT: 126.3us Speed Up:2420.6x ** PASS ** -Trial #004 OpenSSL: 293434.0us QAT: 124.3us Speed Up:2364.3x ** PASS ** -Trial #005 OpenSSL: 287588.2us QAT: 124.5us Speed Up:2313.3x ** PASS ** -Trial #006 OpenSSL: 311858.8us QAT: 126.1us Speed Up:2465.6x ** PASS ** -Trial #007 OpenSSL: 304457.0us QAT: 127.2us Speed Up:2392.1x ** PASS ** -Trial #008 OpenSSL: 308027.1us QAT: 127.2us Speed Up:2419.6x ** PASS ** -Trial #009 OpenSSL: 302825.8us QAT: 128.1us Speed Up:2365.6x ** PASS ** -Trial #010 OpenSSL: 298619.1us QAT: 129.6us Speed Up:2311.0x ** PASS ** -Trial #011 OpenSSL: 310679.2us QAT: 130.1us Speed Up:2390.8x ** PASS ** -Trial #012 OpenSSL: 320779.9us QAT: 129.8us Speed Up:2476.7x ** PASS ** -Trial #013 OpenSSL: 316249.8us QAT: 129.9us Speed Up:2439.6x ** PASS ** -Trial #014 OpenSSL: 317377.6us QAT: 130.5us Speed Up:2436.6x ** PASS ** -Trial #015 OpenSSL: 313582.5us QAT: 130.8us Speed Up:2402.4x ** PASS ** -Trial #016 OpenSSL: 320854.8us QAT: 130.8us Speed Up:2457.8x ** PASS ** -Trial #017 OpenSSL: 321691.6us QAT: 131.1us Speed Up:2459.1x ** PASS ** -Trial #018 OpenSSL: 327720.1us QAT: 131.2us Speed Up:2501.3x ** PASS ** -Trial #019 OpenSSL: 324183.3us QAT: 131.1us Speed Up:2476.5x ** PASS ** -Trial #020 OpenSSL: 321087.0us QAT: 130.9us Speed Up:2455.5x ** PASS ** -Trial #021 OpenSSL: 321788.1us QAT: 130.2us Speed Up:2477.0x ** PASS ** -Trial #022 OpenSSL: 326841.4us QAT: 129.8us Speed Up:2527.1x ** PASS ** -Trial #023 OpenSSL: 324096.7us QAT: 129.2us Speed Up:2515.6x ** PASS ** -Trial #024 OpenSSL: 321539.2us QAT: 128.6us Speed Up:2505.6x ** PASS ** -Trial #025 OpenSSL: 319053.6us QAT: 128.1us Speed Up:2494.7x ** PASS ** -Trial #026 OpenSSL: 323513.8us QAT: 128.0us Speed Up:2532.4x ** PASS ** -Trial #027 OpenSSL: 323800.1us QAT: 127.5us Speed Up:2545.4x ** PASS ** -Trial #028 OpenSSL: 321647.9us QAT: 127.3us Speed Up:2532.2x ** PASS ** -Trial #029 OpenSSL: 325392.3us QAT: 127.2us Speed Up:2564.7x ** PASS ** -Trial #030 OpenSSL: 323317.6us QAT: 126.9us Speed Up:2552.8x ** PASS ** -Trial #031 OpenSSL: 326790.2us QAT: 126.7us Speed Up:2584.7x ** PASS ** -Trial #032 OpenSSL: 330115.9us QAT: 126.6us Speed Up:2613.7x ** PASS ** -Trial #033 OpenSSL: 333228.6us QAT: 126.3us Speed Up:2646.3x ** PASS ** -Trial #034 OpenSSL: 333248.1us QAT: 126.2us Speed Up:2650.0x ** PASS ** -Trial #035 OpenSSL: 331228.4us QAT: 125.9us Speed Up:2637.7x ** PASS ** -Trial #036 OpenSSL: 329369.8us QAT: 125.7us Speed Up:2627.5x ** PASS ** -Trial #037 OpenSSL: 329385.2us QAT: 125.5us Speed Up:2632.3x ** PASS ** -Trial #038 OpenSSL: 332027.5us QAT: 125.5us Speed Up:2653.3x ** PASS ** -Trial #039 OpenSSL: 330198.7us QAT: 125.4us Speed Up:2638.6x ** PASS ** -Trial #040 OpenSSL: 328434.7us QAT: 125.2us Speed Up:2628.1x ** PASS ** -Trial #041 OpenSSL: 326827.1us QAT: 125.1us Speed Up:2617.0x ** PASS ** -Trial #042 OpenSSL: 325289.2us QAT: 124.9us Speed Up:2608.5x ** PASS ** -Trial #043 OpenSSL: 323772.6us QAT: 124.6us Speed Up:2602.5x ** PASS ** -Trial #044 OpenSSL: 322315.8us QAT: 124.6us Speed Up:2590.5x ** PASS ** -Trial #045 OpenSSL: 324769.4us QAT: 124.6us Speed Up:2609.8x ** PASS ** -Trial #046 OpenSSL: 323430.9us QAT: 124.4us Speed Up:2602.2x ** PASS ** -Trial #047 OpenSSL: 325711.1us QAT: 124.4us Speed Up:2622.3x ** PASS ** -Trial #048 OpenSSL: 324337.5us QAT: 124.3us Speed Up:2613.2x ** PASS ** -Trial #049 OpenSSL: 322987.7us QAT: 124.1us Speed Up:2604.2x ** PASS ** -Trial #050 OpenSSL: 323219.7us QAT: 124.0us Speed Up:2609.8x ** PASS ** -Trial #051 OpenSSL: 321979.6us QAT: 124.0us Speed Up:2598.7x ** PASS ** -Trial #052 OpenSSL: 320798.7us QAT: 123.9us Speed Up:2592.3x ** PASS ** -Trial #053 OpenSSL: 320210.6us QAT: 123.6us Speed Up:2593.8x ** PASS ** -Trial #054 OpenSSL: 318710.6us QAT: 123.6us Speed Up:2581.4x ** PASS ** -Trial #055 OpenSSL: 318970.7us QAT: 123.6us Speed Up:2583.0x ** PASS ** -Trial #056 OpenSSL: 319263.5us QAT: 123.6us Speed Up:2585.5x ** PASS ** -Trial #057 OpenSSL: 319510.1us QAT: 123.6us Speed Up:2587.2x ** PASS ** -Trial #058 OpenSSL: 318460.1us QAT: 123.5us Speed Up:2580.5x ** PASS ** -Trial #059 OpenSSL: 317523.4us QAT: 123.4us Speed Up:2575.1x ** PASS ** -Trial #060 OpenSSL: 317776.0us QAT: 123.2us Speed Up:2580.7x ** PASS ** -Trial #061 OpenSSL: 318061.2us QAT: 123.2us Speed Up:2584.2x ** PASS ** -Trial #062 OpenSSL: 318327.0us QAT: 123.0us Speed Up:2589.7x ** PASS ** -Trial #063 OpenSSL: 318595.2us QAT: 123.0us Speed Up:2591.9x ** PASS ** -Trial #064 OpenSSL: 320337.0us QAT: 123.1us Speed Up:2604.8x ** PASS ** -Trial #065 OpenSSL: 320581.9us QAT: 123.0us Speed Up:2609.7x ** PASS ** -Trial #066 OpenSSL: 319664.2us QAT: 122.8us Speed Up:2604.9x ** PASS ** -Trial #067 OpenSSL: 319857.5us QAT: 122.8us Speed Up:2606.4x ** PASS ** -Trial #068 OpenSSL: 320087.8us QAT: 122.8us Speed Up:2608.2x ** PASS ** -Trial #069 OpenSSL: 320303.8us QAT: 122.7us Speed Up:2613.1x ** PASS ** -Trial #070 OpenSSL: 321912.4us QAT: 122.7us Speed Up:2625.8x ** PASS ** -Trial #071 OpenSSL: 321058.5us QAT: 122.6us Speed Up:2619.8x ** PASS ** -Trial #072 OpenSSL: 322237.3us QAT: 122.4us Speed Up:2635.9x ** PASS ** -Trial #073 OpenSSL: 322737.3us QAT: 122.2us Speed Up:2645.2x ** PASS ** -Trial #074 OpenSSL: 322869.1us QAT: 122.2us Speed Up:2647.7x ** PASS ** -Trial #075 OpenSSL: 322004.4us QAT: 122.1us Speed Up:2641.8x ** PASS ** -Trial #076 OpenSSL: 323436.0us QAT: 122.1us Speed Up:2654.2x ** PASS ** -Trial #077 OpenSSL: 324792.0us QAT: 122.1us Speed Up:2664.7x ** PASS ** -Trial #078 OpenSSL: 323988.2us QAT: 122.0us Speed Up:2660.8x ** PASS ** -Trial #079 OpenSSL: 325378.7us QAT: 121.9us Speed Up:2673.1x ** PASS ** -Trial #080 OpenSSL: 326689.1us QAT: 122.0us Speed Up:2682.6x ** PASS ** -Trial #081 OpenSSL: 326746.4us QAT: 121.8us Speed Up:2686.1x ** PASS ** -Trial #082 OpenSSL: 325923.8us QAT: 121.8us Speed Up:2679.8x ** PASS ** -Trial #083 OpenSSL: 327205.9us QAT: 121.8us Speed Up:2690.9x ** PASS ** -Trial #084 OpenSSL: 327270.5us QAT: 121.7us Speed Up:2693.9x ** PASS ** -Trial #085 OpenSSL: 326480.3us QAT: 121.7us Speed Up:2687.6x ** PASS ** -Trial #086 OpenSSL: 325697.7us QAT: 121.7us Speed Up:2681.5x ** PASS ** -Trial #087 OpenSSL: 326916.1us QAT: 121.6us Speed Up:2693.6x ** PASS ** -Trial #088 OpenSSL: 328123.7us QAT: 121.6us Speed Up:2704.4x ** PASS ** -Trial #089 OpenSSL: 327356.1us QAT: 121.6us Speed Up:2697.7x ** PASS ** -Trial #090 OpenSSL: 326631.5us QAT: 121.5us Speed Up:2692.9x ** PASS ** -Trial #091 OpenSSL: 325878.2us QAT: 121.4us Speed Up:2688.2x ** PASS ** -Trial #092 OpenSSL: 327034.9us QAT: 121.5us Speed Up:2696.8x ** PASS ** -Trial #093 OpenSSL: 326317.0us QAT: 121.5us Speed Up:2689.7x ** PASS ** -Trial #094 OpenSSL: 326410.7us QAT: 121.4us Speed Up:2692.3x ** PASS ** -Trial #095 OpenSSL: 325728.4us QAT: 121.4us Speed Up:2687.7x ** PASS ** -Trial #096 OpenSSL: 325807.1us QAT: 121.4us Speed Up:2688.7x ** PASS ** -Trial #097 OpenSSL: 325119.7us QAT: 121.3us Speed Up:2683.7x ** PASS ** -Trial #098 OpenSSL: 324464.4us QAT: 121.3us Speed Up:2679.1x ** PASS ** -Trial #099 OpenSSL: 323807.6us QAT: 121.2us Speed Up:2674.3x ** PASS ** -Trial #100 OpenSSL: 323174.3us QAT: 121.3us Speed Up:2668.9x ** PASS ** diff --git a/profiling/README.md b/profiling/README.md deleted file mode 100644 index 40313d0..0000000 --- a/profiling/README.md +++ /dev/null @@ -1,2 +0,0 @@ -sudo ./telemetry_helper.sh 1 -watch -n.2 cat /sys/devices/pci0000:6b/0000:6b:00.0/telemetry/device_data diff --git a/samples/test_bnModExpBatch.cpp b/samples/test_bnModExpBatch.cpp deleted file mode 100644 index 998c706..0000000 --- a/samples/test_bnModExpBatch.cpp +++ /dev/null @@ -1,232 +0,0 @@ - -#include "he_qat_misc.h" -#include "he_qat_utils.h" -#include "he_qat_bn_ops.h" -#include "he_qat_context.h" -#include "cpa_sample_utils.h" - -#include -#include -#include -#include - -#include -#include -#include - -#ifdef _DESTINY_DEBUG_VERBOSE -int gDebugParam = 1; -#endif - -const unsigned int BATCH_SIZE = 8; - -int main(int argc, const char** argv) { - const int bit_length = 2048; - const size_t num_trials = 32; - - double avg_speed_up = 0.0; - double ssl_avg_time = 0.0; - double qat_avg_time = 0.0; - - clock_t start = CLOCKS_PER_SEC; - clock_t ssl_elapsed = CLOCKS_PER_SEC; - clock_t qat_elapsed = CLOCKS_PER_SEC; - - HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; - - // Set up QAT runtime context - acquire_qat_devices(); - - // Set up OpenSSL context (as baseline) - BN_CTX* ctx = BN_CTX_new(); - BN_CTX_start(ctx); - - for (unsigned int mod = 0; mod < num_trials; mod++) { - // Generate modulus number - BIGNUM* bn_mod = generateTestBNData(bit_length); - - if (!bn_mod) continue; - - char* bn_str = BN_bn2hex(bn_mod); -// printf("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, -// BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); - OPENSSL_free(bn_str); - - // Generate exponent in [0..bn_mod] - BIGNUM* bn_exponent = BN_new(); - if (!BN_rand_range(bn_exponent, bn_mod)) { - BN_free(bn_mod); - continue; - } - - // Generate base number - BIGNUM* bn_base = generateTestBNData(bit_length); - - // Perform OpenSSL ModExp Op - BIGNUM* ssl_res = BN_new(); - start = clock(); - BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); - ssl_elapsed = clock() - start; - - int len_ = (bit_length + 7) >> 3; - - // Start QAT timer (including data conversion overhead) - start = clock(); - - unsigned char* bn_base_data_ = - (unsigned char*)calloc(len_ * BATCH_SIZE, sizeof(unsigned char)); - if (NULL == bn_base_data_) exit(1); - for (unsigned int i = 0; i < BATCH_SIZE; i++) - BN_bn2binpad(bn_base, bn_base_data_+len_*i, len_); - unsigned char* bn_mod_data_ = - (unsigned char*)calloc(len_ * BATCH_SIZE, sizeof(unsigned char)); - if (NULL == bn_mod_data_) exit(1); - for (unsigned int i = 0; i < BATCH_SIZE; i++) - BN_bn2binpad(bn_mod, bn_mod_data_+len_*i, len_); - unsigned char* bn_exponent_data_ = - (unsigned char*)calloc(len_ * BATCH_SIZE, sizeof(unsigned char)); - if (NULL == bn_exponent_data_) exit(1); - for (unsigned int i = 0; i < BATCH_SIZE; i++) - BN_bn2binpad(bn_exponent, bn_exponent_data_+len_*i, len_); - unsigned char* bn_remainder_data_ = - (unsigned char*)calloc(len_ * BATCH_SIZE, sizeof(unsigned char)); - if (NULL == bn_remainder_data_) exit(1); - - clock_t cvt_elapsed = clock() - start; - - // Simulate input number in BigNumber representation - //BigNumber big_num_base((Ipp32u)0); - //BigNumber big_num_mod((Ipp32u)0); - //BigNumber big_num_exponent((Ipp32u)0); - std::vector big_num_base(BATCH_SIZE); - std::vector big_num_mod(BATCH_SIZE); - std::vector big_num_exponent(BATCH_SIZE); - - for (unsigned int i = 0; i < BATCH_SIZE; i++) { - status = binToBigNumber(big_num_base[i], bn_base_data_ + len_*i, bit_length); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("Failed at binToBigNumber()\n"); - exit(1); - } - status = binToBigNumber(big_num_mod[i], bn_mod_data_ + len_*i, bit_length); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("Failed at binToBigNumber()\n"); - exit(1); - } - status = binToBigNumber(big_num_exponent[i], bn_exponent_data_ + len_*i, bit_length); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("Failed at binToBigNumber()\n"); - exit(1); - } - - // Reset numbers to 0 - memset(bn_base_data_ + len_*i, 0, len_); - memset(bn_mod_data_ + len_*i, 0, len_); - memset(bn_exponent_data_ + len_*i, 0, len_); - // Make sure variables are reset - if (memcmp(bn_base_data_ + len_*i, bn_mod_data_ + len_*i, len_) || - memcmp(bn_base_data_ + len_*i, bn_exponent_data_ + len_*i, len_)) { - PRINT_ERR("Pointers are not reset to zero!"); - exit(1); - } - - start = clock(); - status = bigNumberToBin(bn_base_data_ + len_*i, bit_length, big_num_base[i]); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("bn_base_data_: failed at bignumbertobin()\n"); - exit(1); - } - status = bigNumberToBin(bn_mod_data_ + len_*i, bit_length, big_num_mod[i]); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("bn_base_data_: failed at bignumbertobin()\n"); - exit(1); - } - status = bigNumberToBin(bn_exponent_data_ + len_*i, bit_length, big_num_exponent[i]); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("bn_base_data_: failed at bignumbertobin()\n"); - exit(1); - } - cvt_elapsed += (clock() - start); - } - - // Perform BigNumber modular exponentiation on QAT - start = clock(); - for (unsigned int i = 0; i < BATCH_SIZE; i++) - status = HE_QAT_bnModExp(bn_remainder_data_ + len_*i, bn_base_data_ + len_*i, - bn_exponent_data_ + len_*i, bn_mod_data_ + len_*i, bit_length); - getBnModExpRequest(BATCH_SIZE); - qat_elapsed = clock() - start; - - printf("BigNumber data conversion overhead: %.1lfus.\n", - (cvt_elapsed / (CLOCKS_PER_SEC / 1000000.0))); - printf("BigNumber modular exponentiation on QAT: %.1lfus.\n", - (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); - qat_elapsed += cvt_elapsed; - - BIGNUM* qat_res = BN_new(); - BN_bin2bn(bn_remainder_data_, len_, qat_res); - - if (HE_QAT_STATUS_SUCCESS != status) { - PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); - } -#ifdef _DESTINY_DEBUG_VERBOSE - else { - PRINT_DBG("\nQAT bnModExpOp finished\n"); - } -#endif - - start = clock(); - BigNumber big_num((Ipp32u)0); - status = binToBigNumber(big_num, bn_remainder_data_, bit_length); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("bn_remainder_data_: Failed at bigNumberToBin()\n"); - exit(1); - } - qat_elapsed += (clock() - start); - printf("BigNumber ModExp total time: %.1lfus.\n", - (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); - -#ifdef _DESTINY_DEBUG_VERBOSE - bn_str = BN_bn2hex(qat_res); - printf("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, - BN_num_bytes(qat_res), BN_num_bits(qat_res)); -#endif - -#ifdef _DESTINY_DEBUG_VERBOSE - int bit_len = 0; - ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); - std::string str; - big_num.num2hex(str); - printf("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, - bit_len); - printf("---------------------################-----------------------\n"); -#endif - - if (BN_cmp(qat_res, ssl_res) != 0) - printf("\t** FAIL **\n"); - else - printf("\t** PASS **\n"); - - BN_free(bn_mod); - BN_free(bn_base); - BN_free(bn_exponent); - BN_free(qat_res); - BN_free(ssl_res); - -// OPENSSL_free(bn_str); - - free(bn_mod_data_); - free(bn_base_data_); - free(bn_exponent_data_); - free(bn_remainder_data_); - - } - - // Tear down OpenSSL context - BN_CTX_end(ctx); - - // Tear down QAT runtime context - release_qat_devices(); - - return (int)status; -} diff --git a/signit.txt b/signit.txt deleted file mode 100644 index 023b5bf..0000000 --- a/signit.txt +++ /dev/null @@ -1,2 +0,0 @@ -sudo chown fdiasmor $(tty) export GPG_TTY = - $(tty) git commit - S - m "Add initial 'code' to set up QAT context." diff --git a/start_qat_dev.sh b/start_qat_dev.sh deleted file mode 100755 index 429e54c..0000000 --- a/start_qat_dev.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/env bash - -start=$1 -stop=$2 -step=$3 -while [ $start -lt $stop ] -do - echo "start qat_dev$start" - sudo adf_ctl qat_dev$start up - start=`expr $start + $step` -done - diff --git a/stop_qat_dev.sh b/stop_qat_dev.sh deleted file mode 100755 index cd990c4..0000000 --- a/stop_qat_dev.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/env bash - -start=$1 -stop=$2 -step=$3 -while [ $start -lt $stop ] -do - echo "stop qat_dev$start" - sudo adf_ctl qat_dev$start down - start=`expr $start + $step` -done - diff --git a/telemetry_helper.sh b/telemetry_helper.sh deleted file mode 100755 index b8678d6..0000000 --- a/telemetry_helper.sh +++ /dev/null @@ -1,41 +0,0 @@ -#! /bin/bash - -# Command Line Parameters -# - 1 => Enable Telemetry -# - 0 => Disable Telemetry -if [ $# == 0 ]; -then - echo "telemetry helper usage:" - echo " ./telemetry_helper.sh 1 <= Enables Telemetry service on all QAT end points" - echo " ./telemetry_helper.sh 0 <= Disables Telemetry service on all QAT end points" - exit -fi - -# ensure cr/lf are not removed from lspci command -IFS= - -# Capture all QuickAssist Device id info to logfile -echo "$(lspci -d 8086:4940)" > pci_ids.txt -control_file_names=() - -# Parse the logfile extracting just the pci device ids to array -while IFS= read -r line; do - bus_num=${line:0:2} - control_file_name="/sys/devices/pci0000:"$bus_num"/0000:"$bus_num":00.0/telemetry/control" - control_file_names+=($control_file_name) - done < pci_ids.txt - - for ((i=0; i<${#control_file_names[@]}; i++)) - do - if [ $1 = 0 ]; - then - echo "Disabling telemetry for " ${control_file_names[$i]} - else - echo "Enabling telemetry for " ${control_file_names[$i]} - fi - echo $1 > ${control_file_names[$i]} - done - -# Remove temporary file -rm pci_ids.txt - From 0808b9f8a168c1711b6aad0543aefd33a6b60583 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 5 Aug 2022 15:34:38 -0700 Subject: [PATCH 212/364] Minor fix. --- cmake/he_qat/heqat-util.cmake | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 cmake/he_qat/heqat-util.cmake diff --git a/cmake/he_qat/heqat-util.cmake b/cmake/he_qat/heqat-util.cmake new file mode 100644 index 0000000..0b5ca8a --- /dev/null +++ b/cmake/he_qat/heqat-util.cmake @@ -0,0 +1,31 @@ +# Copyright (C) 2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Add dependency to the target archive +function(heqat_create_archive target dependency) + # For proper export of IPCLConfig.cmake / IPCLTargets.cmake, + # we avoid explicitly linking dependencies via target_link_libraries, since + # this would add dependencies to the exported ipcl target. + add_dependencies(${target} ${dependency}) + + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + add_custom_command(TARGET ${target} POST_BUILD + COMMAND ar -x $ + COMMAND ar -x $ + COMMAND ar -qcs $ *.o + COMMAND rm -f *.o + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${target} ${dependency} + ) + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + add_custom_command(TARGET ${target} POST_BUILD + COMMAND lib.exe /OUT:$ + $ + $ + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${target} ${dependency} + ) + else() + message(WARNING "Unsupported compiler ${CMAKE_CXX_COMPILER_ID}") + endif() +endfunction() From 8eef08da435297053b36cde49702aabc1a305076 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 5 Aug 2022 15:47:01 -0700 Subject: [PATCH 213/364] Revert "Minor fix." This reverts commit 5891a28435f556aacf39e7433e65bf1261596bd6. --- cmake/heqat/heqat.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/heqat/heqat.cmake b/cmake/heqat/heqat.cmake index 97f83d5..f59f028 100644 --- a/cmake/heqat/heqat.cmake +++ b/cmake/heqat/heqat.cmake @@ -38,7 +38,7 @@ if(IPCL_SHARED) ExternalProject_Get_Property(ext_he_qat SOURCE_DIR BINARY_DIR) - target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libcpa_sample_utils.a) + target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libcpa_sample_utils.so) if(CMAKE_BUILD_TYPE STREQUAL "Debug") target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat_debug.so) else() From 276fc81a5d3a5f33b04a37063d314660f789ecc1 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 5 Aug 2022 18:23:11 -0700 Subject: [PATCH 214/364] Update HE QAT Lib version. --- cmake/heqat/heqat.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/heqat/heqat.cmake b/cmake/heqat/heqat.cmake index f59f028..10205b2 100644 --- a/cmake/heqat/heqat.cmake +++ b/cmake/heqat/heqat.cmake @@ -5,7 +5,7 @@ include(ExternalProject) MESSAGE(STATUS "Configuring HE QAT") set(HEQAT_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_he_qat) set(HEQAT_GIT_REPO_URL git@github.com:intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.project-destiny.git) -set(HEQAT_GIT_LABEL development) +set(HEQAT_GIT_LABEL v1.0-pre-release) set(HEQAT_SRC_DIR ${HEQAT_PREFIX}/src/ext_he_qat/) set(HEQAT_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS}") From f4fd5bd55320e576161df4af00963b823f69e73b Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 19 Aug 2022 17:50:43 -0700 Subject: [PATCH 215/364] Decouple callback functions, global variables and global constants. --- he_qat/CMakeLists.txt | 4 +- he_qat/he_qat_bn_ops.c | 120 +++++---------------------------- he_qat/he_qat_cb.c | 110 ++++++++++++++++++++++++++++++ he_qat/he_qat_gvars.c | 20 ++++++ he_qat/include/he_qat_bn_ops.h | 42 +----------- he_qat/include/he_qat_gconst.h | 4 ++ he_qat/include/he_qat_types.h | 36 ++++++++++ 7 files changed, 191 insertions(+), 145 deletions(-) create mode 100644 he_qat/he_qat_cb.c create mode 100644 he_qat/he_qat_gvars.c create mode 100644 he_qat/include/he_qat_gconst.h diff --git a/he_qat/CMakeLists.txt b/he_qat/CMakeLists.txt index f8f22e9..724d038 100644 --- a/he_qat/CMakeLists.txt +++ b/he_qat/CMakeLists.txt @@ -1,5 +1,7 @@ -set(HE_QAT_SRC ${HE_QAT_SRC_DIR}/he_qat_bn_ops.c +set(HE_QAT_SRC ${HE_QAT_SRC_DIR}/he_qat_cb.c + ${HE_QAT_SRC_DIR}/he_qat_gvars.c + ${HE_QAT_SRC_DIR}/he_qat_bn_ops.c ${HE_QAT_SRC_DIR}/he_qat_context.c ${HE_QAT_SRC_DIR}/he_qat_utils.c ) diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index 0d276a0..4f8039b 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -18,6 +18,7 @@ double time_taken = 0.0; #include #include #include +#include #ifdef HE_QAT_SYNC_MODE #pragma message "Synchronous execution mode." @@ -25,69 +26,28 @@ double time_taken = 0.0; #pragma message "Asynchronous execution mode." #endif -#define RESTART_LATENCY_MICROSEC 600 -#define NUM_PKE_SLICES 6 +//#define RESTART_LATENCY_MICROSEC 600 +//#define NUM_PKE_SLICES 6 + +#include "he_qat_gconst.h" // Global buffer for the runtime environment HE_QAT_RequestBuffer he_qat_buffer; HE_QAT_OutstandingBuffer outstanding; -volatile unsigned long request_count = 0; -volatile unsigned long response_count = 0; -pthread_mutex_t response_mutex; +extern volatile unsigned long request_count; // = 0; +extern volatile unsigned long response_count; // = 0; +extern pthread_mutex_t response_mutex; -unsigned long request_latency = 0; // unused -unsigned long restart_threshold = NUM_PKE_SLICES;//48; -unsigned long max_pending = (NUM_PKE_SLICES * 2 * HE_QAT_NUM_ACTIVE_INSTANCES); // each QAT endpoint has 6 PKE slices - // single socket has 4 QAT endpoints (24 simultaneous requests) - // dual-socket has 8 QAT endpoints (48 simultaneous requests) - // max_pending = (num_sockets * num_qat_devices * num_pke_slices) / k - // k (default: 1) can be adjusted dynamically as the measured request_latency deviate from the hardware latency +extern unsigned long request_latency; // = 0; // unused +extern unsigned long restart_threshold; // = NUM_PKE_SLICES;//48; +extern unsigned long max_pending; // = (NUM_PKE_SLICES * 2 * HE_QAT_NUM_ACTIVE_INSTANCES); -/// @brief -/// @function -/// Callback function for lnModExpPerformOp. It performs any data processing -/// required after the modular exponentiation. -static void lnModExpCallback(void* pCallbackTag, // This type can be variable - CpaStatus status, - void* pOpData, // This is fixed -- please swap it - CpaFlatBuffer* pOut) { - HE_QAT_TaskRequest* request = NULL; - - // Check if input data for the op is available and do something - if (NULL != pCallbackTag) { - // Read request data - request = (HE_QAT_TaskRequest*)pCallbackTag; - - pthread_mutex_lock(&request->mutex); - // Collect the device output in pOut - request->op_status = status; - if (CPA_STATUS_SUCCESS == status) { - if (pOpData == request->op_data) { - // Mark request as complete or ready to be used - request->request_status = HE_QAT_STATUS_READY; - - BIGNUM* r = BN_bin2bn(request->op_result.pData, - request->op_result.dataLenInBytes, - (BIGNUM*)request->op_output); - if (NULL == r) - request->request_status = HE_QAT_STATUS_FAIL; - - } else { - request->request_status = HE_QAT_STATUS_FAIL; - } - } - // Make it synchronous and blocking - pthread_cond_signal(&request->ready); - pthread_mutex_unlock(&request->mutex); -#ifdef HE_QAT_SYNC_MODE - COMPLETE((struct COMPLETION_STRUCT*)&request->callback); -#endif - } +// Callback functions +extern void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut); +extern void HE_QAT_bnModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut); - return; -} /// @brief /// @function @@ -1082,7 +1042,8 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, } request->op_type = HE_QAT_OP_MODEXP; - request->callback_func = (void*)lnModExpCallback; + //request->callback_func = (void*)lnModExpCallback; + request->callback_func = (void*)HE_QAT_BIGNUMModExpCallback; request->op_status = status; request->op_output = (void*)r; @@ -1269,55 +1230,6 @@ void getBnModExpRequest(unsigned int batch_size) { return; } -/// @brief -/// @function -/// Callback function for HE_QAT_bnModExp. It performs any data processing -/// required after the modular exponentiation. -static void HE_QAT_bnModExpCallback( - void* pCallbackTag, // This type can be variable - CpaStatus status, - void* pOpData, // This is fixed -- please swap it - CpaFlatBuffer* pOut) { - HE_QAT_TaskRequest* request = NULL; - - // Check if input data for the op is available and do something - if (NULL != pCallbackTag) { - // Read request data - request = (HE_QAT_TaskRequest*)pCallbackTag; - - pthread_mutex_lock(&response_mutex); - // Global track of reponses by accelerator - response_count += 1; - pthread_mutex_unlock(&response_mutex); - - pthread_mutex_lock(&request->mutex); - // Collect the device output in pOut - request->op_status = status; - if (CPA_STATUS_SUCCESS == status) { - if (pOpData == request->op_data) { - // Mark request as complete or ready to be used - request->request_status = HE_QAT_STATUS_READY; - // Copy compute results to output destination - memcpy(request->op_output, request->op_result.pData, - request->op_result.dataLenInBytes); -// printf("Request ID %llu Completed.\n",request->id); -#ifdef HE_QAT_PERF - gettimeofday(&request->end, NULL); -#endif - } else { - request->request_status = HE_QAT_STATUS_FAIL; - } - } - // Make it synchronous and blocking - pthread_cond_signal(&request->ready); - pthread_mutex_unlock(&request->mutex); -#ifdef HE_QAT_SYNC_MODE - COMPLETE((struct COMPLETION_STRUCT*)&request->callback); -#endif - } - - return; -} HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, unsigned char* e, unsigned char* m, int nbits) { diff --git a/he_qat/he_qat_cb.c b/he_qat/he_qat_cb.c new file mode 100644 index 0000000..916ee73 --- /dev/null +++ b/he_qat/he_qat_cb.c @@ -0,0 +1,110 @@ +// qatlib headers +#include +#include + +// C library +#include +#include + +// local headers +#include "he_qat_types.h" + +// Global variables +extern volatile unsigned long request_count; // = 0; +extern volatile unsigned long response_count; // = 0; +extern pthread_mutex_t response_mutex; + +/// @brief +/// @function +/// Callback function for lnModExpPerformOp. It performs any data processing +/// required after the modular exponentiation. +void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, + CpaStatus status, + void* pOpData, + CpaFlatBuffer* pOut) { + HE_QAT_TaskRequest* request = NULL; + + // Check if input data for the op is available and do something + if (NULL != pCallbackTag) { + // Read request data + request = (HE_QAT_TaskRequest*)pCallbackTag; + + pthread_mutex_lock(&request->mutex); + // Collect the device output in pOut + request->op_status = status; + if (CPA_STATUS_SUCCESS == status) { + if (pOpData == request->op_data) { + // Mark request as complete or ready to be used + request->request_status = HE_QAT_STATUS_READY; + + BIGNUM* r = BN_bin2bn(request->op_result.pData, + request->op_result.dataLenInBytes, + (BIGNUM*)request->op_output); + if (NULL == r) + request->request_status = HE_QAT_STATUS_FAIL; + + } else { + request->request_status = HE_QAT_STATUS_FAIL; + } + } + // Make it synchronous and blocking + pthread_cond_signal(&request->ready); + pthread_mutex_unlock(&request->mutex); +#ifdef HE_QAT_SYNC_MODE + COMPLETE((struct COMPLETION_STRUCT*)&request->callback); +#endif + } + + return; +} + + +/// @brief +/// @function +/// Callback function for HE_QAT_bnModExp. It performs any data processing +/// required after the modular exponentiation. +void HE_QAT_bnModExpCallback( + void* pCallbackTag, // This type can be variable + CpaStatus status, + void* pOpData, // This is fixed -- please swap it + CpaFlatBuffer* pOut) { + HE_QAT_TaskRequest* request = NULL; + + // Check if input data for the op is available and do something + if (NULL != pCallbackTag) { + // Read request data + request = (HE_QAT_TaskRequest*)pCallbackTag; + + pthread_mutex_lock(&response_mutex); + // Global track of reponses by accelerator + response_count += 1; + pthread_mutex_unlock(&response_mutex); + + pthread_mutex_lock(&request->mutex); + // Collect the device output in pOut + request->op_status = status; + if (CPA_STATUS_SUCCESS == status) { + if (pOpData == request->op_data) { + // Mark request as complete or ready to be used + request->request_status = HE_QAT_STATUS_READY; + // Copy compute results to output destination + memcpy(request->op_output, request->op_result.pData, + request->op_result.dataLenInBytes); +// printf("Request ID %llu Completed.\n",request->id); +#ifdef HE_QAT_PERF + gettimeofday(&request->end, NULL); +#endif + } else { + request->request_status = HE_QAT_STATUS_FAIL; + } + } + // Make it synchronous and blocking + pthread_cond_signal(&request->ready); + pthread_mutex_unlock(&request->mutex); +#ifdef HE_QAT_SYNC_MODE + COMPLETE((struct COMPLETION_STRUCT*)&request->callback); +#endif + } + + return; +} diff --git a/he_qat/he_qat_gvars.c b/he_qat/he_qat_gvars.c new file mode 100644 index 0000000..6d37e34 --- /dev/null +++ b/he_qat/he_qat_gvars.c @@ -0,0 +1,20 @@ +#include + +#include "he_qat_types.h" +#include "he_qat_gconst.h" + +pthread_mutex_t response_mutex; + +volatile unsigned long request_count = 0; +volatile unsigned long response_count = 0; + +unsigned long request_latency = 0; // unused +unsigned long restart_threshold = NUM_PKE_SLICES; // 48; + +unsigned long max_pending = (NUM_PKE_SLICES * 2 * HE_QAT_NUM_ACTIVE_INSTANCES); + +// Each QAT endpoint has 6 PKE slices +// -- single socket has 4 QAT endpoints (24 simultaneous requests) +// -- dual-socket has 8 QAT endpoints (48 simultaneous requests) +// -- max_pending = (num_sockets * num_qat_devices * num_pke_slices) / k +// -- k (default: 1) can be adjusted dynamically as the measured request_latency deviate from the hardware latency diff --git a/he_qat/include/he_qat_bn_ops.h b/he_qat/include/he_qat_bn_ops.h index 2ebda91..f47bbaf 100644 --- a/he_qat/include/he_qat_bn_ops.h +++ b/he_qat/include/he_qat_bn_ops.h @@ -9,51 +9,13 @@ extern "C" { #endif -#include "cpa.h" -#include "cpa_cy_ln.h" - #include "he_qat_types.h" -#include "cpa_sample_utils.h" -#include - -#ifdef HE_QAT_PERF -#include -#endif +//#include "cpa_sample_utils.h" +//#include //#include #include -// #include "bignum.h" or create a standard interface - -#define HE_QAT_MAX_RETRY 100 - -// One for each consumer -typedef struct { - unsigned long long id; - // sem_t callback; - struct COMPLETION_STRUCT callback; - HE_QAT_OP op_type; - CpaStatus op_status; - CpaFlatBuffer op_result; - // CpaCyLnModExpOpData op_data; - void* op_data; - void* op_output; - void* callback_func; - volatile HE_QAT_STATUS request_status; - pthread_mutex_t mutex; - pthread_cond_t ready; -#ifdef HE_QAT_PERF - struct timeval start; - struct timeval end; -#endif -} HE_QAT_TaskRequest; - -// One for each consumer -typedef struct { - HE_QAT_TaskRequest* request[HE_QAT_BUFFER_SIZE]; - unsigned int count; -} HE_QAT_TaskRequestList; - /// @brief /// @function /// Perform big number modular exponentiation for input data in diff --git a/he_qat/include/he_qat_gconst.h b/he_qat/include/he_qat_gconst.h new file mode 100644 index 0000000..9d681e3 --- /dev/null +++ b/he_qat/include/he_qat_gconst.h @@ -0,0 +1,4 @@ + +#define RESTART_LATENCY_MICROSEC 600 +#define NUM_PKE_SLICES 6 + diff --git a/he_qat/include/he_qat_types.h b/he_qat/include/he_qat_types.h index 02f49ca..e49b8ba 100644 --- a/he_qat/include/he_qat_types.h +++ b/he_qat/include/he_qat_types.h @@ -8,14 +8,23 @@ extern "C" { #endif +// QATLib Headers #include "cpa.h" #include "cpa_cy_im.h" +#include "cpa_cy_ln.h" +#include "cpa_sample_utils.h" +// C Libraries #include +#ifdef HE_QAT_PERF +#include +#endif +// Local Constants #define HE_QAT_NUM_ACTIVE_INSTANCES 8 #define HE_QAT_BUFFER_SIZE 1024 #define HE_QAT_BUFFER_COUNT HE_QAT_NUM_ACTIVE_INSTANCES +#define HE_QAT_MAX_RETRY 100 // Type definitions typedef enum { HE_QAT_SYNC = 1, HE_QAT_ASYNC = 2 } HE_QAT_EXEC_MODE; @@ -93,6 +102,33 @@ typedef struct { unsigned int count; } HE_QAT_Config; +// One for each consumer +typedef struct { + unsigned long long id; + // sem_t callback; + struct COMPLETION_STRUCT callback; + HE_QAT_OP op_type; + CpaStatus op_status; + CpaFlatBuffer op_result; + // CpaCyLnModExpOpData op_data; + void* op_data; + void* op_output; + void* callback_func; + volatile HE_QAT_STATUS request_status; + pthread_mutex_t mutex; + pthread_cond_t ready; +#ifdef HE_QAT_PERF + struct timeval start; + struct timeval end; +#endif +} HE_QAT_TaskRequest; + +// One for each consumer +typedef struct { + HE_QAT_TaskRequest* request[HE_QAT_BUFFER_SIZE]; + unsigned int count; +} HE_QAT_TaskRequestList; + #ifdef __cplusplus } // close the extern "C" { #endif From a4fc087be928df268174805165716d8a373f73a3 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 24 Aug 2022 19:28:07 -0700 Subject: [PATCH 216/364] Remove global variables from separate source file. --- he_qat/CMakeLists.txt | 1 - he_qat/he_qat_bn_ops.c | 13 +++++-------- he_qat/he_qat_cb.c | 10 +++++++--- he_qat/he_qat_context.c | 16 ++++++++-------- he_qat/he_qat_gvars.c | 20 -------------------- 5 files changed, 20 insertions(+), 40 deletions(-) delete mode 100644 he_qat/he_qat_gvars.c diff --git a/he_qat/CMakeLists.txt b/he_qat/CMakeLists.txt index 724d038..4071d0e 100644 --- a/he_qat/CMakeLists.txt +++ b/he_qat/CMakeLists.txt @@ -1,6 +1,5 @@ set(HE_QAT_SRC ${HE_QAT_SRC_DIR}/he_qat_cb.c - ${HE_QAT_SRC_DIR}/he_qat_gvars.c ${HE_QAT_SRC_DIR}/he_qat_bn_ops.c ${HE_QAT_SRC_DIR}/he_qat_context.c ${HE_QAT_SRC_DIR}/he_qat_utils.c diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index 4f8039b..c70a934 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -35,14 +35,11 @@ double time_taken = 0.0; HE_QAT_RequestBuffer he_qat_buffer; HE_QAT_OutstandingBuffer outstanding; -extern volatile unsigned long request_count; // = 0; -extern volatile unsigned long response_count; // = 0; -extern pthread_mutex_t response_mutex; - -extern unsigned long request_latency; // = 0; // unused -extern unsigned long restart_threshold; // = NUM_PKE_SLICES;//48; - -extern unsigned long max_pending; // = (NUM_PKE_SLICES * 2 * HE_QAT_NUM_ACTIVE_INSTANCES); +volatile unsigned long response_count = 0; +static volatile unsigned long request_count = 0; +static unsigned long request_latency = 0; // unused +static unsigned long restart_threshold = NUM_PKE_SLICES;//48; +static unsigned long max_pending = (NUM_PKE_SLICES * 2 * HE_QAT_NUM_ACTIVE_INSTANCES); // Callback functions extern void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut); diff --git a/he_qat/he_qat_cb.c b/he_qat/he_qat_cb.c index 916ee73..4aad411 100644 --- a/he_qat/he_qat_cb.c +++ b/he_qat/he_qat_cb.c @@ -10,9 +10,8 @@ #include "he_qat_types.h" // Global variables -extern volatile unsigned long request_count; // = 0; -extern volatile unsigned long response_count; // = 0; -extern pthread_mutex_t response_mutex; +static pthread_mutex_t response_mutex; +extern volatile unsigned long response_count; /// @brief /// @function @@ -28,6 +27,11 @@ void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, if (NULL != pCallbackTag) { // Read request data request = (HE_QAT_TaskRequest*)pCallbackTag; + + pthread_mutex_lock(&response_mutex); + // Global track of reponses by accelerator + response_count += 1; + pthread_mutex_unlock(&response_mutex); pthread_mutex_lock(&request->mutex); // Collect the device output in pOut diff --git a/he_qat/he_qat_context.c b/he_qat/he_qat_context.c index 85e9da5..9067d52 100644 --- a/he_qat/he_qat_context.c +++ b/he_qat/he_qat_context.c @@ -24,15 +24,15 @@ #define MAX_INSTANCES 1 #endif -volatile int context_state = 0; +static volatile int context_state = 0; // Global variable declarations -pthread_t buffer_manager; -pthread_t he_qat_runner; -HE_QAT_Inst he_qat_instances[HE_QAT_NUM_ACTIVE_INSTANCES]; -pthread_attr_t he_qat_inst_attr[HE_QAT_NUM_ACTIVE_INSTANCES]; -HE_QAT_InstConfig he_qat_inst_config[HE_QAT_NUM_ACTIVE_INSTANCES]; -HE_QAT_Config* he_qat_config = NULL; +static pthread_t buffer_manager; +static pthread_t he_qat_runner; +static HE_QAT_Inst he_qat_instances[HE_QAT_NUM_ACTIVE_INSTANCES]; +static pthread_attr_t he_qat_inst_attr[HE_QAT_NUM_ACTIVE_INSTANCES]; +static HE_QAT_InstConfig he_qat_inst_config[HE_QAT_NUM_ACTIVE_INSTANCES]; +static HE_QAT_Config* he_qat_config = NULL; extern HE_QAT_RequestBuffer he_qat_buffer; extern HE_QAT_OutstandingBuffer outstanding; @@ -51,7 +51,7 @@ extern void stop_perform_op(void* _inst_config, unsigned num_inst); // WARNING: Deprecated when "start_instances" becomes default. extern void* start_perform_op(void* _inst_config); -CpaInstanceHandle handle = NULL; +static CpaInstanceHandle handle = NULL; static CpaInstanceHandle get_qat_instance() { static CpaInstanceHandle cyInstHandles[MAX_INSTANCES]; diff --git a/he_qat/he_qat_gvars.c b/he_qat/he_qat_gvars.c deleted file mode 100644 index 6d37e34..0000000 --- a/he_qat/he_qat_gvars.c +++ /dev/null @@ -1,20 +0,0 @@ -#include - -#include "he_qat_types.h" -#include "he_qat_gconst.h" - -pthread_mutex_t response_mutex; - -volatile unsigned long request_count = 0; -volatile unsigned long response_count = 0; - -unsigned long request_latency = 0; // unused -unsigned long restart_threshold = NUM_PKE_SLICES; // 48; - -unsigned long max_pending = (NUM_PKE_SLICES * 2 * HE_QAT_NUM_ACTIVE_INSTANCES); - -// Each QAT endpoint has 6 PKE slices -// -- single socket has 4 QAT endpoints (24 simultaneous requests) -// -- dual-socket has 8 QAT endpoints (48 simultaneous requests) -// -- max_pending = (num_sockets * num_qat_devices * num_pke_slices) / k -// -- k (default: 1) can be adjusted dynamically as the measured request_latency deviate from the hardware latency From 319a947186fb172c81627e081985aa7d03297e3d Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Thu, 25 Aug 2022 14:43:26 +0800 Subject: [PATCH 217/364] Apply public repo changes to internal repo (#124) * ModExp function: remove padding & code clean * unittests: corner case fix --- ipcl/include/ipcl/mod_exp.hpp | 16 +-- ipcl/mod_exp.cpp | 209 ++++++++++++++++------------------ test/test_cryptography.cpp | 6 +- test/test_ops.cpp | 2 +- 4 files changed, 110 insertions(+), 123 deletions(-) diff --git a/ipcl/include/ipcl/mod_exp.hpp b/ipcl/include/ipcl/mod_exp.hpp index 810ff27..0419e60 100644 --- a/ipcl/include/ipcl/mod_exp.hpp +++ b/ipcl/include/ipcl/mod_exp.hpp @@ -12,23 +12,23 @@ namespace ipcl { /** * Modular exponentiation for multi buffer * @param[in] base base of the exponentiation - * @param[in] pow pow of the exponentiation - * @param[in] m modular + * @param[in] exp pow of the exponentiation + * @param[in] mod modular * @return the modular exponentiation result of type BigNumber */ std::vector ippModExp(const std::vector& base, - const std::vector& pow, - const std::vector& m); + const std::vector& exp, + const std::vector& mod); /** * Modular exponentiation for single buffer * @param[in] base base of the exponentiation - * @param[in] pow pow of the exponentiation - * @param[in] m modular + * @param[in] exp pow of the exponentiation + * @param[in] mod modular * @return the modular exponentiation result of type BigNumber */ -BigNumber ippModExp(const BigNumber& base, const BigNumber& pow, - const BigNumber& m); +BigNumber ippModExp(const BigNumber& base, const BigNumber& exp, + const BigNumber& mod); } // namespace ipcl #endif // IPCL_INCLUDE_IPCL_MOD_EXP_HPP_ diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index d7fd91a..cdb729d 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -14,124 +14,131 @@ namespace ipcl { static std::vector ippMBModExp(const std::vector& base, - const std::vector& pow, - const std::vector& m) { - VEC_SIZE_CHECK(base); - VEC_SIZE_CHECK(pow); - VEC_SIZE_CHECK(m); + const std::vector& exp, + const std::vector& mod) { + std::size_t real_v_size = base.size(); + std::size_t pow_v_size = exp.size(); + std::size_t mod_v_size = mod.size(); + ERROR_CHECK((real_v_size == pow_v_size) && (pow_v_size == mod_v_size) && + (real_v_size <= IPCL_CRYPTO_MB_SIZE), + "ippMBModExp: input vector size error"); mbx_status st = MBX_STATUS_OK; - int bits = m.front().BitSize(); - int dwords = BITSIZE_DWORD(bits); - int bufferLen = mbx_exp_BufferSize(bits); - auto buffer = std::vector(bufferLen); - - std::vector out_x(IPCL_CRYPTO_MB_SIZE); - std::vector b_array(IPCL_CRYPTO_MB_SIZE); - std::vector p_array(IPCL_CRYPTO_MB_SIZE); - - int mem_pool_size = IPCL_CRYPTO_MB_SIZE * dwords; - std::vector out_mem_pool(mem_pool_size); - std::vector base_mem_pool(mem_pool_size); - std::vector pow_mem_pool(mem_pool_size); - - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - out_x[i] = &out_mem_pool[i * dwords]; - b_array[i] = &base_mem_pool[i * dwords]; - p_array[i] = &pow_mem_pool[i * dwords]; - } - /* - * These two intermediate variables pow_b & pow_p are necessary + * These two intermediate variables base_data & exp_data are necessary * because if they are not used, the length returned from ippsRef_BN - * will be inconsistent with the length allocated by b_array/p_array, + * will be inconsistent with the length allocated by base_pa/exp_pa, * resulting in data errors. */ - std::vector pow_b(IPCL_CRYPTO_MB_SIZE); - std::vector pow_p(IPCL_CRYPTO_MB_SIZE); - std::vector pow_nsquare(IPCL_CRYPTO_MB_SIZE); - std::vector b_size_v(IPCL_CRYPTO_MB_SIZE); - std::vector p_size_v(IPCL_CRYPTO_MB_SIZE); - std::vector n_size_v(IPCL_CRYPTO_MB_SIZE); + std::vector base_data(IPCL_CRYPTO_MB_SIZE); + std::vector exp_data(IPCL_CRYPTO_MB_SIZE); + std::vector mod_data(IPCL_CRYPTO_MB_SIZE); + std::vector base_bits_v(IPCL_CRYPTO_MB_SIZE); + std::vector exp_bits_v(IPCL_CRYPTO_MB_SIZE); + std::vector mod_bits_v(IPCL_CRYPTO_MB_SIZE); + + for (int i = 0; i < real_v_size; i++) { + ippsRef_BN(nullptr, &base_bits_v[i], + reinterpret_cast(&base_data[i]), base[i]); + ippsRef_BN(nullptr, &exp_bits_v[i], + reinterpret_cast(&exp_data[i]), exp[i]); + ippsRef_BN(nullptr, &mod_bits_v[i], &mod_data[i], mod[i]); + } + + // Find the longest size of module and power + auto longest_mod_it = std::max_element(mod_bits_v.begin(), mod_bits_v.end()); + auto longest_mod_idx = std::distance(mod_bits_v.begin(), longest_mod_it); + BigNumber longest_mod = mod[longest_mod_idx]; + int mod_bits = *longest_mod_it; + int exp_bits = *std::max_element(exp_bits_v.begin(), exp_bits_v.end()); + + std::vector out_pa(IPCL_CRYPTO_MB_SIZE); + std::vector base_pa(IPCL_CRYPTO_MB_SIZE); + std::vector exp_pa(IPCL_CRYPTO_MB_SIZE); + + int mod_dwords = BITSIZE_DWORD(mod_bits); + int num_buff = IPCL_CRYPTO_MB_SIZE * mod_dwords; + std::vector out_buff(num_buff); + std::vector base_buff(num_buff); + std::vector exp_buff(num_buff); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - ippsRef_BN(nullptr, &b_size_v[i], reinterpret_cast(&pow_b[i]), - base[i]); - ippsRef_BN(nullptr, &p_size_v[i], reinterpret_cast(&pow_p[i]), - pow[i]); - ippsRef_BN(nullptr, &n_size_v[i], &pow_nsquare[i], m[i]); - - memcpy(b_array[i], pow_b[i], BITSIZE_WORD(b_size_v[i]) * 4); - memcpy(p_array[i], pow_p[i], BITSIZE_WORD(p_size_v[i]) * 4); + auto idx = i * mod_dwords; + out_pa[i] = &out_buff[idx]; + base_pa[i] = &base_buff[idx]; + exp_pa[i] = &exp_buff[idx]; } - // Find the biggest size of module and exp - int nsqBitLen = *std::max_element(n_size_v.begin(), n_size_v.end()); - int expBitLen = *std::max_element(p_size_v.begin(), p_size_v.end()); + for (int i = 0; i < real_v_size; i++) { + memcpy(base_pa[i], base_data[i], BITSIZE_WORD(base_bits_v[i]) * 4); + memcpy(exp_pa[i], exp_data[i], BITSIZE_WORD(exp_bits_v[i]) * 4); + } + int work_buff_size = mbx_exp_BufferSize(mod_bits); + auto work_buff = std::vector(work_buff_size); // If actual sizes of modules are different, // set the mod_bits parameter equal to maximum size of the actual module in // bit size and extend all the modules with zero bits to the mod_bits value. // The same is applicable for the exp_bits parameter and actual exponents. - st = mbx_exp_mb8(out_x.data(), b_array.data(), p_array.data(), expBitLen, - reinterpret_cast(pow_nsquare.data()), nsqBitLen, - reinterpret_cast(buffer.data()), bufferLen); + st = mbx_exp_mb8(out_pa.data(), base_pa.data(), exp_pa.data(), exp_bits, + reinterpret_cast(mod_data.data()), mod_bits, + reinterpret_cast(work_buff.data()), work_buff_size); - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + for (int i = 0; i < real_v_size; i++) { ERROR_CHECK(MBX_STATUS_OK == MBX_GET_STS(st, i), std::string("ippMultiBuffExp: error multi buffered exp " "modules, error code = ") + std::to_string(MBX_GET_STS(st, i))); } - // It is important to hold a copy of nsquare for thread-safe purpose - std::vector res(IPCL_CRYPTO_MB_SIZE, m.front()); - - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - res[i].Set(reinterpret_cast(out_x[i]), BITSIZE_WORD(nsqBitLen), + // Init res with longest mod value to ensure each + // Big number has enough space. + std::vector res(real_v_size, longest_mod); + for (int i = 0; i < real_v_size; i++) { + res[i].Set(reinterpret_cast(out_pa[i]), BITSIZE_WORD(mod_bits), IppsBigNumPOS); } return res; } -static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, - const BigNumber& m) { +static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& exp, + const BigNumber& mod) { IppStatus stat = ippStsNoErr; // It is important to declare res * bform bit length refer to ipp-crypto spec: // R should not be less than the data length of the modulus m - BigNumber res(m); + BigNumber res(mod); - int bnBitLen; - Ipp32u* pow_m; - ippsRef_BN(nullptr, &bnBitLen, &pow_m, BN(m)); - int nlen = BITSIZE_WORD(bnBitLen); + int mod_bits; + Ipp32u* mod_data; + ippsRef_BN(nullptr, &mod_bits, &mod_data, BN(mod)); + int mod_words = BITSIZE_WORD(mod_bits); int size; // define and initialize Montgomery Engine over Modulus N - stat = ippsMontGetSize(IppsBinaryMethod, nlen, &size); + stat = ippsMontGetSize(IppsBinaryMethod, mod_words, &size); ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: get the size of IppsMontState context error."); auto pMont = std::vector(size); - stat = ippsMontInit(IppsBinaryMethod, nlen, + stat = ippsMontInit(IppsBinaryMethod, mod_words, reinterpret_cast(pMont.data())); ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: init Mont context error."); - stat = - ippsMontSet(pow_m, nlen, reinterpret_cast(pMont.data())); + stat = ippsMontSet(mod_data, mod_words, + reinterpret_cast(pMont.data())); ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: set Mont input error."); // encode base into Montgomery form - BigNumber bform(m); + BigNumber bform(mod); stat = ippsMontForm(BN(base), reinterpret_cast(pMont.data()), BN(bform)); ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: convert big number into Mont form error."); // compute R = base^pow mod N - stat = ippsMontExp(BN(bform), BN(pow), + stat = ippsMontExp(BN(bform), BN(exp), reinterpret_cast(pMont.data()), BN(res)); ERROR_CHECK(stat == ippStsNoErr, std::string("ippsMontExp: error code = ") + std::to_string(stat)); @@ -148,8 +155,8 @@ static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, } std::vector ippModExp(const std::vector& base, - const std::vector& pow, - const std::vector& m) { + const std::vector& exp, + const std::vector& mod) { std::size_t v_size = base.size(); std::vector res(v_size); @@ -157,13 +164,13 @@ std::vector ippModExp(const std::vector& base, // If there is only 1 big number, we don't need to use MBModExp if (v_size == 1) { - res[0] = ippSBModExp(base[0], pow[0], m[0]); + res[0] = ippSBModExp(base[0], exp[0], mod[0]); return res; } - std::size_t offset = 0; - std::size_t num_chunk = v_size / IPCL_CRYPTO_MB_SIZE; std::size_t remainder = v_size % IPCL_CRYPTO_MB_SIZE; + std::size_t num_chunk = + (v_size + IPCL_CRYPTO_MB_SIZE - 1) / IPCL_CRYPTO_MB_SIZE; #ifdef IPCL_USE_OMP int omp_remaining_threads = OMPUtilities::MaxThreads; @@ -171,49 +178,26 @@ std::vector ippModExp(const std::vector& base, OMPUtilities::assignOMPThreads(omp_remaining_threads, num_chunk)) #endif // IPCL_USE_OMP for (std::size_t i = 0; i < num_chunk; i++) { - auto base_start = base.begin() + i * IPCL_CRYPTO_MB_SIZE; - auto base_end = base_start + IPCL_CRYPTO_MB_SIZE; + std::size_t chunk_size = IPCL_CRYPTO_MB_SIZE; + if ((i == (num_chunk - 1)) && (remainder > 0)) chunk_size = remainder; - auto pow_start = pow.begin() + i * IPCL_CRYPTO_MB_SIZE; - auto pow_end = pow_start + IPCL_CRYPTO_MB_SIZE; + std::size_t chunk_offset = i * IPCL_CRYPTO_MB_SIZE; - auto m_start = m.begin() + i * IPCL_CRYPTO_MB_SIZE; - auto m_end = m_start + IPCL_CRYPTO_MB_SIZE; + auto base_start = base.begin() + chunk_offset; + auto base_end = base_start + chunk_size; - auto base_chunk = std::vector(base_start, base_end); - auto pow_chunk = std::vector(pow_start, pow_end); - auto m_chunk = std::vector(m_start, m_end); - - auto tmp = ippMBModExp(base_chunk, pow_chunk, m_chunk); - std::copy(tmp.begin(), tmp.end(), res.begin() + i * IPCL_CRYPTO_MB_SIZE); - } + auto exp_start = exp.begin() + chunk_offset; + auto exp_end = exp_start + chunk_size; - offset = num_chunk * IPCL_CRYPTO_MB_SIZE; - // If only 1 big number left, we don't need to make padding - if (remainder == 1) - res[offset] = ippSBModExp(base[offset], pow[offset], m[offset]); + auto mod_start = mod.begin() + chunk_offset; + auto mod_end = mod_start + chunk_size; - // If the 1 < remainder < IPCL_CRYPTO_MB_SIZE, we need to make padding - if (remainder > 1) { - auto base_start = base.begin() + offset; - auto base_end = base_start + remainder; - - auto pow_start = pow.begin() + offset; - auto pow_end = pow_start + remainder; - - auto m_start = m.begin() + offset; - auto m_end = m_start + remainder; - - std::vector base_chunk(IPCL_CRYPTO_MB_SIZE, 0); - std::vector pow_chunk(IPCL_CRYPTO_MB_SIZE, 0); - std::vector m_chunk(IPCL_CRYPTO_MB_SIZE, 0); - - std::copy(base_start, base_end, base_chunk.begin()); - std::copy(pow_start, pow_end, pow_chunk.begin()); - std::copy(m_start, m_end, m_chunk.begin()); + auto base_chunk = std::vector(base_start, base_end); + auto exp_chunk = std::vector(exp_start, exp_end); + auto mod_chunk = std::vector(mod_start, mod_end); - auto tmp = ippMBModExp(base_chunk, pow_chunk, m_chunk); - std::copy(tmp.begin(), tmp.begin() + remainder, res.begin() + offset); + auto tmp = ippMBModExp(base_chunk, exp_chunk, mod_chunk); + std::copy(tmp.begin(), tmp.end(), res.begin() + chunk_offset); } return res; @@ -225,15 +209,16 @@ std::vector ippModExp(const std::vector& base, #pragma omp parallel for num_threads( \ OMPUtilities::assignOMPThreads(omp_remaining_threads, v_size)) #endif // IPCL_USE_OMP - for (int i = 0; i < v_size; i++) res[i] = ippSBModExp(base[i], pow[i], m[i]); + for (int i = 0; i < v_size; i++) + res[i] = ippSBModExp(base[i], exp[i], mod[i]); return res; #endif // IPCL_CRYPTO_MB_MOD_EXP } -BigNumber ippModExp(const BigNumber& base, const BigNumber& pow, - const BigNumber& m) { - return ippSBModExp(base, pow, m); +BigNumber ippModExp(const BigNumber& base, const BigNumber& exp, + const BigNumber& mod) { + return ippSBModExp(base, exp, mod); } } // namespace ipcl diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index eaaf3e3..abe0928 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -11,7 +11,7 @@ #include "ipcl/keygen.hpp" #include "ipcl/plaintext.hpp" -constexpr int SELF_DEF_NUM_VALUES = 20; +constexpr int SELF_DEF_NUM_VALUES = 9; TEST(CryptoTest, CryptoTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; @@ -45,7 +45,9 @@ TEST(CryptoTest, CryptoTest) { } TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { - const uint32_t num_values = SELF_DEF_NUM_VALUES; + // Ensure that at least 2 different numbers are encrypted + // Because ir_bn_v[1] will set to a specific value + const uint32_t num_values = SELF_DEF_NUM_VALUES + 1; BigNumber p = "0xff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c" diff --git a/test/test_ops.cpp b/test/test_ops.cpp index 30ad188..862f1f4 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -11,7 +11,7 @@ #include "ipcl/keygen.hpp" #include "ipcl/plaintext.hpp" -constexpr int SELF_DEF_NUM_VALUES = 20; +constexpr int SELF_DEF_NUM_VALUES = 7; void CtPlusCt(ipcl::CipherText& res, const ipcl::CipherText& ct1, const ipcl::CipherText& ct2, const ipcl::keyPair key) { From b5fe85281d7bc5bd52dd3e503eea5df3e011020c Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 25 Aug 2022 16:57:34 -0700 Subject: [PATCH 218/364] Add experimental decoupled control from interfaces. --- CMakeLists.txt | 1 + he_qat/CMakeLists.txt | 9 +- he_qat/he_qat_ctrl.c | 902 ++++++++++++++++++++++++++++++++++++++++++ he_qat/he_qat_ops.c | 594 ++++++++++++++++++++++++++++ 4 files changed, 1505 insertions(+), 1 deletion(-) create mode 100644 he_qat/he_qat_ctrl.c create mode 100644 he_qat/he_qat_ops.c diff --git a/CMakeLists.txt b/CMakeLists.txt index f7a49cc..0b94d0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,7 @@ option(HE_QAT_SAMPLES "Enable examples" ON) option(HE_QAT_BENCHMARK "Enable benchmark" OFF) option(HE_QAT_DOCS "Enable document building" OFF) option(HE_QAT_SHARED "Build shared library" ON) +option(HE_QAT_EXPERIMENTAL "Refactored code" OFF) if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(HE_QAT_DEBUG ON) diff --git a/he_qat/CMakeLists.txt b/he_qat/CMakeLists.txt index 4071d0e..1688dab 100644 --- a/he_qat/CMakeLists.txt +++ b/he_qat/CMakeLists.txt @@ -1,10 +1,17 @@ set(HE_QAT_SRC ${HE_QAT_SRC_DIR}/he_qat_cb.c - ${HE_QAT_SRC_DIR}/he_qat_bn_ops.c ${HE_QAT_SRC_DIR}/he_qat_context.c ${HE_QAT_SRC_DIR}/he_qat_utils.c ) +if(HE_QAT_EXPERIMENTAL) + message(STATUS "Using refactored source code.") + list(APPEND ${HE_QAT_SRC_DIR}/he_qat_ops.c + ${HE_QAT_SRC_DIR}/he_qat_ctrl.c) +else() + list(APPEND ${HE_QAT_SRC_DIR}/he_qat_bn_ops.c) +endif() + if(HE_QAT_SHARED) add_library(he_qat SHARED ${HE_QAT_SRC}) else() diff --git a/he_qat/he_qat_ctrl.c b/he_qat/he_qat_ctrl.c new file mode 100644 index 0000000..ba93a35 --- /dev/null +++ b/he_qat/he_qat_ctrl.c @@ -0,0 +1,902 @@ + +#include "cpa.h" +#include "cpa_cy_im.h" +#include "cpa_cy_ln.h" +#include "icp_sal_poll.h" + +#include "cpa_sample_utils.h" + +#include "he_qat_types.h" +#include "he_qat_bn_ops.h" + +#ifdef HE_QAT_PERF +#include +struct timeval start_time, end_time; +double time_taken = 0.0; +#endif + +#include +#include +#include +#include + +#ifdef HE_QAT_SYNC_MODE +#pragma message "Synchronous execution mode." +#else +#pragma message "Asynchronous execution mode." +#endif + +//#define RESTART_LATENCY_MICROSEC 600 +//#define NUM_PKE_SLICES 6 + +#include "he_qat_gconst.h" + +// Global buffer for the runtime environment +HE_QAT_RequestBuffer he_qat_buffer; +HE_QAT_OutstandingBuffer outstanding; + +volatile unsigned long response_count = 0; +static volatile unsigned long request_count = 0; +static unsigned long request_latency = 0; // unused +static unsigned long restart_threshold = NUM_PKE_SLICES;//48; +static unsigned long max_pending = (NUM_PKE_SLICES * 2 * HE_QAT_NUM_ACTIVE_INSTANCES); + +// Callback functions +//extern void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut); +//extern void HE_QAT_bnModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut); + + +/// @brief +/// @function +/// Thread-safe producer implementation for the shared request buffer. +/// Stores requests in a buffer that will be offload to QAT devices. +void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { +#ifdef HE_QAT_DEBUG + printf("Lock write request\n"); +#endif + pthread_mutex_lock(&_buffer->mutex); + +#ifdef HE_QAT_DEBUG + printf("Wait lock write request. [buffer size: %d]\n", _buffer->count); +#endif + while (_buffer->count >= HE_QAT_BUFFER_SIZE) + pthread_cond_wait(&_buffer->any_free_slot, &_buffer->mutex); + + assert(_buffer->count < HE_QAT_BUFFER_SIZE); + + _buffer->data[_buffer->next_free_slot++] = args; + + _buffer->next_free_slot %= HE_QAT_BUFFER_SIZE; + _buffer->count++; + + pthread_cond_signal(&_buffer->any_more_data); + pthread_mutex_unlock(&_buffer->mutex); +#ifdef HE_QAT_DEBUG + printf("Unlocked write request. [buffer size: %d]\n", _buffer->count); +#endif +} + +static void submit_request_list(HE_QAT_RequestBuffer* _buffer, + HE_QAT_TaskRequestList* _requests) { +//#define HE_QAT_DEBUG +#ifdef HE_QAT_DEBUG +// printf("Lock submit request list\n"); +#endif + if (0 == _requests->count) return; + + pthread_mutex_lock(&_buffer->mutex); + +#ifdef HE_QAT_DEBUG + printf( + "Wait lock submit request list. [internal buffer size: %d] [num " + "requests: %u]\n", + _buffer->count, _requests->count); +#endif + + // Wait until buffer can accomodate the number of input requests + while (_buffer->count >= HE_QAT_BUFFER_SIZE || + (HE_QAT_BUFFER_SIZE - _buffer->count) < _requests->count) + pthread_cond_wait(&_buffer->any_free_slot, &_buffer->mutex); + + assert(_buffer->count < HE_QAT_BUFFER_SIZE); + assert(_requests->count <= (HE_QAT_BUFFER_SIZE - _buffer->count)); + + for (unsigned int i = 0; i < _requests->count; i++) { + _buffer->data[_buffer->next_free_slot++] = _requests->request[i]; + _buffer->next_free_slot %= HE_QAT_BUFFER_SIZE; + _requests->request[i] = NULL; + } + _buffer->count += _requests->count; + _requests->count = 0; + + pthread_cond_signal(&_buffer->any_more_data); + pthread_mutex_unlock(&_buffer->mutex); +#ifdef HE_QAT_DEBUG + printf("Unlocked submit request list. [internal buffer size: %d]\n", + _buffer->count); +#endif +} + +/// @brief +/// @function +/// Thread-safe producer implementation for the shared outstanding request +/// buffer that stores request from multiple threads. +/// Stores requests in a buffer that will be sent to the HE QAT buffer. +/// @unused +static void push_request(HE_QAT_RequestBufferList* _outstanding_buffer, + void* args, unsigned int num_requests) { +#ifdef HE_QAT_DEBUG + printf("Lock write outstanding requests\n"); +#endif + pthread_mutex_lock(&_outstanding_buffer->mutex); + +#ifdef HE_QAT_DEBUG + printf("Wait lock write request. [outstanding buffer size: %d]\n", + _outstanding_buffer->count); +#endif + // if (NULL == args) pthread_mutex_unlock(&_outstanding_buffer->mutex); + unsigned int list_size = _outstanding_buffer->size; + unsigned int buffer_size = list_size * HE_QAT_BUFFER_SIZE; + // TODO(fdiasmor): Dynamically expand the outstanding buffer + // while (buffer_size < num_requests && + // buffer_size < HE_QAT_LIST_SIZE * HE_QAT_BUFFER_SIZE) { + // _outstanding_buffer->data[list_size] = + // malloc(sizeof(HE_QAT_TaskRequest)*HE_QAT_BUFFER_SIZE); if + //(_outstanding_buffer) + // buffer_size = ++list_size * HE_QAT_BUFFER_SIZE; + // } + // Create more space, if required, to a certain extent + // For now, it assumes maximum number of requests per thread and per call is + // equal to HE_QAT_BUFFER_SIZE and maximum number of threads is + // HE_QAT_BUFFER_COUNT + while (_outstanding_buffer->count >= buffer_size || + (buffer_size - _outstanding_buffer->count + 1 < num_requests)) + pthread_cond_wait(&_outstanding_buffer->any_free_slot, + &_outstanding_buffer->mutex); + + assert(_outstanding_buffer->count < buffer_size); + assert(buffer_size - _outstanding_buffer->count + 1 >= num_requests); + + HE_QAT_TaskRequestList* requests = (HE_QAT_TaskRequestList*)args; + for (unsigned int i = 0; i < requests->count; i++) { + unsigned int index = _outstanding_buffer->next_free_slot / buffer_size; + unsigned int slot = _outstanding_buffer->next_free_slot % buffer_size; + _outstanding_buffer->data[index][slot] = requests->request[i]; + _outstanding_buffer->next_free_slot++; + _outstanding_buffer->next_free_slot %= buffer_size; + _outstanding_buffer->count++; + } + + pthread_cond_signal(&_outstanding_buffer->any_more_data); + pthread_mutex_unlock(&_outstanding_buffer->mutex); +#ifdef HE_QAT_DEBUG + printf("Unlocked write request. [outstanding buffer count: %d]\n", + _outstanding_buffer->count); +#endif +} + +/// @brief +/// @function +/// Thread-safe consumer implementation for the shared request buffer. +/// Read requests from a buffer to finally offload the work to QAT devices. +/// Supported in single-threaded or multi-threaded mode. +static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) { + void* item = NULL; + static unsigned int counter = 0; + pthread_mutex_lock(&_buffer->mutex); +//#define HE_QAT_DEBUG +#ifdef HE_QAT_DEBUG + printf("Wait lock read request. [internal buffer size: %d] Request #%u\n", + _buffer->count, counter++); +#endif + // Wait while buffer is empty + while (_buffer->count <= 0) + pthread_cond_wait(&_buffer->any_more_data, &_buffer->mutex); + + assert(_buffer->count > 0); + + item = _buffer->data[_buffer->next_data_slot++]; + + _buffer->next_data_slot %= HE_QAT_BUFFER_SIZE; + _buffer->count--; + + pthread_cond_signal(&_buffer->any_free_slot); + pthread_mutex_unlock(&_buffer->mutex); +#ifdef HE_QAT_DEBUG + printf("Unlocked read request. [internal buffer count: %d]\n", + _buffer->count); +#endif + + return (HE_QAT_TaskRequest*)(item); +} + +/// @brief +/// @function +/// Thread-safe consumer implementation for the shared request buffer. +/// Read requests from a buffer to finally offload the work to QAT devices. +/// @future: Meant for multi-threaded mode. +static void read_request_list(HE_QAT_TaskRequestList* _requests, + HE_QAT_RequestBuffer* _buffer, unsigned int max_requests) { + if (NULL == _requests) return; + + pthread_mutex_lock(&_buffer->mutex); + + // Wait while buffer is empty + while (_buffer->count <= 0) + pthread_cond_wait(&_buffer->any_more_data, &_buffer->mutex); + + assert(_buffer->count > 0); + // assert(_buffer->count <= HE_QAT_BUFFER_SIZE); + + unsigned int count = (_buffer->count < max_requests) ? _buffer->count : max_requests; + + //for (unsigned int i = 0; i < _buffer->count; i++) { + for (unsigned int i = 0; i < count; i++) { + _requests->request[i] = _buffer->data[_buffer->next_data_slot++]; + _buffer->next_data_slot %= HE_QAT_BUFFER_SIZE; + } + //_requests->count = _buffer->count; + //_buffer->count = 0; + _requests->count = count; + _buffer->count -= count; + + pthread_cond_signal(&_buffer->any_free_slot); + pthread_mutex_unlock(&_buffer->mutex); + + return; +} + +/// @brief +/// @function +/// Thread-safe consumer implementation for the shared request buffer. +/// Read requests from a buffer to finally offload the work to QAT devices. +/// @deprecated +//[[deprecated("Replaced by pull_outstanding_requests() in schedule_requests().")]] +static void pull_request(HE_QAT_TaskRequestList* _requests, + // HE_QAT_OutstandingBuffer *_outstanding_buffer, + HE_QAT_RequestBufferList* _outstanding_buffer, + unsigned int max_num_requests) { + if (NULL == _requests) return; + + pthread_mutex_lock(&_outstanding_buffer->mutex); + + unsigned int list_size = _outstanding_buffer->size; + unsigned int buffer_size = list_size * HE_QAT_BUFFER_SIZE; + + // Wait while buffer is empty + while (_outstanding_buffer->count <= 0) + pthread_cond_wait(&_outstanding_buffer->any_more_data, + &_outstanding_buffer->mutex); + + assert(_outstanding_buffer->count > 0); + + unsigned int num_requests = (_outstanding_buffer->count <= max_num_requests) + ? _outstanding_buffer->count + : max_num_requests; + + assert(num_requests <= HE_QAT_BUFFER_SIZE); + + //_requests->count = 0; + for (unsigned int i = 0; i < num_requests; i++) { + unsigned int index = _outstanding_buffer->next_data_slot / buffer_size; + unsigned int slot = _outstanding_buffer->next_data_slot % buffer_size; + + _requests->request[i] = _outstanding_buffer->data[index][slot]; + //_requests->count++; + + _outstanding_buffer->next_data_slot++; + _outstanding_buffer->next_data_slot %= buffer_size; + //_outstanding_buffer->count--; + } + _requests->count = num_requests; + _outstanding_buffer->count -= num_requests; + + pthread_cond_signal(&_outstanding_buffer->any_free_slot); + pthread_mutex_unlock(&_outstanding_buffer->mutex); + + return; +} + +static void pull_outstanding_requests( + HE_QAT_TaskRequestList* _requests, + HE_QAT_OutstandingBuffer* _outstanding_buffer, + unsigned int max_num_requests) { + if (NULL == _requests) return; + _requests->count = 0; + + // for now, only one thread can change next_ready_buffer + // so no need for sync tools + + // Select an outstanding buffer to pull requests and add them into the + // processing queue (internal buffer) + pthread_mutex_lock(&_outstanding_buffer->mutex); + // Wait until next outstanding buffer becomes available for use + while (outstanding.busy_count <= 0) + pthread_cond_wait(&_outstanding_buffer->any_ready_buffer, + &_outstanding_buffer->mutex); + + int any_ready = 0; + unsigned int index = _outstanding_buffer->next_ready_buffer; // no fairness + for (unsigned int i = 0; i < HE_QAT_BUFFER_COUNT; i++) { + index = i; // ensure fairness + if (_outstanding_buffer->ready_buffer[index] && + _outstanding_buffer->buffer[index] + .count) { // sync with mutex at interface + any_ready = 1; + break; + } + // index = (index + 1) % HE_QAT_BUFFER_COUNT; + } + // Ensures it gets picked once only + pthread_mutex_unlock(&_outstanding_buffer->mutex); + + if (!any_ready) return; + + // printf("Buffer #%u is Ready\n",index); + + // Extract outstanding requests from outstanding buffer + // (this is the only function that reads from outstanding buffer, from a + // single thread) + pthread_mutex_lock(&_outstanding_buffer->buffer[index].mutex); + // This conditional waiting may not be required + // Wait while buffer is empty + while (_outstanding_buffer->buffer[index].count <= 0) { + pthread_cond_wait(&_outstanding_buffer->buffer[index].any_more_data, + &_outstanding_buffer->buffer[index].mutex); + } + assert(_outstanding_buffer->buffer[index].count > 0); + // + + unsigned int num_requests = + (_outstanding_buffer->buffer[index].count < max_num_requests) + ? _outstanding_buffer->buffer[index].count + : max_num_requests; + + assert(num_requests <= HE_QAT_BUFFER_SIZE); + + for (unsigned int i = 0; i < num_requests; i++) { + _requests->request[i] = + _outstanding_buffer->buffer[index] + .data[_outstanding_buffer->buffer[index].next_data_slot]; + _outstanding_buffer->buffer[index].count--; + _outstanding_buffer->buffer[index].next_data_slot++; + _outstanding_buffer->buffer[index].next_data_slot %= HE_QAT_BUFFER_SIZE; + } + _requests->count = num_requests; + + pthread_cond_signal(&_outstanding_buffer->buffer[index].any_free_slot); + pthread_mutex_unlock(&_outstanding_buffer->buffer[index].mutex); + + // --------------------------------------------------------------------------- + // Notify there is an outstanding buffer in ready for the processing queue + // pthread_mutex_lock(&_outstanding_buffer->mutex); + // + // _outstanding_buffer->ready_count--; + // _outstanding_buffer->ready_buffer[index] = 0; + // + // pthread_cond_signal(&_outstanding_buffer->any_free_buffer); + // pthread_mutex_unlock(&_outstanding_buffer->mutex); + + return; +} + +/// @brief +/// Schedule outstanding requests from outstanding buffers to the internal buffer +/// from which requests are ready to be submitted to the device for processing. +/// @function schedule_requests +/// @param[in] state normally an volatile integer variable to activates(val>0) and disactives(0) the scheduler. +void* schedule_requests(void* state) { + if (NULL == state) { + printf("Failed at buffer_manager: argument is NULL.\n"); + pthread_exit(NULL); + } + + int* active = (int*)state; + + HE_QAT_TaskRequestList outstanding_requests; + for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { + outstanding_requests.request[i] = NULL; + } + outstanding_requests.count = 0; + + // this thread should receive signal from context to exit + while (*active) { + // collect a set of requests from the outstanding buffer + pull_outstanding_requests(&outstanding_requests, &outstanding, + HE_QAT_BUFFER_SIZE); + // printf("Pulled %u outstanding + //requests\n",outstanding_requests.count); + // submit them to the HE QAT buffer for offloading + submit_request_list(&he_qat_buffer, &outstanding_requests); + // printf("Submitted %u outstanding + //requests\n",outstanding_requests.count); + } + + pthread_exit(NULL); +} + +/// @brief +/// @function start_inst_polling +/// @param[in] HE_QAT_InstConfig Parameter values to start and poll instances. +/// +static void* start_inst_polling(void* _inst_config) { + if (NULL == _inst_config) { + printf( + "Failed at start_inst_polling: argument is NULL.\n"); //,__FUNC__); + pthread_exit(NULL); + } + + HE_QAT_InstConfig* config = (HE_QAT_InstConfig*)_inst_config; + + if (NULL == config->inst_handle) return NULL; + +#ifdef HE_QAT_DEBUG + printf("Instance ID %d Polling\n",config->inst_id); +#endif + + // What is harmful for polling without performing any operation? + config->polling = 1; + while (config->polling) { + icp_sal_CyPollInstance(config->inst_handle, 0); + OS_SLEEP(50); + } + + pthread_exit(NULL); +} + + + +void* start_instances(void* _config) { +// static unsigned int request_count = 0; + static unsigned int instance_count = 0; + static unsigned int next_instance = 0; + + if (NULL == _config) { + printf("Failed in start_instances: _config is NULL.\n"); + pthread_exit(NULL); + } + + HE_QAT_Config* config = (HE_QAT_Config*)_config; + instance_count = config->count; + + printf("Instance Count: %d\n",instance_count); + pthread_t* polling_thread = (pthread_t *) malloc(sizeof(pthread_t)*instance_count); + if (NULL == polling_thread) { + printf("Failed in start_instances: polling_thread is NULL.\n"); + pthread_exit(NULL); + } + unsigned* request_count_per_instance = (unsigned *) malloc(sizeof(unsigned)*instance_count); + if (NULL == request_count_per_instance) { + printf("Failed in start_instances: polling_thread is NULL.\n"); + pthread_exit(NULL); + } + for (unsigned i = 0; i < instance_count; i++) { + request_count_per_instance[i] = 0; + } + + CpaStatus status = CPA_STATUS_FAIL; + + for (unsigned int j = 0; j < config->count; j++) { + // Start from zero or restart after stop_perform_op + pthread_mutex_lock(&config->inst_config[j].mutex); + while (config->inst_config[j].active) + pthread_cond_wait(&config->inst_config[j].ready, + &config->inst_config[j].mutex); + + // assert(0 == config->active); + // assert(NULL == config->inst_handle); + + status = cpaCyStartInstance(config->inst_config[j].inst_handle); + config->inst_config[j].status = status; + if (CPA_STATUS_SUCCESS == status) { + printf("Cpa CyInstance has successfully started.\n"); + status = + cpaCySetAddressTranslation(config->inst_config[j].inst_handle, + sampleVirtToPhys); + } + + pthread_cond_signal(&config->inst_config[j].ready); + pthread_mutex_unlock(&config->inst_config[j].mutex); + + if (CPA_STATUS_SUCCESS != status) pthread_exit(NULL); + + printf("Instance ID: %d\n",config->inst_config[j].inst_id); + + // Start QAT instance and start polling + //pthread_t polling_thread; + if (pthread_create(&polling_thread[j], config->inst_config[j].attr, start_inst_polling, + (void*)&(config->inst_config[j])) != 0) { + printf("Failed at creating and starting polling thread.\n"); + pthread_exit(NULL); + } + + if (pthread_detach(polling_thread[j]) != 0) { + printf("Failed at detaching polling thread.\n"); + pthread_exit(NULL); + } + + config->inst_config[j].active = 1; + config->inst_config[j].running = 1; + + } // for loop + + /* NEW CODE */ + HE_QAT_TaskRequestList outstanding_requests; + for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { + outstanding_requests.request[i] = NULL; + } + outstanding_requests.count = 0; + /* END NEW CODE */ + + config->running = 1; + config->active = 1; + while (config->running) { +#ifdef HE_QAT_DEBUG + printf("Try reading request from buffer. Inst #%d\n", config->inst_id); +#endif + /* NEW CODE */ + unsigned long pending = request_count - response_count; + unsigned long available = max_pending - ((pending < max_pending)?pending:max_pending); +#ifdef HE_QAT_DEBUG + printf("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", + request_count,response_count,pending,available); +#endif + while (available < restart_threshold) { +#ifdef HE_QAT_DEBUG + printf("[WAIT]\n"); +#endif + // argument passed in microseconds + OS_SLEEP(RESTART_LATENCY_MICROSEC); + pending = request_count - response_count; + available = max_pending - ((pending < max_pending)?pending:max_pending); +// printf("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", +// request_count,response_count,pending,available); + } +#ifdef HE_QAT_DEBUG + printf("[SUBMIT] request_count: %lu response_count: %lu pending: %lu available: %lu\n", + request_count,response_count,pending,available); +#endif + unsigned int max_requests = available; + // Try consume maximum amount of data from butter to perform requested operation + read_request_list(&outstanding_requests, &he_qat_buffer, max_requests); + /* END NEW CODE */ + +// // Try consume data from butter to perform requested operation +// HE_QAT_TaskRequest* request = +// (HE_QAT_TaskRequest*)read_request(&he_qat_buffer); +// +// if (NULL == request) { +// pthread_cond_signal(&config->ready); +// continue; +// } +#ifdef HE_QAT_DEBUG + printf("Offloading %u requests to the accelerator.\n", outstanding_requests.count); +#endif + for (unsigned int i = 0; i < outstanding_requests.count; i++) { + HE_QAT_TaskRequest* request = outstanding_requests.request[i]; +#ifdef HE_QAT_SYNC_MODE + COMPLETION_INIT(&request->callback); +#endif + + unsigned retry = 0; + do { + // Realize the type of operation from data + switch (request->op_type) { + // Select appropriate action + case HE_QAT_OP_MODEXP: +#ifdef HE_QAT_DEBUG + printf("Offload request using instance #%d\n", next_instance); +#endif +#ifdef HE_QAT_PERF + gettimeofday(&request->start, NULL); +#endif + status = cpaCyLnModExp( + config->inst_config[next_instance].inst_handle, + (CpaCyGenFlatBufCbFunc) + request->callback_func, // lnModExpCallback, + (void*)request, (CpaCyLnModExpOpData*)request->op_data, + &request->op_result); + retry++; + break; + case HE_QAT_OP_NONE: + default: +#ifdef HE_QAT_DEBUG + printf("HE_QAT_OP_NONE to instance #%d\n", next_instance); +#endif + retry = HE_QAT_MAX_RETRY; + break; + } + + if (CPA_STATUS_RETRY == status) { + printf("CPA requested RETRY\n"); + printf("RETRY count = %u\n",retry); + pthread_exit(NULL); // halt the whole system + } + + } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); + + // Ensure every call to perform operation is blocking for each endpoint + if (CPA_STATUS_SUCCESS == status) { + // Global tracking of number of requests + request_count += 1; + request_count_per_instance[next_instance] += 1; +// printf("Instance %d Count %u\n",next_instance,request_count_per_instance[next_instance]); + next_instance = (next_instance + 1) % instance_count; +// printf("retry_count = %d\n",retry_count); +// printf("SUCCESS Next Instance = %d\n",next_instance); + // Wake up any blocked call to stop_perform_op, signaling that now it is + // safe to terminate running instances. Check if this detereorate + // performance. + pthread_cond_signal(&config->inst_config[next_instance].ready); // Prone to the lost wake-up problem +#ifdef HE_QAT_SYNC_MODE + // Wait until the callback function has been called + if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { + request->op_status = CPA_STATUS_FAIL; + request->request_status = HE_QAT_STATUS_FAIL; // Review it + printf("Failed in COMPLETION WAIT\n"); + } + + // Destroy synchronization object + COMPLETION_DESTROY(&request->callback); +#endif + } else { + request->op_status = CPA_STATUS_FAIL; + request->request_status = HE_QAT_STATUS_FAIL; // Review it + printf("Request Submission FAILED\n"); + } + +#ifdef HE_QAT_DEBUG + printf("Offloading completed by instance #%d\n", next_instance-1); +#endif + + // Reset pointer + outstanding_requests.request[i] = NULL; + request = NULL; + + }// for loop over batch of requests + outstanding_requests.count = 0; + } + pthread_exit(NULL); +} + +/// @brief +/// @function perform_op +/// Offload operation to QAT endpoints; for example, large number modular +/// exponentiation. +/// @param[in] HE_QAT_InstConfig *: contains the handle to CPA instance, pointer +/// the global buffer of requests. +void* start_perform_op(void* _inst_config) { +// static unsigned int request_count = 0; + if (NULL == _inst_config) { + printf("Failed in start_perform_op: _inst_config is NULL.\n"); + pthread_exit(NULL); + } + + HE_QAT_InstConfig* config = (HE_QAT_InstConfig*)_inst_config; + + CpaStatus status = CPA_STATUS_FAIL; + + // Start from zero or restart after stop_perform_op + pthread_mutex_lock(&config->mutex); + while (config->active) pthread_cond_wait(&config->ready, &config->mutex); + + // assert(0 == config->active); + // assert(NULL == config->inst_handle); + + status = cpaCyStartInstance(config->inst_handle); + config->status = status; + if (CPA_STATUS_SUCCESS == status) { + printf("Cpa CyInstance has successfully started.\n"); + status = + cpaCySetAddressTranslation(config->inst_handle, sampleVirtToPhys); + } + + pthread_cond_signal(&config->ready); + pthread_mutex_unlock(&config->mutex); + + if (CPA_STATUS_SUCCESS != status) pthread_exit(NULL); + + // Start QAT instance and start polling + pthread_t polling_thread; + if (pthread_create(&polling_thread, config->attr, start_inst_polling, + (void*)config) != 0) { + printf("Failed at creating and starting polling thread.\n"); + pthread_exit(NULL); + } + + if (pthread_detach(polling_thread) != 0) { + printf("Failed at detaching polling thread.\n"); + pthread_exit(NULL); + } + + /* NEW CODE */ + HE_QAT_TaskRequestList outstanding_requests; + for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { + outstanding_requests.request[i] = NULL; + } + outstanding_requests.count = 0; + /* END NEW CODE */ + + config->running = 1; + config->active = 1; + while (config->running) { +#ifdef HE_QAT_DEBUG + printf("Try reading request from buffer. Inst #%d\n", config->inst_id); +#endif + /* NEW CODE */ + unsigned long pending = request_count - response_count; + unsigned long available = max_pending - ((pending < max_pending)?pending:max_pending); +#ifdef HE_QAT_DEBUG + printf("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", + request_count,response_count,pending,available); +#endif + while (available < restart_threshold) { +#ifdef HE_QAT_DEBUG + printf("[WAIT]\n"); +#endif + // argument passed in microseconds + OS_SLEEP(650); + pending = request_count - response_count; + available = max_pending - ((pending < max_pending)?pending:max_pending); + } +#ifdef HE_QAT_DEBUG + printf("[SUBMIT] request_count: %lu response_count: %lu pending: %lu available: %lu\n", + request_count,response_count,pending,available); +#endif + unsigned int max_requests = available; + // Try consume maximum amount of data from butter to perform requested operation + read_request_list(&outstanding_requests, &he_qat_buffer, max_requests); + /* END NEW CODE */ + +// // Try consume data from butter to perform requested operation +// HE_QAT_TaskRequest* request = +// (HE_QAT_TaskRequest*)read_request(&he_qat_buffer); +// +// if (NULL == request) { +// pthread_cond_signal(&config->ready); +// continue; +// } +#ifdef HE_QAT_DEBUG + printf("Offloading %u requests to the accelerator.\n", outstanding_requests.count); +#endif + for (unsigned int i = 0; i < outstanding_requests.count; i++) { + HE_QAT_TaskRequest* request = outstanding_requests.request[i]; +#ifdef HE_QAT_SYNC_MODE + COMPLETION_INIT(&request->callback); +#endif + unsigned retry = 0; + do { + // Realize the type of operation from data + switch (request->op_type) { + // Select appropriate action + case HE_QAT_OP_MODEXP: + //if (retry > 0) printf("Try offloading again last request\n"); +#ifdef HE_QAT_DEBUG + printf("Offload request using instance #%d\n", config->inst_id); +#endif +#ifdef HE_QAT_PERF + gettimeofday(&request->start, NULL); +#endif + status = cpaCyLnModExp( + config->inst_handle, + (CpaCyGenFlatBufCbFunc) + request->callback_func, // lnModExpCallback, + (void*)request, (CpaCyLnModExpOpData*)request->op_data, + &request->op_result); + retry++; + break; + case HE_QAT_OP_NONE: + default: +#ifdef HE_QAT_DEBUG + printf("HE_QAT_OP_NONE to instance #%d\n", config->inst_id); +#endif + retry = HE_QAT_MAX_RETRY; + break; + } + + if (CPA_STATUS_RETRY == status) { + printf("CPA requested RETRY\n"); + printf("RETRY count: %u\n",retry); + OS_SLEEP(600); + } + + } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); + + // Ensure every call to perform operation is blocking for each endpoint + if (CPA_STATUS_SUCCESS == status) { + // Global tracking of number of requests + request_count += 1; + //printf("retry_count = %d\n",retry_count); +#ifdef HE_QAT_SYNC_MODE + // Wait until the callback function has been called + if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { + request->op_status = CPA_STATUS_FAIL; + request->request_status = HE_QAT_STATUS_FAIL; // Review it + printf("Failed in COMPLETION WAIT\n"); + } + + // Destroy synchronization object + COMPLETION_DESTROY(&request->callback); +#endif + } else { + request->op_status = CPA_STATUS_FAIL; + request->request_status = HE_QAT_STATUS_FAIL; // Review it + } + + // Reset pointer + outstanding_requests.request[i] = NULL; + request = NULL; + + }// for loop over batch of requests + outstanding_requests.count = 0; + + // Wake up any blocked call to stop_perform_op, signaling that now it is + // safe to terminate running instances. Check if this detereorate + // performance. + pthread_cond_signal( + &config->ready); // Prone to the lost wake-up problem +#ifdef HE_QAT_DEBUG + printf("Offloading completed by instance #%d\n", config->inst_id); +#endif + } + pthread_exit(NULL); +} + +/// @brief +/// @function +/// Stop first 'num_inst' number of cpaCyInstance(s), including their polling +/// and running threads. +/// @param[in] HE_QAT_InstConfig config Vector of created instances with their +/// configuration setup. +/// @param[in] num_inst Unsigned integer number indicating first number of +/// instances to be terminated. +void stop_perform_op(HE_QAT_InstConfig* config, unsigned num_inst) { + // if () { + // Stop runnning and polling instances + // Release QAT instances handles + if (NULL == config) return; + + CpaStatus status = CPA_STATUS_FAIL; + for (unsigned i = 0; i < num_inst; i++) { + pthread_mutex_lock(&config[i].mutex); +#ifdef HE_QAT_DEBUG + printf("Try teardown HE QAT instance #%d.\n", i); +#endif + while (0 == config[i].active) { + pthread_cond_wait(&config[i].ready, &config[i].mutex); + } + if (CPA_STATUS_SUCCESS == config[i].status && config[i].active) { +#ifdef HE_QAT_DEBUG + printf("Stop polling and running threads #%d\n", i); +#endif + config[i].polling = 0; + config[i].running = 0; + OS_SLEEP(10); +#ifdef HE_QAT_DEBUG + printf("Stop cpaCyInstance #%d\n", i); +#endif + if (config[i].inst_handle == NULL) continue; +#ifdef HE_QAT_DEBUG + printf("cpaCyStopInstance\n"); +#endif + status = cpaCyStopInstance(config[i].inst_handle); + if (CPA_STATUS_SUCCESS != status) { + printf("Failed to stop QAT instance #%d\n", i); + } + } + pthread_cond_signal(&config[i].ready); + pthread_mutex_unlock(&config[i].mutex); + } + //} + + return; +} + +void stop_instances(HE_QAT_Config* _config) { + if (NULL == _config) return; + if (_config->active) _config->active = 0; + if (_config->running) _config->running = 0; + stop_perform_op(_config->inst_config, _config->count); + return ; +} + diff --git a/he_qat/he_qat_ops.c b/he_qat/he_qat_ops.c new file mode 100644 index 0000000..77410cf --- /dev/null +++ b/he_qat/he_qat_ops.c @@ -0,0 +1,594 @@ + +#include "cpa.h" +#include "cpa_cy_im.h" +#include "cpa_cy_ln.h" +#include "icp_sal_poll.h" + +#include "cpa_sample_utils.h" + +#include "he_qat_types.h" +#include "he_qat_bn_ops.h" + +#ifdef HE_QAT_PERF +#include +struct timeval start_time, end_time; +double time_taken = 0.0; +#endif + +#include +#include +#include +#include + +#ifdef HE_QAT_SYNC_MODE +#pragma message "Synchronous execution mode." +#else +#pragma message "Asynchronous execution mode." +#endif + +//#define RESTART_LATENCY_MICROSEC 600 +//#define NUM_PKE_SLICES 6 + +#include "he_qat_gconst.h" + +// Global buffer for the runtime environment +extern HE_QAT_RequestBuffer he_qat_buffer; +extern HE_QAT_OutstandingBuffer outstanding; + +//volatile unsigned long response_count = 0; +//static volatile unsigned long request_count = 0; +//static unsigned long request_latency = 0; // unused +//static unsigned long restart_threshold = NUM_PKE_SLICES;//48; +//static unsigned long max_pending = (NUM_PKE_SLICES * 2 * HE_QAT_NUM_ACTIVE_INSTANCES); + +// Callback functions +extern void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut); +extern void HE_QAT_bnModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut); + + +/// @brief +/// @function +/// Thread-safe producer implementation for the shared request buffer. +/// Stores requests in a buffer that will be offload to QAT devices. +extern void submit_request(HE_QAT_RequestBuffer* _buffer, void* args); + +// Frontend for multithreading support +HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id) { + if (NULL == _buffer_id) return HE_QAT_STATUS_INVALID_PARAM; + + pthread_mutex_lock(&outstanding.mutex); + // Wait until next outstanding buffer becomes available for use + while (outstanding.busy_count >= HE_QAT_BUFFER_COUNT) + pthread_cond_wait(&outstanding.any_free_buffer, &outstanding.mutex); + + assert(outstanding.busy_count < HE_QAT_BUFFER_COUNT); + + // find next available + unsigned int next_free_buffer = outstanding.next_free_buffer; + for (unsigned int i = 0; i < HE_QAT_BUFFER_COUNT; i++) { + if (outstanding.free_buffer[next_free_buffer]) { + outstanding.free_buffer[next_free_buffer] = 0; + *_buffer_id = next_free_buffer; + break; + } + next_free_buffer = (next_free_buffer + 1) % HE_QAT_BUFFER_COUNT; + } + + outstanding.next_free_buffer = (*_buffer_id + 1) % HE_QAT_BUFFER_COUNT; + outstanding.next_ready_buffer = *_buffer_id; + outstanding.ready_buffer[*_buffer_id] = 1; + outstanding.busy_count++; + // busy meaning: + // taken by a thread, enqueued requests, in processing, waiting results + + pthread_cond_signal(&outstanding.any_ready_buffer); + pthread_mutex_unlock(&outstanding.mutex); + + return HE_QAT_STATUS_SUCCESS; +} + +HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, + int nbits) { + // Unpack data and copy to QAT friendly memory space + int len = (nbits + 7) >> 3; // nbits / 8; + + Cpa8U* pBase = NULL; + Cpa8U* pModulus = NULL; + Cpa8U* pExponent = NULL; + + HE_QAT_TaskRequest* request = + (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); + if (NULL == request) { + printf( + "HE_QAT_TaskRequest memory allocation failed in " + "bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + + // TODO: @fdiasmor Try it with 8-byte alignment. + CpaStatus status = CPA_STATUS_FAIL; + status = PHYS_CONTIG_ALLOC(&pBase, len); + if (CPA_STATUS_SUCCESS == status && NULL != pBase) { + //{ + // unsigned char* bin = (unsigned char*)calloc(len, sizeof(unsigned + // char)); if (BN_bn2binpad(b, bin, len)) { + if (BN_bn2binpad(b, pBase, len)) { + // memcpy(pBase, bin, len); + // pBase = (Cpa8U*)bin; + } else { + printf("BN_bn2binpad (base) failed in bnModExpPerformOp.\n"); + PHYS_CONTIG_FREE(pBase); + // free(bin); + // bin = NULL; + return HE_QAT_STATUS_FAIL; + } + //} + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + status = PHYS_CONTIG_ALLOC(&pExponent, len); + if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { + //{ + // unsigned char* bin = (unsigned char*)calloc(len, sizeof(unsigned + // char)); if (BN_bn2binpad(e, bin, len)) { + if (BN_bn2binpad(e, pExponent, len)) { + // memcpy(pExponent, bin, len); + // pExponent = (Cpa8U*)bin; + } else { + printf("BN_bn2binpad (exponent) failed in bnModExpPerformOp.\n"); + PHYS_CONTIG_FREE(pExponent); + // free(bin); + // bin = NULL; + return HE_QAT_STATUS_FAIL; + } + //} + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + status = PHYS_CONTIG_ALLOC(&pModulus, len); + if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { + //{ + // unsigned char* bin = (unsigned char*)calloc(len, sizeof(unsigned + // char)); if (BN_bn2binpad(m, bin, len)) { + if (BN_bn2binpad(m, pModulus, len)) { + // memcpy(pModulus, bin, len); + // pModulus = (Cpa8U*)bin; + } else { + printf("BN_bn2binpad failed in bnModExpPerformOp.\n"); + PHYS_CONTIG_FREE(pModulus); + // free(bin); + // bin = NULL; + return HE_QAT_STATUS_FAIL; + } + //} + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + // Pack it as a QAT Task Request + CpaCyLnModExpOpData* op_data = + (CpaCyLnModExpOpData*)calloc(1, sizeof(CpaCyLnModExpOpData)); + if (NULL == op_data) { + printf("Cpa memory allocation failed in bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + op_data->base.pData = pBase; + op_data->base.dataLenInBytes = len; + op_data->exponent.pData = pExponent; + op_data->exponent.dataLenInBytes = len; + op_data->modulus.pData = pModulus; + op_data->modulus.dataLenInBytes = len; + request->op_data = (void*)op_data; + + status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); + if (CPA_STATUS_SUCCESS == status && NULL != request->op_result.pData) { + request->op_result.dataLenInBytes = len; + } else { + printf( + "CpaFlatBuffer.pData memory allocation failed in " + "bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + + request->op_type = HE_QAT_OP_MODEXP; + //request->callback_func = (void*)lnModExpCallback; + request->callback_func = (void*)HE_QAT_BIGNUMModExpCallback; + request->op_status = status; + request->op_output = (void*)r; + + // Ensure calls are synchronized at exit (blocking) + pthread_mutex_init(&request->mutex, NULL); + pthread_cond_init(&request->ready, NULL); + + // Submit request using producer function + submit_request(&he_qat_buffer, (void*)request); + + return HE_QAT_STATUS_SUCCESS; +} + +// Assume allocate_bnModExp_buffer(&_buffer_id) to be called first +// to secure and allocate an outstanding buffer for the target thread. +// Multithread support for release_bnModExp_buffer(_buffer_id, batch_size) +void release_bnModExp_buffer(unsigned int _buffer_id, + unsigned int _batch_size) { + unsigned int next_data_out = outstanding.buffer[_buffer_id].next_data_out; + unsigned int j = 0; + +#ifdef HE_QAT_DEBUG + printf("release_bnModExp_buffer #%u\n", _buffer_id); +#endif + +#ifdef HE_QAT_PERF + gettimeofday(&start_time, NULL); +#endif + + while (j < _batch_size) { + // Buffer read may be safe for single-threaded blocking calls only. + // Note: Not tested on multithreaded environment. + HE_QAT_TaskRequest* task = + (HE_QAT_TaskRequest*)outstanding.buffer[_buffer_id] + .data[next_data_out]; + + if (NULL == task) continue; + +#ifdef HE_QAT_DEBUG + printf("BatchSize %u Buffer #%u Request #%u Waiting\n", _batch_size, + _buffer_id, j); +#endif + + // Block and synchronize: Wait for the most recently offloaded request + // to complete processing + pthread_mutex_lock( + &task->mutex); // mutex only needed for the conditional variable + while (HE_QAT_STATUS_READY != task->request_status) + pthread_cond_wait(&task->ready, &task->mutex); + +#ifdef HE_QAT_PERF + time_taken = (task->end.tv_sec - task->start.tv_sec) * 1e6; + time_taken = + (time_taken + (task->end.tv_usec - task->start.tv_usec)); //*1e-6; + printf("%u time: %.1lfus\n", j, time_taken); +#endif + + // Free up QAT temporary memory + CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; + if (op_data) { + PHYS_CONTIG_FREE(op_data->base.pData); + PHYS_CONTIG_FREE(op_data->exponent.pData); + PHYS_CONTIG_FREE(op_data->modulus.pData); + } + free(task->op_data); + task->op_data = NULL; + if (task->op_result.pData) { + PHYS_CONTIG_FREE(task->op_result.pData); + } + + // Move forward to wait for the next request that will be offloaded + pthread_mutex_unlock(&task->mutex); + +#ifdef HE_QAT_DEBUG + printf("Buffer #%u Request #%u Completed\n", _buffer_id, j); +#endif + // outstanding.buffer[_buffer_id].count--; + + // Fix segmentation fault? + free(outstanding.buffer[_buffer_id].data[next_data_out]); + outstanding.buffer[_buffer_id].data[next_data_out] = NULL; + + // update for next thread on the next external iteration + next_data_out = (next_data_out + 1) % HE_QAT_BUFFER_SIZE; + + j++; + } + +#ifdef HE_QAT_PERF + gettimeofday(&end_time, NULL); + time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; + time_taken = + (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; + printf("Batch Wall Time: %.1lfus\n", time_taken); +#endif + + outstanding.buffer[_buffer_id].next_data_out = next_data_out; + + // Release outstanding buffer for usage by another thread + pthread_mutex_lock(&outstanding.mutex); + + outstanding.next_free_buffer = _buffer_id; + outstanding.ready_buffer[_buffer_id] = 0; + outstanding.free_buffer[_buffer_id] = 1; + outstanding.busy_count--; + + pthread_cond_signal(&outstanding.any_free_buffer); + pthread_mutex_unlock(&outstanding.mutex); + + return; +} + +// Maybe it will be useful to pass the number of requests to retrieve +// Pass post-processing function as argument to bring output to expected type +void getBnModExpRequest(unsigned int batch_size) { + static unsigned long block_at_index = 0; + unsigned int j = 0; + +#ifdef HE_QAT_PERF + gettimeofday(&start_time, NULL); +#endif +//printf("batch_size=%u \n",batch_size); +// while (j < batch_size) { + do { + // Buffer read may be safe for single-threaded blocking calls only. + // Note: Not tested on multithreaded environment. + HE_QAT_TaskRequest* task = + (HE_QAT_TaskRequest*)he_qat_buffer.data[block_at_index]; + + if (NULL == task) + continue; + +//printf("j=%u ",j); + + // Block and synchronize: Wait for the most recently offloaded request + // to complete processing + pthread_mutex_lock( + &task->mutex); // mutex only needed for the conditional variable + while (HE_QAT_STATUS_READY != task->request_status) + pthread_cond_wait(&task->ready, &task->mutex); + +#ifdef HE_QAT_PERF + time_taken = (task->end.tv_sec - task->start.tv_sec) * 1e6; + time_taken = + (time_taken + (task->end.tv_usec - task->start.tv_usec)); //*1e-6; + printf("%u time: %.1lfus\n", j, time_taken); +#endif + + // Free up QAT temporary memory + CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; + if (op_data) { + PHYS_CONTIG_FREE(op_data->base.pData); + PHYS_CONTIG_FREE(op_data->exponent.pData); + PHYS_CONTIG_FREE(op_data->modulus.pData); + } + free(task->op_data); + task->op_data = NULL; + if (task->op_result.pData) { + PHYS_CONTIG_FREE(task->op_result.pData); + } + + // Move forward to wait for the next request that will be offloaded + pthread_mutex_unlock(&task->mutex); + + // Fix segmentation fault? + free(he_qat_buffer.data[block_at_index]); + he_qat_buffer.data[block_at_index] = NULL; + + block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; +// j++; +// } + } while (++j < batch_size); // number of null pointers equal batch size ? + +#ifdef HE_QAT_PERF + gettimeofday(&end_time, NULL); + time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; + time_taken = + (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; + printf("Batch Wall Time: %.1lfus\n", time_taken); +#endif + +// printf("\n"); + + return; +} + + +HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, + unsigned char* e, unsigned char* m, int nbits) { +//#ifdef HE_QAT_DEBUG + static unsigned long long req_count = 0; +//#endif + // Unpack data and copy to QAT friendly memory space + //int len = nbits / 8; + int len = (nbits + 7) >> 3; // nbits / 8; + + if (NULL == r) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == b) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == e) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == m) return HE_QAT_STATUS_INVALID_PARAM; + + Cpa8U* pBase = NULL; + Cpa8U* pModulus = NULL; + Cpa8U* pExponent = NULL; + + // TODO(fdiasmor): Try it with 8-byte alignment. + CpaStatus status = CPA_STATUS_FAIL; + // status = PHYS_CONTIG_ALLOC(&pBase, len); + status = PHYS_CONTIG_ALLOC_ALIGNED(&pBase, len, 8); + if (CPA_STATUS_SUCCESS == status && NULL != pBase) { + memcpy(pBase, b, len); + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + // status = PHYS_CONTIG_ALLOC(&pExponent, len); + status = PHYS_CONTIG_ALLOC_ALIGNED(&pExponent, len, 8); + if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { + memcpy(pExponent, e, len); + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + // status = PHYS_CONTIG_ALLOC(&pModulus, len); + status = PHYS_CONTIG_ALLOC_ALIGNED(&pModulus, len, 8); + if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { + memcpy(pModulus, m, len); + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + // HE_QAT_TaskRequest request = + // HE_QAT_PACK_MODEXP_REQUEST(pBase, pExponent, pModulus, r) + // Pack it as a QAT Task Request + HE_QAT_TaskRequest* request = + (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); + if (NULL == request) { + printf( + "HE_QAT_TaskRequest memory allocation failed in " + "bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + + CpaCyLnModExpOpData* op_data = + (CpaCyLnModExpOpData*)calloc(1, sizeof(CpaCyLnModExpOpData)); + if (NULL == op_data) { + printf("Cpa memory allocation failed in bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + op_data->base.pData = pBase; + op_data->base.dataLenInBytes = len; + op_data->exponent.pData = pExponent; + op_data->exponent.dataLenInBytes = len; + op_data->modulus.pData = pModulus; + op_data->modulus.dataLenInBytes = len; + request->op_data = (void*)op_data; + + // status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); + status = PHYS_CONTIG_ALLOC_ALIGNED(&request->op_result.pData, len, 8); + if (CPA_STATUS_SUCCESS == status && NULL != request->op_result.pData) { + request->op_result.dataLenInBytes = len; + } else { + printf( + "CpaFlatBuffer.pData memory allocation failed in " + "bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + + request->op_type = HE_QAT_OP_MODEXP; + request->callback_func = (void*)HE_QAT_bnModExpCallback; + request->op_status = status; + request->op_output = (void*)r; + + // Ensure calls are synchronized at exit (blocking) + pthread_mutex_init(&request->mutex, NULL); + pthread_cond_init(&request->ready, NULL); + + request->id = req_count; +#ifdef HE_QAT_DEBUG + printf("BN ModExp interface call for request #%llu\n", ++req_count); +#endif + + // Submit request using producer function + submit_request(&he_qat_buffer, (void*)request); + + return HE_QAT_STATUS_SUCCESS; +} + +HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, + unsigned char* b, unsigned char* e, + unsigned char* m, int nbits) { +#ifdef HE_QAT_DEBUG + static unsigned long long req_count = 0; + // printf("Wait lock write request. [buffer size: %d]\n",_buffer->count); +#endif + // Unpack data and copy to QAT friendly memory space + int len = nbits / 8; + + if (NULL == r) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == b) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == e) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == m) return HE_QAT_STATUS_INVALID_PARAM; + + Cpa8U* pBase = NULL; + Cpa8U* pModulus = NULL; + Cpa8U* pExponent = NULL; + + // TODO(fdiasmor): Try it with 8-byte alignment. + CpaStatus status = CPA_STATUS_FAIL; + // status = PHYS_CONTIG_ALLOC(&pBase, len); + status = PHYS_CONTIG_ALLOC_ALIGNED(&pBase, len, 8); + if (CPA_STATUS_SUCCESS == status && NULL != pBase) { + memcpy(pBase, b, len); + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + // status = PHYS_CONTIG_ALLOC(&pExponent, len); + status = PHYS_CONTIG_ALLOC_ALIGNED(&pExponent, len, 8); + if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { + memcpy(pExponent, e, len); + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + // status = PHYS_CONTIG_ALLOC(&pModulus, len); + status = PHYS_CONTIG_ALLOC_ALIGNED(&pModulus, len, 8); + if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { + memcpy(pModulus, m, len); + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + // HE_QAT_TaskRequest request = + // HE_QAT_PACK_MODEXP_REQUEST(pBase, pExponent, pModulus, r) + // Pack it as a QAT Task Request + HE_QAT_TaskRequest* request = + (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); + if (NULL == request) { + printf( + "HE_QAT_TaskRequest memory allocation failed in " + "bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + + CpaCyLnModExpOpData* op_data = + (CpaCyLnModExpOpData*)calloc(1, sizeof(CpaCyLnModExpOpData)); + if (NULL == op_data) { + printf("Cpa memory allocation failed in bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + op_data->base.pData = pBase; + op_data->base.dataLenInBytes = len; + op_data->exponent.pData = pExponent; + op_data->exponent.dataLenInBytes = len; + op_data->modulus.pData = pModulus; + op_data->modulus.dataLenInBytes = len; + request->op_data = (void*)op_data; + + // status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); + status = PHYS_CONTIG_ALLOC_ALIGNED(&request->op_result.pData, len, 8); + if (CPA_STATUS_SUCCESS == status && NULL != request->op_result.pData) { + request->op_result.dataLenInBytes = len; + } else { + printf( + "CpaFlatBuffer.pData memory allocation failed in " + "bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + + request->op_type = HE_QAT_OP_MODEXP; + request->callback_func = (void*)HE_QAT_bnModExpCallback; + request->op_status = status; + request->op_output = (void*)r; + + // Ensure calls are synchronized at exit (blocking) + pthread_mutex_init(&request->mutex, NULL); + pthread_cond_init(&request->ready, NULL); + +#ifdef HE_QAT_DEBUG + printf("BN ModExp interface call for request #%llu\n", ++req_count); +#endif + + // Submit request using producer function + submit_request(&outstanding.buffer[_buffer_id], (void*)request); + + return HE_QAT_STATUS_SUCCESS; +} From 5748e676ed0a18d7cbe49a52bdc17a12854611a5 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 25 Aug 2022 17:34:46 -0700 Subject: [PATCH 219/364] Some comments clean-up. --- CMakeLists.txt | 5 ----- icp/CMakeLists.txt | 6 ------ 2 files changed, 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b94d0d..52a7963 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -150,8 +150,6 @@ find_package(OpenSSL REQUIRED) find_package(Threads REQUIRED) set(CMAKE_THREAD_PREFER_PTHREAD ON) set(THREADS_PREFER_PTHREAD_FLAG ON) -#set(OPENSSL_INC_DIR /opt/openssl/include) -#set(OPENSSL_LIB_DIR /opt/openssl/lib) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/he_qat) include(heqat-util) @@ -200,6 +198,3 @@ endif() if(HE_QAT_DOCS) add_subdirectory(docs) endif() - - - diff --git a/icp/CMakeLists.txt b/icp/CMakeLists.txt index 5040fc4..8bae5b4 100644 --- a/icp/CMakeLists.txt +++ b/icp/CMakeLists.txt @@ -14,12 +14,6 @@ set(ICP_OSAL_DIR ${ICP_ROOT}/quickassist/utilities/oasl) set(ICP_ADF_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/qat_direct) set(CMN_ROOT ${ICP_ROOT}/quickassist/utilities/libusdm_drv) -#list(APPEND COMMON_INC_DIR ${ICP_API_DIR}/include -# ${ICP_LAC_DIR}/include -# ${ICP_ADF_DIR}/include -# ${CMN_ROOT} -#) - set(ICP_INC_DIR ${ICP_API_DIR}/include ${ICP_LAC_DIR}/include ${ICP_ADF_DIR}/include From 09c66caa1d84c65f57a571b696fadeb80e43dd9c Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 25 Aug 2022 17:36:17 -0700 Subject: [PATCH 220/364] Add documentation to callback functions. --- he_qat/he_qat_cb.c | 53 ++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/he_qat/he_qat_cb.c b/he_qat/he_qat_cb.c index 4aad411..80bae5e 100644 --- a/he_qat/he_qat_cb.c +++ b/he_qat/he_qat_cb.c @@ -1,26 +1,29 @@ -// qatlib headers +/// @file he_qat_cb.c + +// QAT-API headers #include #include -// C library +// C support libraries #include #include -// local headers +// Local headers #include "he_qat_types.h" // Global variables -static pthread_mutex_t response_mutex; -extern volatile unsigned long response_count; +static pthread_mutex_t response_mutex; ///< It protects against race condition on response_count due to concurrent callback events. +extern volatile unsigned long response_count; ///< It counts the number of requests completed by the accelerator. -/// @brief -/// @function -/// Callback function for lnModExpPerformOp. It performs any data processing -/// required after the modular exponentiation. -void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, - CpaStatus status, - void* pOpData, - CpaFlatBuffer* pOut) { +/// @brief Callback implementation for the API HE_QAT_BIGNUMModExp(...) +/// Callback function for the interface HE_QAT_BIGNUMModExp(). It performs +/// any data post-processing required after the modular exponentiation. +/// @param[in] pCallbackTag work request package containing the original input data and other resources for post-processing. +/// @param[in] status CPA_STATUS of the performed operation, e.g. CyLnModExp(). +/// @param[in] pOpData original input data passed to accelerator to perform the target operation (cannot be NULL). +/// @param[out] pOut output returned by the accelerator after executing the target operation. +void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut) +{ HE_QAT_TaskRequest* request = NULL; // Check if input data for the op is available and do something @@ -46,7 +49,9 @@ void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, (BIGNUM*)request->op_output); if (NULL == r) request->request_status = HE_QAT_STATUS_FAIL; - +#ifdef HE_QAT_PERF + gettimeofday(&request->end, NULL); +#endif } else { request->request_status = HE_QAT_STATUS_FAIL; } @@ -62,16 +67,15 @@ void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, return; } - -/// @brief -/// @function -/// Callback function for HE_QAT_bnModExp. It performs any data processing -/// required after the modular exponentiation. -void HE_QAT_bnModExpCallback( - void* pCallbackTag, // This type can be variable - CpaStatus status, - void* pOpData, // This is fixed -- please swap it - CpaFlatBuffer* pOut) { +/// @brief Callback implementation for the API HE_QAT_bnModExp(...) +/// Callback function for the interface HE_QAT_bnModExp(). It performs +/// any data post-processing required after the modular exponentiation. +/// @param[in] pCallbackTag work request package containing the original input data and other resources for post-processing. +/// @param[in] status CPA_STATUS of the performed operation, e.g. CyLnModExp(). +/// @param[in] pOpData original input data passed to accelerator to perform the target operation (cannot be NULL). +/// @param[out] pOut output returned by the accelerator after executing the target operation. +void HE_QAT_bnModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut) +{ HE_QAT_TaskRequest* request = NULL; // Check if input data for the op is available and do something @@ -94,7 +98,6 @@ void HE_QAT_bnModExpCallback( // Copy compute results to output destination memcpy(request->op_output, request->op_result.pData, request->op_result.dataLenInBytes); -// printf("Request ID %llu Completed.\n",request->id); #ifdef HE_QAT_PERF gettimeofday(&request->end, NULL); #endif From aceb175cd0d4d11f5b6ca4e3c8caf06bd71476bd Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 25 Aug 2022 18:32:15 -0700 Subject: [PATCH 221/364] Partial documentation of he_qat_ctrl.c. --- he_qat/he_qat_ctrl.c | 212 +++++++++++-------------------------------- 1 file changed, 54 insertions(+), 158 deletions(-) diff --git a/he_qat/he_qat_ctrl.c b/he_qat/he_qat_ctrl.c index ba93a35..5194965 100644 --- a/he_qat/he_qat_ctrl.c +++ b/he_qat/he_qat_ctrl.c @@ -1,55 +1,50 @@ +/// @file he_qat_ctrl.c +// QAT-API headers #include "cpa.h" #include "cpa_cy_im.h" #include "cpa_cy_ln.h" #include "icp_sal_poll.h" - #include "cpa_sample_utils.h" -#include "he_qat_types.h" -#include "he_qat_bn_ops.h" - +// Global variables used to hold measured performance numbers. #ifdef HE_QAT_PERF #include struct timeval start_time, end_time; double time_taken = 0.0; #endif +// C support libraries #include #include #include #include +// Loca headers +#include "he_qat_types.h" +#include "he_qat_bn_ops.h" +#include "he_qat_gconst.h" + +// Warn user on selected execution mode #ifdef HE_QAT_SYNC_MODE #pragma message "Synchronous execution mode." #else #pragma message "Asynchronous execution mode." #endif -//#define RESTART_LATENCY_MICROSEC 600 -//#define NUM_PKE_SLICES 6 - -#include "he_qat_gconst.h" - // Global buffer for the runtime environment -HE_QAT_RequestBuffer he_qat_buffer; -HE_QAT_OutstandingBuffer outstanding; - -volatile unsigned long response_count = 0; -static volatile unsigned long request_count = 0; -static unsigned long request_latency = 0; // unused -static unsigned long restart_threshold = NUM_PKE_SLICES;//48; -static unsigned long max_pending = (NUM_PKE_SLICES * 2 * HE_QAT_NUM_ACTIVE_INSTANCES); - -// Callback functions -//extern void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut); -//extern void HE_QAT_bnModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut); - - -/// @brief -/// @function -/// Thread-safe producer implementation for the shared request buffer. -/// Stores requests in a buffer that will be offload to QAT devices. +HE_QAT_RequestBuffer he_qat_buffer; ///< This the internal buffer that holds and serializes the requests to the accelerator. +HE_QAT_OutstandingBuffer outstanding; ///< This is the data structure that holds outstanding requests from separate active threads calling the API. +volatile unsigned long response_count = 0; ///< Counter of processed requests and it is used to help control throttling. +static volatile unsigned long request_count = 0; ///< Counter of received requests and it is used to help control throttling. +static unsigned long request_latency = 0; ///< Variable used to hold measured averaged latency of requests (currently unused). +static unsigned long restart_threshold = NUM_PKE_SLICES; ///< Number of concurrent requests allowed to be sent to accelerator at once. +static unsigned long max_pending = (NUM_PKE_SLICES * 2 * HE_QAT_NUM_ACTIVE_INSTANCES); ///< Number of requests sent to the accelerator that are pending completion. + +/// @brief Populates either internal or outstanding buffer with request. +/// This function is called inside the API to submit request to a shared internal buffer. It is a thread-safe implementation of the producer for the either the internal buffer or the outstanding buffer to host incoming requests. Depending on the buffer type, the submitted request is either ready to be scheduled or to be processed by the accelerator. +/// @param[out] _buffer either `he_qat_buffer` or `outstanding` buffer. +/// @param[in] args work request packaged in a custom data structure. void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { #ifdef HE_QAT_DEBUG printf("Lock write request\n"); @@ -76,11 +71,14 @@ void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { #endif } +/// @brief Populates internal buffer with a list of work request. +/// This function is called by the request scheduler thread. It is a thread-safe implementation of the producer for the shared internal request buffer. This buffer stores and serializes the offloading of requests that are ready to be processed by the accelerator. +/// @param[out] _buffer reference pointer to the internal buffer `he_qat_buffer`. +/// @param[in] _requests list of requests retrieved from the buffer (`outstanding`) holding outstanding requests. static void submit_request_list(HE_QAT_RequestBuffer* _buffer, HE_QAT_TaskRequestList* _requests) { -//#define HE_QAT_DEBUG #ifdef HE_QAT_DEBUG -// printf("Lock submit request list\n"); + printf("Lock submit request list\n"); #endif if (0 == _requests->count) return; @@ -117,70 +115,15 @@ static void submit_request_list(HE_QAT_RequestBuffer* _buffer, #endif } -/// @brief -/// @function -/// Thread-safe producer implementation for the shared outstanding request -/// buffer that stores request from multiple threads. -/// Stores requests in a buffer that will be sent to the HE QAT buffer. -/// @unused -static void push_request(HE_QAT_RequestBufferList* _outstanding_buffer, - void* args, unsigned int num_requests) { -#ifdef HE_QAT_DEBUG - printf("Lock write outstanding requests\n"); -#endif - pthread_mutex_lock(&_outstanding_buffer->mutex); -#ifdef HE_QAT_DEBUG - printf("Wait lock write request. [outstanding buffer size: %d]\n", - _outstanding_buffer->count); -#endif - // if (NULL == args) pthread_mutex_unlock(&_outstanding_buffer->mutex); - unsigned int list_size = _outstanding_buffer->size; - unsigned int buffer_size = list_size * HE_QAT_BUFFER_SIZE; - // TODO(fdiasmor): Dynamically expand the outstanding buffer - // while (buffer_size < num_requests && - // buffer_size < HE_QAT_LIST_SIZE * HE_QAT_BUFFER_SIZE) { - // _outstanding_buffer->data[list_size] = - // malloc(sizeof(HE_QAT_TaskRequest)*HE_QAT_BUFFER_SIZE); if - //(_outstanding_buffer) - // buffer_size = ++list_size * HE_QAT_BUFFER_SIZE; - // } - // Create more space, if required, to a certain extent - // For now, it assumes maximum number of requests per thread and per call is - // equal to HE_QAT_BUFFER_SIZE and maximum number of threads is - // HE_QAT_BUFFER_COUNT - while (_outstanding_buffer->count >= buffer_size || - (buffer_size - _outstanding_buffer->count + 1 < num_requests)) - pthread_cond_wait(&_outstanding_buffer->any_free_slot, - &_outstanding_buffer->mutex); - - assert(_outstanding_buffer->count < buffer_size); - assert(buffer_size - _outstanding_buffer->count + 1 >= num_requests); - - HE_QAT_TaskRequestList* requests = (HE_QAT_TaskRequestList*)args; - for (unsigned int i = 0; i < requests->count; i++) { - unsigned int index = _outstanding_buffer->next_free_slot / buffer_size; - unsigned int slot = _outstanding_buffer->next_free_slot % buffer_size; - _outstanding_buffer->data[index][slot] = requests->request[i]; - _outstanding_buffer->next_free_slot++; - _outstanding_buffer->next_free_slot %= buffer_size; - _outstanding_buffer->count++; - } - - pthread_cond_signal(&_outstanding_buffer->any_more_data); - pthread_mutex_unlock(&_outstanding_buffer->mutex); -#ifdef HE_QAT_DEBUG - printf("Unlocked write request. [outstanding buffer count: %d]\n", - _outstanding_buffer->count); -#endif -} - -/// @brief -/// @function +/// @brief Read requests from internal buffer. /// Thread-safe consumer implementation for the shared request buffer. -/// Read requests from a buffer to finally offload the work to QAT devices. +/// Read requests from internal buffer `he_qat_buffer` to finally offload the request to be processed by QAT devices. /// Supported in single-threaded or multi-threaded mode. -static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) { +/// @param[in] _buffer buffer of type HE_QAT_RequestBuffer, typically the internal buffer in current implementation. +/// @retval single work request in HE_QAT_TaskRequest data structure. +static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) +{ void* item = NULL; static unsigned int counter = 0; pthread_mutex_lock(&_buffer->mutex); @@ -210,11 +153,13 @@ static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) { return (HE_QAT_TaskRequest*)(item); } -/// @brief -/// @function -/// Thread-safe consumer implementation for the shared request buffer. -/// Read requests from a buffer to finally offload the work to QAT devices. -/// @future: Meant for multi-threaded mode. +/// @brief Read requests from the outstanding buffer. +/// Thread-safe consumer implementation for the outstanding request buffer. +/// Read requests from outstanding buffer (requests ready to be scheduled) to later pass them to the internal buffer `he_qat_buffer`. As those requests move from the outstanding buffer into the internal buffer, their state changes from ready-to-be-scheduled to ready-to-be-processed. +/// Supported in single-threaded or multi-threaded mode. +/// @param[out] _requests list of requests retrieved from internal buffer. +/// @param[in] _buffer buffer of type HE_QAT_RequestBuffer, typically the internal buffer in current implementation. +/// @param[in] max_requests maximum number of requests to retrieve from internal buffer, if available. static void read_request_list(HE_QAT_TaskRequestList* _requests, HE_QAT_RequestBuffer* _buffer, unsigned int max_requests) { if (NULL == _requests) return; @@ -246,61 +191,15 @@ static void read_request_list(HE_QAT_TaskRequestList* _requests, return; } -/// @brief -/// @function -/// Thread-safe consumer implementation for the shared request buffer. -/// Read requests from a buffer to finally offload the work to QAT devices. -/// @deprecated -//[[deprecated("Replaced by pull_outstanding_requests() in schedule_requests().")]] -static void pull_request(HE_QAT_TaskRequestList* _requests, - // HE_QAT_OutstandingBuffer *_outstanding_buffer, - HE_QAT_RequestBufferList* _outstanding_buffer, - unsigned int max_num_requests) { - if (NULL == _requests) return; - - pthread_mutex_lock(&_outstanding_buffer->mutex); - - unsigned int list_size = _outstanding_buffer->size; - unsigned int buffer_size = list_size * HE_QAT_BUFFER_SIZE; - - // Wait while buffer is empty - while (_outstanding_buffer->count <= 0) - pthread_cond_wait(&_outstanding_buffer->any_more_data, - &_outstanding_buffer->mutex); - - assert(_outstanding_buffer->count > 0); - - unsigned int num_requests = (_outstanding_buffer->count <= max_num_requests) - ? _outstanding_buffer->count - : max_num_requests; - - assert(num_requests <= HE_QAT_BUFFER_SIZE); - - //_requests->count = 0; - for (unsigned int i = 0; i < num_requests; i++) { - unsigned int index = _outstanding_buffer->next_data_slot / buffer_size; - unsigned int slot = _outstanding_buffer->next_data_slot % buffer_size; - - _requests->request[i] = _outstanding_buffer->data[index][slot]; - //_requests->count++; - - _outstanding_buffer->next_data_slot++; - _outstanding_buffer->next_data_slot %= buffer_size; - //_outstanding_buffer->count--; - } - _requests->count = num_requests; - _outstanding_buffer->count -= num_requests; - - pthread_cond_signal(&_outstanding_buffer->any_free_slot); - pthread_mutex_unlock(&_outstanding_buffer->mutex); - - return; -} - -static void pull_outstanding_requests( - HE_QAT_TaskRequestList* _requests, - HE_QAT_OutstandingBuffer* _outstanding_buffer, - unsigned int max_num_requests) { +/// @brief Read requests from the outstanding buffer. +/// Thread-safe consumer implementation for the outstanding request buffer. +/// Retrieve work requests from outstanding buffer (requests ready to be scheduled) to later on pass them to the internal buffer `he_qat_buffer`. As those requests move from the outstanding buffer into the internal buffer, their state changes from ready-to-be-scheduled to ready-to-be-processed. +/// This function is supported in single-threaded or multi-threaded mode. +/// @param[out] _requests list of work requests retrieved from outstanding buffer. +/// @param[in] _outstanding_buffer outstanding buffer holding requests in ready-to-be-scheduled state. +/// @param[in] max_requests maximum number of requests to retrieve from outstanding buffer if available. +static void pull_outstanding_requests(HE_QAT_TaskRequestList* _requests, HE_QAT_OutstandingBuffer* _outstanding_buffer, unsigned int max_num_requests) +{ if (NULL == _requests) return; _requests->count = 0; @@ -380,9 +279,9 @@ static void pull_outstanding_requests( return; } -/// @brief -/// Schedule outstanding requests from outstanding buffers to the internal buffer -/// from which requests are ready to be submitted to the device for processing. +/// @brief Schedule outstanding requests to the internal buffer and be ready for processing. +/// Schedule outstanding requests from outstanding buffers to the internal buffer, +/// from which requests are ready to be submitted to the device for processing. /// @function schedule_requests /// @param[in] state normally an volatile integer variable to activates(val>0) and disactives(0) the scheduler. void* schedule_requests(void* state) { @@ -415,10 +314,9 @@ void* schedule_requests(void* state) { pthread_exit(NULL); } -/// @brief +/// @brief Poll responses from a specific QAT instance. /// @function start_inst_polling -/// @param[in] HE_QAT_InstConfig Parameter values to start and poll instances. -/// +/// @param[in] HE_QAT_InstConfig Parameter values to start and to poll instances. static void* start_inst_polling(void* _inst_config) { if (NULL == _inst_config) { printf( @@ -444,8 +342,6 @@ static void* start_inst_polling(void* _inst_config) { pthread_exit(NULL); } - - void* start_instances(void* _config) { // static unsigned int request_count = 0; static unsigned int instance_count = 0; From 257e37ce4bb7c388b38d7c999550c06bd956381f Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 2 Sep 2022 13:59:51 -0700 Subject: [PATCH 222/364] Fix undefined references. --- he_qat/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/he_qat/CMakeLists.txt b/he_qat/CMakeLists.txt index 1688dab..9686665 100644 --- a/he_qat/CMakeLists.txt +++ b/he_qat/CMakeLists.txt @@ -6,10 +6,10 @@ set(HE_QAT_SRC ${HE_QAT_SRC_DIR}/he_qat_cb.c if(HE_QAT_EXPERIMENTAL) message(STATUS "Using refactored source code.") - list(APPEND ${HE_QAT_SRC_DIR}/he_qat_ops.c + list(APPEND HE_QAT_SRC ${HE_QAT_SRC_DIR}/he_qat_ops.c ${HE_QAT_SRC_DIR}/he_qat_ctrl.c) else() - list(APPEND ${HE_QAT_SRC_DIR}/he_qat_bn_ops.c) + list(APPEND HE_QAT_SRC ${HE_QAT_SRC_DIR}/he_qat_bn_ops.c) endif() if(HE_QAT_SHARED) From 4b675b04f7a9dec8b5ea39f7c0a11f96dbabbb39 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 2 Sep 2022 14:17:17 -0700 Subject: [PATCH 223/364] Isolate global constants. --- he_qat/include/he_qat_gconst.h | 13 ++++++++ he_qat/include/he_qat_types.h | 55 ++++++++++++++++------------------ misc/he_qat_misc.h | 1 + 3 files changed, 39 insertions(+), 30 deletions(-) diff --git a/he_qat/include/he_qat_gconst.h b/he_qat/include/he_qat_gconst.h index 9d681e3..1883577 100644 --- a/he_qat/include/he_qat_gconst.h +++ b/he_qat/include/he_qat_gconst.h @@ -1,4 +1,17 @@ +/// @file he_qat_gconst.h +#pragma once + +#ifndef _HE_QAT_CONST_H_ +#define _HE_QAT_CONST_H_ + +// Local Constants +#define HE_QAT_NUM_ACTIVE_INSTANCES 8 +#define HE_QAT_BUFFER_SIZE 1024 +#define HE_QAT_BUFFER_COUNT HE_QAT_NUM_ACTIVE_INSTANCES +#define HE_QAT_MAX_RETRY 100 #define RESTART_LATENCY_MICROSEC 600 #define NUM_PKE_SLICES 6 +#endif // _HE_QAT_CONST_H_ + diff --git a/he_qat/include/he_qat_types.h b/he_qat/include/he_qat_types.h index e49b8ba..6aef6ac 100644 --- a/he_qat/include/he_qat_types.h +++ b/he_qat/include/he_qat_types.h @@ -20,11 +20,7 @@ extern "C" { #include #endif -// Local Constants -#define HE_QAT_NUM_ACTIVE_INSTANCES 8 -#define HE_QAT_BUFFER_SIZE 1024 -#define HE_QAT_BUFFER_COUNT HE_QAT_NUM_ACTIVE_INSTANCES -#define HE_QAT_MAX_RETRY 100 +#include "he_qat_gconst.h" // Type definitions typedef enum { HE_QAT_SYNC = 1, HE_QAT_ASYNC = 2 } HE_QAT_EXEC_MODE; @@ -51,35 +47,34 @@ typedef struct { // for all the request to complete processing unsigned int next_data_out; pthread_mutex_t mutex; // - pthread_cond_t any_more_data; // more - pthread_cond_t any_free_slot; // less + pthread_cond_t any_more_data; ///< Conditional variable used to synchronize the consumption of data in buffer (wait until more data is available to be consumed) + pthread_cond_t any_free_slot; ///< Conditional variable used to synchronize the provision of free slots in buffer (wait until enough slots are available to add more data in buffer) } HE_QAT_RequestBuffer; -typedef struct { - void* data[HE_QAT_BUFFER_COUNT][HE_QAT_BUFFER_SIZE]; // - unsigned int count; - unsigned int size; - unsigned int - next_free_slot; // nextin index of the next free slot for a request - unsigned int - next_data_slot; // nextout index of next request to be processed - pthread_mutex_t mutex; // - pthread_cond_t any_more_data; // more - pthread_cond_t any_free_slot; // less -} HE_QAT_RequestBufferList; +// Unused type. Intention to remove it. +//typedef struct { +// void* data[HE_QAT_BUFFER_COUNT][HE_QAT_BUFFER_SIZE]; // +// unsigned int count; +// unsigned int size; +// unsigned int +// next_free_slot; // nextin index of the next free slot for a request +// unsigned int +// next_data_slot; // nextout index of next request to be processed +// pthread_mutex_t mutex; // +// pthread_cond_t any_more_data; // more +// pthread_cond_t any_free_slot; // less +//} HE_QAT_RequestBufferList; typedef struct { - HE_QAT_RequestBuffer buffer[HE_QAT_BUFFER_COUNT]; // - unsigned int busy_count; - unsigned int - next_free_buffer; // nextin index of the next free slot for a request - int free_buffer[HE_QAT_BUFFER_COUNT]; - unsigned int - next_ready_buffer; // nextout index of next request to be processed - int ready_buffer[HE_QAT_BUFFER_COUNT]; - pthread_mutex_t mutex; // - pthread_cond_t any_ready_buffer; // more - pthread_cond_t any_free_buffer; // less + HE_QAT_RequestBuffer buffer[HE_QAT_BUFFER_COUNT]; ///< Buffers to support concurrent threads with less sync overhead + unsigned int busy_count; ///< Counts number of currently occupied buffers + unsigned int next_free_buffer; ///< Next in: index of the next free slot for a request + int free_buffer[HE_QAT_BUFFER_COUNT]; ///< Keeps track of buffers that are available (any value > 0 means the buffer at index i is available). The next_free_buffer does not necessarily mean that the buffer is already released from usage. + unsigned int next_ready_buffer; ///< Next out: index of next request to be processed + int ready_buffer[HE_QAT_BUFFER_COUNT]; ///< Keeps track of buffers that are ready (any value > 0 means the buffer at index i is ready). The next_ready_buffer does not necessarily mean that the buffer is not busy at any time instance. + pthread_mutex_t mutex; ///< Used for synchronization of concurrent access of an object of the type + pthread_cond_t any_ready_buffer; ///< Conditional variable used to synchronize the consumption of the contents in buffers + pthread_cond_t any_free_buffer; ///< Conditional variable used to synchronize the provision of buffers } HE_QAT_OutstandingBuffer; typedef struct { diff --git a/misc/he_qat_misc.h b/misc/he_qat_misc.h index 495347d..ac77a09 100644 --- a/misc/he_qat_misc.h +++ b/misc/he_qat_misc.h @@ -2,6 +2,7 @@ #ifndef HE_QAT_MISC_H_ #define HE_QAT_MISC_H_ +#include "he_qat_gconst.h" #include "he_qat_types.h" #include "bignum.h" #include From 142acf2c3bbe8640bdf87005d92127750624be7e Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 2 Sep 2022 18:09:45 -0700 Subject: [PATCH 224/364] Update comments, documentation and some clean-up. --- he_qat/he_qat_ctrl.c | 73 +++++++++++++++----- he_qat/he_qat_ops.c | 13 +--- he_qat/include/he_qat_bn_ops.h | 118 ++++++++++++++++++++++---------- he_qat/include/he_qat_context.h | 7 +- 4 files changed, 137 insertions(+), 74 deletions(-) diff --git a/he_qat/he_qat_ctrl.c b/he_qat/he_qat_ctrl.c index 5194965..d23ba6d 100644 --- a/he_qat/he_qat_ctrl.c +++ b/he_qat/he_qat_ctrl.c @@ -283,7 +283,8 @@ static void pull_outstanding_requests(HE_QAT_TaskRequestList* _requests, HE_QAT_ /// Schedule outstanding requests from outstanding buffers to the internal buffer, /// from which requests are ready to be submitted to the device for processing. /// @function schedule_requests -/// @param[in] state normally an volatile integer variable to activates(val>0) and disactives(0) the scheduler. +/// @param[in] state A volatile integer variable used to activate (val>0) or +/// disactive (val=0) the scheduler. void* schedule_requests(void* state) { if (NULL == state) { printf("Failed at buffer_manager: argument is NULL.\n"); @@ -316,7 +317,8 @@ void* schedule_requests(void* state) { /// @brief Poll responses from a specific QAT instance. /// @function start_inst_polling -/// @param[in] HE_QAT_InstConfig Parameter values to start and to poll instances. +/// @param[in] _inst_config Instance configuration containing the parameter +/// values to start and poll responses from the accelerator. static void* start_inst_polling(void* _inst_config) { if (NULL == _inst_config) { printf( @@ -342,8 +344,27 @@ static void* start_inst_polling(void* _inst_config) { pthread_exit(NULL); } +/// @brief +/// Initialize and start multiple instances, their polling thread, +/// and a single processing thread. +/// +/// @function start_instances +/// It initializes multiple QAT instances and launches their respective independent +/// polling threads that will listen to responses to requests sent to the accelerators +/// concurrently. Then, it becomes the thread that collect the incoming requests stored +/// in a shared buffer and send them to the accelerator for processing. This is the only +/// processing thread for requests handled by multiple instances -- unlike when using +/// multiple instances with the `start_perform_op` function, in which case each instance +/// has a separate processing thread. The implementation of the multiple instance support +/// using `start_perform_op` is obsolete and slower. The way is using this function, which +/// delivers better performance. The scheduling of request offloads uses a +/// round-robin approach. It collects multiple requests from the internal buffer and then +/// send them to the multiple accelerator instances to process in a round-robin fashion. +/// It was designed to support processing requests of different operation types but +/// currently only supports Modular Exponentiation. +/// +/// @param[in] _config Data structure containing the configuration of multiple instances. void* start_instances(void* _config) { -// static unsigned int request_count = 0; static unsigned int instance_count = 0; static unsigned int next_instance = 0; @@ -556,13 +577,19 @@ void* start_instances(void* _config) { } /// @brief -/// @function perform_op -/// Offload operation to QAT endpoints; for example, large number modular -/// exponentiation. -/// @param[in] HE_QAT_InstConfig *: contains the handle to CPA instance, pointer -/// the global buffer of requests. +/// Start independent processing and polling threads for an instance. +/// +/// @function start_perform_op +/// It initializes a QAT instance and launches its polling thread to listen +/// to responses (request outputs) from the accelerator. It is also reponsible +/// to collect requests from the internal buffer and send them to the accelerator +/// periodiacally. It was designed to extend to receiving and offloading +/// requests of different operation types but currently only supports Modular +/// Exponentiation. +/// +/// @param[in] _inst_config Data structure containing the configuration of a single +/// instance. void* start_perform_op(void* _inst_config) { -// static unsigned int request_count = 0; if (NULL == _inst_config) { printf("Failed in start_perform_op: _inst_config is NULL.\n"); pthread_exit(NULL); @@ -738,18 +765,20 @@ void* start_perform_op(void* _inst_config) { pthread_exit(NULL); } -/// @brief -/// @function -/// Stop first 'num_inst' number of cpaCyInstance(s), including their polling -/// and running threads. -/// @param[in] HE_QAT_InstConfig config Vector of created instances with their -/// configuration setup. +/// @brief +/// Stop specified number of instances from running. +/// +/// @function stop_perform_op +/// Stop first 'num_inst' number of cpaCyInstance(s), including their polling +/// and running threads. +/// +/// @details +/// Stop runnning and polling instances. Release QAT instances handles. +/// +/// @param[in] config List of all created QAT instances and their configurations. /// @param[in] num_inst Unsigned integer number indicating first number of -/// instances to be terminated. +/// instances to be terminated. void stop_perform_op(HE_QAT_InstConfig* config, unsigned num_inst) { - // if () { - // Stop runnning and polling instances - // Release QAT instances handles if (NULL == config) return; CpaStatus status = CPA_STATUS_FAIL; @@ -788,6 +817,12 @@ void stop_perform_op(HE_QAT_InstConfig* config, unsigned num_inst) { return; } +/// @brief Stop all running instances. +/// @function stop_instances +/// @details +/// Stop all running instances after calling `start_instances()`. +/// It will set the states of the instances to terminate gracefully. +/// @param[in] _config All QAT instances configurations holding their states. void stop_instances(HE_QAT_Config* _config) { if (NULL == _config) return; if (_config->active) _config->active = 0; diff --git a/he_qat/he_qat_ops.c b/he_qat/he_qat_ops.c index 77410cf..84cf864 100644 --- a/he_qat/he_qat_ops.c +++ b/he_qat/he_qat_ops.c @@ -26,26 +26,16 @@ double time_taken = 0.0; #pragma message "Asynchronous execution mode." #endif -//#define RESTART_LATENCY_MICROSEC 600 -//#define NUM_PKE_SLICES 6 - #include "he_qat_gconst.h" // Global buffer for the runtime environment extern HE_QAT_RequestBuffer he_qat_buffer; extern HE_QAT_OutstandingBuffer outstanding; -//volatile unsigned long response_count = 0; -//static volatile unsigned long request_count = 0; -//static unsigned long request_latency = 0; // unused -//static unsigned long restart_threshold = NUM_PKE_SLICES;//48; -//static unsigned long max_pending = (NUM_PKE_SLICES * 2 * HE_QAT_NUM_ACTIVE_INSTANCES); - // Callback functions extern void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut); extern void HE_QAT_bnModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut); - /// @brief /// @function /// Thread-safe producer implementation for the shared request buffer. @@ -87,8 +77,7 @@ HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id) { return HE_QAT_STATUS_SUCCESS; } -HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, - int nbits) { +HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int nbits) { // Unpack data and copy to QAT friendly memory space int len = (nbits + 7) >> 3; // nbits / 8; diff --git a/he_qat/include/he_qat_bn_ops.h b/he_qat/include/he_qat_bn_ops.h index f47bbaf..a054c03 100644 --- a/he_qat/include/he_qat_bn_ops.h +++ b/he_qat/include/he_qat_bn_ops.h @@ -1,3 +1,34 @@ +/** + * @file he_qat_bn_ops.h + * + * @description + * In this file, functions for Big Number operations accelerated by the + * QuickAssist (QAT) co-processor are specified. + * + * @note + * Unless otherwise specified, Big numbers are represented by octet strings + * and stored in memory as pointers of type unsigned char*. On the QAT API the + * octect string is copied into a data structure of type CpaFlatBuffer. The octet + * strings representing Big Numbers are encoded with compliance to PKCA#1 v2.1, + * section 4, which is consistent with ASN.1 syntax. + * + * The largest number supported here has 4096 bits, i.e. numbers from 0 to + * 2^(4096)-1. The most significant bit is located at index n-1. If the number is + * N, then the bit length is defined by n = floor(log2(N))+1. The memory buffer b to + * hold such number N needs to have at least M = ceiling(n/8) bytes allocated. In + * general, it will be larger and a power of 2, e.g. total bytes allocated is T=128 + * for numbers having up to n=1024 bits, total bytes allocated is T=256 for numbers + * having up to n=2048 bits, and so forth. Finally, the big number N is stored in + * `big endian` format, i.e. the least significant byte (LSB) is located at index [T-1], + * whereas the most significant byte is stored at [T-M]. + * + * The API client is responsible for allocation and release of their memory spaces of + * the function arguments. Allocated memory spaces must be contiguous. Once a function + * is called, the ownership of the memory spaces is transfered to the function until + * their completion such that concurrent usage by the client during excution may result + * in undefined behavior. + */ + // New compilers #pragma once @@ -9,62 +40,38 @@ extern "C" { #endif -#include "he_qat_types.h" -//#include "cpa_sample_utils.h" -//#include - -//#include #include +#include "he_qat_types.h" -/// @brief +/// @brief Modular exponentiation using BIGNUM. +/// /// @function -/// Perform big number modular exponentiation for input data in -/// OpenSSL's BIGNUM format. +/// Perform big number modular exponentiation operation accelerated with QAT for input data +/// using OpenSSL BIGNUM data structure. +/// /// @details /// Create private buffer for code section. Create QAT contiguous memory space. /// Copy data and package into a request and call producer function to submit /// request into qat buffer. +/// /// @param r [out] Remainder number of the modular exponentiation operation. /// @param b [in] Base number of the modular exponentiation operation. /// @param e [in] Exponent number of the modular exponentiation operation. /// @param m [in] Modulus number of the modular exponentiation operation. /// @param nbits[in] Number of bits (bit precision) of input/output big numbers. -HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, - int nbits); - -/// @brief -/// @function setModExpRequest(unsigned worksize) -/// Allocate buffer to hold and monitor up to 'worksize' number of outstanding -/// requests. -/// @param[in] worksize Total number of modular exponentiation to perform in the -/// next code section. -// void setModExpRequest(unsigned worksize) - -/// @brief -/// @function getModExpRequest() -/// Monitor outstanding request to be complete and then deallocate buffer -/// holding outstanding request; -/// @details -/// Releasing QAT temporary memory. - -// wait for all outstanding requests to complete -// void getBnModExpRequest(); -void getBnModExpRequest(unsigned int num_requests); -/// thus, releasing temporary memory. -// create private buffer for code section -// create QAT contiguous memory space -// copy data and package into a request -// use producer to place request into qat buffer -// wait for all outstanding requests to complete +HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int nbits); /// @brief +/// /// @function /// Generic big number modular exponentiation for input data in primitive type /// format (unsigned char *). +/// /// @details /// Create private buffer for code section. Create QAT contiguous memory space. /// Copy data and package into a request and call producer function to submit /// request into qat buffer. +/// /// @param[out] r Remainder number of the modular exponentiation operation. /// @param[in] b Base number of the modular exponentiation operation. /// @param[in] e Exponent number of the modular exponentiation operation. @@ -73,13 +80,48 @@ void getBnModExpRequest(unsigned int num_requests); HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, unsigned char* e, unsigned char* m, int nbits); -/* ***** Multi-threading supported interface ******* */ +/// @brief +/// It waits for number of requests sent by HE_QAT_bnModExp or bnModExpPerformOp +/// to complete. +/// +/// @function getModExpRequest(unsigned int batch_size) +/// +/// @details +/// This function is blocking and works as barrier. The purpose of this function +/// is to wait for all outstanding requests to complete processing. It will also +/// release all temporary memory allocated to support the requests. +/// Monitor outstanding request to be complete and then deallocate buffer +/// holding outstanding request. +/// +/// @param[in] num_requests Number of requests to wait to complete processing. +void getBnModExpRequest(unsigned int num_requests); + +/** + * + * Interfaces for the Multithreading Support + * + **/ HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id); +/// @brief +/// +/// @function +/// Generic big number modular exponentiation for input data in primitive type +/// format (unsigned char *). +/// +/// @details +/// Create private buffer for code section. Create QAT contiguous memory space. +/// Copy data and package into a request and call producer function to submit +/// request into qat buffer. +/// +/// @param[out] r Remainder number of the modular exponentiation operation. +/// @param[in] b Base number of the modular exponentiation operation. +/// @param[in] e Exponent number of the modular exponentiation operation. +/// @param[in] m Modulus number of the modular exponentiation operation. +/// @param[in] nbits Number of bits (bit precision) of input/output big numbers. HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, - unsigned char* b, unsigned char* e, - unsigned char* m, int nbits); + unsigned char* b, unsigned char* e, unsigned char* m, int nbits); void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size); diff --git a/he_qat/include/he_qat_context.h b/he_qat/include/he_qat_context.h index 96195c1..a528b34 100644 --- a/he_qat/include/he_qat_context.h +++ b/he_qat/include/he_qat_context.h @@ -9,10 +9,7 @@ extern "C" { #endif #include "he_qat_types.h" -#include - -//#define HE_QAT_MAX_NUM_INST 8 -// const unsigned HE_QAT_MAX_NUM_INST = 8 +//#include /// @brief /// @function acquire_qat_devices @@ -21,7 +18,7 @@ HE_QAT_STATUS acquire_qat_devices(); /// @brief /// @function release_qat_devices -/// Configure and initialize QAT runtime environment. +/// Release and free resources of the QAT runtime environment. HE_QAT_STATUS release_qat_devices(); #ifdef __cplusplus From e7638aa24f365babedb2db208ec7e7bd39f9086a Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 7 Sep 2022 19:07:10 -0700 Subject: [PATCH 225/364] [WIP] Update code cleanup and refactoring. --- he_qat/he_qat_ctrl.c | 85 +++-- he_qat/he_qat_ops.c | 514 +++++++++++++++---------------- he_qat/include/he_qat_bn_ops.h | 5 +- samples/test_bnModExpPerformOp.c | 2 +- 4 files changed, 289 insertions(+), 317 deletions(-) diff --git a/he_qat/he_qat_ctrl.c b/he_qat/he_qat_ctrl.c index d23ba6d..dc8381e 100644 --- a/he_qat/he_qat_ctrl.c +++ b/he_qat/he_qat_ctrl.c @@ -41,8 +41,12 @@ static unsigned long request_latency = 0; ///< Variable used to hold measured av static unsigned long restart_threshold = NUM_PKE_SLICES; ///< Number of concurrent requests allowed to be sent to accelerator at once. static unsigned long max_pending = (NUM_PKE_SLICES * 2 * HE_QAT_NUM_ACTIVE_INSTANCES); ///< Number of requests sent to the accelerator that are pending completion. -/// @brief Populates either internal or outstanding buffer with request. -/// This function is called inside the API to submit request to a shared internal buffer. It is a thread-safe implementation of the producer for the either the internal buffer or the outstanding buffer to host incoming requests. Depending on the buffer type, the submitted request is either ready to be scheduled or to be processed by the accelerator. +/// @brief Populate internal buffer with incoming requests from API calls. +/// @details This function is called from the main APIs to submit requests to +/// a shared internal buffer for processing on QAT. It is a thread-safe implementation +/// of the producer for the either the internal buffer or the outstanding buffer to +/// host incoming requests. Depending on the buffer type, the submitted request +/// is either ready to be scheduled or to be processed by the accelerator. /// @param[out] _buffer either `he_qat_buffer` or `outstanding` buffer. /// @param[in] args work request packaged in a custom data structure. void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { @@ -66,6 +70,7 @@ void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { pthread_cond_signal(&_buffer->any_more_data); pthread_mutex_unlock(&_buffer->mutex); + #ifdef HE_QAT_DEBUG printf("Unlocked write request. [buffer size: %d]\n", _buffer->count); #endif @@ -116,9 +121,9 @@ static void submit_request_list(HE_QAT_RequestBuffer* _buffer, } -/// @brief Read requests from internal buffer. -/// Thread-safe consumer implementation for the shared request buffer. -/// Read requests from internal buffer `he_qat_buffer` to finally offload the request to be processed by QAT devices. +/// @brief Retrive single request from internal buffer. +/// @details Thread-safe consumer implementation for the shared request buffer. +/// Read request from internal buffer `he_qat_buffer` to finally offload the request to be processed by QAT devices. /// Supported in single-threaded or multi-threaded mode. /// @param[in] _buffer buffer of type HE_QAT_RequestBuffer, typically the internal buffer in current implementation. /// @retval single work request in HE_QAT_TaskRequest data structure. @@ -126,8 +131,9 @@ static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) { void* item = NULL; static unsigned int counter = 0; + pthread_mutex_lock(&_buffer->mutex); -//#define HE_QAT_DEBUG + #ifdef HE_QAT_DEBUG printf("Wait lock read request. [internal buffer size: %d] Request #%u\n", _buffer->count, counter++); @@ -145,6 +151,7 @@ static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) pthread_cond_signal(&_buffer->any_free_slot); pthread_mutex_unlock(&_buffer->mutex); + #ifdef HE_QAT_DEBUG printf("Unlocked read request. [internal buffer count: %d]\n", _buffer->count); @@ -153,10 +160,12 @@ static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) return (HE_QAT_TaskRequest*)(item); } -/// @brief Read requests from the outstanding buffer. -/// Thread-safe consumer implementation for the outstanding request buffer. -/// Read requests from outstanding buffer (requests ready to be scheduled) to later pass them to the internal buffer `he_qat_buffer`. As those requests move from the outstanding buffer into the internal buffer, their state changes from ready-to-be-scheduled to ready-to-be-processed. -/// Supported in single-threaded or multi-threaded mode. +/// @brief Retrieve multiple requests from the outstanding buffer. +/// @details Thread-safe consumer implementation for the outstanding request buffer. +/// Read requests from outstanding buffer (requests ready to be scheduled) to later pass +/// them to the internal buffer `he_qat_buffer`. As those requests move from the outstanding +/// buffer into the internal buffer, their state changes from ready-to-be-scheduled to +/// ready-to-be-processed. This function is supported both in single-threaded or multi-threaded mode. /// @param[out] _requests list of requests retrieved from internal buffer. /// @param[in] _buffer buffer of type HE_QAT_RequestBuffer, typically the internal buffer in current implementation. /// @param[in] max_requests maximum number of requests to retrieve from internal buffer, if available. @@ -192,7 +201,7 @@ static void read_request_list(HE_QAT_TaskRequestList* _requests, } /// @brief Read requests from the outstanding buffer. -/// Thread-safe consumer implementation for the outstanding request buffer. +/// @details Thread-safe consumer implementation for the outstanding request buffer. /// Retrieve work requests from outstanding buffer (requests ready to be scheduled) to later on pass them to the internal buffer `he_qat_buffer`. As those requests move from the outstanding buffer into the internal buffer, their state changes from ready-to-be-scheduled to ready-to-be-processed. /// This function is supported in single-threaded or multi-threaded mode. /// @param[out] _requests list of work requests retrieved from outstanding buffer. @@ -231,12 +240,11 @@ static void pull_outstanding_requests(HE_QAT_TaskRequestList* _requests, HE_QAT_ if (!any_ready) return; - // printf("Buffer #%u is Ready\n",index); - // Extract outstanding requests from outstanding buffer - // (this is the only function that reads from outstanding buffer, from a - // single thread) + // (this is the only function that reads from outstanding buffer, + // from a single thread) pthread_mutex_lock(&_outstanding_buffer->buffer[index].mutex); + // This conditional waiting may not be required // Wait while buffer is empty while (_outstanding_buffer->buffer[index].count <= 0) { @@ -244,7 +252,6 @@ static void pull_outstanding_requests(HE_QAT_TaskRequestList* _requests, HE_QAT_ &_outstanding_buffer->buffer[index].mutex); } assert(_outstanding_buffer->buffer[index].count > 0); - // unsigned int num_requests = (_outstanding_buffer->buffer[index].count < max_num_requests) @@ -280,7 +287,7 @@ static void pull_outstanding_requests(HE_QAT_TaskRequestList* _requests, HE_QAT_ } /// @brief Schedule outstanding requests to the internal buffer and be ready for processing. -/// Schedule outstanding requests from outstanding buffers to the internal buffer, +/// @details Schedule outstanding requests from outstanding buffers to the internal buffer, /// from which requests are ready to be submitted to the device for processing. /// @function schedule_requests /// @param[in] state A volatile integer variable used to activate (val>0) or @@ -301,15 +308,11 @@ void* schedule_requests(void* state) { // this thread should receive signal from context to exit while (*active) { - // collect a set of requests from the outstanding buffer + // Collect a set of requests from the outstanding buffer pull_outstanding_requests(&outstanding_requests, &outstanding, HE_QAT_BUFFER_SIZE); - // printf("Pulled %u outstanding - //requests\n",outstanding_requests.count); - // submit them to the HE QAT buffer for offloading + // Submit them to the HE QAT buffer for offloading submit_request_list(&he_qat_buffer, &outstanding_requests); - // printf("Submitted %u outstanding - //requests\n",outstanding_requests.count); } pthread_exit(NULL); @@ -437,13 +440,11 @@ void* start_instances(void* _config) { } // for loop - /* NEW CODE */ HE_QAT_TaskRequestList outstanding_requests; for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { outstanding_requests.request[i] = NULL; } outstanding_requests.count = 0; - /* END NEW CODE */ config->running = 1; config->active = 1; @@ -451,7 +452,6 @@ void* start_instances(void* _config) { #ifdef HE_QAT_DEBUG printf("Try reading request from buffer. Inst #%d\n", config->inst_id); #endif - /* NEW CODE */ unsigned long pending = request_count - response_count; unsigned long available = max_pending - ((pending < max_pending)?pending:max_pending); #ifdef HE_QAT_DEBUG @@ -466,26 +466,20 @@ void* start_instances(void* _config) { OS_SLEEP(RESTART_LATENCY_MICROSEC); pending = request_count - response_count; available = max_pending - ((pending < max_pending)?pending:max_pending); -// printf("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", -// request_count,response_count,pending,available); +#ifdef HE_QAT_DEBUG + printf("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", + request_count,response_count,pending,available); +#endif } #ifdef HE_QAT_DEBUG printf("[SUBMIT] request_count: %lu response_count: %lu pending: %lu available: %lu\n", request_count,response_count,pending,available); #endif unsigned int max_requests = available; + // Try consume maximum amount of data from butter to perform requested operation read_request_list(&outstanding_requests, &he_qat_buffer, max_requests); - /* END NEW CODE */ -// // Try consume data from butter to perform requested operation -// HE_QAT_TaskRequest* request = -// (HE_QAT_TaskRequest*)read_request(&he_qat_buffer); -// -// if (NULL == request) { -// pthread_cond_signal(&config->ready); -// continue; -// } #ifdef HE_QAT_DEBUG printf("Offloading %u requests to the accelerator.\n", outstanding_requests.count); #endif @@ -537,14 +531,13 @@ void* start_instances(void* _config) { // Global tracking of number of requests request_count += 1; request_count_per_instance[next_instance] += 1; -// printf("Instance %d Count %u\n",next_instance,request_count_per_instance[next_instance]); next_instance = (next_instance + 1) % instance_count; -// printf("retry_count = %d\n",retry_count); -// printf("SUCCESS Next Instance = %d\n",next_instance); - // Wake up any blocked call to stop_perform_op, signaling that now it is - // safe to terminate running instances. Check if this detereorate - // performance. - pthread_cond_signal(&config->inst_config[next_instance].ready); // Prone to the lost wake-up problem + + // Wake up any blocked call to stop_perform_op, signaling that now it is + // safe to terminate running instances. Check if this detereorate + // performance. + pthread_cond_signal(&config->inst_config[next_instance].ready); // Prone to the lost wake-up problem + #ifdef HE_QAT_SYNC_MODE // Wait until the callback function has been called if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { @@ -632,13 +625,11 @@ void* start_perform_op(void* _inst_config) { pthread_exit(NULL); } - /* NEW CODE */ HE_QAT_TaskRequestList outstanding_requests; for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { outstanding_requests.request[i] = NULL; } outstanding_requests.count = 0; - /* END NEW CODE */ config->running = 1; config->active = 1; @@ -646,7 +637,6 @@ void* start_perform_op(void* _inst_config) { #ifdef HE_QAT_DEBUG printf("Try reading request from buffer. Inst #%d\n", config->inst_id); #endif - /* NEW CODE */ unsigned long pending = request_count - response_count; unsigned long available = max_pending - ((pending < max_pending)?pending:max_pending); #ifdef HE_QAT_DEBUG @@ -669,7 +659,6 @@ void* start_perform_op(void* _inst_config) { unsigned int max_requests = available; // Try consume maximum amount of data from butter to perform requested operation read_request_list(&outstanding_requests, &he_qat_buffer, max_requests); - /* END NEW CODE */ // // Try consume data from butter to perform requested operation // HE_QAT_TaskRequest* request = diff --git a/he_qat/he_qat_ops.c b/he_qat/he_qat_ops.c index 84cf864..1a11b46 100644 --- a/he_qat/he_qat_ops.c +++ b/he_qat/he_qat_ops.c @@ -1,3 +1,4 @@ +/// @file he_qat_ops.c #include "cpa.h" #include "cpa_cy_im.h" @@ -36,50 +37,126 @@ extern HE_QAT_OutstandingBuffer outstanding; extern void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut); extern void HE_QAT_bnModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut); -/// @brief -/// @function -/// Thread-safe producer implementation for the shared request buffer. -/// Stores requests in a buffer that will be offload to QAT devices. +/// @brief Thread-safe producer implementation for the shared request buffer. +/// @details Fill internal or outstanding buffer with incoming work requests. +/// This function is implemented in he_qat_ctrl.c. extern void submit_request(HE_QAT_RequestBuffer* _buffer, void* args); -// Frontend for multithreading support -HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id) { - if (NULL == _buffer_id) return HE_QAT_STATUS_INVALID_PARAM; - pthread_mutex_lock(&outstanding.mutex); - // Wait until next outstanding buffer becomes available for use - while (outstanding.busy_count >= HE_QAT_BUFFER_COUNT) - pthread_cond_wait(&outstanding.any_free_buffer, &outstanding.mutex); +/* + * ************************************************************************** + * Implementation of Functions for the Single Interface Support + * ************************************************************************** + */ - assert(outstanding.busy_count < HE_QAT_BUFFER_COUNT); +HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, + unsigned char* e, unsigned char* m, int nbits) { + static unsigned long long req_count = 0; + + // Unpack data and copy to QAT friendly memory space + int len = (nbits + 7) >> 3; // nbits / 8; - // find next available - unsigned int next_free_buffer = outstanding.next_free_buffer; - for (unsigned int i = 0; i < HE_QAT_BUFFER_COUNT; i++) { - if (outstanding.free_buffer[next_free_buffer]) { - outstanding.free_buffer[next_free_buffer] = 0; - *_buffer_id = next_free_buffer; - break; - } - next_free_buffer = (next_free_buffer + 1) % HE_QAT_BUFFER_COUNT; + if (NULL == r) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == b) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == e) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == m) return HE_QAT_STATUS_INVALID_PARAM; + + Cpa8U* pBase = NULL; + Cpa8U* pModulus = NULL; + Cpa8U* pExponent = NULL; + + // TODO(fdiasmor): Try it with 8-byte alignment. + CpaStatus status = CPA_STATUS_FAIL; + // status = PHYS_CONTIG_ALLOC(&pBase, len); + status = PHYS_CONTIG_ALLOC_ALIGNED(&pBase, len, 8); + if (CPA_STATUS_SUCCESS == status && NULL != pBase) { + memcpy(pBase, b, len); + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; } - outstanding.next_free_buffer = (*_buffer_id + 1) % HE_QAT_BUFFER_COUNT; - outstanding.next_ready_buffer = *_buffer_id; - outstanding.ready_buffer[*_buffer_id] = 1; - outstanding.busy_count++; - // busy meaning: - // taken by a thread, enqueued requests, in processing, waiting results + // status = PHYS_CONTIG_ALLOC(&pExponent, len); + status = PHYS_CONTIG_ALLOC_ALIGNED(&pExponent, len, 8); + if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { + memcpy(pExponent, e, len); + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } - pthread_cond_signal(&outstanding.any_ready_buffer); - pthread_mutex_unlock(&outstanding.mutex); + // status = PHYS_CONTIG_ALLOC(&pModulus, len); + status = PHYS_CONTIG_ALLOC_ALIGNED(&pModulus, len, 8); + if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { + memcpy(pModulus, m, len); + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + // HE_QAT_TaskRequest request = + // HE_QAT_PACK_MODEXP_REQUEST(pBase, pExponent, pModulus, r) + // Pack it as a QAT Task Request + HE_QAT_TaskRequest* request = + (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); + if (NULL == request) { + printf( + "HE_QAT_TaskRequest memory allocation failed in " + "bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + + CpaCyLnModExpOpData* op_data = + (CpaCyLnModExpOpData*)calloc(1, sizeof(CpaCyLnModExpOpData)); + if (NULL == op_data) { + printf("Cpa memory allocation failed in bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + op_data->base.pData = pBase; + op_data->base.dataLenInBytes = len; + op_data->exponent.pData = pExponent; + op_data->exponent.dataLenInBytes = len; + op_data->modulus.pData = pModulus; + op_data->modulus.dataLenInBytes = len; + request->op_data = (void*)op_data; + + // status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); + status = PHYS_CONTIG_ALLOC_ALIGNED(&request->op_result.pData, len, 8); + if (CPA_STATUS_SUCCESS == status && NULL != request->op_result.pData) { + request->op_result.dataLenInBytes = len; + } else { + printf( + "CpaFlatBuffer.pData memory allocation failed in " + "bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + + request->op_type = HE_QAT_OP_MODEXP; + request->callback_func = (void*)HE_QAT_bnModExpCallback; + request->op_status = status; + request->op_output = (void*)r; + + request->id = req_count++; + + // Ensure calls are synchronized at exit (blocking) + pthread_mutex_init(&request->mutex, NULL); + pthread_cond_init(&request->ready, NULL); + +#ifdef HE_QAT_DEBUG + printf("BN ModExp interface call for request #%llu\n", req_count); +#endif + + // Submit request using producer function + submit_request(&he_qat_buffer, (void*)request); return HE_QAT_STATUS_SUCCESS; } -HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int nbits) { +HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int nbits) { + static unsigned long long req_count = 0; + // Unpack data and copy to QAT friendly memory space - int len = (nbits + 7) >> 3; // nbits / 8; + int len = (nbits + 7) >> 3; Cpa8U* pBase = NULL; Cpa8U* pModulus = NULL; @@ -98,20 +175,11 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int CpaStatus status = CPA_STATUS_FAIL; status = PHYS_CONTIG_ALLOC(&pBase, len); if (CPA_STATUS_SUCCESS == status && NULL != pBase) { - //{ - // unsigned char* bin = (unsigned char*)calloc(len, sizeof(unsigned - // char)); if (BN_bn2binpad(b, bin, len)) { - if (BN_bn2binpad(b, pBase, len)) { - // memcpy(pBase, bin, len); - // pBase = (Cpa8U*)bin; - } else { + if (!BN_bn2binpad(b, pBase, len)) { printf("BN_bn2binpad (base) failed in bnModExpPerformOp.\n"); PHYS_CONTIG_FREE(pBase); - // free(bin); - // bin = NULL; return HE_QAT_STATUS_FAIL; } - //} } else { printf("Contiguous memory allocation failed for pBase.\n"); return HE_QAT_STATUS_FAIL; @@ -119,20 +187,11 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int status = PHYS_CONTIG_ALLOC(&pExponent, len); if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { - //{ - // unsigned char* bin = (unsigned char*)calloc(len, sizeof(unsigned - // char)); if (BN_bn2binpad(e, bin, len)) { - if (BN_bn2binpad(e, pExponent, len)) { - // memcpy(pExponent, bin, len); - // pExponent = (Cpa8U*)bin; - } else { + if (!BN_bn2binpad(e, pExponent, len)) { printf("BN_bn2binpad (exponent) failed in bnModExpPerformOp.\n"); PHYS_CONTIG_FREE(pExponent); - // free(bin); - // bin = NULL; return HE_QAT_STATUS_FAIL; } - //} } else { printf("Contiguous memory allocation failed for pBase.\n"); return HE_QAT_STATUS_FAIL; @@ -140,20 +199,11 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int status = PHYS_CONTIG_ALLOC(&pModulus, len); if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { - //{ - // unsigned char* bin = (unsigned char*)calloc(len, sizeof(unsigned - // char)); if (BN_bn2binpad(m, bin, len)) { - if (BN_bn2binpad(m, pModulus, len)) { - // memcpy(pModulus, bin, len); - // pModulus = (Cpa8U*)bin; - } else { + if (!BN_bn2binpad(m, pModulus, len)) { printf("BN_bn2binpad failed in bnModExpPerformOp.\n"); PHYS_CONTIG_FREE(pModulus); - // free(bin); - // bin = NULL; return HE_QAT_STATUS_FAIL; } - //} } else { printf("Contiguous memory allocation failed for pBase.\n"); return HE_QAT_STATUS_FAIL; @@ -185,11 +235,11 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int } request->op_type = HE_QAT_OP_MODEXP; - //request->callback_func = (void*)lnModExpCallback; request->callback_func = (void*)HE_QAT_BIGNUMModExpCallback; request->op_status = status; request->op_output = (void*)r; - + + request->id = req_count++; // Ensure calls are synchronized at exit (blocking) pthread_mutex_init(&request->mutex, NULL); pthread_cond_init(&request->ready, NULL); @@ -200,107 +250,6 @@ HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int return HE_QAT_STATUS_SUCCESS; } -// Assume allocate_bnModExp_buffer(&_buffer_id) to be called first -// to secure and allocate an outstanding buffer for the target thread. -// Multithread support for release_bnModExp_buffer(_buffer_id, batch_size) -void release_bnModExp_buffer(unsigned int _buffer_id, - unsigned int _batch_size) { - unsigned int next_data_out = outstanding.buffer[_buffer_id].next_data_out; - unsigned int j = 0; - -#ifdef HE_QAT_DEBUG - printf("release_bnModExp_buffer #%u\n", _buffer_id); -#endif - -#ifdef HE_QAT_PERF - gettimeofday(&start_time, NULL); -#endif - - while (j < _batch_size) { - // Buffer read may be safe for single-threaded blocking calls only. - // Note: Not tested on multithreaded environment. - HE_QAT_TaskRequest* task = - (HE_QAT_TaskRequest*)outstanding.buffer[_buffer_id] - .data[next_data_out]; - - if (NULL == task) continue; - -#ifdef HE_QAT_DEBUG - printf("BatchSize %u Buffer #%u Request #%u Waiting\n", _batch_size, - _buffer_id, j); -#endif - - // Block and synchronize: Wait for the most recently offloaded request - // to complete processing - pthread_mutex_lock( - &task->mutex); // mutex only needed for the conditional variable - while (HE_QAT_STATUS_READY != task->request_status) - pthread_cond_wait(&task->ready, &task->mutex); - -#ifdef HE_QAT_PERF - time_taken = (task->end.tv_sec - task->start.tv_sec) * 1e6; - time_taken = - (time_taken + (task->end.tv_usec - task->start.tv_usec)); //*1e-6; - printf("%u time: %.1lfus\n", j, time_taken); -#endif - - // Free up QAT temporary memory - CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; - if (op_data) { - PHYS_CONTIG_FREE(op_data->base.pData); - PHYS_CONTIG_FREE(op_data->exponent.pData); - PHYS_CONTIG_FREE(op_data->modulus.pData); - } - free(task->op_data); - task->op_data = NULL; - if (task->op_result.pData) { - PHYS_CONTIG_FREE(task->op_result.pData); - } - - // Move forward to wait for the next request that will be offloaded - pthread_mutex_unlock(&task->mutex); - -#ifdef HE_QAT_DEBUG - printf("Buffer #%u Request #%u Completed\n", _buffer_id, j); -#endif - // outstanding.buffer[_buffer_id].count--; - - // Fix segmentation fault? - free(outstanding.buffer[_buffer_id].data[next_data_out]); - outstanding.buffer[_buffer_id].data[next_data_out] = NULL; - - // update for next thread on the next external iteration - next_data_out = (next_data_out + 1) % HE_QAT_BUFFER_SIZE; - - j++; - } - -#ifdef HE_QAT_PERF - gettimeofday(&end_time, NULL); - time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; - time_taken = - (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; - printf("Batch Wall Time: %.1lfus\n", time_taken); -#endif - - outstanding.buffer[_buffer_id].next_data_out = next_data_out; - - // Release outstanding buffer for usage by another thread - pthread_mutex_lock(&outstanding.mutex); - - outstanding.next_free_buffer = _buffer_id; - outstanding.ready_buffer[_buffer_id] = 0; - outstanding.free_buffer[_buffer_id] = 1; - outstanding.busy_count--; - - pthread_cond_signal(&outstanding.any_free_buffer); - pthread_mutex_unlock(&outstanding.mutex); - - return; -} - -// Maybe it will be useful to pass the number of requests to retrieve -// Pass post-processing function as argument to bring output to expected type void getBnModExpRequest(unsigned int batch_size) { static unsigned long block_at_index = 0; unsigned int j = 0; @@ -308,7 +257,6 @@ void getBnModExpRequest(unsigned int batch_size) { #ifdef HE_QAT_PERF gettimeofday(&start_time, NULL); #endif -//printf("batch_size=%u \n",batch_size); // while (j < batch_size) { do { // Buffer read may be safe for single-threaded blocking calls only. @@ -319,8 +267,6 @@ void getBnModExpRequest(unsigned int batch_size) { if (NULL == task) continue; -//printf("j=%u ",j); - // Block and synchronize: Wait for the most recently offloaded request // to complete processing pthread_mutex_lock( @@ -368,20 +314,22 @@ void getBnModExpRequest(unsigned int batch_size) { printf("Batch Wall Time: %.1lfus\n", time_taken); #endif -// printf("\n"); - return; } +/* + * ************************************************************************** + * Implementation of Functions for the Multithreading Interface Support + * ************************************************************************** + */ -HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, - unsigned char* e, unsigned char* m, int nbits) { -//#ifdef HE_QAT_DEBUG +HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, + unsigned char* b, unsigned char* e, + unsigned char* m, int nbits) { static unsigned long long req_count = 0; -//#endif + // Unpack data and copy to QAT friendly memory space - //int len = nbits / 8; - int len = (nbits + 7) >> 3; // nbits / 8; + int len = (nbits + 7) >> 3; if (NULL == r) return HE_QAT_STATUS_INVALID_PARAM; if (NULL == b) return HE_QAT_STATUS_INVALID_PARAM; @@ -462,122 +410,158 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, request->callback_func = (void*)HE_QAT_bnModExpCallback; request->op_status = status; request->op_output = (void*)r; - + + request->id = req_count++; + // Ensure calls are synchronized at exit (blocking) pthread_mutex_init(&request->mutex, NULL); pthread_cond_init(&request->ready, NULL); - request->id = req_count; #ifdef HE_QAT_DEBUG - printf("BN ModExp interface call for request #%llu\n", ++req_count); + printf("BN ModExp interface call for request #%llu\n", req_count); #endif // Submit request using producer function - submit_request(&he_qat_buffer, (void*)request); + submit_request(&outstanding.buffer[_buffer_id], (void*)request); return HE_QAT_STATUS_SUCCESS; } -HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, - unsigned char* b, unsigned char* e, - unsigned char* m, int nbits) { -#ifdef HE_QAT_DEBUG - static unsigned long long req_count = 0; - // printf("Wait lock write request. [buffer size: %d]\n",_buffer->count); -#endif - // Unpack data and copy to QAT friendly memory space - int len = nbits / 8; +/// @brief Frontend for multithreading support. +/// @details Try to acquire an outstanding buffer available. +/// If none available, it waits until another concurrent +/// thread releases one. This function must be called before +/// calling HE_QAT_bnModExp_MT(). +HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id) { + if (NULL == _buffer_id) return HE_QAT_STATUS_INVALID_PARAM; - if (NULL == r) return HE_QAT_STATUS_INVALID_PARAM; - if (NULL == b) return HE_QAT_STATUS_INVALID_PARAM; - if (NULL == e) return HE_QAT_STATUS_INVALID_PARAM; - if (NULL == m) return HE_QAT_STATUS_INVALID_PARAM; + pthread_mutex_lock(&outstanding.mutex); - Cpa8U* pBase = NULL; - Cpa8U* pModulus = NULL; - Cpa8U* pExponent = NULL; + // Wait until next outstanding buffer becomes available for use + while (outstanding.busy_count >= HE_QAT_BUFFER_COUNT) + pthread_cond_wait(&outstanding.any_free_buffer, &outstanding.mutex); - // TODO(fdiasmor): Try it with 8-byte alignment. - CpaStatus status = CPA_STATUS_FAIL; - // status = PHYS_CONTIG_ALLOC(&pBase, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pBase, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pBase) { - memcpy(pBase, b, len); - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; - } + assert(outstanding.busy_count < HE_QAT_BUFFER_COUNT); - // status = PHYS_CONTIG_ALLOC(&pExponent, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pExponent, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { - memcpy(pExponent, e, len); - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; + // Find next outstanding buffer available + unsigned int next_free_buffer = outstanding.next_free_buffer; + for (unsigned int i = 0; i < HE_QAT_BUFFER_COUNT; i++) { + if (outstanding.free_buffer[next_free_buffer]) { + outstanding.free_buffer[next_free_buffer] = 0; + *_buffer_id = next_free_buffer; + break; + } + next_free_buffer = (next_free_buffer + 1) % HE_QAT_BUFFER_COUNT; } - // status = PHYS_CONTIG_ALLOC(&pModulus, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pModulus, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { - memcpy(pModulus, m, len); - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; - } + outstanding.next_free_buffer = (*_buffer_id + 1) % HE_QAT_BUFFER_COUNT; + outstanding.next_ready_buffer = *_buffer_id; + outstanding.ready_buffer[*_buffer_id] = 1; + outstanding.busy_count++; + // busy meaning: + // taken by a thread, enqueued requests, in processing, waiting results - // HE_QAT_TaskRequest request = - // HE_QAT_PACK_MODEXP_REQUEST(pBase, pExponent, pModulus, r) - // Pack it as a QAT Task Request - HE_QAT_TaskRequest* request = - (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); - if (NULL == request) { - printf( - "HE_QAT_TaskRequest memory allocation failed in " - "bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } + pthread_cond_signal(&outstanding.any_ready_buffer); + pthread_mutex_unlock(&outstanding.mutex); - CpaCyLnModExpOpData* op_data = - (CpaCyLnModExpOpData*)calloc(1, sizeof(CpaCyLnModExpOpData)); - if (NULL == op_data) { - printf("Cpa memory allocation failed in bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } - op_data->base.pData = pBase; - op_data->base.dataLenInBytes = len; - op_data->exponent.pData = pExponent; - op_data->exponent.dataLenInBytes = len; - op_data->modulus.pData = pModulus; - op_data->modulus.dataLenInBytes = len; - request->op_data = (void*)op_data; + return HE_QAT_STATUS_SUCCESS; +} - // status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&request->op_result.pData, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != request->op_result.pData) { - request->op_result.dataLenInBytes = len; - } else { - printf( - "CpaFlatBuffer.pData memory allocation failed in " - "bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } +/// @brief Wait for request processing to complete and release previously acquired buffer. +/// @details Caution: It assumes acquire_bnModExp_buffer(&_buffer_id) to be called first +/// to secure and be assigned an outstanding buffer for the target thread. +/// Equivalent to getBnModExpRequests() for the multithreading support interfaces. +void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size) { + unsigned int next_data_out = outstanding.buffer[_buffer_id].next_data_out; + unsigned int j = 0; - request->op_type = HE_QAT_OP_MODEXP; - request->callback_func = (void*)HE_QAT_bnModExpCallback; - request->op_status = status; - request->op_output = (void*)r; +#ifdef HE_QAT_DEBUG + printf("release_bnModExp_buffer #%u\n", _buffer_id); +#endif - // Ensure calls are synchronized at exit (blocking) - pthread_mutex_init(&request->mutex, NULL); - pthread_cond_init(&request->ready, NULL); +#ifdef HE_QAT_PERF + gettimeofday(&start_time, NULL); +#endif + + while (j < _batch_size) { + // Buffer read may be safe for single-threaded blocking calls only. + // Note: Not tested on multithreaded environment. + HE_QAT_TaskRequest* task = + (HE_QAT_TaskRequest*)outstanding.buffer[_buffer_id] + .data[next_data_out]; + + if (NULL == task) continue; #ifdef HE_QAT_DEBUG - printf("BN ModExp interface call for request #%llu\n", ++req_count); + printf("BatchSize %u Buffer #%u Request #%u Waiting\n", _batch_size, + _buffer_id, j); #endif - // Submit request using producer function - submit_request(&outstanding.buffer[_buffer_id], (void*)request); + // Block and synchronize: Wait for the most recently offloaded request + // to complete processing + pthread_mutex_lock( + &task->mutex); // mutex only needed for the conditional variable + while (HE_QAT_STATUS_READY != task->request_status) + pthread_cond_wait(&task->ready, &task->mutex); - return HE_QAT_STATUS_SUCCESS; +#ifdef HE_QAT_PERF + time_taken = (task->end.tv_sec - task->start.tv_sec) * 1e6; + time_taken = + (time_taken + (task->end.tv_usec - task->start.tv_usec)); //*1e-6; + printf("%u time: %.1lfus\n", j, time_taken); +#endif + + // Free up QAT temporary memory + CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; + if (op_data) { + PHYS_CONTIG_FREE(op_data->base.pData); + PHYS_CONTIG_FREE(op_data->exponent.pData); + PHYS_CONTIG_FREE(op_data->modulus.pData); + } + free(task->op_data); + task->op_data = NULL; + if (task->op_result.pData) { + PHYS_CONTIG_FREE(task->op_result.pData); + } + + // Move forward to wait for the next request that will be offloaded + pthread_mutex_unlock(&task->mutex); + +#ifdef HE_QAT_DEBUG + printf("Buffer #%u Request #%u Completed\n", _buffer_id, j); +#endif + // outstanding.buffer[_buffer_id].count--; + + // Fix segmentation fault? + free(outstanding.buffer[_buffer_id].data[next_data_out]); + outstanding.buffer[_buffer_id].data[next_data_out] = NULL; + + // update for next thread on the next external iteration + next_data_out = (next_data_out + 1) % HE_QAT_BUFFER_SIZE; + + j++; + } + +#ifdef HE_QAT_PERF + gettimeofday(&end_time, NULL); + time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; + time_taken = + (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; + printf("Batch Wall Time: %.1lfus\n", time_taken); +#endif + + outstanding.buffer[_buffer_id].next_data_out = next_data_out; + + // Release outstanding buffer for usage by another thread + pthread_mutex_lock(&outstanding.mutex); + + outstanding.next_free_buffer = _buffer_id; + outstanding.ready_buffer[_buffer_id] = 0; + outstanding.free_buffer[_buffer_id] = 1; + outstanding.busy_count--; + + pthread_cond_signal(&outstanding.any_free_buffer); + pthread_mutex_unlock(&outstanding.mutex); + + return; } diff --git a/he_qat/include/he_qat_bn_ops.h b/he_qat/include/he_qat_bn_ops.h index a054c03..fbce595 100644 --- a/he_qat/include/he_qat_bn_ops.h +++ b/he_qat/include/he_qat_bn_ops.h @@ -59,7 +59,7 @@ extern "C" { /// @param e [in] Exponent number of the modular exponentiation operation. /// @param m [in] Modulus number of the modular exponentiation operation. /// @param nbits[in] Number of bits (bit precision) of input/output big numbers. -HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int nbits); +HE_QAT_STATUS HE_QAT_BIGUMbnModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int nbits); /// @brief /// @@ -102,8 +102,6 @@ void getBnModExpRequest(unsigned int num_requests); * **/ -HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id); - /// @brief /// /// @function @@ -123,6 +121,7 @@ HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id); HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, unsigned char* b, unsigned char* e, unsigned char* m, int nbits); +HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id); void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size); #ifdef __cplusplus diff --git a/samples/test_bnModExpPerformOp.c b/samples/test_bnModExpPerformOp.c index 2d06e5a..a3487ed 100644 --- a/samples/test_bnModExpPerformOp.c +++ b/samples/test_bnModExpPerformOp.c @@ -82,7 +82,7 @@ int main(int argc, const char** argv) { BIGNUM* qat_res = BN_new(); start = clock(); for (unsigned int j = 0; j < BATCH_SIZE; j++) - status = bnModExpPerformOp(qat_res, bn_base, bn_exponent, bn_mod, + status = HE_QAT_BIGNUMModExp(qat_res, bn_base, bn_exponent, bn_mod, bit_length); getBnModExpRequest(BATCH_SIZE); qat_elapsed = clock() - start; From 3f65d5c139df2eba40a8360cd2f931d53e16bbcb Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 7 Sep 2022 19:14:17 -0700 Subject: [PATCH 226/364] Remove outdated comments. --- he_qat/he_qat_ops.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/he_qat/he_qat_ops.c b/he_qat/he_qat_ops.c index 1a11b46..dba7c74 100644 --- a/he_qat/he_qat_ops.c +++ b/he_qat/he_qat_ops.c @@ -484,8 +484,6 @@ void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size) #endif while (j < _batch_size) { - // Buffer read may be safe for single-threaded blocking calls only. - // Note: Not tested on multithreaded environment. HE_QAT_TaskRequest* task = (HE_QAT_TaskRequest*)outstanding.buffer[_buffer_id] .data[next_data_out]; @@ -498,9 +496,8 @@ void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size) #endif // Block and synchronize: Wait for the most recently offloaded request - // to complete processing - pthread_mutex_lock( - &task->mutex); // mutex only needed for the conditional variable + // to complete processing. Mutex only needed for the conditional variable. + pthread_mutex_lock(&task->mutex); while (HE_QAT_STATUS_READY != task->request_status) pthread_cond_wait(&task->ready, &task->mutex); @@ -532,11 +529,10 @@ void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size) #endif // outstanding.buffer[_buffer_id].count--; - // Fix segmentation fault? free(outstanding.buffer[_buffer_id].data[next_data_out]); outstanding.buffer[_buffer_id].data[next_data_out] = NULL; - // update for next thread on the next external iteration + // Update for next thread on the next external iteration next_data_out = (next_data_out + 1) % HE_QAT_BUFFER_SIZE; j++; From 884042a8250baf97211a271d054dcd1cda9ed9b5 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 7 Sep 2022 19:20:10 -0700 Subject: [PATCH 227/364] Remove dead code. --- misc/he_qat_misc.cpp | 63 -------------------------------------------- 1 file changed, 63 deletions(-) diff --git a/misc/he_qat_misc.cpp b/misc/he_qat_misc.cpp index 79fc256..f0d0ce3 100644 --- a/misc/he_qat_misc.cpp +++ b/misc/he_qat_misc.cpp @@ -7,69 +7,6 @@ #include #include -BIGNUM* generateTestBNData(int nbits) { - if (!RAND_status()) return NULL; -#ifdef _DESTINY_DEBUG_VERBOSE - printf("PRNG properly seeded.\n"); -#endif - - BIGNUM* bn = BN_new(); - - if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { - BN_free(bn); - printf("Error while generating BN random number: %lu\n", - ERR_get_error()); - return NULL; - } - - return bn; -} - -unsigned char* paddingZeros(BIGNUM* bn, int nbits) { - if (!bn) return NULL; - - // Returns same address if it fails - int num_bytes = BN_num_bytes(bn); - int bytes_left = nbits / 8 - num_bytes; - if (bytes_left <= 0) return NULL; - - // Returns same address if it fails - unsigned char* bin = NULL; - int len = bytes_left + num_bytes; - if (!(bin = reinterpret_cast(OPENSSL_zalloc(len)))) - return NULL; - -#ifdef _DESTINY_DEBUG_VERBOSE - printf("Padding bn with %d bytes to total %d bytes\n", bytes_left, len); -#endif - BN_bn2binpad(bn, bin, len); - if (ERR_get_error()) { - OPENSSL_free(bin); - return NULL; - } - - return bin; -} - -void showHexBN(BIGNUM* bn, int nbits) { - int len = nbits / 8; - unsigned char* bin = reinterpret_cast(OPENSSL_zalloc(len)); - if (!bin) return; - if (BN_bn2binpad(bn, bin, len)) { - for (size_t i = 0; i < len; i++) printf("%d", bin[i]); - printf("\n"); - } - OPENSSL_free(bin); - return; -} - -void showHexBin(unsigned char* bin, int len) { - if (!bin) return; - for (size_t i = 0; i < len; i++) printf("%d", bin[i]); - printf("\n"); - return; -} - //#ifdef __cplusplus HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, int nbits) { From 15a68aee4582eecb9bf121ef62eba449f5178290 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 7 Sep 2022 19:22:25 -0700 Subject: [PATCH 228/364] Fix interface name. --- he_qat/include/he_qat_bn_ops.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/he_qat/include/he_qat_bn_ops.h b/he_qat/include/he_qat_bn_ops.h index fbce595..05fdc83 100644 --- a/he_qat/include/he_qat_bn_ops.h +++ b/he_qat/include/he_qat_bn_ops.h @@ -59,7 +59,7 @@ extern "C" { /// @param e [in] Exponent number of the modular exponentiation operation. /// @param m [in] Modulus number of the modular exponentiation operation. /// @param nbits[in] Number of bits (bit precision) of input/output big numbers. -HE_QAT_STATUS HE_QAT_BIGUMbnModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int nbits); +HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int nbits); /// @brief /// From 8e9d2c6b2e10e3420480d9c15f22f36a4a5da769 Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Thu, 8 Sep 2022 15:31:51 +0800 Subject: [PATCH 229/364] Apply public repo changes: 2 insecure rng fix (#126) * Improve RNG security - Add RDSEED and RDRAND instruction check in compile time - Prioritize RDSEED/RDRAND based RNG to produce random big number - Use IPP-Crypto pseudo random number generator if none of those instructions are supported - Remove seed setup for prime number generator - Add support to TRNGen_RDSEED and PRNGen_RDRAND for prime number generator * Refactor apply obfuscator - Refactor apply_obfuscator - minor typo fix --- CMakeLists.txt | 17 +++++++ ipcl/CMakeLists.txt | 1 + ipcl/common.cpp | 56 ++++++++++++++++++++++ ipcl/include/ipcl/common.hpp | 29 +++++++++++ ipcl/include/ipcl/pub_key.hpp | 20 ++------ ipcl/keygen.cpp | 62 +++++++++--------------- ipcl/pub_key.cpp | 90 ++++++++++------------------------- 7 files changed, 154 insertions(+), 121 deletions(-) create mode 100644 ipcl/common.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4bdaf00..92aab59 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,6 +115,23 @@ else() endif() endif() +# check whether cpu support rdseed or rdrand instruction +set(CPU_RDSEED_FLAG "rdseed") +execute_process(COMMAND lscpu COMMAND grep ${CPU_RDSEED_FLAG} OUTPUT_VARIABLE CPU_ENABLE_RDSEED) +if("${CPU_ENABLE_RDSEED}" STREQUAL "") + set(CPU_RDRAND_FLAG "rdrand") + execute_process(COMMAND lscpu COMMAND grep ${CPU_RDRAND_FLAG} OUTPUT_VARIABLE CPU_ENABLE_RDRAND) + if("${CPU_ENABLE_RDRAND}" STREQUAL "") + message(WARNING "CPU doesn't support RDSEED and RDRAND instruction, using random generator will cause errors.") + else () + message(STATUS "Support RDRAND instruction: True") + add_compile_definitions(IPCL_RNG_INSTR_RDRAND) + endif() +else() + message(STATUS "Support RDSEED instruction: True") + add_compile_definitions(IPCL_RNG_INSTR_RDSEED) +endif() + # find package for OpenSSL and Threads set(OPENSSL_USE_STATIC_LIBS TRUE) find_package(Threads REQUIRED) diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index ef76656..b1388b2 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -10,6 +10,7 @@ set(IPCL_SRCS pri_key.cpp plaintext.cpp ciphertext.cpp util.cpp + common.cpp ) diff --git a/ipcl/common.cpp b/ipcl/common.cpp new file mode 100644 index 0000000..90209eb --- /dev/null +++ b/ipcl/common.cpp @@ -0,0 +1,56 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/common.hpp" + +#include + +#include "ipcl/util.hpp" + +namespace ipcl { + +IppStatus ippGenRandom(Ipp32u* rand, int bits, void* ctx) { +#ifdef IPCL_RNG_INSTR_RDSEED + return ippsTRNGenRDSEED(rand, bits, ctx); +#elif defined(IPCL_RNG_INSTR_RDRAND) + return ippsPRNGenRDRAND(rand, bits, ctx); +#else + return ippsPRNGen(rand, bits, ctx); +#endif +} + +IppStatus ippGenRandomBN(IppsBigNumState* rand, int bits, void* ctx) { +#ifdef IPCL_RNG_INSTR_RDSEED + return ippsTRNGenRDSEED_BN(rand, bits, ctx); +#elif defined(IPCL_RNG_INSTR_RDRAND) + return ippsPRNGenRDRAND_BN(rand, bits, ctx); +#else + return ippsPRNGen_BN(rand, bits, ctx); +#endif +} + +BigNumber getRandomBN(int bits) { + IppStatus stat; + int bn_buf_size; + + int bn_len = BITSIZE_WORD(bits); + stat = ippsBigNumGetSize(bn_len, &bn_buf_size); + ERROR_CHECK(stat == ippStsNoErr, + "getRandomBN: get IppsBigNumState context error."); + + IppsBigNumState* pBN = + reinterpret_cast(alloca(bn_buf_size)); + ERROR_CHECK(pBN != nullptr, "getRandomBN: big number alloca error"); + + stat = ippsBigNumInit(bn_len, pBN); + ERROR_CHECK(stat == ippStsNoErr, + "getRandomBN: init big number context error."); + + stat = ippGenRandomBN(pBN, bits, NULL); + ERROR_CHECK(stat == ippStsNoErr, + "getRandomBN: generate random big number error."); + + return BigNumber{pBN}; +} + +} // namespace ipcl diff --git a/ipcl/include/ipcl/common.hpp b/ipcl/include/ipcl/common.hpp index f954026..e15d44e 100644 --- a/ipcl/include/ipcl/common.hpp +++ b/ipcl/include/ipcl/common.hpp @@ -4,9 +4,38 @@ #ifndef IPCL_INCLUDE_IPCL_COMMON_HPP_ #define IPCL_INCLUDE_IPCL_COMMON_HPP_ +#include "ipcl/bignum.h" + namespace ipcl { constexpr int IPCL_CRYPTO_MB_SIZE = 8; +/** + * Random generator wrapper.Generates a random unsigned Big Number of the + * specified bit length + * @param[in] rand Pointer to the output unsigned integer big number + * @param[in] bits The number of generated bits + * @param[in] ctx Pointer to the IppsPRNGState context. + * @return Error code + */ +IppStatus ippGenRandom(Ipp32u* rand, int bits, void* ctx); + +/** + * Random generator wrapper.Generates a random positive Big Number of the + * specified bit length + * @param[in] rand Pointer to the output Big Number + * @param[in] bits The number of generated bits + * @param[in] ctx Pointer to the IppsPRNGState context. + * @return Error code + */ +IppStatus ippGenRandomBN(IppsBigNumState* rand, int bits, void* ctx); + +/** + * Get random value + * @param[in] bits The number of Big Number bits + * @return The random value of type Big Number + */ +BigNumber getRandomBN(int bits); + } // namespace ipcl #endif // IPCL_INCLUDE_IPCL_COMMON_HPP_ diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp index 6938e40..130c5bd 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -82,7 +82,7 @@ class PublicKey { * Apply obfuscator for ciphertext * @param[out] obfuscator output of obfuscator with random value */ - void applyObfuscator(std::vector& obfuscator) const; + void applyObfuscator(std::vector& ciphertext) const; /** * Set the Random object for ISO/IEC 18033-6 compliance check @@ -128,13 +128,6 @@ class PublicKey { std::vector m_r; bool m_testv; - /** - * Get random value - * @param[in] size size of random - * @return addr of random of type Ipp32u vector - */ - std::vector randIpp32u(int size) const; - /** * Big number vector multi buffer encryption * @param[in] pt plaintext of BigNumber vector type @@ -144,16 +137,9 @@ class PublicKey { std::vector raw_encrypt(const std::vector& pt, bool make_secure = true) const; - /** - * Get random value - * @param[in] length bit length - * @return the random value of type BigNumber - */ - BigNumber getRandom(int length) const; - - void applyDjnObfuscator(std::vector& obfuscator) const; + std::vector getDJNObfuscator(std::size_t sz) const; - void applyNormalObfuscator(std::vector& obfuscator) const; + std::vector getNormalObfuscator(std::size_t sz) const; }; } // namespace ipcl diff --git a/ipcl/keygen.cpp b/ipcl/keygen.cpp index efbf1d6..290e502 100644 --- a/ipcl/keygen.cpp +++ b/ipcl/keygen.cpp @@ -3,8 +3,6 @@ #include "ipcl/keygen.hpp" -#include -#include #include #include "ipcl/util.hpp" @@ -12,45 +10,31 @@ namespace ipcl { constexpr int N_BIT_SIZE_MAX = 2048; -constexpr int N_BIT_SIZE_MIN = 16; - -static void rand32u(std::vector& addr) { - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - for (auto& x : addr) x = (dist(rng) << 16) + dist(rng); -} - -BigNumber getPrimeBN(int maxBitSize) { - int PrimeSize; - ippsPrimeGetSize(maxBitSize, &PrimeSize); - auto primeGen = std::vector(PrimeSize); - ippsPrimeInit(maxBitSize, reinterpret_cast(primeGen.data())); - - // define Pseudo Random Generator (default settings) - constexpr int seedBitSize = 160; - constexpr int seedSize = BITSIZE_WORD(seedBitSize); - - ippsPRNGGetSize(&PrimeSize); - auto rand = std::vector(PrimeSize); - ippsPRNGInit(seedBitSize, reinterpret_cast(rand.data())); - - auto seed = std::vector(seedSize); - rand32u(seed); - BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); - - ippsPRNGSetSeed(BN(bseed), reinterpret_cast(rand.data())); - - // generate maxBit prime - BigNumber pBN(0, maxBitSize / 8); +constexpr int N_BIT_SIZE_MIN = 200; + +BigNumber getPrimeBN(int max_bits) { + int prime_size; + ippsPrimeGetSize(max_bits, &prime_size); + auto prime_ctx = std::vector(prime_size); + ippsPrimeInit(max_bits, reinterpret_cast(prime_ctx.data())); + +#if defined(IPCL_RNG_INSTR_RDSEED) || defined(IPCL_RNG_INSTR_RDRAND) + bool rand_param = NULL; +#else + auto buff = std::vector(prime_size); + auto rand_param = buff.data(); + ippsPRNGInit(160, reinterpret_cast(rand_param)); +#endif + + BigNumber prime_bn(0, max_bits / 8); while (ippStsNoErr != - ippsPrimeGen_BN(pBN, maxBitSize, 10, - reinterpret_cast(primeGen.data()), - ippsPRNGen, - reinterpret_cast(rand.data()))) { + ippsPrimeGen_BN(prime_bn, max_bits, 10, + reinterpret_cast(prime_ctx.data()), + ippGenRandom, + reinterpret_cast(rand_param))) { } - return pBN; + return prime_bn; } static BigNumber getPrimeDistance(int64_t key_size) { @@ -111,7 +95,7 @@ keyPair generateKeypair(int64_t n_length, bool enable_DJN) { "generateKeyPair: modulus size in bits should belong to either 1Kb, 2Kb, " "3Kb or 4Kb range only, key size exceed the range!!!"); ERROR_CHECK((n_length >= N_BIT_SIZE_MIN) && (n_length % 4 == 0), - "generateKeyPair: key size should >=16, and divisible by 4"); + "generateKeyPair: key size should >=200, and divisible by 4"); BigNumber ref_dist = getPrimeDistance(n_length); diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index d19c915..01f8124 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -35,44 +35,12 @@ PublicKey::PublicKey(const BigNumber& n, int bits, bool enableDJN_) if (enableDJN_) this->enableDJN(); // sets m_enable_DJN } -// array of 32-bit random, using rand() from stdlib -std::vector PublicKey::randIpp32u(int size) const { - std::vector addr(size); - // TODO(skmono): check if copy of m_init_seed is needed for const - unsigned int init_seed = m_init_seed; - for (auto& a : addr) a = (rand_r(&init_seed) << 16) + rand_r(&init_seed); - return addr; -} - -// length is arbitrary -BigNumber PublicKey::getRandom(int bit_len) const { - IppStatus stat; - int bn_buf_size; - - // define length Big Numbers - int bn_len = BITSIZE_WORD(bit_len); - stat = ippsBigNumGetSize(bn_len, &bn_buf_size); - ERROR_CHECK(stat == ippStsNoErr, - "getRandom: get IppsBigNumState context error."); - - IppsBigNumState* pBN = - reinterpret_cast(alloca(bn_buf_size)); - ERROR_CHECK(pBN != nullptr, "getRandom: big number alloca error"); - - stat = ippsBigNumInit(bn_len, pBN); - ERROR_CHECK(stat == ippStsNoErr, "getRandom: init big number context error."); - - ippsPRNGenRDRAND_BN(pBN, bit_len, NULL); - - return BigNumber{pBN}; -} - void PublicKey::enableDJN() { BigNumber gcd; BigNumber rmod; do { int rand_bit = m_n.BitSize(); - BigNumber rand = getRandom(rand_bit + 128); + BigNumber rand = getRandomBN(rand_bit + 128); rmod = rand % m_n; gcd = rand.gcd(m_n); } while (gcd.compare(1)); @@ -86,46 +54,45 @@ void PublicKey::enableDJN() { m_enable_DJN = true; } -void PublicKey::applyDjnObfuscator(std::vector& obfuscator) const { - std::size_t obf_size = obfuscator.size(); - std::vector r(obf_size); - std::vector base(obf_size, m_hs); - std::vector sq(obf_size, m_nsquare); +std::vector PublicKey::getDJNObfuscator(std::size_t sz) const { + std::vector r(sz); + std::vector base(sz, m_hs); + std::vector sq(sz, m_nsquare); if (m_testv) { r = m_r; } else { for (auto& r_ : r) { - r_ = getRandom(m_randbits); + r_ = getRandomBN(m_randbits); } } - obfuscator = ipcl::ippModExp(base, r, sq); + return ipcl::ippModExp(base, r, sq); } -void PublicKey::applyNormalObfuscator( - std::vector& obfuscator) const { - std::size_t obf_size = obfuscator.size(); - std::vector r(obf_size); - std::vector sq(obf_size, m_nsquare); - std::vector pown(obf_size, m_n); +std::vector PublicKey::getNormalObfuscator(std::size_t sz) const { + std::vector r(sz); + std::vector sq(sz, m_nsquare); + std::vector pown(sz, m_n); if (m_testv) { r = m_r; } else { - for (int i = 0; i < obf_size; i++) { - r[i] = getRandom(m_bits); + for (int i = 0; i < sz; i++) { + r[i] = getRandomBN(m_bits); r[i] = r[i] % (m_n - 1) + 1; } } - obfuscator = ipcl::ippModExp(r, pown, sq); + return ipcl::ippModExp(r, pown, sq); } -void PublicKey::applyObfuscator(std::vector& obfuscator) const { - if (m_enable_DJN) { - applyDjnObfuscator(obfuscator); - } else { - applyNormalObfuscator(obfuscator); - } +void PublicKey::applyObfuscator(std::vector& ciphertext) const { + std::size_t sz = ciphertext.size(); + std::vector obfuscator = + m_enable_DJN ? getDJNObfuscator(sz) : getNormalObfuscator(sz); + BigNumber sq = m_nsquare; + + for (std::size_t i = 0; i < sz; ++i) + ciphertext[i] = sq.ModMul(ciphertext[i], obfuscator[i]); } void PublicKey::setRandom(const std::vector& r) { @@ -140,25 +107,18 @@ std::vector PublicKey::raw_encrypt(const std::vector& pt, std::size_t pt_size = pt.size(); std::vector ct(pt_size); - BigNumber sq = m_nsquare; - for (std::size_t i = 0; i < pt_size; i++) { + for (std::size_t i = 0; i < pt_size; i++) ct[i] = (m_n * pt[i] + 1) % m_nsquare; - } - if (make_secure) { - std::vector obfuscator(pt_size); - applyObfuscator(obfuscator); + if (make_secure) applyObfuscator(ct); - for (std::size_t i = 0; i < pt_size; i++) - ct[i] = sq.ModMul(ct[i], obfuscator[i]); - } return ct; } CipherText PublicKey::encrypt(const PlainText& pt, bool make_secure) const { std::size_t pt_size = pt.getSize(); - ERROR_CHECK(pt_size > 0, "encrypt: Cannot encrypt emtpy PlainText"); + ERROR_CHECK(pt_size > 0, "encrypt: Cannot encrypt empty PlainText"); std::vector ct_bn_v(pt_size); ct_bn_v = raw_encrypt(pt.getTexts(), make_secure); From 2a499b45d1fc51fc668a06f247a48f8fb30e9e87 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 19 Sep 2022 22:26:31 -0700 Subject: [PATCH 230/364] Enable Doxygen documentation install. --- CMakeLists.txt | 14 ++++++++++++-- doc/CMakeLists.txt | 25 +++++++++++++++++++++++++ doc/Doxyfile.in | 33 +++++++++++++++++++++++++++++++++ doc/index.html | 2 ++ doc/index.rst | 5 +++++ 5 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 doc/CMakeLists.txt create mode 100644 doc/Doxyfile.in create mode 100644 doc/index.html create mode 100644 doc/index.rst diff --git a/CMakeLists.txt b/CMakeLists.txt index 52a7963..5ccf867 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,7 +66,7 @@ option(HE_QAT_TEST "Enable testing" OFF) option(HE_QAT_OMP "Enable tests using OpenMP" ON) option(HE_QAT_SAMPLES "Enable examples" ON) option(HE_QAT_BENCHMARK "Enable benchmark" OFF) -option(HE_QAT_DOCS "Enable document building" OFF) +option(HE_QAT_DOCS "Enable document building" ON) option(HE_QAT_SHARED "Build shared library" ON) option(HE_QAT_EXPERIMENTAL "Refactored code" OFF) @@ -196,5 +196,15 @@ if(HE_QAT_BENCHMARK) endif() if(HE_QAT_DOCS) - add_subdirectory(docs) + # sudo apt-get install doxygen + find_package(Doxygen) + option(BUILD_DOCS "Create and install the HTML based API docs (requires Doxygen)" ${DOXYGEN_FOUND}) + if(BUILD_DOCS) + if(NOT DOXYGEN_FOUND) + message(FATAL_ERROR "Doxygen was not found (Required)") + else() + add_subdirectory(doc) + endif() + endif() endif() + diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt new file mode 100644 index 0000000..c3dfd67 --- /dev/null +++ b/doc/CMakeLists.txt @@ -0,0 +1,25 @@ +# Copyright (C) 2022-2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Build Doxygen documentation +SET(DOXYGEN_MIN_VERSION "1.8.5") +find_package(Doxygen ${DOXYGEN_MIN_VERSION} REQUIRED) + +set(DOXYGEN_OUTPUT_DIR ${CMAKE_BINARY_DIR}/doxygen) +set(DOXYGEN_INDEX_FILE ${DOXYGEN_OUTPUT_DIR}/xml/indexl.html) +set(DOXYFILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in) +set(DOXYFILE_OUT ${CMAKE_BINARY_DIR}/Doxyfile) + +# Create Doxyfile +configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY) + +add_custom_command(OUTPUT ${DOXYGEN_INDEX_FILE} + COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE_OUT} + MAIN_DEPENDENCY ${DOXYFILE_OUT} ${DOXYFILE_IN} + COMMENT "Generating Doxygen documentation") + +add_custom_target(docs ALL DEPENDS ${DOXYGEN_INDEX_FILE}) + +install(DIRECTORY + ${CMAKE_BINARY_DIR}/doc/doxygen + DESTINATION doc) diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in new file mode 100644 index 0000000..6bf8078 --- /dev/null +++ b/doc/Doxyfile.in @@ -0,0 +1,33 @@ +# Copyright (C) 2022-2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +PROJECT_NAME = "Intel HE Acceleration Library for QAT" +PROJECT_BRIEF = "Intel Homomorphic Encryption Acceleration Library for QAT, accelerating the modular arithmetic operations used in partial homomorphic encryption on Intel QAT." + +OUTPUT_DIRECTORY = @CMAKE_BINARY_DIR@/doc/doxygen +INPUT = @CMAKE_SOURCE_DIR@/he_qat/include \ + @CMAKE_SOURCE_DIR@/misc \ + @CMAKE_SOURCE_DIR@/icp \ + @CMAKE_SOURCE_DIR@/samples \ + @CMAKE_SOURCE_DIR@/README.md +RECURSIVE = YES +USE_MDFILE_AS_MAINPAGE = @CMAKE_SOURCE_DIR@/README.md +USE_MATHJAX = YES +FULL_PATH_NAMES = NO + +GENERATE_XML = YES +EXTRACT_ALL = YES +EXTRACT_PRIVATE = NO +SHOW_NAMESPACES = YES +GENERATE_LATEX = YES + +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = YES +WARN_AS_ERROR = YES + +QUIET = NO + +SEARCHENGINE = YES +SERVER_BASED_SEARCH = NO diff --git a/doc/index.html b/doc/index.html new file mode 100644 index 0000000..c344624 --- /dev/null +++ b/doc/index.html @@ -0,0 +1,2 @@ + + diff --git a/doc/index.rst b/doc/index.rst new file mode 100644 index 0000000..db1489b --- /dev/null +++ b/doc/index.rst @@ -0,0 +1,5 @@ +## Intel HE Acceleration Library for QAT Documentation ## +.. toctree:: + api + +.. mdinclude:: ../README.md From 30fe2c20df51b26f068f6e033a7a22693ea1a566 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 19 Sep 2022 22:32:37 -0700 Subject: [PATCH 231/364] Change doc comments to fix doxygen compilation. --- he_qat/he_qat_bn_ops.c | 2 +- he_qat/he_qat_context.c | 3 +-- he_qat/he_qat_ctrl.c | 21 ++++++++----------- he_qat/he_qat_ops.c | 9 ++++++--- he_qat/include/he_qat_bn_ops.h | 36 +++++++++++++++++++-------------- he_qat/include/he_qat_context.h | 4 +--- he_qat/include/he_qat_types.h | 33 ++++++++++++------------------ misc/he_qat_misc.cpp | 2 ++ misc/he_qat_misc.h | 5 +++-- 9 files changed, 56 insertions(+), 59 deletions(-) diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c index c70a934..98e276c 100644 --- a/he_qat/he_qat_bn_ops.c +++ b/he_qat/he_qat_bn_ops.c @@ -1,4 +1,4 @@ - +/// @file he_qat #include "cpa.h" #include "cpa_cy_im.h" #include "cpa_cy_ln.h" diff --git a/he_qat/he_qat_context.c b/he_qat/he_qat_context.c index 9067d52..6d2de68 100644 --- a/he_qat/he_qat_context.c +++ b/he_qat/he_qat_context.c @@ -1,3 +1,4 @@ +/// @file he_qat_context.c #define _GNU_SOURCE @@ -113,7 +114,6 @@ static CpaInstanceHandle get_qat_instance() { } /// @brief -/// @function acquire_qat_devices /// Acquire QAT instances and set up QAT execution environment. HE_QAT_STATUS acquire_qat_devices() { CpaStatus status = CPA_STATUS_FAIL; @@ -272,7 +272,6 @@ HE_QAT_STATUS acquire_qat_devices() { } /// @brief -/// @function release_qat_devices /// Release QAT instances and tear down QAT execution environment. HE_QAT_STATUS release_qat_devices() { CpaStatus status = CPA_STATUS_FAIL; diff --git a/he_qat/he_qat_ctrl.c b/he_qat/he_qat_ctrl.c index dc8381e..f0656c8 100644 --- a/he_qat/he_qat_ctrl.c +++ b/he_qat/he_qat_ctrl.c @@ -47,8 +47,8 @@ static unsigned long max_pending = (NUM_PKE_SLICES * 2 * HE_QAT_NUM_ACTIVE_INSTA /// of the producer for the either the internal buffer or the outstanding buffer to /// host incoming requests. Depending on the buffer type, the submitted request /// is either ready to be scheduled or to be processed by the accelerator. -/// @param[out] _buffer either `he_qat_buffer` or `outstanding` buffer. -/// @param[in] args work request packaged in a custom data structure. +/// @param[out] _buffer Either `he_qat_buffer` or `outstanding` buffer. +/// @param[in] args Work request packaged in a custom data structure. void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { #ifdef HE_QAT_DEBUG printf("Lock write request\n"); @@ -77,7 +77,7 @@ void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { } /// @brief Populates internal buffer with a list of work request. -/// This function is called by the request scheduler thread. It is a thread-safe implementation of the producer for the shared internal request buffer. This buffer stores and serializes the offloading of requests that are ready to be processed by the accelerator. +/// @details This function is called by the request scheduler thread. It is a thread-safe implementation of the producer for the shared internal request buffer. This buffer stores and serializes the offloading of requests that are ready to be processed by the accelerator. /// @param[out] _buffer reference pointer to the internal buffer `he_qat_buffer`. /// @param[in] _requests list of requests retrieved from the buffer (`outstanding`) holding outstanding requests. static void submit_request_list(HE_QAT_RequestBuffer* _buffer, @@ -289,7 +289,6 @@ static void pull_outstanding_requests(HE_QAT_TaskRequestList* _requests, HE_QAT_ /// @brief Schedule outstanding requests to the internal buffer and be ready for processing. /// @details Schedule outstanding requests from outstanding buffers to the internal buffer, /// from which requests are ready to be submitted to the device for processing. -/// @function schedule_requests /// @param[in] state A volatile integer variable used to activate (val>0) or /// disactive (val=0) the scheduler. void* schedule_requests(void* state) { @@ -319,7 +318,6 @@ void* schedule_requests(void* state) { } /// @brief Poll responses from a specific QAT instance. -/// @function start_inst_polling /// @param[in] _inst_config Instance configuration containing the parameter /// values to start and poll responses from the accelerator. static void* start_inst_polling(void* _inst_config) { @@ -351,7 +349,7 @@ static void* start_inst_polling(void* _inst_config) { /// Initialize and start multiple instances, their polling thread, /// and a single processing thread. /// -/// @function start_instances +/// @details /// It initializes multiple QAT instances and launches their respective independent /// polling threads that will listen to responses to requests sent to the accelerators /// concurrently. Then, it becomes the thread that collect the incoming requests stored @@ -572,7 +570,7 @@ void* start_instances(void* _config) { /// @brief /// Start independent processing and polling threads for an instance. /// -/// @function start_perform_op +/// @details /// It initializes a QAT instance and launches its polling thread to listen /// to responses (request outputs) from the accelerator. It is also reponsible /// to collect requests from the internal buffer and send them to the accelerator @@ -757,12 +755,10 @@ void* start_perform_op(void* _inst_config) { /// @brief /// Stop specified number of instances from running. /// -/// @function stop_perform_op -/// Stop first 'num_inst' number of cpaCyInstance(s), including their polling -/// and running threads. -/// /// @details -/// Stop runnning and polling instances. Release QAT instances handles. +/// Stop first 'num_inst' number of cpaCyInstance(s), including their polling +/// and running threads. Stop runnning and polling instances. +/// Release QAT instances handles. /// /// @param[in] config List of all created QAT instances and their configurations. /// @param[in] num_inst Unsigned integer number indicating first number of @@ -807,7 +803,6 @@ void stop_perform_op(HE_QAT_InstConfig* config, unsigned num_inst) { } /// @brief Stop all running instances. -/// @function stop_instances /// @details /// Stop all running instances after calling `start_instances()`. /// It will set the states of the instances to terminate gracefully. diff --git a/he_qat/he_qat_ops.c b/he_qat/he_qat_ops.c index dba7c74..6c6bd02 100644 --- a/he_qat/he_qat_ops.c +++ b/he_qat/he_qat_ops.c @@ -428,10 +428,11 @@ HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, } /// @brief Frontend for multithreading support. -/// @details Try to acquire an outstanding buffer available. -/// If none available, it waits until another concurrent +/// @details Try to acquire an available buffer to store outstanding work requests sent by caller. +/// If none is available, it blocks further processing and waits until another caller's concurrent /// thread releases one. This function must be called before -/// calling HE_QAT_bnModExp_MT(). +/// calling HE_QAT_bnModExp_MT(.). +/// @param[out] Pointer to memory space allocated by caller to hold the buffer ID of the buffer used to store caller's outstanding requests. HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id) { if (NULL == _buffer_id) return HE_QAT_STATUS_INVALID_PARAM; @@ -471,6 +472,8 @@ HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id) { /// @details Caution: It assumes acquire_bnModExp_buffer(&_buffer_id) to be called first /// to secure and be assigned an outstanding buffer for the target thread. /// Equivalent to getBnModExpRequests() for the multithreading support interfaces. +/// param[in] _buffer_id Buffer ID of the buffer to be released/unlock for reuse by the next concurrent thread. +/// param[in] _batch_size Total number of requests to wait for completion before releasing the buffer. void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size) { unsigned int next_data_out = outstanding.buffer[_buffer_id].next_data_out; unsigned int j = 0; diff --git a/he_qat/include/he_qat_bn_ops.h b/he_qat/include/he_qat_bn_ops.h index 05fdc83..74f1c5f 100644 --- a/he_qat/include/he_qat_bn_ops.h +++ b/he_qat/include/he_qat_bn_ops.h @@ -1,7 +1,7 @@ /** * @file he_qat_bn_ops.h * - * @description + * @details * In this file, functions for Big Number operations accelerated by the * QuickAssist (QAT) co-processor are specified. * @@ -43,9 +43,7 @@ extern "C" { #include #include "he_qat_types.h" -/// @brief Modular exponentiation using BIGNUM. -/// -/// @function +/// @brief Modular exponentiation using BIGNUM data structure. /// Perform big number modular exponentiation operation accelerated with QAT for input data /// using OpenSSL BIGNUM data structure. /// @@ -54,16 +52,14 @@ extern "C" { /// Copy data and package into a request and call producer function to submit /// request into qat buffer. /// -/// @param r [out] Remainder number of the modular exponentiation operation. -/// @param b [in] Base number of the modular exponentiation operation. -/// @param e [in] Exponent number of the modular exponentiation operation. -/// @param m [in] Modulus number of the modular exponentiation operation. -/// @param nbits[in] Number of bits (bit precision) of input/output big numbers. +/// @param[out] r Remainder number of the modular exponentiation operation. +/// @param[in] b Base number of the modular exponentiation operation. +/// @param[in] e Exponent number of the modular exponentiation operation. +/// @param[in] m Modulus number of the modular exponentiation operation. +/// @param[in] nbits Number of bits (bit precision) of input/output big numbers. HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int nbits); /// @brief -/// -/// @function /// Generic big number modular exponentiation for input data in primitive type /// format (unsigned char *). /// @@ -84,8 +80,6 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, /// It waits for number of requests sent by HE_QAT_bnModExp or bnModExpPerformOp /// to complete. /// -/// @function getModExpRequest(unsigned int batch_size) -/// /// @details /// This function is blocking and works as barrier. The purpose of this function /// is to wait for all outstanding requests to complete processing. It will also @@ -103,8 +97,6 @@ void getBnModExpRequest(unsigned int num_requests); **/ /// @brief -/// -/// @function /// Generic big number modular exponentiation for input data in primitive type /// format (unsigned char *). /// @@ -113,6 +105,7 @@ void getBnModExpRequest(unsigned int num_requests); /// Copy data and package into a request and call producer function to submit /// request into qat buffer. /// +/// @param[in] _buffer_id Buffer ID of the reserved buffer for the caller's thread. /// @param[out] r Remainder number of the modular exponentiation operation. /// @param[in] b Base number of the modular exponentiation operation. /// @param[in] e Exponent number of the modular exponentiation operation. @@ -121,7 +114,20 @@ void getBnModExpRequest(unsigned int num_requests); HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, unsigned char* b, unsigned char* e, unsigned char* m, int nbits); +/// @brief Reserve/acquire buffer for multithreading support. +/// @details Try to acquire an available buffer to store outstanding work requests sent by caller. +/// If none is available, it blocks further processing and waits until another caller's concurrent +/// thread releases one. This function must be called before +/// calling HE_QAT_bnModExp_MT(.). +/// @param[out] _buffer_id Pointer to memory space allocated by caller to hold the buffer ID of the buffer used to store caller's outstanding requests. HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id); + +/// @brief Wait for request processing to complete and release previously acquired buffer. +/// @details Caution: It assumes acquire_bnModExp_buffer(&_buffer_id) to be called first +/// to secure and be assigned an outstanding buffer for the target thread. +/// Equivalent to getBnModExpRequests() for the multithreading support interfaces. +/// param[in] _buffer_id Buffer ID of the buffer to be released/unlock for reuse by the next concurrent thread. +/// param[in] _batch_size Total number of requests to wait for completion before releasing the buffer. void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size); #ifdef __cplusplus diff --git a/he_qat/include/he_qat_context.h b/he_qat/include/he_qat_context.h index a528b34..e260793 100644 --- a/he_qat/include/he_qat_context.h +++ b/he_qat/include/he_qat_context.h @@ -1,3 +1,4 @@ +/// @file he_qat_context.h #pragma once @@ -9,15 +10,12 @@ extern "C" { #endif #include "he_qat_types.h" -//#include /// @brief -/// @function acquire_qat_devices /// Configure and initialize QAT runtime environment. HE_QAT_STATUS acquire_qat_devices(); /// @brief -/// @function release_qat_devices /// Release and free resources of the QAT runtime environment. HE_QAT_STATUS release_qat_devices(); diff --git a/he_qat/include/he_qat_types.h b/he_qat/include/he_qat_types.h index 6aef6ac..a3ab432 100644 --- a/he_qat/include/he_qat_types.h +++ b/he_qat/include/he_qat_types.h @@ -1,3 +1,4 @@ +/// @file he_qat_types.h #pragma once @@ -23,7 +24,10 @@ extern "C" { #include "he_qat_gconst.h" // Type definitions -typedef enum { HE_QAT_SYNC = 1, HE_QAT_ASYNC = 2 } HE_QAT_EXEC_MODE; +typedef enum { + HE_QAT_SYNC = 1, + HE_QAT_ASYNC = 2 +} HE_QAT_EXEC_MODE; typedef enum { HE_QAT_STATUS_INVALID_PARAM = 2, @@ -32,7 +36,10 @@ typedef enum { HE_QAT_STATUS_FAIL = -1 } HE_QAT_STATUS; -typedef enum { HE_QAT_OP_NONE = 0, HE_QAT_OP_MODEXP = 1 } HE_QAT_OP; +typedef enum { + HE_QAT_OP_NONE = 0, ///< No Operation (NO OP) + HE_QAT_OP_MODEXP = 1 ///< QAT Modular Exponentiation +} HE_QAT_OP; typedef pthread_t HE_QAT_Inst; @@ -51,20 +58,6 @@ typedef struct { pthread_cond_t any_free_slot; ///< Conditional variable used to synchronize the provision of free slots in buffer (wait until enough slots are available to add more data in buffer) } HE_QAT_RequestBuffer; -// Unused type. Intention to remove it. -//typedef struct { -// void* data[HE_QAT_BUFFER_COUNT][HE_QAT_BUFFER_SIZE]; // -// unsigned int count; -// unsigned int size; -// unsigned int -// next_free_slot; // nextin index of the next free slot for a request -// unsigned int -// next_data_slot; // nextout index of next request to be processed -// pthread_mutex_t mutex; // -// pthread_cond_t any_more_data; // more -// pthread_cond_t any_free_slot; // less -//} HE_QAT_RequestBufferList; - typedef struct { HE_QAT_RequestBuffer buffer[HE_QAT_BUFFER_COUNT]; ///< Buffers to support concurrent threads with less sync overhead unsigned int busy_count; ///< Counts number of currently occupied buffers @@ -91,10 +84,10 @@ typedef struct { } HE_QAT_InstConfig; typedef struct { - HE_QAT_InstConfig *inst_config; - volatile int active; - volatile int running; - unsigned int count; + HE_QAT_InstConfig *inst_config; + volatile int active; + volatile int running; + unsigned int count; } HE_QAT_Config; // One for each consumer diff --git a/misc/he_qat_misc.cpp b/misc/he_qat_misc.cpp index f0d0ce3..efee2e2 100644 --- a/misc/he_qat_misc.cpp +++ b/misc/he_qat_misc.cpp @@ -1,3 +1,5 @@ +/// @file he_qat_misc.cpp + #include "he_qat_misc.h" //#ifdef __cplusplus diff --git a/misc/he_qat_misc.h b/misc/he_qat_misc.h index ac77a09..459d5e0 100644 --- a/misc/he_qat_misc.h +++ b/misc/he_qat_misc.h @@ -1,14 +1,16 @@ +/// @file he_qat_misc.h #ifndef HE_QAT_MISC_H_ #define HE_QAT_MISC_H_ +#pragma once + #include "he_qat_gconst.h" #include "he_qat_types.h" #include "bignum.h" #include /// @brief -/// @function binToBigNumber /// Convert QAT large number into little endian format and encapsulate it into a /// BigNumber object. /// @param[out] bn BigNumber object representing multi-precision number in @@ -19,7 +21,6 @@ HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, int nbits); /// @brief -/// @function bigNumberToBin /// Convert BigNumber object into raw data compatible with QAT. /// @param[out] data BigNumber object's raw data in big endian format. /// @param[in] nbits Number of bits. Has to be power of 2, e.g. 1024, 2048, From 275a9cc780f4b4ce2ef218ce92dd73389d2d7113 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 20 Sep 2022 15:08:01 -0700 Subject: [PATCH 232/364] Update comments on types. Signed-off-by: Souza, Fillipe --- he_qat/include/he_qat_types.h | 77 +++++++++++++++++------------------ 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/he_qat/include/he_qat_types.h b/he_qat/include/he_qat_types.h index a3ab432..b20d910 100644 --- a/he_qat/include/he_qat_types.h +++ b/he_qat/include/he_qat_types.h @@ -44,74 +44,73 @@ typedef enum { typedef pthread_t HE_QAT_Inst; typedef struct { - void* data[HE_QAT_BUFFER_SIZE]; // - volatile unsigned int count; // occupied track number of buffer enties + void* data[HE_QAT_BUFFER_SIZE]; ///< Stores work requests ready to be sent to the accelerator. + volatile unsigned int count; ///< Tracks the number of occupied entries/slots in the data[] buffer. // nextin index of the next free slot for a request - unsigned int next_free_slot; + unsigned int next_free_slot; ///< Index of the next slot available to store a new request. // nextout index of next request to be processed - unsigned int next_data_slot; + unsigned int next_data_slot; ///< Index of the next slot containing request ready to be consumed for processing. // index of next output data to be read by a thread waiting // for all the request to complete processing - unsigned int next_data_out; - pthread_mutex_t mutex; // - pthread_cond_t any_more_data; ///< Conditional variable used to synchronize the consumption of data in buffer (wait until more data is available to be consumed) - pthread_cond_t any_free_slot; ///< Conditional variable used to synchronize the provision of free slots in buffer (wait until enough slots are available to add more data in buffer) + unsigned int next_data_out; ///< Index of the next slot containing request whose processing has been completed and its output is ready to be consumed by the caller. + pthread_mutex_t mutex; ///< Synchronization object used to control access to the buffer. + pthread_cond_t any_more_data; ///< Conditional variable used to synchronize the consumption of data in buffer (wait until more data is available to be consumed). + pthread_cond_t any_free_slot; ///< Conditional variable used to synchronize the provision of free slots in buffer (wait until enough slots are available to add more data in buffer). } HE_QAT_RequestBuffer; typedef struct { - HE_QAT_RequestBuffer buffer[HE_QAT_BUFFER_COUNT]; ///< Buffers to support concurrent threads with less sync overhead - unsigned int busy_count; ///< Counts number of currently occupied buffers - unsigned int next_free_buffer; ///< Next in: index of the next free slot for a request + HE_QAT_RequestBuffer buffer[HE_QAT_BUFFER_COUNT]; ///< Buffers to support concurrent threads with less sync overhead. Stores incoming request from different threads. + unsigned int busy_count; ///< Counts number of currently occupied buffers. + unsigned int next_free_buffer; ///< Next in: index of the next free slot for a request. int free_buffer[HE_QAT_BUFFER_COUNT]; ///< Keeps track of buffers that are available (any value > 0 means the buffer at index i is available). The next_free_buffer does not necessarily mean that the buffer is already released from usage. - unsigned int next_ready_buffer; ///< Next out: index of next request to be processed + unsigned int next_ready_buffer; ///< Next out: index of next request to be processed. int ready_buffer[HE_QAT_BUFFER_COUNT]; ///< Keeps track of buffers that are ready (any value > 0 means the buffer at index i is ready). The next_ready_buffer does not necessarily mean that the buffer is not busy at any time instance. - pthread_mutex_t mutex; ///< Used for synchronization of concurrent access of an object of the type - pthread_cond_t any_ready_buffer; ///< Conditional variable used to synchronize the consumption of the contents in buffers - pthread_cond_t any_free_buffer; ///< Conditional variable used to synchronize the provision of buffers + pthread_mutex_t mutex; ///< Used for synchronization of concurrent access of an object of the type + pthread_cond_t any_ready_buffer; ///< Conditional variable used to synchronize the consumption of the contents in the buffers storing outstanding requests and ready to be scheduled to move to the internal buffer. + pthread_cond_t any_free_buffer; ///< Conditional variable used to synchronize the provisioning of buffers to store incoming requests from concurrent threads. } HE_QAT_OutstandingBuffer; typedef struct { - int inst_id; - CpaInstanceHandle inst_handle; - pthread_attr_t* attr; - HE_QAT_RequestBuffer* he_qat_buffer; + int inst_id; ///< QAT instance ID. + CpaInstanceHandle inst_handle; ///< Handle of this QAT instance. + pthread_attr_t* attr; ///< Unused member. + HE_QAT_RequestBuffer* he_qat_buffer; ///< Unused member. pthread_mutex_t mutex; pthread_cond_t ready; - volatile int active; - volatile int polling; - volatile int running; - CpaStatus status; + volatile int active; ///< State of this QAT instance. + volatile int polling; ///< State of this QAT instance's polling thread (any value different from 0 indicates that it is running). + volatile int running; ///< State of this QAT instance's processing thread (any value different from 0 indicates that it is running). + CpaStatus status; ///< Status of the latest activity by this QAT instance. } HE_QAT_InstConfig; typedef struct { - HE_QAT_InstConfig *inst_config; - volatile int active; - volatile int running; - unsigned int count; + HE_QAT_InstConfig *inst_config; ///< List of the QAT instance's configurations. + volatile int active; ///< Value different from 0 indicates all QAT instances are created and active. + volatile int running; ///< Value different from 0 indicates all created QAT instances are running. + unsigned int count; ///< Total number of created QAT instances. } HE_QAT_Config; // One for each consumer typedef struct { - unsigned long long id; + unsigned long long id; ///< Work request ID. // sem_t callback; - struct COMPLETION_STRUCT callback; - HE_QAT_OP op_type; - CpaStatus op_status; - CpaFlatBuffer op_result; + struct COMPLETION_STRUCT callback; ///< Synchronization object. + HE_QAT_OP op_type; ///< Work type: type of operation to be offloaded to QAT. + CpaStatus op_status; ///< Status of the operation after completion. + CpaFlatBuffer op_result; ///< Output of the operation in contiguous memory. // CpaCyLnModExpOpData op_data; - void* op_data; - void* op_output; - void* callback_func; - volatile HE_QAT_STATUS request_status; + void* op_data; ///< Input data packaged in QAT's data structure for the target type of operation. + void* op_output; ///< Pointer to the memory space where to store the output for the caller. + void* callback_func; ///< Pointer to the callback function. + volatile HE_QAT_STATUS request_status; pthread_mutex_t mutex; pthread_cond_t ready; #ifdef HE_QAT_PERF - struct timeval start; - struct timeval end; + struct timeval start; ///< Time when the request was first received from the caller. + struct timeval end; ///< Time when the request completed processing and callback function was triggered. #endif } HE_QAT_TaskRequest; -// One for each consumer typedef struct { HE_QAT_TaskRequest* request[HE_QAT_BUFFER_SIZE]; unsigned int count; From 3a3731a1821fb5773736b8c7617f63e3ad79381a Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 20 Sep 2022 17:15:37 -0700 Subject: [PATCH 233/364] Remove unused header. Signed-off-by: Souza, Fillipe --- include/cpa_sample_cnv_utils.h | 275 --------------------------------- 1 file changed, 275 deletions(-) delete mode 100644 include/cpa_sample_cnv_utils.h diff --git a/include/cpa_sample_cnv_utils.h b/include/cpa_sample_cnv_utils.h deleted file mode 100644 index 5670737..0000000 --- a/include/cpa_sample_cnv_utils.h +++ /dev/null @@ -1,275 +0,0 @@ -/*************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Corporation - * - * BSD LICENSE - * - * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * version: QAT.L.4.15.0-00011 - * - ***************************************************************************/ - -/** - ***************************************************************************** - * @file qat_compression_cnv_utils.h - * - * @defgroup compression - * - * @ingroup compression - * - * @description - * Functions types and macros to determine CnV-E environment - * Helper functions and macros to set the CnV flag in API - * - * - ***************************************************************************/ -#ifndef QAT_SAMPLE_CNV_UTILS_H_ -#define QAT_SAMPLE_CNV_UTILS_H_ - -#ifdef __cplusplus -extern "C" { -#include -#endif - -/* Common macro definitions */ -#ifndef DC_API_VERSION_AT_LEAST -#define DC_API_VERSION_AT_LEAST(major, minor) \ - (CPA_DC_API_VERSION_NUM_MAJOR > major || \ - (CPA_DC_API_VERSION_NUM_MAJOR == major && \ - CPA_DC_API_VERSION_NUM_MINOR >= minor)) -#endif - -/* CNV with Recovery mode capability is present in DC API version 2.2 - * and higher. - */ -#if DC_API_VERSION_AT_LEAST(2, 2) -#define CNV(x) (x)->compressAndVerify -#define SET_CNV(x, v) (CNV(x) = (v)) -#define CNV_RECOVERY(x) (x)->compressAndVerifyAndRecover -#define SET_CNV_RECOVERY(x, v) (CNV_RECOVERY(x) = v) -#else -#define CNV(x) CPA_FALSE -#define SET_CNV(x, v) -#define CNV_RECOVERY(x) CPA_FALSE -#define SET_CNV_RECOVERY(x, v) -#endif - -#define INIT_OPDATA(x, flag) \ - do \ - { \ - (x)->flushFlag = (flag); \ - SET_CNV(x, getCnVFlag()); \ - SET_CNV_RECOVERY(x, getCnVnRFlag()); \ - (x)->inputSkipData.skipMode = CPA_DC_SKIP_DISABLED; \ - (x)->outputSkipData.skipMode = CPA_DC_SKIP_DISABLED; \ - } while (0) - -#define INIT_DC_DP_CNV_OPDATA(x) \ - do \ - { \ - SET_CNV(x, getCnVFlag()); \ - SET_CNV_RECOVERY(x, getCnVnRFlag()); \ - } while (0) - -static CpaBoolean getCnVFlag(void) __attribute__((unused)); -static CpaBoolean getCnVnRFlag(void) __attribute__((unused)); -static const char *getSampleCnVModeStr(void) __attribute__((unused)); - -static void getCnvFlagInternal(CpaBoolean *cnv, CpaBoolean *cnvnr); -static void EvaluateSampleCnVFlag(const CpaDcInstanceCapabilities *const cap, - CpaBoolean *cnv, - CpaBoolean *cnvnr); -static CpaStatus getSampleDcCapabilities( - CpaDcInstanceCapabilities *capabilities); - -static CpaBoolean getCnVFlag(void) -{ - static CpaBoolean cnvOpFlag; - static CpaBoolean initialised = CPA_FALSE; - - if (initialised == CPA_FALSE) - { - getCnvFlagInternal(&cnvOpFlag, NULL); - initialised = CPA_TRUE; - } - - return cnvOpFlag; -} - -static CpaBoolean getCnVnRFlag(void) -{ - static CpaBoolean cnvnrOpFlag; - static CpaBoolean initialised = CPA_FALSE; - - if (initialised == CPA_FALSE) - { - getCnvFlagInternal(NULL, &cnvnrOpFlag); - initialised = CPA_TRUE; - } - - return cnvnrOpFlag; -} - -static const char *getSampleCnVModeStr(void) -{ - static const char *cmpWithVer = "Compression with Verification"; - static const char *cmpOnly = "Compression Only"; - - return (getCnVFlag() == CPA_TRUE ? cmpWithVer : cmpOnly); -} - -static void getCnvFlagInternal(CpaBoolean *cnv, CpaBoolean *cnvnr) -{ -#ifdef __cplusplus - CpaDcInstanceCapabilities cap; - memset(&cap, 0, sizeof(CpaDcInstanceCapabilities)); -#else - CpaDcInstanceCapabilities cap = {0}; -#endif - if (getSampleDcCapabilities(&cap) != CPA_STATUS_SUCCESS) - { - return EvaluateSampleCnVFlag(NULL, cnv, cnvnr); - } - - return EvaluateSampleCnVFlag(&cap, cnv, cnvnr); -} - -static void EvaluateSampleCnVFlag(const CpaDcInstanceCapabilities *const cap, - CpaBoolean *cnv, - CpaBoolean *cnvnr) -{ - CpaBoolean fw_cnv_capable = CPA_FALSE; - CpaBoolean cnv_loose_mode = CPA_FALSE; - CpaBoolean cnvOpFlag = CPA_FALSE; - CpaBoolean cnvnrOpFlag = CPA_FALSE; - - /* When capabilities are known, fill in the queried values */ - if (cap != NULL) - { - fw_cnv_capable = CNV(cap); -/* CNV mode capabilities is present in DC API version 2.1 and above */ -#if DC_API_VERSION_AT_LEAST(2, 1) - cnv_loose_mode = - (cap->compressAndVerifyStrict != CPA_TRUE) ? CPA_TRUE : CPA_FALSE; -#endif - cnvnrOpFlag = CNV_RECOVERY(cap); - } - /* Determine the value of CompressAndVerify flag used by DP and - * Traditional API depending on the FW CNV capability and CNV mode - * of operation. The API will accept the submission of payload only - * if this flag value is correct for the combination. - * FW-CNV-CAPABLE MODE PERMITTED-OPERATION CNVFLAG - * Y S CompressWithVerify CPA_TRUE - * Y L Compress only CPA_FALSE - * N S NONE NA - * N L Compress only CPA_FALSE - */ - if (fw_cnv_capable == CPA_TRUE) - { - cnvOpFlag = (cnv_loose_mode == CPA_FALSE) ? CPA_TRUE : CPA_FALSE; - } - else - { - cnvOpFlag = CPA_FALSE; - } - - /* CNV Recovery only possible when - * CNV is enabled/present. - */ - if (cnvOpFlag == CPA_FALSE) - { - cnvnrOpFlag = CPA_FALSE; - } - - if (cnv != NULL) - *cnv = cnvOpFlag; - - if (cnvnr != NULL) - *cnvnr = cnvnrOpFlag; - - return; -} - -static CpaStatus getSampleDcCapabilities( - CpaDcInstanceCapabilities *capabilities) -{ - CpaStatus status; - CpaInstanceHandle instHandle; - Cpa16U numInstances = 0; - - /* Get the number of instances */ - status = cpaDcGetNumInstances(&numInstances); - if (CPA_STATUS_SUCCESS != status) - return CPA_STATUS_FAIL; - - if (numInstances == 0) - return CPA_STATUS_FAIL; - - status = cpaDcGetInstances(1, &instHandle); - if (status != CPA_STATUS_SUCCESS) - return CPA_STATUS_FAIL; - - status = cpaDcQueryCapabilities(instHandle, capabilities); - if (CPA_STATUS_SUCCESS != status) - return CPA_STATUS_FAIL; - - return CPA_STATUS_SUCCESS; -} - -#ifdef __cplusplus -} // close extern "C" { -#endif - -#endif /* QAT_SAMPLE_CNV_UTILS_H_ */ From bde2dd9917b36b96fa1abeb0854871326430b3b8 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 20 Sep 2022 17:16:45 -0700 Subject: [PATCH 234/364] Update API doc comments. Signed-off-by: Souza, Fillipe --- he_qat/include/he_qat_bn_ops.h | 52 ++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/he_qat/include/he_qat_bn_ops.h b/he_qat/include/he_qat_bn_ops.h index 74f1c5f..dd27a00 100644 --- a/he_qat/include/he_qat_bn_ops.h +++ b/he_qat/include/he_qat_bn_ops.h @@ -43,14 +43,13 @@ extern "C" { #include #include "he_qat_types.h" -/// @brief Modular exponentiation using BIGNUM data structure. -/// Perform big number modular exponentiation operation accelerated with QAT for input data -/// using OpenSSL BIGNUM data structure. +/// @brief Performs modular exponentiation using BIGNUM data structure. /// /// @details -/// Create private buffer for code section. Create QAT contiguous memory space. -/// Copy data and package into a request and call producer function to submit -/// request into qat buffer. +/// Perform big number modular exponentiation operation accelerated with QAT for input data +/// using OpenSSL BIGNUM data structure. Create QAT contiguous memory space. +/// Copy BIGNUM binary data and package it into a request (HE_QAT_Request data structure) and +/// call producer function to submit request to the internal buffer. /// /// @param[out] r Remainder number of the modular exponentiation operation. /// @param[in] b Base number of the modular exponentiation operation. @@ -59,14 +58,14 @@ extern "C" { /// @param[in] nbits Number of bits (bit precision) of input/output big numbers. HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int nbits); -/// @brief -/// Generic big number modular exponentiation for input data in primitive type -/// format (unsigned char *). +/// @brief Performs big number modular exponentiation for input data (an octet string) +/// in primitive type format (unsigned char *). /// /// @details -/// Create private buffer for code section. Create QAT contiguous memory space. -/// Copy data and package into a request and call producer function to submit -/// request into qat buffer. +/// Perform big number modular exponentiation operation accelerated with QAT for +/// input data as an octet string of unsigned chars. Create QAT contiguous memory +/// space. Upon call it copies input data and package it into a request, then calls +/// producer function to submit request to internal buffer. /// /// @param[out] r Remainder number of the modular exponentiation operation. /// @param[in] b Base number of the modular exponentiation operation. @@ -77,17 +76,17 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, unsigned char* e, unsigned char* m, int nbits); /// @brief -/// It waits for number of requests sent by HE_QAT_bnModExp or bnModExpPerformOp +/// It waits for number of requests sent by HE_QAT_bnModExp or HE_QAT_BIGNUMModExp /// to complete. /// /// @details -/// This function is blocking and works as barrier. The purpose of this function +/// This function is blocking and works as a barrier. The purpose of this function /// is to wait for all outstanding requests to complete processing. It will also -/// release all temporary memory allocated to support the requests. -/// Monitor outstanding request to be complete and then deallocate buffer -/// holding outstanding request. +/// release all temporary memory allocated used to support the submission and +/// processing of the requests. It monitors outstanding requests to be completed +/// and then it deallocates buffer holding outstanding request. /// -/// @param[in] num_requests Number of requests to wait to complete processing. +/// @param[in] num_requests Number of requests to wait for processing completion. void getBnModExpRequest(unsigned int num_requests); /** @@ -96,14 +95,15 @@ void getBnModExpRequest(unsigned int num_requests); * **/ -/// @brief -/// Generic big number modular exponentiation for input data in primitive type -/// format (unsigned char *). +/// @brief Performs big number modular exponentiation for input data (an octet string) +/// in primitive type format (unsigned char *). Same as HE_QAT_bnModExp with +/// multithreading support. /// /// @details -/// Create private buffer for code section. Create QAT contiguous memory space. -/// Copy data and package into a request and call producer function to submit -/// request into qat buffer. +/// Perform big number modular exponentiation operation accelerated with QAT for +/// input data as an octet string of unsigned chars. Create QAT contiguous memory +/// space. Upon call it copies input data and package it into a request, then calls +/// producer function to submit request to internal buffer. /// /// @param[in] _buffer_id Buffer ID of the reserved buffer for the caller's thread. /// @param[out] r Remainder number of the modular exponentiation operation. @@ -115,17 +115,21 @@ HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, unsigned char* b, unsigned char* e, unsigned char* m, int nbits); /// @brief Reserve/acquire buffer for multithreading support. +/// /// @details Try to acquire an available buffer to store outstanding work requests sent by caller. /// If none is available, it blocks further processing and waits until another caller's concurrent /// thread releases one. This function must be called before /// calling HE_QAT_bnModExp_MT(.). +/// /// @param[out] _buffer_id Pointer to memory space allocated by caller to hold the buffer ID of the buffer used to store caller's outstanding requests. HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id); /// @brief Wait for request processing to complete and release previously acquired buffer. +/// /// @details Caution: It assumes acquire_bnModExp_buffer(&_buffer_id) to be called first /// to secure and be assigned an outstanding buffer for the target thread. /// Equivalent to getBnModExpRequests() for the multithreading support interfaces. +/// /// param[in] _buffer_id Buffer ID of the buffer to be released/unlock for reuse by the next concurrent thread. /// param[in] _batch_size Total number of requests to wait for completion before releasing the buffer. void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size); From a0f344a1dbad873e2583858da543af3ec2a67667 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 20 Sep 2022 18:30:20 -0700 Subject: [PATCH 235/364] Update device config files. Signed-off-by: Souza, Fillipe --- config/1inst1dev/4xxx_dev2.conf | 212 ------------------ config/1inst1dev/4xxx_dev3.conf | 212 ------------------ config/1inst1dev/4xxx_dev4.conf | 212 ------------------ config/1inst1dev/4xxx_dev5.conf | 212 ------------------ config/1inst1dev/4xxx_dev6.conf | 212 ------------------ config/1inst1dev/4xxx_dev7.conf | 212 ------------------ config/2inst1dev/4xxx_dev0.conf | 212 ------------------ config/2inst1dev/4xxx_dev1.conf | 212 ------------------ config/2inst1dev/4xxx_dev2.conf | 212 ------------------ config/2inst1dev/4xxx_dev3.conf | 212 ------------------ config/2inst1dev/4xxx_dev4.conf | 212 ------------------ config/2inst1dev/4xxx_dev5.conf | 212 ------------------ config/2inst1dev/4xxx_dev6.conf | 212 ------------------ config/2inst1dev/4xxx_dev7.conf | 212 ------------------ .../4xxx_dev1.conf => 4xxx_dev0.conf} | 38 +--- .../4xxx_dev0.conf => 4xxxvf_dev0.conf} | 92 +------- config/8inst/4xxx_dev0.conf | 212 ------------------ 17 files changed, 11 insertions(+), 3299 deletions(-) delete mode 100644 config/1inst1dev/4xxx_dev2.conf delete mode 100644 config/1inst1dev/4xxx_dev3.conf delete mode 100644 config/1inst1dev/4xxx_dev4.conf delete mode 100644 config/1inst1dev/4xxx_dev5.conf delete mode 100644 config/1inst1dev/4xxx_dev6.conf delete mode 100644 config/1inst1dev/4xxx_dev7.conf delete mode 100644 config/2inst1dev/4xxx_dev0.conf delete mode 100644 config/2inst1dev/4xxx_dev1.conf delete mode 100644 config/2inst1dev/4xxx_dev2.conf delete mode 100644 config/2inst1dev/4xxx_dev3.conf delete mode 100644 config/2inst1dev/4xxx_dev4.conf delete mode 100644 config/2inst1dev/4xxx_dev5.conf delete mode 100644 config/2inst1dev/4xxx_dev6.conf delete mode 100644 config/2inst1dev/4xxx_dev7.conf rename config/{1inst1dev/4xxx_dev1.conf => 4xxx_dev0.conf} (89%) mode change 100644 => 100755 rename config/{1inst1dev/4xxx_dev0.conf => 4xxxvf_dev0.conf} (68%) mode change 100644 => 100755 delete mode 100644 config/8inst/4xxx_dev0.conf diff --git a/config/1inst1dev/4xxx_dev2.conf b/config/1inst1dev/4xxx_dev2.conf deleted file mode 100644 index 8325bc9..0000000 --- a/config/1inst1dev/4xxx_dev2.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 256 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 1 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 2 - -## Crypto - User instance #1 -#Cy1Name = "SSL1" -#Cy1IsPolled = 1 -## List of core affinities -#Cy1CoreAffinity = 5 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/1inst1dev/4xxx_dev3.conf b/config/1inst1dev/4xxx_dev3.conf deleted file mode 100644 index f0ac925..0000000 --- a/config/1inst1dev/4xxx_dev3.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 256 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 1 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 3 - -## Crypto - User instance #1 -#Cy1Name = "SSL1" -#Cy1IsPolled = 1 -## List of core affinities -#Cy1CoreAffinity = 7 -# -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/1inst1dev/4xxx_dev4.conf b/config/1inst1dev/4xxx_dev4.conf deleted file mode 100644 index 91aa45e..0000000 --- a/config/1inst1dev/4xxx_dev4.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 256 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 1 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 56 - -## Crypto - User instance #1 -#Cy1Name = "SSL1" -#Cy1IsPolled = 1 -## List of core affinities -#Cy1CoreAffinity = 57 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/1inst1dev/4xxx_dev5.conf b/config/1inst1dev/4xxx_dev5.conf deleted file mode 100644 index bedce9d..0000000 --- a/config/1inst1dev/4xxx_dev5.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 256 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 1 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 57 - -## Crypto - User instance #1 -#Cy1Name = "SSL1" -#Cy1IsPolled = 1 -## List of core affinities -#Cy1CoreAffinity = 59 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/1inst1dev/4xxx_dev6.conf b/config/1inst1dev/4xxx_dev6.conf deleted file mode 100644 index 8e099f0..0000000 --- a/config/1inst1dev/4xxx_dev6.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 256 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 1 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 58 - -## Crypto - User instance #1 -#Cy1Name = "SSL1" -#Cy1IsPolled = 1 -## List of core affinities -#Cy1CoreAffinity = 61 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/1inst1dev/4xxx_dev7.conf b/config/1inst1dev/4xxx_dev7.conf deleted file mode 100644 index b39ce63..0000000 --- a/config/1inst1dev/4xxx_dev7.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 256 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 1 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 59 - -## Crypto - User instance #1 -#Cy1Name = "SSL1" -#Cy1IsPolled = 1 -## List of core affinities -#Cy1CoreAffinity = 63 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/2inst1dev/4xxx_dev0.conf b/config/2inst1dev/4xxx_dev0.conf deleted file mode 100644 index 4e8e87d..0000000 --- a/config/2inst1dev/4xxx_dev0.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 256 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 2 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 0 - -# Crypto - User instance #1 -Cy1Name = "SSL1" -Cy1IsPolled = 1 -# List of core affinities -Cy1CoreAffinity = 1 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/2inst1dev/4xxx_dev1.conf b/config/2inst1dev/4xxx_dev1.conf deleted file mode 100644 index 659ac07..0000000 --- a/config/2inst1dev/4xxx_dev1.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 256 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 2 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 2 - -# Crypto - User instance #1 -Cy1Name = "SSL1" -Cy1IsPolled = 1 -# List of core affinities -Cy1CoreAffinity = 3 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/2inst1dev/4xxx_dev2.conf b/config/2inst1dev/4xxx_dev2.conf deleted file mode 100644 index f66a2e8..0000000 --- a/config/2inst1dev/4xxx_dev2.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 256 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 2 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 4 - -# Crypto - User instance #1 -Cy1Name = "SSL1" -Cy1IsPolled = 1 -# List of core affinities -Cy1CoreAffinity = 5 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/2inst1dev/4xxx_dev3.conf b/config/2inst1dev/4xxx_dev3.conf deleted file mode 100644 index 0a97044..0000000 --- a/config/2inst1dev/4xxx_dev3.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 256 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 2 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 6 - -# Crypto - User instance #1 -Cy1Name = "SSL1" -Cy1IsPolled = 1 -# List of core affinities -Cy1CoreAffinity = 7 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/2inst1dev/4xxx_dev4.conf b/config/2inst1dev/4xxx_dev4.conf deleted file mode 100644 index b572b74..0000000 --- a/config/2inst1dev/4xxx_dev4.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 256 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 2 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 56 - -# Crypto - User instance #1 -Cy1Name = "SSL1" -Cy1IsPolled = 1 -# List of core affinities -Cy1CoreAffinity = 57 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/2inst1dev/4xxx_dev5.conf b/config/2inst1dev/4xxx_dev5.conf deleted file mode 100644 index 545ccfd..0000000 --- a/config/2inst1dev/4xxx_dev5.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 256 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 2 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 58 - -# Crypto - User instance #1 -Cy1Name = "SSL1" -Cy1IsPolled = 1 -# List of core affinities -Cy1CoreAffinity = 59 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/2inst1dev/4xxx_dev6.conf b/config/2inst1dev/4xxx_dev6.conf deleted file mode 100644 index 41b0df2..0000000 --- a/config/2inst1dev/4xxx_dev6.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 256 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 2 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 60 - -# Crypto - User instance #1 -Cy1Name = "SSL1" -Cy1IsPolled = 1 -# List of core affinities -Cy1CoreAffinity = 61 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/2inst1dev/4xxx_dev7.conf b/config/2inst1dev/4xxx_dev7.conf deleted file mode 100644 index 09d014b..0000000 --- a/config/2inst1dev/4xxx_dev7.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 256 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 2 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 62 - -# Crypto - User instance #1 -Cy1Name = "SSL1" -Cy1IsPolled = 1 -# List of core affinities -Cy1CoreAffinity = 63 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/config/1inst1dev/4xxx_dev1.conf b/config/4xxx_dev0.conf old mode 100644 new mode 100755 similarity index 89% rename from config/1inst1dev/4xxx_dev1.conf rename to config/4xxx_dev0.conf index 056b430..870318c --- a/config/1inst1dev/4xxx_dev1.conf +++ b/config/4xxx_dev0.conf @@ -68,7 +68,7 @@ FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 256 +CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 @@ -161,43 +161,13 @@ Cy0CoreAffinity = 1 #Cy1Name = "SSL1" #Cy1IsPolled = 1 ## List of core affinities -#Cy1CoreAffinity = 3 - +#Cy1CoreAffinity = 2 +# ## Crypto - User instance #2 #Cy2Name = "SSL2" #Cy2IsPolled = 1 ## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 +#Cy2CoreAffinity = 3 # Data Compression - User instance #0 Dc0Name = "Dc0" diff --git a/config/1inst1dev/4xxx_dev0.conf b/config/4xxxvf_dev0.conf old mode 100644 new mode 100755 similarity index 68% rename from config/1inst1dev/4xxx_dev0.conf rename to config/4xxxvf_dev0.conf index 51c9c39..3a7fa18 --- a/config/1inst1dev/4xxx_dev0.conf +++ b/config/4xxxvf_dev0.conf @@ -63,12 +63,9 @@ ServicesEnabled = asym;dc ConfigVersion = 2 -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 256 +CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 @@ -93,55 +90,15 @@ PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - +# Disable Address translation services +ATEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] -NumberCyInstances = 1 +NumberCyInstances = 0 NumberDcInstances = 0 -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - ############################################## # User Process Instance Section ############################################## @@ -155,49 +112,13 @@ LimitDevAccess = 0 Cy0Name = "SSL0" Cy0IsPolled = 1 # List of core affinities -Cy0CoreAffinity = 0 +Cy0CoreAffinity = 1 ## Crypto - User instance #1 #Cy1Name = "SSL1" #Cy1IsPolled = 1 ## List of core affinities -#Cy1CoreAffinity = 1 - -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 2 -# -## Crypto - User instance #0 -#Cy3Name = "SSL3" -#Cy3IsPolled = 1 -## List of core affinities -#Cy3CoreAffinity = 3 -# -## Crypto - User instance #1 -#Cy4Name = "SSL4" -#Cy4IsPolled = 1 -## List of core affinities -#Cy4CoreAffinity = 4 -# -## Crypto - User instance #2 -#Cy5Name = "SSL5" -#Cy5IsPolled = 1 -## List of core affinities -#Cy5CoreAffinity = 5 -# -## Crypto - User instance #1 -#Cy6Name = "SSL6" -#Cy6IsPolled = 1 -## List of core affinities -#Cy6CoreAffinity = 6 -# -## Crypto - User instance #2 -#Cy7Name = "SSL7" -#Cy7IsPolled = 1 -## List of core affinities -#Cy7CoreAffinity = 7 +#Cy1CoreAffinity = 2 # Data Compression - User instance #0 Dc0Name = "Dc0" @@ -210,3 +131,4 @@ Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 2 + diff --git a/config/8inst/4xxx_dev0.conf b/config/8inst/4xxx_dev0.conf deleted file mode 100644 index 15f0abe..0000000 --- a/config/8inst/4xxx_dev0.conf +++ /dev/null @@ -1,212 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 256 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 8 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 0 - -# Crypto - User instance #1 -Cy1Name = "SSL1" -Cy1IsPolled = 1 -# List of core affinities -Cy1CoreAffinity = 1 - -# Crypto - User instance #2 -Cy2Name = "SSL2" -Cy2IsPolled = 1 -# List of core affinities -Cy2CoreAffinity = 2 - -# Crypto - User instance #0 -Cy3Name = "SSL3" -Cy3IsPolled = 1 -# List of core affinities -Cy3CoreAffinity = 3 - -# Crypto - User instance #1 -Cy4Name = "SSL4" -Cy4IsPolled = 1 -# List of core affinities -Cy4CoreAffinity = 4 - -# Crypto - User instance #2 -Cy5Name = "SSL5" -Cy5IsPolled = 1 -# List of core affinities -Cy5CoreAffinity = 5 - -# Crypto - User instance #1 -Cy6Name = "SSL6" -Cy6IsPolled = 1 -# List of core affinities -Cy6CoreAffinity = 6 - -# Crypto - User instance #2 -Cy7Name = "SSL7" -Cy7IsPolled = 1 -# List of core affinities -Cy7CoreAffinity = 7 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 From bbcb920453372e973bd0fed8864276e9d3d465f0 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 20 Sep 2022 18:31:00 -0700 Subject: [PATCH 236/364] Update strict to setup devices. Signed-off-by: Souza, Fillipe --- setup_devices.sh | 55 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/setup_devices.sh b/setup_devices.sh index 25d272f..7878d41 100755 --- a/setup_devices.sh +++ b/setup_devices.sh @@ -1,35 +1,54 @@ -#!/bin/env bash +#!/bin/bash -num_phys_dev=8 # num_dev=$(lspci -d 8086:4940 | wc -l) -conf_virt_func=0 # total_virt_func=$(lspci -d 8086:4941 | wc -l) -num_virt_func=0 # conf_virt_func=`expr $total_virt_func / $num_dev` +num_phys_dev=$(lspci -d 8086:4940 | wc -l) +if [ $num_phys_dev -eq 0 ]; then + echo "No QAT Device Found !" + exit +else + echo "$num_phys_dev QAT Devices Found !" +fi + +total_virt_func=$(lspci -d 8086:4941 | wc -l) +num_virt_func=`expr $total_virt_func / $num_phys_dev` dev_step=1 if [ $# -eq 0 ]; then - echo "Parameters:" - echo "-- num_phys_dev: Number of physical devices to be active. (default: 8)" - echo "-- conf_virt_func: Number of configured virtual functions per device. (default: 0)" - echo "-- num_virt_func: Number of virtual functions to be active per device. (default: 0)" - echo "./setup_devices " + echo "Usage: ./setup_devices " + echo " Parameters:" + echo " -- num_phys_dev: Number of physical devices to be active. (default: auto)" + echo " -- conf_virt_func: Number of configured virtual functions per device. (default: 0)" + echo " -- num_virt_func: Number of virtual functions to be active per device. (default: 0)" fi +nphysdev=$num_phys_dev if [ -n "$1" ]; then - num_phys_dev=$1 + nphysdev=$1 + if [ $nphysdev -gt $num_phys_dev ]; then + nphysdev=$num_phys_dev + fi fi +conf_virt_func=0 +# Check if virtual function is enabled +if [ $num_virt_func -gt 0 ]; then + conf_virt_func=1 +fi + if [ -n "$2" ]; then conf_virt_func=$2 + # if user attempts to request higher than available + if [ $conf_virt_func -gt $num_virt_func ]; then + conf_virt_func=$num_virt_func + fi fi -if [ -n "$3" ]; then - num_virt_func=$3 -fi - -if [ $conf_virt_func -gt 0 ]; then - dev_step=$conf_virt_func +start=0 +# If on virtualization mode +if [ $num_virt_func -gt 0 & $conf_virt_func -gt 0 ]; then + start=$num_phys_dev + dev_step=$num_virt_func fi -start=$num_phys_dev stop=`expr $num_phy_dev \\* $conf_virt_func` stop=`expr $start + $stop` step=$dev_step @@ -50,7 +69,7 @@ do sudo adf_ctl qat_dev$start up; # start up additional instances mapped to the same physical device j=1; - while [ $j -lt $num_virt_func ]; + while [ $j -lt $conf_virt_func ]; do dev_id=`expr $j + $start`; sudo adf_ctl qat_dev$dev_id up; From 24d6819df1907c2efc71a3c2f5c9b6d90ea7eed4 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 20 Sep 2022 18:44:31 -0700 Subject: [PATCH 237/364] Update sample test for HE_QAT_BIGNUMModExp(). Signed-off-by: Souza, Fillipe --- samples/CMakeLists.txt | 16 +++---- ...nModExpPerformOp.c => test_BIGNUMModExp.c} | 48 ++++++++++--------- 2 files changed, 33 insertions(+), 31 deletions(-) rename samples/{test_bnModExpPerformOp.c => test_BIGNUMModExp.c} (75%) diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 47b82f7..2a62889 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -17,17 +17,17 @@ install(TARGETS test_context RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) # ------------------------------------------------------------------------------------------- -add_executable(test_bnModExpPerformOp test_bnModExpPerformOp.c) +add_executable(test_BIGNUMModExp test_BIGNUMModExp.c) -target_include_directories(test_bnModExpPerformOp PUBLIC ${COMMON_INC_DIR}) # ${HE_QAT_UTILS_INC_DIR}) -#target_include_directories(test_bnModExpPerformOp PUBLIC ${HE_QAT_INC_DIR}) -target_include_directories(test_bnModExpPerformOp PUBLIC ${ICP_INC_DIR}) +target_include_directories(test_BIGNUMModExp PUBLIC ${COMMON_INC_DIR}) # ${HE_QAT_UTILS_INC_DIR}) +#target_include_directories(test_BIGNUMModExp PUBLIC ${HE_QAT_INC_DIR}) +target_include_directories(test_BIGNUMModExp PUBLIC ${ICP_INC_DIR}) -target_link_libraries(test_bnModExpPerformOp PUBLIC he_qat) -target_link_libraries(test_bnModExpPerformOp PUBLIC OpenSSL::SSL) # OpenSSL::Crypto) -#target_link_libraries(test_bnModExpPerformOp PUBLIC IPPCP::ippcp) +target_link_libraries(test_BIGNUMModExp PUBLIC he_qat) +target_link_libraries(test_BIGNUMModExp PUBLIC OpenSSL::SSL) # OpenSSL::Crypto) +#target_link_libraries(test_BIGNUMModExp PUBLIC IPPCP::ippcp) -install(TARGETS test_bnModExpPerformOp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS test_BIGNUMModExp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) # ------------------------------------------------------------------------------------------- diff --git a/samples/test_bnModExpPerformOp.c b/samples/test_BIGNUMModExp.c similarity index 75% rename from samples/test_bnModExpPerformOp.c rename to samples/test_BIGNUMModExp.c index a3487ed..a0b7676 100644 --- a/samples/test_bnModExpPerformOp.c +++ b/samples/test_BIGNUMModExp.c @@ -9,6 +9,10 @@ #include #include +#include +struct timeval start_time, end_time; +double time_taken = 0.0; + int gDebugParam = 1; // Active in Debug mode const unsigned int BATCH_SIZE = 1; @@ -55,9 +59,15 @@ int main(int argc, const char** argv) { // Perform OpenSSL ModExp Op BIGNUM* ssl_res = BN_new(); - start = clock(); - BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); - ssl_elapsed = clock() - start; + //start = clock(); + gettimeofday(&start_time, NULL); + BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); + //ssl_elapsed = clock() - start; + gettimeofday(&end_time, NULL); + time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; + time_taken = + (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; + ssl_elapsed = time_taken; if (!ERR_get_error()) { #ifdef _DESTINY_DEBUG_VERBOSE @@ -75,40 +85,32 @@ int main(int argc, const char** argv) { PRINT_DBG("\nStarting QAT bnModExp...\n"); #endif - // printf("OpenSSL: %.1lfus\t", ssl_elapsed / (CLOCKS_PER_SEC / - // 1000000.0)); - // Perform QAT ModExp Op BIGNUM* qat_res = BN_new(); - start = clock(); + //start = clock(); + gettimeofday(&start_time, NULL); for (unsigned int j = 0; j < BATCH_SIZE; j++) status = HE_QAT_BIGNUMModExp(qat_res, bn_base, bn_exponent, bn_mod, bit_length); getBnModExpRequest(BATCH_SIZE); - qat_elapsed = clock() - start; - - ssl_avg_time = (mod * ssl_avg_time + - (ssl_elapsed / (CLOCKS_PER_SEC / 1000000.0))) / - (mod + 1); + //qat_elapsed = clock() - start; + gettimeofday(&end_time, NULL); + time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; + time_taken = + (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; + qat_elapsed = time_taken; + + ssl_avg_time = (mod * ssl_avg_time + ssl_elapsed) / (mod + 1); qat_avg_time = - (mod * qat_avg_time + - (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0)) / BATCH_SIZE) / - (mod + 1); + (mod * qat_avg_time + qat_elapsed / BATCH_SIZE) / (mod + 1); avg_speed_up = (mod * avg_speed_up + - (ssl_elapsed / (CLOCKS_PER_SEC / 1000000.0)) / - ((qat_elapsed / (CLOCKS_PER_SEC / 1000000.0)) / BATCH_SIZE)) / - (mod + 1); + (ssl_elapsed) / (qat_elapsed/BATCH_SIZE)) / (mod + 1); printf( "Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", (mod + 1), ssl_avg_time, qat_avg_time, avg_speed_up); - // printf("QAT: %.1lfus\t", qat_elapsed / (CLOCKS_PER_SEC / - // 1000000.0)); printf("Speed Up: %.1lfx\t", (ssl_elapsed / - // (CLOCKS_PER_SEC / 1000000.0) / BATCH_SIZE) / (qat_elapsed / - // (CLOCKS_PER_SEC / 1000000.0) / BATCH_SIZE) ); - if (HE_QAT_STATUS_SUCCESS != status) { PRINT_ERR("\nQAT bnModExpOp failed\n"); } From 4ff1792796e233d8022a751f635c1bbb90128e05 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 20 Sep 2022 18:59:13 -0700 Subject: [PATCH 238/364] Fix hexadecimal print. Signed-off-by: Souza, Fillipe --- he_qat/he_qat_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/he_qat/he_qat_utils.c b/he_qat/he_qat_utils.c index 002847f..2677e1b 100644 --- a/he_qat/he_qat_utils.c +++ b/he_qat/he_qat_utils.c @@ -51,7 +51,7 @@ void showHexBN(BIGNUM* bn, int nbits) { unsigned char* bin = (unsigned char*)OPENSSL_zalloc(len); if (!bin) return; if (BN_bn2binpad(bn, bin, len)) { - for (size_t i = 0; i < len; i++) printf("%d", bin[i]); + for (size_t i = 0; i < len; i++) printf("%2.2x", bin[i]); printf("\n"); } OPENSSL_free(bin); @@ -60,7 +60,7 @@ void showHexBN(BIGNUM* bn, int nbits) { void showHexBin(unsigned char* bin, int len) { if (!bin) return; - for (size_t i = 0; i < len; i++) printf("%d", bin[i]); + for (size_t i = 0; i < len; i++) printf("%2.2x", bin[i]); printf("\n"); return; } From f726ff98d3923515f7eaa8bb20e00435014406a3 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 20 Sep 2022 18:59:40 -0700 Subject: [PATCH 239/364] Update time measurer. Signed-off-by: Souza, Fillipe --- samples/test_BIGNUMModExp.c | 5 ++--- samples/test_bnConversion.cpp | 33 ++++++++++++++++++++++++--------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/samples/test_BIGNUMModExp.c b/samples/test_BIGNUMModExp.c index a0b7676..9a91a98 100644 --- a/samples/test_BIGNUMModExp.c +++ b/samples/test_BIGNUMModExp.c @@ -24,9 +24,8 @@ int main(int argc, const char** argv) { double ssl_avg_time = 0.0; double qat_avg_time = 0.0; - clock_t start = CLOCKS_PER_SEC; - clock_t ssl_elapsed = CLOCKS_PER_SEC; - clock_t qat_elapsed = CLOCKS_PER_SEC; + double ssl_elapsed = 0.0 ; + double qat_elapsed = 0.0 ; HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; diff --git a/samples/test_bnConversion.cpp b/samples/test_bnConversion.cpp index 4f6fd3e..2234482 100644 --- a/samples/test_bnConversion.cpp +++ b/samples/test_bnConversion.cpp @@ -14,13 +14,16 @@ #include +#include +struct timeval start_time, end_time; +double time_taken = 0.0; + int main(int argc, const char** argv) { const int bit_length = 1024; const size_t num_trials = 4; - clock_t start = CLOCKS_PER_SEC; - clock_t ssl_elapsed = CLOCKS_PER_SEC; - clock_t qat_elapsed = CLOCKS_PER_SEC; + double ssl_elapsed = 0.0 ; + double qat_elapsed = 0.0 ; HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; @@ -52,15 +55,21 @@ int main(int argc, const char** argv) { BigNumber big_num((Ipp32u)0); - start = clock(); + gettimeofday(&start_time, NULL); + //start = clock(); status = binToBigNumber(big_num, bn_mod_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { printf("Failed at binToBigNumber()\n"); exit(1); } - ssl_elapsed = clock() - start; + //ssl_elapsed = clock() - start; + gettimeofday(&end_time, NULL); + time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; + time_taken = + (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; + ssl_elapsed = time_taken; printf("Conversion to BigNumber has completed in %.1lfus.\n", - (ssl_elapsed / (CLOCKS_PER_SEC / 1000000.0))); + (ssl_elapsed)); int bit_len = 0; ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); @@ -69,7 +78,8 @@ int main(int argc, const char** argv) { printf("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, bit_len); - start = clock(); +// start = clock(); + gettimeofday(&start_time, NULL); unsigned char* ref_bn_data_ = (unsigned char*)calloc(len_, sizeof(unsigned char)); if (NULL == ref_bn_data_) exit(1); @@ -78,9 +88,14 @@ int main(int argc, const char** argv) { printf("Failed at bigNumberToBin()\n"); exit(1); } - qat_elapsed = clock() - start; +// qat_elapsed = clock() - start; + gettimeofday(&end_time, NULL); + time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; + time_taken = + (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; + qat_elapsed = time_taken; printf("Conversion from BigNumber has completed %.1lfus.\n", - (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); + (qat_elapsed)); BIGNUM* ref_bin_ = BN_new(); BN_bin2bn(ref_bn_data_, len_, ref_bin_); From 269af749587127bdc10074dff67d12071f9cc00d Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 20 Sep 2022 19:12:46 -0700 Subject: [PATCH 240/364] Update example. Signed-off-by: Souza, Fillipe --- example/example.cpp | 108 +++++++++----------------------------------- 1 file changed, 22 insertions(+), 86 deletions(-) diff --git a/example/example.cpp b/example/example.cpp index e4a6294..da19a99 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -1,6 +1,7 @@ #include "he_qat_bn_ops.h" #include "he_qat_context.h" +#include "he_qat_utils.h" #include "cpa_sample_utils.h" #include @@ -16,67 +17,9 @@ #define ODD_RND_NUM 1 #define BATCH_SIZE 1 -BIGNUM* generateTestBNData(int nbits) { - if (!RAND_status()) return NULL; -#ifdef _DESTINY_DEBUG_VERBOSE - printf("PRNG properly seeded.\n"); -#endif - - BIGNUM* bn = BN_new(); - - if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { - BN_free(bn); - printf("Error while generating BN random number: %lu\n", - ERR_get_error()); - return NULL; - } - - return bn; -} - -unsigned char* paddingZeros(BIGNUM* bn, int nbits) { - if (!bn) return NULL; - - // Returns same address if it fails - int num_bytes = BN_num_bytes(bn); - int bytes_left = nbits / 8 - num_bytes; - if (bytes_left <= 0) return NULL; - - // Returns same address if it fails - unsigned char* bin = NULL; - int len = bytes_left + num_bytes; - if (!(bin = OPENSSL_zalloc(len))) return NULL; - -#ifdef _DESTINY_DEBUG_VERBOSE - printf("Padding bn with %d bytes to total %d bytes\n", bytes_left, len); -#endif - BN_bn2binpad(bn, bin, len); - if (ERR_get_error()) { - OPENSSL_free(bin); - return NULL; - } - - return bin; -} - -void showHexBN(BIGNUM* bn, int nbits) { - int len = nbits / 8; - unsigned char* bin = OPENSSL_zalloc(len); - if (!bin) return; - if (BN_bn2binpad(bn, bin, len)) { - for (size_t i = 0; i < len; i++) printf("%d", bin[i]); - printf("\n"); - } - OPENSSL_free(bin); - return; -} - -void showHexBin(unsigned char* bin, int len) { - if (!bin) return; - for (size_t i = 0; i < len; i++) printf("%d", bin[i]); - printf("\n"); - return; -} +#include +struct timeval start_time, end_time; +double time_taken = 0.0; int main(int argc, const char** argv) { const int bit_length = 4096; // 1024; @@ -86,9 +29,8 @@ int main(int argc, const char** argv) { double ssl_avg_time = 0.0; double qat_avg_time = 0.0; - clock_t start = CLOCKS_PER_SEC; - clock_t ssl_elapsed = CLOCKS_PER_SEC; - clock_t qat_elapsed = CLOCKS_PER_SEC; + double ssl_elapsed = 0.0; + double qat_elapsed = 0.0; HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; @@ -121,9 +63,13 @@ int main(int argc, const char** argv) { // Perform OpenSSL ModExp Op BIGNUM* ssl_res = BN_new(); - start = clock(); + gettimeofday(&start_time, NULL); BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); - ssl_elapsed = clock() - start; + gettimeofday(&end_time, NULL); + time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; + time_taken = + (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; + ssl_elapsed = time_taken; if (!ERR_get_error()) { #ifdef _DESTINY_DEBUG_VERBOSE @@ -141,41 +87,31 @@ int main(int argc, const char** argv) { PRINT_DBG("\nStarting QAT bnModExp...\n"); #endif - // printf("OpenSSL: %.1lfus\t", ssl_elapsed / (CLOCKS_PER_SEC / - // 1000000.0)); - // Perform QAT ModExp Op BIGNUM* qat_res = BN_new(); - start = clock(); + gettimeofday(&start_time, NULL); for (unsigned int j = 0; j < BATCH_SIZE; j++) status = bnModExpPerformOp(qat_res, bn_base, bn_exponent, bn_mod, bit_length); getBnModExpRequest(BATCH_SIZE); - qat_elapsed = clock() - start; + gettimeofday(&end_time, NULL); + time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; + time_taken = + (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; + qat_elapsed = time_taken; - ssl_avg_time = (mod * ssl_avg_time + - (ssl_elapsed / (CLOCKS_PER_SEC / 1000000.0))) / - (mod + 1); + ssl_avg_time = (mod * ssl_avg_time + ssl_elapsed) / (mod + 1); qat_avg_time = - (mod * qat_avg_time + - (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0)) / BATCH_SIZE) / - (mod + 1); + (mod * qat_avg_time + qat_elapsed / BATCH_SIZE) / (mod + 1); avg_speed_up = (mod * avg_speed_up + - (ssl_elapsed / (CLOCKS_PER_SEC / 1000000.0)) / - ((qat_elapsed / (CLOCKS_PER_SEC / 1000000.0)) / BATCH_SIZE)) / - (mod + 1); + (ssl_elapsed) / (qat_elapsed/BATCH_SIZE)) / (mod + 1); printf( "Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", (mod + 1), ssl_avg_time, qat_avg_time, avg_speed_up); - // printf("QAT: %.1lfus\t", qat_elapsed / (CLOCKS_PER_SEC / - // 1000000.0)); printf("Speed Up: %.1lfx\t", (ssl_elapsed / - // (CLOCKS_PER_SEC / 1000000.0) / BATCH_SIZE) / (qat_elapsed / - // (CLOCKS_PER_SEC / 1000000.0) / BATCH_SIZE) ); - - if (HE_QAT_STATUS_SUCCESS != status) { + if (HE_QAT_STATUS_SUCCESS != status) { PRINT_ERR("\nQAT bnModExpOp failed\n"); } #ifdef _DESTINY_DEBUG_VERBOSE From b98c26cb293efade7e3015772adc088ddc50c6af Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 21 Sep 2022 17:38:27 -0700 Subject: [PATCH 241/364] Update device setup script. Signed-off-by: Souza, Fillipe --- README.md | 36 ++++++++++++---- setup_devices.sh | 106 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 116 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index ff5ed16..66e96e9 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ f2:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) f7:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) ``` -In the example above, the platform is a dual-socket Sapphire Rapids (SPR) and it shows 8 QAT endpoints, 4 on each socket. +In the example above, the platform is a dual-socket server with Sapphire Rapids (SPR) CPU and it shows 8 QAT endpoints, 4 on each socket. #### Installing Dependencies @@ -138,22 +138,39 @@ sudo service qat_service status If all checks out, following the instructions below to build the HE QAT library. +#### Setup Environment + +This step is required. Note that if the step [Installing QAT Software Stack](#installing-qat-software-stack) has just been performed, then the exact path of the installation is known, i.e. + +``` +$ export ICP_ROOT=$HOME/QAT +``` + +Alternatively, if the system has a ore-built QAT software stack, the script `auto_find_qat_install.sh` can used to help automatically find the path where it was installed (see command below). + +``` +$ export ICP_ROOT=$(./auto_find_qat_install.sh) +``` + #### Building the Library -Without `BigNumber` support: +Execute step []() before building the library. + +- How to build without `BigNumber` support ``` $ git clone https://github.com/intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.project-destiny.git $ git checkout development -$ export ICP_ROOT=$HOME/QAT $ cmake -S . -B build -DHE_QAT_MISC=OFF $ cmake --build build $ cmake --install build ``` -The cmake configuration variable `HE_QAT_MISC=ON` enables `BigNumber` resources and samples, requiring IPP Crypto installation as a dependency. If usage of the utility functions that support `BigNumber` data type is needed, follow the building instructions below to install IPP Crypto and then rebuild the library with the cmake flag `HE_QAT_MISC=ON`: +- How to build with `BigNumber` support + +The `cmake` configuration variable `HE_QAT_MISC=ON` enables `BigNumber` resources and samples, requiring IPP Crypto installation as a dependency. If usage of the utility functions that support `BigNumber` data type is needed, follow the building instructions below to install IPP Crypto and then rebuild the library with the cmake flag `HE_QAT_MISC=ON`: -Installing `nasm-2.15`: +- Installing `nasm-2.15` ``` $ wget -c https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.xz @@ -164,7 +181,7 @@ $ make -j $ sudo make install ``` -Installing `ippcrypto`: +- Installing `ippcrypto` ``` $ cd ~ @@ -177,11 +194,12 @@ $ sudo cmake --install _build #### Configure QAT endpoints -Before trying to run any application or example that uses the HE QAT Lib, the QAT endpoints must be configured. Examples of configurations can be found in the directory `config`. The configuration that we found to serve us with the best performance is located at `config/1inst1dev`. +Before trying to run any application or example that uses the HE QAT Lib, the QAT endpoints must be configured. +The default configuration provided in this release is the optimal configuration to provide computing acceleration support for IPCL. +The boilerplate configurations can be found in the directory `config`. ``` -$ sudo cp config/1inst1dev/4xxx_dev*.conf /etc/ -$ sudo service qat_service restart +$ ./setup_devices.sh ``` #### Configuration Options diff --git a/setup_devices.sh b/setup_devices.sh index 7878d41..76f34e5 100755 --- a/setup_devices.sh +++ b/setup_devices.sh @@ -1,5 +1,9 @@ #!/bin/bash +# Refresh +echo "sudo service restart qat_service" +sudo service qat_service restart + num_phys_dev=$(lspci -d 8086:4940 | wc -l) if [ $num_phys_dev -eq 0 ]; then echo "No QAT Device Found !" @@ -42,40 +46,108 @@ if [ -n "$2" ]; then fi fi +# Shutdown QAT PFs +i=0 +while [ $i -lt $num_phys_dev ]; +do + echo "sudo adf_ctl qat_dev$i down"; + sudo adf_ctl qat_dev$i down; + i=`expr $i + 1`; +done + +# Reconfigure Target QAT PFs +i=0 +n=$nphysdev +while [ $i -lt $n ]; +do + echo "sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf"; + sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf; + echo "sudo adf_ctl qat_dev$i up"; + sudo adf_ctl qat_dev$i up; + i=`expr $i + 1`; +done + +# Refresh +echo "sudo service restart qat_service" +sudo service qat_service restart + +# If Virtualization Mode Enabled start=0 -# If on virtualization mode -if [ $num_virt_func -gt 0 & $conf_virt_func -gt 0 ]; then - start=$num_phys_dev - dev_step=$num_virt_func +if [ $num_virt_func -gt 0 ]; then + if [ $conf_virt_func -gt 0 ]; then + start=$num_phys_dev + dev_step=$num_virt_func + fi fi -stop=`expr $num_phy_dev \\* $conf_virt_func` +# Shutdown QAT VFs +i=$start +stop=`expr $num_phys_dev \\* $num_virt_func` stop=`expr $start + $stop` step=$dev_step - -i=$start; -n=`expr $start \\* $conf_virt_func`; -n=`expr $i + $n`; -while [ $i -lt $n ]; +while [ $i -lt $stop ]; do echo "sudo adf_ctl qat_dev$i down"; sudo adf_ctl qat_dev$i down; i=`expr $i + 1`; done -while [ $start -lt $stop ]; +#i=0 +#while [ $i -lt $total_virt_func ]; +#do +# echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$i.conf"; +# sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$i.conf; +# i=`expr $i + 1`; +#done + +i=0 +while [ $i -lt $nphysdev ]; +do + # Reconfigure QAT PF + echo "sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf"; + sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf; + # Start QAT PF + echo "sudo adf_ctl qat_dev$i up"; + sudo adf_ctl qat_dev$i up; + i=`expr $i + 1`; +done + +start=$num_phys_dev +i=$start +stop=`expr $nphysdev \\* $num_virt_func` +stop=`expr $start + $stop` +step=$dev_step +while [ $i -lt $stop ]; do - echo "adf_ctl qat_dev$start up" - sudo adf_ctl qat_dev$start up; - # start up additional instances mapped to the same physical device + k=`expr $i - $start` + # Reconfigure QAT VF (must match PF's config) + echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf"; + sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf; + # Start QAT VF + echo "adf_ctl qat_dev$i up" + sudo adf_ctl qat_dev$i up; + # Start up additional instances mapped to the same physical device j=1; while [ $j -lt $conf_virt_func ]; do - dev_id=`expr $j + $start`; + dev_id=`expr $i + $j`; + k=`expr $dev_id - $start`; + # Reconfigure QAT VF (must match PF's config) + echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf"; + sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf; + # Start QAT VF + echo "adf_ctl qat_dev$dev_id up" sudo adf_ctl qat_dev$dev_id up; j=`expr $j + 1`; done - start=`expr $start + $dev_step` + i=`expr $i + $dev_step` done - +# Shutdown Unused QAT PFs +i=$nphysdev +while [ $i -lt $num_phys_dev ]; +do + echo "sudo adf_ctl qat_dev$i down"; + sudo adf_ctl qat_dev$i down; + i=`expr $i + 1`; +done From d85b88ecbfcae39749b4201c1b05977baf14a843 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 21 Sep 2022 18:55:47 -0700 Subject: [PATCH 242/364] Add auxiliary scripts. Signed-off-by: Souza, Fillipe --- auto_find_qat_install.sh | 1 + reset_asym_buffer_size.sh | 75 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100755 auto_find_qat_install.sh create mode 100755 reset_asym_buffer_size.sh diff --git a/auto_find_qat_install.sh b/auto_find_qat_install.sh new file mode 100755 index 0000000..4150685 --- /dev/null +++ b/auto_find_qat_install.sh @@ -0,0 +1 @@ +for item in $(locate QAT/build); do [ -d $item ] && [ $(echo $item | grep $HOME) ] && echo ${item%/*}; done diff --git a/reset_asym_buffer_size.sh b/reset_asym_buffer_size.sh new file mode 100755 index 0000000..80b591e --- /dev/null +++ b/reset_asym_buffer_size.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +if [[ -z "${@}" ]]; then + echo "Usage: ./reset_asym_buffer_size " + exit +fi + +OLD_BUFFER_SIZE=$1 + +if [[ -z ${2} ]]; then + echo "Error: second parameter missing" + echo "Usage: ./reset_asym_buffer_size " + exit +fi + +NEW_BUFFER_SIZE=$2 + +num_phys_dev=$(lspci -d 8086:4940 | wc -l) +num_virt_dev=$(lspci -d 8086:4941 | wc -l) + +# Update physical device configuration files +i=0; +while [ $i -lt $num_phys_dev ]; +do + sudo sed -i /etc/4xxx_dev$i.conf -e "s/CyNumConcurrentAsymRequests = $OLD_BUFFER_SIZE/CyNumConcurrentAsymRequests = $NEW_BUFFER_SIZE/g"; + i=`expr $i + 1`; +done + +# Update virtual function configuration files +i=0; +while [ $i -lt $num_virt_dev ]; +do + sudo sed -i /etc/4xxxvf_dev$i.conf -e "s/CyNumConcurrentAsymRequests = $OLD_BUFFER_SIZE/CyNumConcurrentAsymRequests = $NEW_BUFFER_SIZE/g"; + i=`expr $i + 1`; +done + +## Power Off PFs +#i=0; +#while [ $i -lt $num_phys_dev ]; +#do +# sudo adf_ctl qat_dev$i down; +# i=`expr $i + 1`; +#done +# +## Power On PFs +#i=0; +#while [ $i -lt $num_phys_dev ]; +#do +# sudo adf_ctl qat_dev$i up; +# i=`expr $i + 1`; +#done +# +## Restart QAT service (This will bring up PFs and VFs) +#echo "sudo service qat_service restart" +#sudo service qat_service restart +# +## Power Off All VFs +#i=$num_phys_dev; +#vf_per_pf=`expr $num_virt_dev / $num_phys_dev` +#n=`expr $vf_per_pf \\* $num_phys_dev` +#n=`expr $n + $num_phys_dev` +#while [ $i -lt $n ]; +#do +# sudo adf_ctl qat_dev$i down; +# i=`expr $i + 1`; +#done +# +## Power On One QAT VF per QAT PF +#i=$num_phys_dev; +#while [ $i -lt $n ]; +#do +# sudo adf_ctl qat_dev$i up; +# i=`expr $i + $vf_per_pf`; +#done + From 076d291a4dbbc1c9fb057a798c9d1948149340c9 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 21 Sep 2022 19:00:03 -0700 Subject: [PATCH 243/364] Remove old source code. Signed-off-by: Souza, Fillipe --- CMakeLists.txt | 1 - he_qat/CMakeLists.txt | 9 +- he_qat/he_qat_bn_ops.c | 1436 ---------------------------------------- 3 files changed, 2 insertions(+), 1444 deletions(-) delete mode 100644 he_qat/he_qat_bn_ops.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ccf867..9cb6694 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,7 +68,6 @@ option(HE_QAT_SAMPLES "Enable examples" ON) option(HE_QAT_BENCHMARK "Enable benchmark" OFF) option(HE_QAT_DOCS "Enable document building" ON) option(HE_QAT_SHARED "Build shared library" ON) -option(HE_QAT_EXPERIMENTAL "Refactored code" OFF) if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(HE_QAT_DEBUG ON) diff --git a/he_qat/CMakeLists.txt b/he_qat/CMakeLists.txt index 9686665..563210b 100644 --- a/he_qat/CMakeLists.txt +++ b/he_qat/CMakeLists.txt @@ -4,13 +4,8 @@ set(HE_QAT_SRC ${HE_QAT_SRC_DIR}/he_qat_cb.c ${HE_QAT_SRC_DIR}/he_qat_utils.c ) -if(HE_QAT_EXPERIMENTAL) - message(STATUS "Using refactored source code.") - list(APPEND HE_QAT_SRC ${HE_QAT_SRC_DIR}/he_qat_ops.c - ${HE_QAT_SRC_DIR}/he_qat_ctrl.c) -else() - list(APPEND HE_QAT_SRC ${HE_QAT_SRC_DIR}/he_qat_bn_ops.c) -endif() +list(APPEND HE_QAT_SRC ${HE_QAT_SRC_DIR}/he_qat_ops.c + ${HE_QAT_SRC_DIR}/he_qat_ctrl.c) if(HE_QAT_SHARED) add_library(he_qat SHARED ${HE_QAT_SRC}) diff --git a/he_qat/he_qat_bn_ops.c b/he_qat/he_qat_bn_ops.c deleted file mode 100644 index 98e276c..0000000 --- a/he_qat/he_qat_bn_ops.c +++ /dev/null @@ -1,1436 +0,0 @@ -/// @file he_qat -#include "cpa.h" -#include "cpa_cy_im.h" -#include "cpa_cy_ln.h" -#include "icp_sal_poll.h" - -#include "cpa_sample_utils.h" - -#include "he_qat_types.h" -#include "he_qat_bn_ops.h" - -#ifdef HE_QAT_PERF -#include -struct timeval start_time, end_time; -double time_taken = 0.0; -#endif - -#include -#include -#include -#include - -#ifdef HE_QAT_SYNC_MODE -#pragma message "Synchronous execution mode." -#else -#pragma message "Asynchronous execution mode." -#endif - -//#define RESTART_LATENCY_MICROSEC 600 -//#define NUM_PKE_SLICES 6 - -#include "he_qat_gconst.h" - -// Global buffer for the runtime environment -HE_QAT_RequestBuffer he_qat_buffer; -HE_QAT_OutstandingBuffer outstanding; - -volatile unsigned long response_count = 0; -static volatile unsigned long request_count = 0; -static unsigned long request_latency = 0; // unused -static unsigned long restart_threshold = NUM_PKE_SLICES;//48; -static unsigned long max_pending = (NUM_PKE_SLICES * 2 * HE_QAT_NUM_ACTIVE_INSTANCES); - -// Callback functions -extern void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut); -extern void HE_QAT_bnModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut); - - -/// @brief -/// @function -/// Thread-safe producer implementation for the shared request buffer. -/// Stores requests in a buffer that will be offload to QAT devices. -static void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { -#ifdef HE_QAT_DEBUG - printf("Lock write request\n"); -#endif - pthread_mutex_lock(&_buffer->mutex); - -#ifdef HE_QAT_DEBUG - printf("Wait lock write request. [buffer size: %d]\n", _buffer->count); -#endif - while (_buffer->count >= HE_QAT_BUFFER_SIZE) - pthread_cond_wait(&_buffer->any_free_slot, &_buffer->mutex); - - assert(_buffer->count < HE_QAT_BUFFER_SIZE); - - _buffer->data[_buffer->next_free_slot++] = args; - - _buffer->next_free_slot %= HE_QAT_BUFFER_SIZE; - _buffer->count++; - - pthread_cond_signal(&_buffer->any_more_data); - pthread_mutex_unlock(&_buffer->mutex); -#ifdef HE_QAT_DEBUG - printf("Unlocked write request. [buffer size: %d]\n", _buffer->count); -#endif -} - -static void submit_request_list(HE_QAT_RequestBuffer* _buffer, - HE_QAT_TaskRequestList* _requests) { -//#define HE_QAT_DEBUG -#ifdef HE_QAT_DEBUG -// printf("Lock submit request list\n"); -#endif - if (0 == _requests->count) return; - - pthread_mutex_lock(&_buffer->mutex); - -#ifdef HE_QAT_DEBUG - printf( - "Wait lock submit request list. [internal buffer size: %d] [num " - "requests: %u]\n", - _buffer->count, _requests->count); -#endif - - // Wait until buffer can accomodate the number of input requests - while (_buffer->count >= HE_QAT_BUFFER_SIZE || - (HE_QAT_BUFFER_SIZE - _buffer->count) < _requests->count) - pthread_cond_wait(&_buffer->any_free_slot, &_buffer->mutex); - - assert(_buffer->count < HE_QAT_BUFFER_SIZE); - assert(_requests->count <= (HE_QAT_BUFFER_SIZE - _buffer->count)); - - for (unsigned int i = 0; i < _requests->count; i++) { - _buffer->data[_buffer->next_free_slot++] = _requests->request[i]; - _buffer->next_free_slot %= HE_QAT_BUFFER_SIZE; - _requests->request[i] = NULL; - } - _buffer->count += _requests->count; - _requests->count = 0; - - pthread_cond_signal(&_buffer->any_more_data); - pthread_mutex_unlock(&_buffer->mutex); -#ifdef HE_QAT_DEBUG - printf("Unlocked submit request list. [internal buffer size: %d]\n", - _buffer->count); -#endif -} - -/// @brief -/// @function -/// Thread-safe producer implementation for the shared outstanding request -/// buffer that stores request from multiple threads. -/// Stores requests in a buffer that will be sent to the HE QAT buffer. -/// @unused -static void push_request(HE_QAT_RequestBufferList* _outstanding_buffer, - void* args, unsigned int num_requests) { -#ifdef HE_QAT_DEBUG - printf("Lock write outstanding requests\n"); -#endif - pthread_mutex_lock(&_outstanding_buffer->mutex); - -#ifdef HE_QAT_DEBUG - printf("Wait lock write request. [outstanding buffer size: %d]\n", - _outstanding_buffer->count); -#endif - // if (NULL == args) pthread_mutex_unlock(&_outstanding_buffer->mutex); - unsigned int list_size = _outstanding_buffer->size; - unsigned int buffer_size = list_size * HE_QAT_BUFFER_SIZE; - // TODO(fdiasmor): Dynamically expand the outstanding buffer - // while (buffer_size < num_requests && - // buffer_size < HE_QAT_LIST_SIZE * HE_QAT_BUFFER_SIZE) { - // _outstanding_buffer->data[list_size] = - // malloc(sizeof(HE_QAT_TaskRequest)*HE_QAT_BUFFER_SIZE); if - //(_outstanding_buffer) - // buffer_size = ++list_size * HE_QAT_BUFFER_SIZE; - // } - // Create more space, if required, to a certain extent - // For now, it assumes maximum number of requests per thread and per call is - // equal to HE_QAT_BUFFER_SIZE and maximum number of threads is - // HE_QAT_BUFFER_COUNT - while (_outstanding_buffer->count >= buffer_size || - (buffer_size - _outstanding_buffer->count + 1 < num_requests)) - pthread_cond_wait(&_outstanding_buffer->any_free_slot, - &_outstanding_buffer->mutex); - - assert(_outstanding_buffer->count < buffer_size); - assert(buffer_size - _outstanding_buffer->count + 1 >= num_requests); - - HE_QAT_TaskRequestList* requests = (HE_QAT_TaskRequestList*)args; - for (unsigned int i = 0; i < requests->count; i++) { - unsigned int index = _outstanding_buffer->next_free_slot / buffer_size; - unsigned int slot = _outstanding_buffer->next_free_slot % buffer_size; - _outstanding_buffer->data[index][slot] = requests->request[i]; - _outstanding_buffer->next_free_slot++; - _outstanding_buffer->next_free_slot %= buffer_size; - _outstanding_buffer->count++; - } - - pthread_cond_signal(&_outstanding_buffer->any_more_data); - pthread_mutex_unlock(&_outstanding_buffer->mutex); -#ifdef HE_QAT_DEBUG - printf("Unlocked write request. [outstanding buffer count: %d]\n", - _outstanding_buffer->count); -#endif -} - -/// @brief -/// @function -/// Thread-safe consumer implementation for the shared request buffer. -/// Read requests from a buffer to finally offload the work to QAT devices. -/// Supported in single-threaded or multi-threaded mode. -static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) { - void* item = NULL; - static unsigned int counter = 0; - pthread_mutex_lock(&_buffer->mutex); -//#define HE_QAT_DEBUG -#ifdef HE_QAT_DEBUG - printf("Wait lock read request. [internal buffer size: %d] Request #%u\n", - _buffer->count, counter++); -#endif - // Wait while buffer is empty - while (_buffer->count <= 0) - pthread_cond_wait(&_buffer->any_more_data, &_buffer->mutex); - - assert(_buffer->count > 0); - - item = _buffer->data[_buffer->next_data_slot++]; - - _buffer->next_data_slot %= HE_QAT_BUFFER_SIZE; - _buffer->count--; - - pthread_cond_signal(&_buffer->any_free_slot); - pthread_mutex_unlock(&_buffer->mutex); -#ifdef HE_QAT_DEBUG - printf("Unlocked read request. [internal buffer count: %d]\n", - _buffer->count); -#endif - - return (HE_QAT_TaskRequest*)(item); -} - -/// @brief -/// @function -/// Thread-safe consumer implementation for the shared request buffer. -/// Read requests from a buffer to finally offload the work to QAT devices. -/// @future: Meant for multi-threaded mode. -static void read_request_list(HE_QAT_TaskRequestList* _requests, - HE_QAT_RequestBuffer* _buffer, unsigned int max_requests) { - if (NULL == _requests) return; - - pthread_mutex_lock(&_buffer->mutex); - - // Wait while buffer is empty - while (_buffer->count <= 0) - pthread_cond_wait(&_buffer->any_more_data, &_buffer->mutex); - - assert(_buffer->count > 0); - // assert(_buffer->count <= HE_QAT_BUFFER_SIZE); - - unsigned int count = (_buffer->count < max_requests) ? _buffer->count : max_requests; - - //for (unsigned int i = 0; i < _buffer->count; i++) { - for (unsigned int i = 0; i < count; i++) { - _requests->request[i] = _buffer->data[_buffer->next_data_slot++]; - _buffer->next_data_slot %= HE_QAT_BUFFER_SIZE; - } - //_requests->count = _buffer->count; - //_buffer->count = 0; - _requests->count = count; - _buffer->count -= count; - - pthread_cond_signal(&_buffer->any_free_slot); - pthread_mutex_unlock(&_buffer->mutex); - - return; -} - -/// @brief -/// @function -/// Thread-safe consumer implementation for the shared request buffer. -/// Read requests from a buffer to finally offload the work to QAT devices. -/// @deprecated -//[[deprecated("Replaced by pull_outstanding_requests() in schedule_requests().")]] -static void pull_request(HE_QAT_TaskRequestList* _requests, - // HE_QAT_OutstandingBuffer *_outstanding_buffer, - HE_QAT_RequestBufferList* _outstanding_buffer, - unsigned int max_num_requests) { - if (NULL == _requests) return; - - pthread_mutex_lock(&_outstanding_buffer->mutex); - - unsigned int list_size = _outstanding_buffer->size; - unsigned int buffer_size = list_size * HE_QAT_BUFFER_SIZE; - - // Wait while buffer is empty - while (_outstanding_buffer->count <= 0) - pthread_cond_wait(&_outstanding_buffer->any_more_data, - &_outstanding_buffer->mutex); - - assert(_outstanding_buffer->count > 0); - - unsigned int num_requests = (_outstanding_buffer->count <= max_num_requests) - ? _outstanding_buffer->count - : max_num_requests; - - assert(num_requests <= HE_QAT_BUFFER_SIZE); - - //_requests->count = 0; - for (unsigned int i = 0; i < num_requests; i++) { - unsigned int index = _outstanding_buffer->next_data_slot / buffer_size; - unsigned int slot = _outstanding_buffer->next_data_slot % buffer_size; - - _requests->request[i] = _outstanding_buffer->data[index][slot]; - //_requests->count++; - - _outstanding_buffer->next_data_slot++; - _outstanding_buffer->next_data_slot %= buffer_size; - //_outstanding_buffer->count--; - } - _requests->count = num_requests; - _outstanding_buffer->count -= num_requests; - - pthread_cond_signal(&_outstanding_buffer->any_free_slot); - pthread_mutex_unlock(&_outstanding_buffer->mutex); - - return; -} - -static void pull_outstanding_requests( - HE_QAT_TaskRequestList* _requests, - HE_QAT_OutstandingBuffer* _outstanding_buffer, - unsigned int max_num_requests) { - if (NULL == _requests) return; - _requests->count = 0; - - // for now, only one thread can change next_ready_buffer - // so no need for sync tools - - // Select an outstanding buffer to pull requests and add them into the - // processing queue (internal buffer) - pthread_mutex_lock(&_outstanding_buffer->mutex); - // Wait until next outstanding buffer becomes available for use - while (outstanding.busy_count <= 0) - pthread_cond_wait(&_outstanding_buffer->any_ready_buffer, - &_outstanding_buffer->mutex); - - int any_ready = 0; - unsigned int index = _outstanding_buffer->next_ready_buffer; // no fairness - for (unsigned int i = 0; i < HE_QAT_BUFFER_COUNT; i++) { - index = i; // ensure fairness - if (_outstanding_buffer->ready_buffer[index] && - _outstanding_buffer->buffer[index] - .count) { // sync with mutex at interface - any_ready = 1; - break; - } - // index = (index + 1) % HE_QAT_BUFFER_COUNT; - } - // Ensures it gets picked once only - pthread_mutex_unlock(&_outstanding_buffer->mutex); - - if (!any_ready) return; - - // printf("Buffer #%u is Ready\n",index); - - // Extract outstanding requests from outstanding buffer - // (this is the only function that reads from outstanding buffer, from a - // single thread) - pthread_mutex_lock(&_outstanding_buffer->buffer[index].mutex); - // This conditional waiting may not be required - // Wait while buffer is empty - while (_outstanding_buffer->buffer[index].count <= 0) { - pthread_cond_wait(&_outstanding_buffer->buffer[index].any_more_data, - &_outstanding_buffer->buffer[index].mutex); - } - assert(_outstanding_buffer->buffer[index].count > 0); - // - - unsigned int num_requests = - (_outstanding_buffer->buffer[index].count < max_num_requests) - ? _outstanding_buffer->buffer[index].count - : max_num_requests; - - assert(num_requests <= HE_QAT_BUFFER_SIZE); - - for (unsigned int i = 0; i < num_requests; i++) { - _requests->request[i] = - _outstanding_buffer->buffer[index] - .data[_outstanding_buffer->buffer[index].next_data_slot]; - _outstanding_buffer->buffer[index].count--; - _outstanding_buffer->buffer[index].next_data_slot++; - _outstanding_buffer->buffer[index].next_data_slot %= HE_QAT_BUFFER_SIZE; - } - _requests->count = num_requests; - - pthread_cond_signal(&_outstanding_buffer->buffer[index].any_free_slot); - pthread_mutex_unlock(&_outstanding_buffer->buffer[index].mutex); - - // --------------------------------------------------------------------------- - // Notify there is an outstanding buffer in ready for the processing queue - // pthread_mutex_lock(&_outstanding_buffer->mutex); - // - // _outstanding_buffer->ready_count--; - // _outstanding_buffer->ready_buffer[index] = 0; - // - // pthread_cond_signal(&_outstanding_buffer->any_free_buffer); - // pthread_mutex_unlock(&_outstanding_buffer->mutex); - - return; -} - -// Frontend for multithreading support -HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id) { - if (NULL == _buffer_id) return HE_QAT_STATUS_INVALID_PARAM; - - pthread_mutex_lock(&outstanding.mutex); - // Wait until next outstanding buffer becomes available for use - while (outstanding.busy_count >= HE_QAT_BUFFER_COUNT) - pthread_cond_wait(&outstanding.any_free_buffer, &outstanding.mutex); - - assert(outstanding.busy_count < HE_QAT_BUFFER_COUNT); - - // find next available - unsigned int next_free_buffer = outstanding.next_free_buffer; - for (unsigned int i = 0; i < HE_QAT_BUFFER_COUNT; i++) { - if (outstanding.free_buffer[next_free_buffer]) { - outstanding.free_buffer[next_free_buffer] = 0; - *_buffer_id = next_free_buffer; - break; - } - next_free_buffer = (next_free_buffer + 1) % HE_QAT_BUFFER_COUNT; - } - - outstanding.next_free_buffer = (*_buffer_id + 1) % HE_QAT_BUFFER_COUNT; - outstanding.next_ready_buffer = *_buffer_id; - outstanding.ready_buffer[*_buffer_id] = 1; - outstanding.busy_count++; - // busy meaning: - // taken by a thread, enqueued requests, in processing, waiting results - - pthread_cond_signal(&outstanding.any_ready_buffer); - pthread_mutex_unlock(&outstanding.mutex); - - return HE_QAT_STATUS_SUCCESS; -} - -void* schedule_requests(void* state) { - if (NULL == state) { - printf("Failed at buffer_manager: argument is NULL.\n"); - pthread_exit(NULL); - } - - int* active = (int*)state; - - HE_QAT_TaskRequestList outstanding_requests; - for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { - outstanding_requests.request[i] = NULL; - } - outstanding_requests.count = 0; - - // this thread should receive signal from context to exit - while (*active) { - // collect a set of requests from the outstanding buffer - pull_outstanding_requests(&outstanding_requests, &outstanding, - HE_QAT_BUFFER_SIZE); - // printf("Pulled %u outstanding - //requests\n",outstanding_requests.count); - // submit them to the HE QAT buffer for offloading - submit_request_list(&he_qat_buffer, &outstanding_requests); - // printf("Submitted %u outstanding - //requests\n",outstanding_requests.count); - } - - pthread_exit(NULL); -} - -/// @brief -/// @function start_inst_polling -/// @param[in] HE_QAT_InstConfig Parameter values to start and poll instances. -/// -static void* start_inst_polling(void* _inst_config) { - if (NULL == _inst_config) { - printf( - "Failed at start_inst_polling: argument is NULL.\n"); //,__FUNC__); - pthread_exit(NULL); - } - - HE_QAT_InstConfig* config = (HE_QAT_InstConfig*)_inst_config; - - if (NULL == config->inst_handle) return NULL; - -#ifdef HE_QAT_DEBUG - printf("Instance ID %d Polling\n",config->inst_id); -#endif - - // What is harmful for polling without performing any operation? - config->polling = 1; - while (config->polling) { - icp_sal_CyPollInstance(config->inst_handle, 0); - OS_SLEEP(50); - } - - pthread_exit(NULL); -} - - - -void* start_instances(void* _config) { -// static unsigned int request_count = 0; - static unsigned int instance_count = 0; - static unsigned int next_instance = 0; - - if (NULL == _config) { - printf("Failed in start_instances: _config is NULL.\n"); - pthread_exit(NULL); - } - - HE_QAT_Config* config = (HE_QAT_Config*)_config; - instance_count = config->count; - - printf("Instance Count: %d\n",instance_count); - pthread_t* polling_thread = (pthread_t *) malloc(sizeof(pthread_t)*instance_count); - if (NULL == polling_thread) { - printf("Failed in start_instances: polling_thread is NULL.\n"); - pthread_exit(NULL); - } - unsigned* request_count_per_instance = (unsigned *) malloc(sizeof(unsigned)*instance_count); - if (NULL == request_count_per_instance) { - printf("Failed in start_instances: polling_thread is NULL.\n"); - pthread_exit(NULL); - } - for (unsigned i = 0; i < instance_count; i++) { - request_count_per_instance[i] = 0; - } - - CpaStatus status = CPA_STATUS_FAIL; - - for (unsigned int j = 0; j < config->count; j++) { - // Start from zero or restart after stop_perform_op - pthread_mutex_lock(&config->inst_config[j].mutex); - while (config->inst_config[j].active) - pthread_cond_wait(&config->inst_config[j].ready, - &config->inst_config[j].mutex); - - // assert(0 == config->active); - // assert(NULL == config->inst_handle); - - status = cpaCyStartInstance(config->inst_config[j].inst_handle); - config->inst_config[j].status = status; - if (CPA_STATUS_SUCCESS == status) { - printf("Cpa CyInstance has successfully started.\n"); - status = - cpaCySetAddressTranslation(config->inst_config[j].inst_handle, - sampleVirtToPhys); - } - - pthread_cond_signal(&config->inst_config[j].ready); - pthread_mutex_unlock(&config->inst_config[j].mutex); - - if (CPA_STATUS_SUCCESS != status) pthread_exit(NULL); - - printf("Instance ID: %d\n",config->inst_config[j].inst_id); - - // Start QAT instance and start polling - //pthread_t polling_thread; - if (pthread_create(&polling_thread[j], config->inst_config[j].attr, start_inst_polling, - (void*)&(config->inst_config[j])) != 0) { - printf("Failed at creating and starting polling thread.\n"); - pthread_exit(NULL); - } - - if (pthread_detach(polling_thread[j]) != 0) { - printf("Failed at detaching polling thread.\n"); - pthread_exit(NULL); - } - - config->inst_config[j].active = 1; - config->inst_config[j].running = 1; - - } // for loop - - /* NEW CODE */ - HE_QAT_TaskRequestList outstanding_requests; - for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { - outstanding_requests.request[i] = NULL; - } - outstanding_requests.count = 0; - /* END NEW CODE */ - - config->running = 1; - config->active = 1; - while (config->running) { -#ifdef HE_QAT_DEBUG - printf("Try reading request from buffer. Inst #%d\n", config->inst_id); -#endif - /* NEW CODE */ - unsigned long pending = request_count - response_count; - unsigned long available = max_pending - ((pending < max_pending)?pending:max_pending); -#ifdef HE_QAT_DEBUG - printf("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", - request_count,response_count,pending,available); -#endif - while (available < restart_threshold) { -#ifdef HE_QAT_DEBUG - printf("[WAIT]\n"); -#endif - // argument passed in microseconds - OS_SLEEP(RESTART_LATENCY_MICROSEC); - pending = request_count - response_count; - available = max_pending - ((pending < max_pending)?pending:max_pending); -// printf("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", -// request_count,response_count,pending,available); - } -#ifdef HE_QAT_DEBUG - printf("[SUBMIT] request_count: %lu response_count: %lu pending: %lu available: %lu\n", - request_count,response_count,pending,available); -#endif - unsigned int max_requests = available; - // Try consume maximum amount of data from butter to perform requested operation - read_request_list(&outstanding_requests, &he_qat_buffer, max_requests); - /* END NEW CODE */ - -// // Try consume data from butter to perform requested operation -// HE_QAT_TaskRequest* request = -// (HE_QAT_TaskRequest*)read_request(&he_qat_buffer); -// -// if (NULL == request) { -// pthread_cond_signal(&config->ready); -// continue; -// } -#ifdef HE_QAT_DEBUG - printf("Offloading %u requests to the accelerator.\n", outstanding_requests.count); -#endif - for (unsigned int i = 0; i < outstanding_requests.count; i++) { - HE_QAT_TaskRequest* request = outstanding_requests.request[i]; -#ifdef HE_QAT_SYNC_MODE - COMPLETION_INIT(&request->callback); -#endif - - unsigned retry = 0; - do { - // Realize the type of operation from data - switch (request->op_type) { - // Select appropriate action - case HE_QAT_OP_MODEXP: -#ifdef HE_QAT_DEBUG - printf("Offload request using instance #%d\n", next_instance); -#endif -#ifdef HE_QAT_PERF - gettimeofday(&request->start, NULL); -#endif - status = cpaCyLnModExp( - config->inst_config[next_instance].inst_handle, - (CpaCyGenFlatBufCbFunc) - request->callback_func, // lnModExpCallback, - (void*)request, (CpaCyLnModExpOpData*)request->op_data, - &request->op_result); - retry++; - break; - case HE_QAT_OP_NONE: - default: -#ifdef HE_QAT_DEBUG - printf("HE_QAT_OP_NONE to instance #%d\n", next_instance); -#endif - retry = HE_QAT_MAX_RETRY; - break; - } - - if (CPA_STATUS_RETRY == status) { - printf("CPA requested RETRY\n"); - printf("RETRY count = %u\n",retry); - pthread_exit(NULL); // halt the whole system - } - - } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); - - // Ensure every call to perform operation is blocking for each endpoint - if (CPA_STATUS_SUCCESS == status) { - // Global tracking of number of requests - request_count += 1; - request_count_per_instance[next_instance] += 1; -// printf("Instance %d Count %u\n",next_instance,request_count_per_instance[next_instance]); - next_instance = (next_instance + 1) % instance_count; -// printf("retry_count = %d\n",retry_count); -// printf("SUCCESS Next Instance = %d\n",next_instance); - // Wake up any blocked call to stop_perform_op, signaling that now it is - // safe to terminate running instances. Check if this detereorate - // performance. - pthread_cond_signal(&config->inst_config[next_instance].ready); // Prone to the lost wake-up problem -#ifdef HE_QAT_SYNC_MODE - // Wait until the callback function has been called - if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { - request->op_status = CPA_STATUS_FAIL; - request->request_status = HE_QAT_STATUS_FAIL; // Review it - printf("Failed in COMPLETION WAIT\n"); - } - - // Destroy synchronization object - COMPLETION_DESTROY(&request->callback); -#endif - } else { - request->op_status = CPA_STATUS_FAIL; - request->request_status = HE_QAT_STATUS_FAIL; // Review it - printf("Request Submission FAILED\n"); - } - -#ifdef HE_QAT_DEBUG - printf("Offloading completed by instance #%d\n", next_instance-1); -#endif - - // Reset pointer - outstanding_requests.request[i] = NULL; - request = NULL; - - }// for loop over batch of requests - outstanding_requests.count = 0; - } - pthread_exit(NULL); -} - -/// @brief -/// @function perform_op -/// Offload operation to QAT endpoints; for example, large number modular -/// exponentiation. -/// @param[in] HE_QAT_InstConfig *: contains the handle to CPA instance, pointer -/// the global buffer of requests. -void* start_perform_op(void* _inst_config) { -// static unsigned int request_count = 0; - if (NULL == _inst_config) { - printf("Failed in start_perform_op: _inst_config is NULL.\n"); - pthread_exit(NULL); - } - - HE_QAT_InstConfig* config = (HE_QAT_InstConfig*)_inst_config; - - CpaStatus status = CPA_STATUS_FAIL; - - // Start from zero or restart after stop_perform_op - pthread_mutex_lock(&config->mutex); - while (config->active) pthread_cond_wait(&config->ready, &config->mutex); - - // assert(0 == config->active); - // assert(NULL == config->inst_handle); - - status = cpaCyStartInstance(config->inst_handle); - config->status = status; - if (CPA_STATUS_SUCCESS == status) { - printf("Cpa CyInstance has successfully started.\n"); - status = - cpaCySetAddressTranslation(config->inst_handle, sampleVirtToPhys); - } - - pthread_cond_signal(&config->ready); - pthread_mutex_unlock(&config->mutex); - - if (CPA_STATUS_SUCCESS != status) pthread_exit(NULL); - - // Start QAT instance and start polling - pthread_t polling_thread; - if (pthread_create(&polling_thread, config->attr, start_inst_polling, - (void*)config) != 0) { - printf("Failed at creating and starting polling thread.\n"); - pthread_exit(NULL); - } - - if (pthread_detach(polling_thread) != 0) { - printf("Failed at detaching polling thread.\n"); - pthread_exit(NULL); - } - - /* NEW CODE */ - HE_QAT_TaskRequestList outstanding_requests; - for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { - outstanding_requests.request[i] = NULL; - } - outstanding_requests.count = 0; - /* END NEW CODE */ - - config->running = 1; - config->active = 1; - while (config->running) { -#ifdef HE_QAT_DEBUG - printf("Try reading request from buffer. Inst #%d\n", config->inst_id); -#endif - /* NEW CODE */ - unsigned long pending = request_count - response_count; - unsigned long available = max_pending - ((pending < max_pending)?pending:max_pending); -#ifdef HE_QAT_DEBUG - printf("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", - request_count,response_count,pending,available); -#endif - while (available < restart_threshold) { -#ifdef HE_QAT_DEBUG - printf("[WAIT]\n"); -#endif - // argument passed in microseconds - OS_SLEEP(650); - pending = request_count - response_count; - available = max_pending - ((pending < max_pending)?pending:max_pending); - } -#ifdef HE_QAT_DEBUG - printf("[SUBMIT] request_count: %lu response_count: %lu pending: %lu available: %lu\n", - request_count,response_count,pending,available); -#endif - unsigned int max_requests = available; - // Try consume maximum amount of data from butter to perform requested operation - read_request_list(&outstanding_requests, &he_qat_buffer, max_requests); - /* END NEW CODE */ - -// // Try consume data from butter to perform requested operation -// HE_QAT_TaskRequest* request = -// (HE_QAT_TaskRequest*)read_request(&he_qat_buffer); -// -// if (NULL == request) { -// pthread_cond_signal(&config->ready); -// continue; -// } -#ifdef HE_QAT_DEBUG - printf("Offloading %u requests to the accelerator.\n", outstanding_requests.count); -#endif - for (unsigned int i = 0; i < outstanding_requests.count; i++) { - HE_QAT_TaskRequest* request = outstanding_requests.request[i]; -#ifdef HE_QAT_SYNC_MODE - COMPLETION_INIT(&request->callback); -#endif - unsigned retry = 0; - do { - // Realize the type of operation from data - switch (request->op_type) { - // Select appropriate action - case HE_QAT_OP_MODEXP: - //if (retry > 0) printf("Try offloading again last request\n"); -#ifdef HE_QAT_DEBUG - printf("Offload request using instance #%d\n", config->inst_id); -#endif -#ifdef HE_QAT_PERF - gettimeofday(&request->start, NULL); -#endif - status = cpaCyLnModExp( - config->inst_handle, - (CpaCyGenFlatBufCbFunc) - request->callback_func, // lnModExpCallback, - (void*)request, (CpaCyLnModExpOpData*)request->op_data, - &request->op_result); - retry++; - break; - case HE_QAT_OP_NONE: - default: -#ifdef HE_QAT_DEBUG - printf("HE_QAT_OP_NONE to instance #%d\n", config->inst_id); -#endif - retry = HE_QAT_MAX_RETRY; - break; - } - - if (CPA_STATUS_RETRY == status) { - printf("CPA requested RETRY\n"); - printf("RETRY count: %u\n",retry); - OS_SLEEP(600); - } - - } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); - - // Ensure every call to perform operation is blocking for each endpoint - if (CPA_STATUS_SUCCESS == status) { - // Global tracking of number of requests - request_count += 1; - //printf("retry_count = %d\n",retry_count); -#ifdef HE_QAT_SYNC_MODE - // Wait until the callback function has been called - if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { - request->op_status = CPA_STATUS_FAIL; - request->request_status = HE_QAT_STATUS_FAIL; // Review it - printf("Failed in COMPLETION WAIT\n"); - } - - // Destroy synchronization object - COMPLETION_DESTROY(&request->callback); -#endif - } else { - request->op_status = CPA_STATUS_FAIL; - request->request_status = HE_QAT_STATUS_FAIL; // Review it - } - - // Reset pointer - outstanding_requests.request[i] = NULL; - request = NULL; - - }// for loop over batch of requests - outstanding_requests.count = 0; - - // Wake up any blocked call to stop_perform_op, signaling that now it is - // safe to terminate running instances. Check if this detereorate - // performance. - pthread_cond_signal( - &config->ready); // Prone to the lost wake-up problem -#ifdef HE_QAT_DEBUG - printf("Offloading completed by instance #%d\n", config->inst_id); -#endif - } - pthread_exit(NULL); -} - -/// @brief -/// @function -/// Stop first 'num_inst' number of cpaCyInstance(s), including their polling -/// and running threads. -/// @param[in] HE_QAT_InstConfig config Vector of created instances with their -/// configuration setup. -/// @param[in] num_inst Unsigned integer number indicating first number of -/// instances to be terminated. -void stop_perform_op(HE_QAT_InstConfig* config, unsigned num_inst) { - // if () { - // Stop runnning and polling instances - // Release QAT instances handles - if (NULL == config) return; - - CpaStatus status = CPA_STATUS_FAIL; - for (unsigned i = 0; i < num_inst; i++) { - pthread_mutex_lock(&config[i].mutex); -#ifdef HE_QAT_DEBUG - printf("Try teardown HE QAT instance #%d.\n", i); -#endif - while (0 == config[i].active) { - pthread_cond_wait(&config[i].ready, &config[i].mutex); - } - if (CPA_STATUS_SUCCESS == config[i].status && config[i].active) { -#ifdef HE_QAT_DEBUG - printf("Stop polling and running threads #%d\n", i); -#endif - config[i].polling = 0; - config[i].running = 0; - OS_SLEEP(10); -#ifdef HE_QAT_DEBUG - printf("Stop cpaCyInstance #%d\n", i); -#endif - if (config[i].inst_handle == NULL) continue; -#ifdef HE_QAT_DEBUG - printf("cpaCyStopInstance\n"); -#endif - status = cpaCyStopInstance(config[i].inst_handle); - if (CPA_STATUS_SUCCESS != status) { - printf("Failed to stop QAT instance #%d\n", i); - } - } - pthread_cond_signal(&config[i].ready); - pthread_mutex_unlock(&config[i].mutex); - } - //} - - return; -} - -void stop_instances(HE_QAT_Config* _config) { - if (NULL == _config) return; - if (_config->active) _config->active = 0; - if (_config->running) _config->running = 0; - stop_perform_op(_config->inst_config, _config->count); - return ; -} - -HE_QAT_STATUS bnModExpPerformOp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, - int nbits) { - // Unpack data and copy to QAT friendly memory space - int len = (nbits + 7) >> 3; // nbits / 8; - - Cpa8U* pBase = NULL; - Cpa8U* pModulus = NULL; - Cpa8U* pExponent = NULL; - - HE_QAT_TaskRequest* request = - (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); - if (NULL == request) { - printf( - "HE_QAT_TaskRequest memory allocation failed in " - "bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } - - // TODO: @fdiasmor Try it with 8-byte alignment. - CpaStatus status = CPA_STATUS_FAIL; - status = PHYS_CONTIG_ALLOC(&pBase, len); - if (CPA_STATUS_SUCCESS == status && NULL != pBase) { - //{ - // unsigned char* bin = (unsigned char*)calloc(len, sizeof(unsigned - // char)); if (BN_bn2binpad(b, bin, len)) { - if (BN_bn2binpad(b, pBase, len)) { - // memcpy(pBase, bin, len); - // pBase = (Cpa8U*)bin; - } else { - printf("BN_bn2binpad (base) failed in bnModExpPerformOp.\n"); - PHYS_CONTIG_FREE(pBase); - // free(bin); - // bin = NULL; - return HE_QAT_STATUS_FAIL; - } - //} - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; - } - - status = PHYS_CONTIG_ALLOC(&pExponent, len); - if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { - //{ - // unsigned char* bin = (unsigned char*)calloc(len, sizeof(unsigned - // char)); if (BN_bn2binpad(e, bin, len)) { - if (BN_bn2binpad(e, pExponent, len)) { - // memcpy(pExponent, bin, len); - // pExponent = (Cpa8U*)bin; - } else { - printf("BN_bn2binpad (exponent) failed in bnModExpPerformOp.\n"); - PHYS_CONTIG_FREE(pExponent); - // free(bin); - // bin = NULL; - return HE_QAT_STATUS_FAIL; - } - //} - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; - } - - status = PHYS_CONTIG_ALLOC(&pModulus, len); - if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { - //{ - // unsigned char* bin = (unsigned char*)calloc(len, sizeof(unsigned - // char)); if (BN_bn2binpad(m, bin, len)) { - if (BN_bn2binpad(m, pModulus, len)) { - // memcpy(pModulus, bin, len); - // pModulus = (Cpa8U*)bin; - } else { - printf("BN_bn2binpad failed in bnModExpPerformOp.\n"); - PHYS_CONTIG_FREE(pModulus); - // free(bin); - // bin = NULL; - return HE_QAT_STATUS_FAIL; - } - //} - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; - } - - // Pack it as a QAT Task Request - CpaCyLnModExpOpData* op_data = - (CpaCyLnModExpOpData*)calloc(1, sizeof(CpaCyLnModExpOpData)); - if (NULL == op_data) { - printf("Cpa memory allocation failed in bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } - op_data->base.pData = pBase; - op_data->base.dataLenInBytes = len; - op_data->exponent.pData = pExponent; - op_data->exponent.dataLenInBytes = len; - op_data->modulus.pData = pModulus; - op_data->modulus.dataLenInBytes = len; - request->op_data = (void*)op_data; - - status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); - if (CPA_STATUS_SUCCESS == status && NULL != request->op_result.pData) { - request->op_result.dataLenInBytes = len; - } else { - printf( - "CpaFlatBuffer.pData memory allocation failed in " - "bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } - - request->op_type = HE_QAT_OP_MODEXP; - //request->callback_func = (void*)lnModExpCallback; - request->callback_func = (void*)HE_QAT_BIGNUMModExpCallback; - request->op_status = status; - request->op_output = (void*)r; - - // Ensure calls are synchronized at exit (blocking) - pthread_mutex_init(&request->mutex, NULL); - pthread_cond_init(&request->ready, NULL); - - // Submit request using producer function - submit_request(&he_qat_buffer, (void*)request); - - return HE_QAT_STATUS_SUCCESS; -} - -// Assume allocate_bnModExp_buffer(&_buffer_id) to be called first -// to secure and allocate an outstanding buffer for the target thread. -// Multithread support for release_bnModExp_buffer(_buffer_id, batch_size) -void release_bnModExp_buffer(unsigned int _buffer_id, - unsigned int _batch_size) { - unsigned int next_data_out = outstanding.buffer[_buffer_id].next_data_out; - unsigned int j = 0; - -#ifdef HE_QAT_DEBUG - printf("release_bnModExp_buffer #%u\n", _buffer_id); -#endif - -#ifdef HE_QAT_PERF - gettimeofday(&start_time, NULL); -#endif - - while (j < _batch_size) { - // Buffer read may be safe for single-threaded blocking calls only. - // Note: Not tested on multithreaded environment. - HE_QAT_TaskRequest* task = - (HE_QAT_TaskRequest*)outstanding.buffer[_buffer_id] - .data[next_data_out]; - - if (NULL == task) continue; - -#ifdef HE_QAT_DEBUG - printf("BatchSize %u Buffer #%u Request #%u Waiting\n", _batch_size, - _buffer_id, j); -#endif - - // Block and synchronize: Wait for the most recently offloaded request - // to complete processing - pthread_mutex_lock( - &task->mutex); // mutex only needed for the conditional variable - while (HE_QAT_STATUS_READY != task->request_status) - pthread_cond_wait(&task->ready, &task->mutex); - -#ifdef HE_QAT_PERF - time_taken = (task->end.tv_sec - task->start.tv_sec) * 1e6; - time_taken = - (time_taken + (task->end.tv_usec - task->start.tv_usec)); //*1e-6; - printf("%u time: %.1lfus\n", j, time_taken); -#endif - - // Free up QAT temporary memory - CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; - if (op_data) { - PHYS_CONTIG_FREE(op_data->base.pData); - PHYS_CONTIG_FREE(op_data->exponent.pData); - PHYS_CONTIG_FREE(op_data->modulus.pData); - } - free(task->op_data); - task->op_data = NULL; - if (task->op_result.pData) { - PHYS_CONTIG_FREE(task->op_result.pData); - } - - // Move forward to wait for the next request that will be offloaded - pthread_mutex_unlock(&task->mutex); - -#ifdef HE_QAT_DEBUG - printf("Buffer #%u Request #%u Completed\n", _buffer_id, j); -#endif - // outstanding.buffer[_buffer_id].count--; - - // Fix segmentation fault? - free(outstanding.buffer[_buffer_id].data[next_data_out]); - outstanding.buffer[_buffer_id].data[next_data_out] = NULL; - - // update for next thread on the next external iteration - next_data_out = (next_data_out + 1) % HE_QAT_BUFFER_SIZE; - - j++; - } - -#ifdef HE_QAT_PERF - gettimeofday(&end_time, NULL); - time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; - time_taken = - (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; - printf("Batch Wall Time: %.1lfus\n", time_taken); -#endif - - outstanding.buffer[_buffer_id].next_data_out = next_data_out; - - // Release outstanding buffer for usage by another thread - pthread_mutex_lock(&outstanding.mutex); - - outstanding.next_free_buffer = _buffer_id; - outstanding.ready_buffer[_buffer_id] = 0; - outstanding.free_buffer[_buffer_id] = 1; - outstanding.busy_count--; - - pthread_cond_signal(&outstanding.any_free_buffer); - pthread_mutex_unlock(&outstanding.mutex); - - return; -} - -// Maybe it will be useful to pass the number of requests to retrieve -// Pass post-processing function as argument to bring output to expected type -void getBnModExpRequest(unsigned int batch_size) { - static unsigned long block_at_index = 0; - unsigned int j = 0; - -#ifdef HE_QAT_PERF - gettimeofday(&start_time, NULL); -#endif -//printf("batch_size=%u \n",batch_size); -// while (j < batch_size) { - do { - // Buffer read may be safe for single-threaded blocking calls only. - // Note: Not tested on multithreaded environment. - HE_QAT_TaskRequest* task = - (HE_QAT_TaskRequest*)he_qat_buffer.data[block_at_index]; - - if (NULL == task) - continue; - -//printf("j=%u ",j); - - // Block and synchronize: Wait for the most recently offloaded request - // to complete processing - pthread_mutex_lock( - &task->mutex); // mutex only needed for the conditional variable - while (HE_QAT_STATUS_READY != task->request_status) - pthread_cond_wait(&task->ready, &task->mutex); - -#ifdef HE_QAT_PERF - time_taken = (task->end.tv_sec - task->start.tv_sec) * 1e6; - time_taken = - (time_taken + (task->end.tv_usec - task->start.tv_usec)); //*1e-6; - printf("%u time: %.1lfus\n", j, time_taken); -#endif - - // Free up QAT temporary memory - CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; - if (op_data) { - PHYS_CONTIG_FREE(op_data->base.pData); - PHYS_CONTIG_FREE(op_data->exponent.pData); - PHYS_CONTIG_FREE(op_data->modulus.pData); - } - free(task->op_data); - task->op_data = NULL; - if (task->op_result.pData) { - PHYS_CONTIG_FREE(task->op_result.pData); - } - - // Move forward to wait for the next request that will be offloaded - pthread_mutex_unlock(&task->mutex); - - // Fix segmentation fault? - free(he_qat_buffer.data[block_at_index]); - he_qat_buffer.data[block_at_index] = NULL; - - block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; -// j++; -// } - } while (++j < batch_size); // number of null pointers equal batch size ? - -#ifdef HE_QAT_PERF - gettimeofday(&end_time, NULL); - time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; - time_taken = - (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; - printf("Batch Wall Time: %.1lfus\n", time_taken); -#endif - -// printf("\n"); - - return; -} - - -HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, - unsigned char* e, unsigned char* m, int nbits) { -//#ifdef HE_QAT_DEBUG - static unsigned long long req_count = 0; -//#endif - // Unpack data and copy to QAT friendly memory space - int len = nbits / 8; - - if (NULL == r) return HE_QAT_STATUS_INVALID_PARAM; - if (NULL == b) return HE_QAT_STATUS_INVALID_PARAM; - if (NULL == e) return HE_QAT_STATUS_INVALID_PARAM; - if (NULL == m) return HE_QAT_STATUS_INVALID_PARAM; - - Cpa8U* pBase = NULL; - Cpa8U* pModulus = NULL; - Cpa8U* pExponent = NULL; - - // TODO(fdiasmor): Try it with 8-byte alignment. - CpaStatus status = CPA_STATUS_FAIL; - // status = PHYS_CONTIG_ALLOC(&pBase, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pBase, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pBase) { - memcpy(pBase, b, len); - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; - } - - // status = PHYS_CONTIG_ALLOC(&pExponent, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pExponent, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { - memcpy(pExponent, e, len); - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; - } - - // status = PHYS_CONTIG_ALLOC(&pModulus, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pModulus, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { - memcpy(pModulus, m, len); - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; - } - - // HE_QAT_TaskRequest request = - // HE_QAT_PACK_MODEXP_REQUEST(pBase, pExponent, pModulus, r) - // Pack it as a QAT Task Request - HE_QAT_TaskRequest* request = - (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); - if (NULL == request) { - printf( - "HE_QAT_TaskRequest memory allocation failed in " - "bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } - - CpaCyLnModExpOpData* op_data = - (CpaCyLnModExpOpData*)calloc(1, sizeof(CpaCyLnModExpOpData)); - if (NULL == op_data) { - printf("Cpa memory allocation failed in bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } - op_data->base.pData = pBase; - op_data->base.dataLenInBytes = len; - op_data->exponent.pData = pExponent; - op_data->exponent.dataLenInBytes = len; - op_data->modulus.pData = pModulus; - op_data->modulus.dataLenInBytes = len; - request->op_data = (void*)op_data; - - // status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&request->op_result.pData, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != request->op_result.pData) { - request->op_result.dataLenInBytes = len; - } else { - printf( - "CpaFlatBuffer.pData memory allocation failed in " - "bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } - - request->op_type = HE_QAT_OP_MODEXP; - request->callback_func = (void*)HE_QAT_bnModExpCallback; - request->op_status = status; - request->op_output = (void*)r; - - // Ensure calls are synchronized at exit (blocking) - pthread_mutex_init(&request->mutex, NULL); - pthread_cond_init(&request->ready, NULL); - - request->id = req_count; -#ifdef HE_QAT_DEBUG - printf("BN ModExp interface call for request #%llu\n", ++req_count); -#endif - - // Submit request using producer function - submit_request(&he_qat_buffer, (void*)request); - - return HE_QAT_STATUS_SUCCESS; -} - -HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, - unsigned char* b, unsigned char* e, - unsigned char* m, int nbits) { -#ifdef HE_QAT_DEBUG - static unsigned long long req_count = 0; - // printf("Wait lock write request. [buffer size: %d]\n",_buffer->count); -#endif - // Unpack data and copy to QAT friendly memory space - int len = nbits / 8; - - if (NULL == r) return HE_QAT_STATUS_INVALID_PARAM; - if (NULL == b) return HE_QAT_STATUS_INVALID_PARAM; - if (NULL == e) return HE_QAT_STATUS_INVALID_PARAM; - if (NULL == m) return HE_QAT_STATUS_INVALID_PARAM; - - Cpa8U* pBase = NULL; - Cpa8U* pModulus = NULL; - Cpa8U* pExponent = NULL; - - // TODO(fdiasmor): Try it with 8-byte alignment. - CpaStatus status = CPA_STATUS_FAIL; - // status = PHYS_CONTIG_ALLOC(&pBase, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pBase, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pBase) { - memcpy(pBase, b, len); - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; - } - - // status = PHYS_CONTIG_ALLOC(&pExponent, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pExponent, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { - memcpy(pExponent, e, len); - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; - } - - // status = PHYS_CONTIG_ALLOC(&pModulus, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pModulus, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { - memcpy(pModulus, m, len); - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; - } - - // HE_QAT_TaskRequest request = - // HE_QAT_PACK_MODEXP_REQUEST(pBase, pExponent, pModulus, r) - // Pack it as a QAT Task Request - HE_QAT_TaskRequest* request = - (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); - if (NULL == request) { - printf( - "HE_QAT_TaskRequest memory allocation failed in " - "bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } - - CpaCyLnModExpOpData* op_data = - (CpaCyLnModExpOpData*)calloc(1, sizeof(CpaCyLnModExpOpData)); - if (NULL == op_data) { - printf("Cpa memory allocation failed in bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } - op_data->base.pData = pBase; - op_data->base.dataLenInBytes = len; - op_data->exponent.pData = pExponent; - op_data->exponent.dataLenInBytes = len; - op_data->modulus.pData = pModulus; - op_data->modulus.dataLenInBytes = len; - request->op_data = (void*)op_data; - - // status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&request->op_result.pData, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != request->op_result.pData) { - request->op_result.dataLenInBytes = len; - } else { - printf( - "CpaFlatBuffer.pData memory allocation failed in " - "bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } - - request->op_type = HE_QAT_OP_MODEXP; - request->callback_func = (void*)HE_QAT_bnModExpCallback; - request->op_status = status; - request->op_output = (void*)r; - - // Ensure calls are synchronized at exit (blocking) - pthread_mutex_init(&request->mutex, NULL); - pthread_cond_init(&request->ready, NULL); - -#ifdef HE_QAT_DEBUG - printf("BN ModExp interface call for request #%llu\n", ++req_count); -#endif - - // Submit request using producer function - submit_request(&outstanding.buffer[_buffer_id], (void*)request); - - return HE_QAT_STATUS_SUCCESS; -} From b633fd8dcdca44b521e4e09c94c2e7f18e0183f7 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 22 Sep 2022 10:40:02 -0700 Subject: [PATCH 244/364] Move scripts to scripts folder. Signed-off-by: Souza, Fillipe --- scripts/auto_find_qat_install.sh | 1 + scripts/reset_asym_buffer_size.sh | 75 +++++++++++++++ scripts/restart_devices.sh | 132 ++++++++++++++++++++++++++ scripts/run.sh | 20 ++++ scripts/setup_devices.sh | 153 ++++++++++++++++++++++++++++++ 5 files changed, 381 insertions(+) create mode 100755 scripts/auto_find_qat_install.sh create mode 100755 scripts/reset_asym_buffer_size.sh create mode 100755 scripts/restart_devices.sh create mode 100755 scripts/run.sh create mode 100755 scripts/setup_devices.sh diff --git a/scripts/auto_find_qat_install.sh b/scripts/auto_find_qat_install.sh new file mode 100755 index 0000000..4150685 --- /dev/null +++ b/scripts/auto_find_qat_install.sh @@ -0,0 +1 @@ +for item in $(locate QAT/build); do [ -d $item ] && [ $(echo $item | grep $HOME) ] && echo ${item%/*}; done diff --git a/scripts/reset_asym_buffer_size.sh b/scripts/reset_asym_buffer_size.sh new file mode 100755 index 0000000..80b591e --- /dev/null +++ b/scripts/reset_asym_buffer_size.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +if [[ -z "${@}" ]]; then + echo "Usage: ./reset_asym_buffer_size " + exit +fi + +OLD_BUFFER_SIZE=$1 + +if [[ -z ${2} ]]; then + echo "Error: second parameter missing" + echo "Usage: ./reset_asym_buffer_size " + exit +fi + +NEW_BUFFER_SIZE=$2 + +num_phys_dev=$(lspci -d 8086:4940 | wc -l) +num_virt_dev=$(lspci -d 8086:4941 | wc -l) + +# Update physical device configuration files +i=0; +while [ $i -lt $num_phys_dev ]; +do + sudo sed -i /etc/4xxx_dev$i.conf -e "s/CyNumConcurrentAsymRequests = $OLD_BUFFER_SIZE/CyNumConcurrentAsymRequests = $NEW_BUFFER_SIZE/g"; + i=`expr $i + 1`; +done + +# Update virtual function configuration files +i=0; +while [ $i -lt $num_virt_dev ]; +do + sudo sed -i /etc/4xxxvf_dev$i.conf -e "s/CyNumConcurrentAsymRequests = $OLD_BUFFER_SIZE/CyNumConcurrentAsymRequests = $NEW_BUFFER_SIZE/g"; + i=`expr $i + 1`; +done + +## Power Off PFs +#i=0; +#while [ $i -lt $num_phys_dev ]; +#do +# sudo adf_ctl qat_dev$i down; +# i=`expr $i + 1`; +#done +# +## Power On PFs +#i=0; +#while [ $i -lt $num_phys_dev ]; +#do +# sudo adf_ctl qat_dev$i up; +# i=`expr $i + 1`; +#done +# +## Restart QAT service (This will bring up PFs and VFs) +#echo "sudo service qat_service restart" +#sudo service qat_service restart +# +## Power Off All VFs +#i=$num_phys_dev; +#vf_per_pf=`expr $num_virt_dev / $num_phys_dev` +#n=`expr $vf_per_pf \\* $num_phys_dev` +#n=`expr $n + $num_phys_dev` +#while [ $i -lt $n ]; +#do +# sudo adf_ctl qat_dev$i down; +# i=`expr $i + 1`; +#done +# +## Power On One QAT VF per QAT PF +#i=$num_phys_dev; +#while [ $i -lt $n ]; +#do +# sudo adf_ctl qat_dev$i up; +# i=`expr $i + $vf_per_pf`; +#done + diff --git a/scripts/restart_devices.sh b/scripts/restart_devices.sh new file mode 100755 index 0000000..fc26b0e --- /dev/null +++ b/scripts/restart_devices.sh @@ -0,0 +1,132 @@ +#!/bin/bash + +# Refresh +echo "sudo service restart qat_service" +sudo service qat_service restart + +num_phys_dev=$(lspci -d 8086:4940 | wc -l) +if [ $num_phys_dev -eq 0 ]; then + echo "No QAT Device Found !" + exit +else + echo "$num_phys_dev QAT Devices Found !" +fi + +total_virt_func=$(lspci -d 8086:4941 | wc -l) +num_virt_func=`expr $total_virt_func / $num_phys_dev` +dev_step=1 + +if [ $# -eq 0 ]; then + echo "Usage: ./setup_devices " + echo " Parameters:" + echo " -- num_phys_dev: Number of physical devices to be active. (default: auto)" + echo " -- conf_virt_func: Number of configured virtual functions per device. (default: 0)" + echo " -- num_virt_func: Number of virtual functions to be active per device. (default: 0)" +fi + +nphysdev=$num_phys_dev +if [ -n "$1" ]; then + nphysdev=$1 + if [ $nphysdev -gt $num_phys_dev ]; then + nphysdev=$num_phys_dev + fi +fi + +conf_virt_func=0 +# Check if virtual function is enabled +if [ $num_virt_func -gt 0 ]; then + conf_virt_func=1 +fi + +if [ -n "$2" ]; then + conf_virt_func=$2 + # if user attempts to request higher than available + if [ $conf_virt_func -gt $num_virt_func ]; then + conf_virt_func=$num_virt_func + fi +fi + +# Shutdown QAT PFs +i=0 +while [ $i -lt $num_phys_dev ]; +do + echo "sudo adf_ctl qat_dev$i down"; + sudo adf_ctl qat_dev$i down; + i=`expr $i + 1`; +done + +# Reconfigure Target QAT PFs +i=0 +n=$nphysdev +while [ $i -lt $n ]; +do + echo "sudo adf_ctl qat_dev$i up"; + sudo adf_ctl qat_dev$i up; + i=`expr $i + 1`; +done + +# Refresh +echo "sudo service restart qat_service" +sudo service qat_service restart + +# If Virtualization Mode Enabled +start=0 +if [ $num_virt_func -gt 0 ]; then + if [ $conf_virt_func -gt 0 ]; then + start=$num_phys_dev + dev_step=$num_virt_func + fi +fi + +# Shutdown QAT VFs +i=$start +stop=`expr $num_phys_dev \\* $num_virt_func` +stop=`expr $start + $stop` +step=$dev_step +while [ $i -lt $stop ]; +do + echo "sudo adf_ctl qat_dev$i down"; + sudo adf_ctl qat_dev$i down; + i=`expr $i + 1`; +done + +i=0 +while [ $i -lt $nphysdev ]; +do + # Start QAT PF + echo "sudo adf_ctl qat_dev$i up"; + sudo adf_ctl qat_dev$i up; + i=`expr $i + 1`; +done + +start=$num_phys_dev +i=$start +stop=`expr $nphysdev \\* $num_virt_func` +stop=`expr $start + $stop` +step=$dev_step +while [ $i -lt $stop ]; +do + # Start QAT VF + echo "adf_ctl qat_dev$i up" + sudo adf_ctl qat_dev$i up; + # Start up additional instances mapped to the same physical device + j=1; + while [ $j -lt $conf_virt_func ]; + do + dev_id=`expr $i + $j`; + # Start QAT VF + echo "adf_ctl qat_dev$dev_id up" + sudo adf_ctl qat_dev$dev_id up; + j=`expr $j + 1`; + done + i=`expr $i + $dev_step` +done + +# Shutdown Unused QAT PFs +i=$nphysdev +while [ $i -lt $num_phys_dev ]; +do + echo "sudo adf_ctl qat_dev$i down"; + sudo adf_ctl qat_dev$i down; + i=`expr $i + 1`; +done diff --git a/scripts/run.sh b/scripts/run.sh new file mode 100755 index 0000000..aa451dd --- /dev/null +++ b/scripts/run.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +export HEQATLIB_INSTALL_DIR=$HEQATLIB_ROOT_DIR/install +export ICP_ROOT=$($HEQATLIB_ROOT_DIR/scripts/auto_find_qat_install.sh) +export LD_LIBRARY_PATH=$HEQATLIB_INSTALL_DIR/lib:$ICP_ROOT/build:$LD_LIBRARY_PATH + +pushd $HEQATLIB_INSTALL_DIR/bin + +for app in $(ls test_*) +do + echo "*****************************************************************" + echo "* [START] RUNNING TEST SAMPLE $app *" + echo "*****************************************************************" + ./$app + echo "*****************************************************************" + echo "* [STOP] RUNNING TEST SAMPLE $app *" + echo "*****************************************************************" +done + +popd diff --git a/scripts/setup_devices.sh b/scripts/setup_devices.sh new file mode 100755 index 0000000..76f34e5 --- /dev/null +++ b/scripts/setup_devices.sh @@ -0,0 +1,153 @@ +#!/bin/bash + +# Refresh +echo "sudo service restart qat_service" +sudo service qat_service restart + +num_phys_dev=$(lspci -d 8086:4940 | wc -l) +if [ $num_phys_dev -eq 0 ]; then + echo "No QAT Device Found !" + exit +else + echo "$num_phys_dev QAT Devices Found !" +fi + +total_virt_func=$(lspci -d 8086:4941 | wc -l) +num_virt_func=`expr $total_virt_func / $num_phys_dev` +dev_step=1 + +if [ $# -eq 0 ]; then + echo "Usage: ./setup_devices " + echo " Parameters:" + echo " -- num_phys_dev: Number of physical devices to be active. (default: auto)" + echo " -- conf_virt_func: Number of configured virtual functions per device. (default: 0)" + echo " -- num_virt_func: Number of virtual functions to be active per device. (default: 0)" +fi + +nphysdev=$num_phys_dev +if [ -n "$1" ]; then + nphysdev=$1 + if [ $nphysdev -gt $num_phys_dev ]; then + nphysdev=$num_phys_dev + fi +fi + +conf_virt_func=0 +# Check if virtual function is enabled +if [ $num_virt_func -gt 0 ]; then + conf_virt_func=1 +fi + +if [ -n "$2" ]; then + conf_virt_func=$2 + # if user attempts to request higher than available + if [ $conf_virt_func -gt $num_virt_func ]; then + conf_virt_func=$num_virt_func + fi +fi + +# Shutdown QAT PFs +i=0 +while [ $i -lt $num_phys_dev ]; +do + echo "sudo adf_ctl qat_dev$i down"; + sudo adf_ctl qat_dev$i down; + i=`expr $i + 1`; +done + +# Reconfigure Target QAT PFs +i=0 +n=$nphysdev +while [ $i -lt $n ]; +do + echo "sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf"; + sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf; + echo "sudo adf_ctl qat_dev$i up"; + sudo adf_ctl qat_dev$i up; + i=`expr $i + 1`; +done + +# Refresh +echo "sudo service restart qat_service" +sudo service qat_service restart + +# If Virtualization Mode Enabled +start=0 +if [ $num_virt_func -gt 0 ]; then + if [ $conf_virt_func -gt 0 ]; then + start=$num_phys_dev + dev_step=$num_virt_func + fi +fi + +# Shutdown QAT VFs +i=$start +stop=`expr $num_phys_dev \\* $num_virt_func` +stop=`expr $start + $stop` +step=$dev_step +while [ $i -lt $stop ]; +do + echo "sudo adf_ctl qat_dev$i down"; + sudo adf_ctl qat_dev$i down; + i=`expr $i + 1`; +done + +#i=0 +#while [ $i -lt $total_virt_func ]; +#do +# echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$i.conf"; +# sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$i.conf; +# i=`expr $i + 1`; +#done + +i=0 +while [ $i -lt $nphysdev ]; +do + # Reconfigure QAT PF + echo "sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf"; + sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf; + # Start QAT PF + echo "sudo adf_ctl qat_dev$i up"; + sudo adf_ctl qat_dev$i up; + i=`expr $i + 1`; +done + +start=$num_phys_dev +i=$start +stop=`expr $nphysdev \\* $num_virt_func` +stop=`expr $start + $stop` +step=$dev_step +while [ $i -lt $stop ]; +do + k=`expr $i - $start` + # Reconfigure QAT VF (must match PF's config) + echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf"; + sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf; + # Start QAT VF + echo "adf_ctl qat_dev$i up" + sudo adf_ctl qat_dev$i up; + # Start up additional instances mapped to the same physical device + j=1; + while [ $j -lt $conf_virt_func ]; + do + dev_id=`expr $i + $j`; + k=`expr $dev_id - $start`; + # Reconfigure QAT VF (must match PF's config) + echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf"; + sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf; + # Start QAT VF + echo "adf_ctl qat_dev$dev_id up" + sudo adf_ctl qat_dev$dev_id up; + j=`expr $j + 1`; + done + i=`expr $i + $dev_step` +done + +# Shutdown Unused QAT PFs +i=$nphysdev +while [ $i -lt $num_phys_dev ]; +do + echo "sudo adf_ctl qat_dev$i down"; + sudo adf_ctl qat_dev$i down; + i=`expr $i + 1`; +done From b673bebd15a5d7ab02043113342c686ddd8228a5 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 22 Sep 2022 10:53:45 -0700 Subject: [PATCH 245/364] Test samples clean-up. Signed-off-by: Souza, Fillipe --- samples/test_bnConversion.cpp | 13 ------------- samples/test_bnModExp.cpp | 28 +--------------------------- 2 files changed, 1 insertion(+), 40 deletions(-) diff --git a/samples/test_bnConversion.cpp b/samples/test_bnConversion.cpp index 2234482..2e51b30 100644 --- a/samples/test_bnConversion.cpp +++ b/samples/test_bnConversion.cpp @@ -1,9 +1,6 @@ #include "he_qat_misc.h" #include "he_qat_utils.h" -#include "he_qat_bn_ops.h" -#include "he_qat_context.h" -#include "cpa_sample_utils.h" #include #include @@ -27,9 +24,6 @@ int main(int argc, const char** argv) { HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; - // Set up QAT runtime context - acquire_qat_devices(); - // Set up OpenSSL context (as baseline) BN_CTX* ctx = BN_CTX_new(); BN_CTX_start(ctx); @@ -56,13 +50,11 @@ int main(int argc, const char** argv) { BigNumber big_num((Ipp32u)0); gettimeofday(&start_time, NULL); - //start = clock(); status = binToBigNumber(big_num, bn_mod_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { printf("Failed at binToBigNumber()\n"); exit(1); } - //ssl_elapsed = clock() - start; gettimeofday(&end_time, NULL); time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; time_taken = @@ -78,7 +70,6 @@ int main(int argc, const char** argv) { printf("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, bit_len); -// start = clock(); gettimeofday(&start_time, NULL); unsigned char* ref_bn_data_ = (unsigned char*)calloc(len_, sizeof(unsigned char)); @@ -88,7 +79,6 @@ int main(int argc, const char** argv) { printf("Failed at bigNumberToBin()\n"); exit(1); } -// qat_elapsed = clock() - start; gettimeofday(&end_time, NULL); time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; time_taken = @@ -113,8 +103,5 @@ int main(int argc, const char** argv) { // Tear down OpenSSL context BN_CTX_end(ctx); - // Tear down QAT runtime context - release_qat_devices(); - return (int)status; } diff --git a/samples/test_bnModExp.cpp b/samples/test_bnModExp.cpp index 27003a0..7499445 100644 --- a/samples/test_bnModExp.cpp +++ b/samples/test_bnModExp.cpp @@ -24,16 +24,12 @@ using namespace std::chrono; int main(int argc, const char** argv) { const int bit_length = 4096; - const size_t num_trials = 10000; + const size_t num_trials = 100; double avg_speed_up = 0.0; double ssl_avg_time = 0.0; double qat_avg_time = 0.0; - // clock_t start = CLOCKS_PER_SEC; - // clock_t ssl_elapsed = CLOCKS_PER_SEC; - // clock_t qat_elapsed = CLOCKS_PER_SEC; - HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; // Set up QAT runtime context @@ -69,16 +65,13 @@ int main(int argc, const char** argv) { // Perform OpenSSL ModExp Op BIGNUM* ssl_res = BN_new(); auto start = high_resolution_clock::now(); - // start = clock(); BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); auto stop = high_resolution_clock::now(); auto ssl_duration = duration_cast(stop - start); - // ssl_elapsed = clock() - start; int len_ = (bit_length + 7) >> 3; // Start QAT timer (including data conversion overhead) - // start = clock(); start = high_resolution_clock::now(); unsigned char* bn_base_data_ = (unsigned char*)calloc(len_, sizeof(unsigned char)); @@ -97,7 +90,6 @@ int main(int argc, const char** argv) { if (NULL == bn_remainder_data_) exit(1); stop = high_resolution_clock::now(); auto cvt_duration = duration_cast(stop - start); - // clock_t cvt_elapsed = clock() - start; // Simulate input number in BigNumber representation BigNumber big_num_base((Ipp32u)0); @@ -131,7 +123,6 @@ int main(int argc, const char** argv) { exit(1); } - // start = clock(); start = high_resolution_clock::now(); status = bigNumberToBin(bn_base_data_, bit_length, big_num_base); if (HE_QAT_STATUS_SUCCESS != status) { @@ -149,13 +140,10 @@ int main(int argc, const char** argv) { printf("bn_base_data_: failed at bignumbertobin()\n"); exit(1); } - // cvt_elapsed += (clock() - start); cvt_duration += duration_cast(high_resolution_clock::now() - start); // Perform BigNumber modular exponentiation on QAT - // start = clock(); - start = high_resolution_clock::now(); for (unsigned int b = 0; b < BATCH_SIZE; b++) status = @@ -174,19 +162,11 @@ int main(int argc, const char** argv) { (ssl_duration.count() / (double)(qat_duration.count() / BATCH_SIZE))) / (mod + 1); - // qat_elapsed = clock() - start; - - // printf("BigNumber data conversion overhead: %.1lfus.\n", - // (cvt_elapsed / (CLOCKS_PER_SEC / 1000000.0))); - // printf("BigNumber modular exponentiation on QAT: %.1lfus.\n", - // (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); - // qat_elapsed += cvt_elapsed; printf("Request #%u\t", mod + 1); printf("Overhead: %.1luus", cvt_duration.count()); printf("\tOpenSSL: %.1lfus", ssl_avg_time); printf("\tQAT: %.1lfus", qat_avg_time); printf("\tSpeed-up: %.1lfx", avg_speed_up); - // qat_elapsed += cvt_elapsed; BIGNUM* qat_res = BN_new(); BN_bin2bn(bn_remainder_data_, len_, qat_res); @@ -200,16 +180,12 @@ int main(int argc, const char** argv) { } #endif - // start = clock(); BigNumber big_num((Ipp32u)0); status = binToBigNumber(big_num, bn_remainder_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { printf("bn_remainder_data_: Failed at bigNumberToBin()\n"); exit(1); } - // qat_elapsed += (clock() - start); - // printf("BigNumber ModExp total time: %.1lfus.\n", - // (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); #ifdef _DESTINY_DEBUG_VERBOSE bn_str = BN_bn2hex(qat_res); @@ -239,8 +215,6 @@ int main(int argc, const char** argv) { BN_free(qat_res); BN_free(ssl_res); - // OPENSSL_free(bn_str); - free(bn_mod_data_); free(bn_base_data_); free(bn_exponent_data_); From 81bd62d06336f9edd177c63e2cbe10863ce2087d Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 22 Sep 2022 11:01:56 -0700 Subject: [PATCH 246/364] Add copyright header. Signed-off-by: Souza, Fillipe --- scripts/setup_devices.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/setup_devices.sh b/scripts/setup_devices.sh index 76f34e5..2cc3bb6 100755 --- a/scripts/setup_devices.sh +++ b/scripts/setup_devices.sh @@ -1,3 +1,6 @@ +# Copyright (C) 2022-2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + #!/bin/bash # Refresh From 566fc4866dd660ef81b264a7f8ac464c2a26978f Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 22 Sep 2022 11:03:21 -0700 Subject: [PATCH 247/364] Remove scripts from parent folder. Signed-off-by: Souza, Fillipe --- auto_find_qat_install.sh | 1 - reset_asym_buffer_size.sh | 75 ------------------- run.sh | 8 -- setup_devices.sh | 153 -------------------------------------- 4 files changed, 237 deletions(-) delete mode 100755 auto_find_qat_install.sh delete mode 100755 reset_asym_buffer_size.sh delete mode 100755 run.sh delete mode 100755 setup_devices.sh diff --git a/auto_find_qat_install.sh b/auto_find_qat_install.sh deleted file mode 100755 index 4150685..0000000 --- a/auto_find_qat_install.sh +++ /dev/null @@ -1 +0,0 @@ -for item in $(locate QAT/build); do [ -d $item ] && [ $(echo $item | grep $HOME) ] && echo ${item%/*}; done diff --git a/reset_asym_buffer_size.sh b/reset_asym_buffer_size.sh deleted file mode 100755 index 80b591e..0000000 --- a/reset_asym_buffer_size.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash - -if [[ -z "${@}" ]]; then - echo "Usage: ./reset_asym_buffer_size " - exit -fi - -OLD_BUFFER_SIZE=$1 - -if [[ -z ${2} ]]; then - echo "Error: second parameter missing" - echo "Usage: ./reset_asym_buffer_size " - exit -fi - -NEW_BUFFER_SIZE=$2 - -num_phys_dev=$(lspci -d 8086:4940 | wc -l) -num_virt_dev=$(lspci -d 8086:4941 | wc -l) - -# Update physical device configuration files -i=0; -while [ $i -lt $num_phys_dev ]; -do - sudo sed -i /etc/4xxx_dev$i.conf -e "s/CyNumConcurrentAsymRequests = $OLD_BUFFER_SIZE/CyNumConcurrentAsymRequests = $NEW_BUFFER_SIZE/g"; - i=`expr $i + 1`; -done - -# Update virtual function configuration files -i=0; -while [ $i -lt $num_virt_dev ]; -do - sudo sed -i /etc/4xxxvf_dev$i.conf -e "s/CyNumConcurrentAsymRequests = $OLD_BUFFER_SIZE/CyNumConcurrentAsymRequests = $NEW_BUFFER_SIZE/g"; - i=`expr $i + 1`; -done - -## Power Off PFs -#i=0; -#while [ $i -lt $num_phys_dev ]; -#do -# sudo adf_ctl qat_dev$i down; -# i=`expr $i + 1`; -#done -# -## Power On PFs -#i=0; -#while [ $i -lt $num_phys_dev ]; -#do -# sudo adf_ctl qat_dev$i up; -# i=`expr $i + 1`; -#done -# -## Restart QAT service (This will bring up PFs and VFs) -#echo "sudo service qat_service restart" -#sudo service qat_service restart -# -## Power Off All VFs -#i=$num_phys_dev; -#vf_per_pf=`expr $num_virt_dev / $num_phys_dev` -#n=`expr $vf_per_pf \\* $num_phys_dev` -#n=`expr $n + $num_phys_dev` -#while [ $i -lt $n ]; -#do -# sudo adf_ctl qat_dev$i down; -# i=`expr $i + 1`; -#done -# -## Power On One QAT VF per QAT PF -#i=$num_phys_dev; -#while [ $i -lt $n ]; -#do -# sudo adf_ctl qat_dev$i up; -# i=`expr $i + $vf_per_pf`; -#done - diff --git a/run.sh b/run.sh deleted file mode 100755 index bc1c383..0000000 --- a/run.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash -export ICP_ROOT=$HOME/QAT -export LD_LIBRARY_PATH=$PWD/install/lib:$ICP_ROOT/build:$LD_LIBRARY_PATH -pushd ./install/bin -./test_context -./test_bnModExpPerformOp -./test_bnConversion -popd diff --git a/setup_devices.sh b/setup_devices.sh deleted file mode 100755 index 76f34e5..0000000 --- a/setup_devices.sh +++ /dev/null @@ -1,153 +0,0 @@ -#!/bin/bash - -# Refresh -echo "sudo service restart qat_service" -sudo service qat_service restart - -num_phys_dev=$(lspci -d 8086:4940 | wc -l) -if [ $num_phys_dev -eq 0 ]; then - echo "No QAT Device Found !" - exit -else - echo "$num_phys_dev QAT Devices Found !" -fi - -total_virt_func=$(lspci -d 8086:4941 | wc -l) -num_virt_func=`expr $total_virt_func / $num_phys_dev` -dev_step=1 - -if [ $# -eq 0 ]; then - echo "Usage: ./setup_devices " - echo " Parameters:" - echo " -- num_phys_dev: Number of physical devices to be active. (default: auto)" - echo " -- conf_virt_func: Number of configured virtual functions per device. (default: 0)" - echo " -- num_virt_func: Number of virtual functions to be active per device. (default: 0)" -fi - -nphysdev=$num_phys_dev -if [ -n "$1" ]; then - nphysdev=$1 - if [ $nphysdev -gt $num_phys_dev ]; then - nphysdev=$num_phys_dev - fi -fi - -conf_virt_func=0 -# Check if virtual function is enabled -if [ $num_virt_func -gt 0 ]; then - conf_virt_func=1 -fi - -if [ -n "$2" ]; then - conf_virt_func=$2 - # if user attempts to request higher than available - if [ $conf_virt_func -gt $num_virt_func ]; then - conf_virt_func=$num_virt_func - fi -fi - -# Shutdown QAT PFs -i=0 -while [ $i -lt $num_phys_dev ]; -do - echo "sudo adf_ctl qat_dev$i down"; - sudo adf_ctl qat_dev$i down; - i=`expr $i + 1`; -done - -# Reconfigure Target QAT PFs -i=0 -n=$nphysdev -while [ $i -lt $n ]; -do - echo "sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf"; - sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf; - echo "sudo adf_ctl qat_dev$i up"; - sudo adf_ctl qat_dev$i up; - i=`expr $i + 1`; -done - -# Refresh -echo "sudo service restart qat_service" -sudo service qat_service restart - -# If Virtualization Mode Enabled -start=0 -if [ $num_virt_func -gt 0 ]; then - if [ $conf_virt_func -gt 0 ]; then - start=$num_phys_dev - dev_step=$num_virt_func - fi -fi - -# Shutdown QAT VFs -i=$start -stop=`expr $num_phys_dev \\* $num_virt_func` -stop=`expr $start + $stop` -step=$dev_step -while [ $i -lt $stop ]; -do - echo "sudo adf_ctl qat_dev$i down"; - sudo adf_ctl qat_dev$i down; - i=`expr $i + 1`; -done - -#i=0 -#while [ $i -lt $total_virt_func ]; -#do -# echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$i.conf"; -# sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$i.conf; -# i=`expr $i + 1`; -#done - -i=0 -while [ $i -lt $nphysdev ]; -do - # Reconfigure QAT PF - echo "sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf"; - sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf; - # Start QAT PF - echo "sudo adf_ctl qat_dev$i up"; - sudo adf_ctl qat_dev$i up; - i=`expr $i + 1`; -done - -start=$num_phys_dev -i=$start -stop=`expr $nphysdev \\* $num_virt_func` -stop=`expr $start + $stop` -step=$dev_step -while [ $i -lt $stop ]; -do - k=`expr $i - $start` - # Reconfigure QAT VF (must match PF's config) - echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf"; - sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf; - # Start QAT VF - echo "adf_ctl qat_dev$i up" - sudo adf_ctl qat_dev$i up; - # Start up additional instances mapped to the same physical device - j=1; - while [ $j -lt $conf_virt_func ]; - do - dev_id=`expr $i + $j`; - k=`expr $dev_id - $start`; - # Reconfigure QAT VF (must match PF's config) - echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf"; - sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf; - # Start QAT VF - echo "adf_ctl qat_dev$dev_id up" - sudo adf_ctl qat_dev$dev_id up; - j=`expr $j + 1`; - done - i=`expr $i + $dev_step` -done - -# Shutdown Unused QAT PFs -i=$nphysdev -while [ $i -lt $num_phys_dev ]; -do - echo "sudo adf_ctl qat_dev$i down"; - sudo adf_ctl qat_dev$i down; - i=`expr $i + 1`; -done From ccbe29244447a937a28f2f7ae6d6a4ece1884925 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 22 Sep 2022 11:04:04 -0700 Subject: [PATCH 248/364] Environment vars. Signed-off-by: Souza, Fillipe --- setup_env.sh | 5 +++++ 1 file changed, 5 insertions(+) create mode 100755 setup_env.sh diff --git a/setup_env.sh b/setup_env.sh new file mode 100755 index 0000000..27dffda --- /dev/null +++ b/setup_env.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +export HEQATLIB_ROOT_DIR=$(pwd) +export ICP_ROOT=$($PWD/scripts/auto_find_qat_install.sh) + From 131fed9b2816be3f0447ea9eee5cc8ed20a67416 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 22 Sep 2022 11:05:48 -0700 Subject: [PATCH 249/364] Fix on Debug mode. Signed-off-by: Souza, Fillipe --- he_qat/he_qat_ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/he_qat/he_qat_ctrl.c b/he_qat/he_qat_ctrl.c index f0656c8..76d60d8 100644 --- a/he_qat/he_qat_ctrl.c +++ b/he_qat/he_qat_ctrl.c @@ -448,7 +448,7 @@ void* start_instances(void* _config) { config->active = 1; while (config->running) { #ifdef HE_QAT_DEBUG - printf("Try reading request from buffer. Inst #%d\n", config->inst_id); + printf("Try reading request from buffer. Inst #%d\n", next_instance); #endif unsigned long pending = request_count - response_count; unsigned long available = max_pending - ((pending < max_pending)?pending:max_pending); From cf425ef17c12b19879bfa8e87e0f42fcfef112b4 Mon Sep 17 00:00:00 2001 From: Fillipe Souza Date: Thu, 22 Sep 2022 16:11:14 -0700 Subject: [PATCH 250/364] Update README.md --- README.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 66e96e9..978e7a8 100644 --- a/README.md +++ b/README.md @@ -16,28 +16,29 @@ Intel Homomorphic Encryption Acceleration Library for QAT (HE QAT Lib) is an ope ## Introduction -This library is underconstruction and currently only offers acceleration of modular exponentiation of multi-precision numbers, i.e. large numbers whose precision range from 1024 to 8192 bits. Current stage of implementation supports modular exponentiation of big numbers encoded with OpenSSL's BIGNUM data type and IPP Crypto's BigNumber class. More details about the modes of operation and characteristics of the execution flow are described below: +This library currently only offers acceleration of modular exponentiation of multi-precision numbers, i.e. large numbers whose precision range from 1024 to 8192 bits. Current stage of implementation supports modular exponentiation of big numbers encoded with OpenSSL `BIGNUM` data type, `ippcrypto`'s `BigNumber` class and octet strings encoded with `unsigned char`. More details about the modes of operation and characteristics of the execution flow are described below: - - Synchronous: It means that calls will be made to send modular exponentiation work requests to be offloaded to the accelerator and processed in the order they are issued. + - Synchronous: API calls will submit requests that will be executed in the order they are first issued by the host caller, i.e. a series of modular exponentiation operation requests will be offloaded for processing by the accelerator in the order they are issued. - - Asynchronous: It means that multiple concurrent modular exponentiation work requests can be offloaded to the accelerator and processed not necessarily in the order they are issued from the host side. + - Asynchronous: API calls will submit requests that will NOT necessarily be executed in the order they are first issued by the host caller, i.e. a sequence of multiple requests for the modular exponentiation operation could be scheduled out of order and executed concurrently by the accelerator; thus, completed out of order. - - Blocking: It means that the next buffered work request waits for completion of the processing of the most recent request offloaded to the accelerator, when processing must be currently in progress. - - - Batch Support: The internal buffer is set accommodate 256 requests at a time so that the maximum batch size is 256. Therefore, only up to 256 requests can be exercised asynchronously from the application side, be it from a single `for loop` or static code block. Finally, in order to collect the requests, a call to the `getBnModExpRequest()` function must be performed to wait for completion of all submitted asynchronous requests. + - Blocking: API calls will be blocked until work request processing completion. Internally, the next buffered work request waits for completion of the processing of the most recently offloaded request to the accelerator. + + - Non-Blocking: API calls will be non-blocking, it does not wait for completion of the work request to return from call. After multiple non-blocking calls to the API, a blocking function to wait for the requests to complete processing must be called. Internally, non-blocking request submissions are scheduled to the accelerator asynchronously. When there are multiple requests from concurrent API callers, the requests are not guaranteed to be processed in order of arrival. - - Single-Threaded: It is currently desinged (and safer) to use it with a single-threaded applications, although multithreading is partially supported (try it at your own risk). Multithreading support is limited to work under restrictive conditions, namely, the total number of incoming requests at any point in time from multiple threads does not exceed the size of the internal buffer from which work requests are taken to be offloaded to QAT devices. Effective multithreading support will relax this condition by relying on a separate buffer that admits outstanding work requests. - + - Batch Support: The internal buffers are set accommodate up to 1024 requests at a time so that the maximum number of non-blocking API calls is 1024 for each concurrent thread caller. Therefore, only up to 1024 requests can be exercised asynchronously from the application side, be it from a single `for loop` or static code block. Finally, in order to collect the requests, a call to the `getBnModExpRequest()` function must be performed to wait for completion of all submitted asynchronous requests. On multithreaded mode, the blocking function to be called at the end of the code block shall be `release_bnModExp_buffer()`. + +- Multithreading Support: This feature permits the API to be called by concurrently threads running on the host. Effective multithreading support relies on a separate buffer that admits outstanding work requests. This buffer is acquired before an API call to submit work requests to the accelerator. This is accomplished by first calling `acquire_bnModExp_buffer()` to reserve an internal buffer to store outstanding requests from the host API caller. - Multiple Instances/Devices: The library accesses all logical instances from all visible and configured QAT endpoints at the creation of the QAT runtime context. Therefore, if 8 QAT endpoints are available, it will attempt to use them all, including all the total number of logical instances configured per process. ->> _**Note**_: Current implementation does not verify if the instance/endpoint has the capabilities needed by the library. For example, the library needs access to the _asym_ capabilities like `CyLnModExp`, therefore it the configuration file of an endpoint happens to be configured not offer it, the application will exit with an error at some point during execution. +>> _**Note**_: Current implementation does not verify if the instance/endpoint has the capabilities needed by the library. For example, the library needs access to the _asym_ capabilities like `CyLnModExp`, therefore if the configuration file of an endpoint happens to be configured to not offer it, the application will exit with an error at some point during execution. ## Building the HE QAT Library ### Requirements The hardware requirement to use the library is the following: - - Intel Sapphire Rapids + - Intel 4xxx co-processor As for the operating systems, the library has been tested and confirmed to work on Ubuntu 20.04. From d411a0488be8d150f8a39c619f5ec396d5de75bb Mon Sep 17 00:00:00 2001 From: Fillipe Souza Date: Thu, 22 Sep 2022 16:19:17 -0700 Subject: [PATCH 251/364] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 978e7a8..d240a67 100644 --- a/README.md +++ b/README.md @@ -207,12 +207,12 @@ $ ./setup_devices.sh In addition to the standard CMake configuration options, Intel HE Acceleration Library for QAT supports several cmake options to configure the build. For convenience, they are listed below: - - -| HE_QAT_MISC | ON / OFF (default OFF) | Set to OFF, enable benchmark suite via Google benchmark | --> - - - +| CMake option | Values | Description | +| ------------------------------| ---------------------- | ------------------------------------------------------- | +| HE_QAT_MISC | ON / OFF (default OFF) | Enable/Disable BigNumber conversion functions. | +| HE_QAT_DEBUG | ON / OFF (default OFF) | Enable/Disable debug log at large runtime penalty. | +| HE_QAT_SAMPLES | ON / OFF (default ON) | Enable/Disable building of samples. | +| HE_QAT_DOCS | ON / OFF (default ON) | Enable/Disable building of documentation. | #### Running Samples From a28899ce44e20f6ac99b28176dbd632d8db7fc44 Mon Sep 17 00:00:00 2001 From: Fillipe Souza Date: Thu, 22 Sep 2022 19:00:38 -0700 Subject: [PATCH 252/364] Update README.md Update CMake flags description. --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index d240a67..50f8f9d 100644 --- a/README.md +++ b/README.md @@ -213,6 +213,12 @@ In addition to the standard CMake configuration options, Intel HE Acceleration L | HE_QAT_DEBUG | ON / OFF (default OFF) | Enable/Disable debug log at large runtime penalty. | | HE_QAT_SAMPLES | ON / OFF (default ON) | Enable/Disable building of samples. | | HE_QAT_DOCS | ON / OFF (default ON) | Enable/Disable building of documentation. | +| HE_QAT_SYNC | ON / OFF (default OFF) | Enable/Disable synchronous mode execution. | +| HE_QAT_MT | ON / OFF (default ON) | Enable/Disable interfaces for multithreaded programs. | +| HE_QAT_PERF | ON / OFF (default OFF) | Enable/Disable display of measured request performance. | +| HE_QAT_TEST | ON / OFF (default OFF) | Enable/Disable testing. | +| HE_QAT_OMP | ON / OFF (default ON) | Enable/Disable tests using OpenMP. | +| HE_QAT_SHARED | ON / OFF (default ON) | Enable/Disable building shared library. | #### Running Samples From 74162ec4134cc7360fe783dc88b4faee4b47b289 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 23 Sep 2022 17:28:07 -0700 Subject: [PATCH 253/364] HE QAT lib repo migration. Signed-off-by: Souza, Fillipe --- CMakeLists.txt | 2 +- module/heqat.cmake | 54 ++++++++++++++++++++++++++++++++++++++++++ module/heqat/README.md | 4 ++-- 3 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 module/heqat.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index f608f99..74e6117 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,7 +131,7 @@ include(ipcl-util) include(cmake/ippcrypto.cmake) if(IPCL_ENABLE_QAT) - include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/heqat/heqat.cmake) + include(module/heqat.cmake) endif() if(IPCL_TEST) diff --git a/module/heqat.cmake b/module/heqat.cmake new file mode 100644 index 0000000..d572db6 --- /dev/null +++ b/module/heqat.cmake @@ -0,0 +1,54 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +include(ExternalProject) +MESSAGE(STATUS "Configuring HE QAT") +set(HEQAT_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_he_qat) +set(HEQAT_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/module/heqat) +set(HEQAT_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS}") + +ExternalProject_Add( + ext_he_qat + SOURCE_DIR ${HEQAT_SRC_DIR} + PREFIX ${HEQAT_PREFIX} + INSTALL_DIR ${HEQAT_PREFIX} + CMAKE_ARGS ${HEQAT_CXX_FLAGS} + -DCMAKE_INSTALL_PREFIX=${HEQAT_PREFIX} + -DHE_QAT_MISC=OFF + -DHE_QAT_DOCS=${IPCL_DOCS} + -DIPPCP_PREFIX_PATH=${IPPCRYPTO_PREFIX}/lib/cmake + -DHE_QAT_SHARED=${IPCL_SHARED} + -DCMAKE_BUILD_TYPE=Release + UPDATE_COMMAND "" +) +add_dependencies(ext_he_qat ext_ipp-crypto) + +set(HEQAT_INC_DIR ${HEQAT_PREFIX}/include) + +# Bring up CPA variables +include(${HEQAT_SRC_DIR}/icp/CMakeLists.txt) +list(APPEND HEQAT_INC_DIR ${ICP_INC_DIR}) + +if(IPCL_SHARED) + add_library(libhe_qat INTERFACE) + add_dependencies(libhe_qat ext_he_qat) + + ExternalProject_Get_Property(ext_he_qat SOURCE_DIR BINARY_DIR) + + target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libcpa_sample_utils.so) + if(CMAKE_BUILD_TYPE STREQUAL "Debug") + target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat_debug.so) + else() + target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat.so) + endif() + target_include_directories(libhe_qat SYSTEM INTERFACE ${HEQAT_INC_DIR}) +else() + add_library(libhe_qat STATIC IMPORTED GLOBAL) + add_dependencies(libhe_qat ext_he_qat) + + ExternalProject_Get_Property(ext_he_qat SOURCE_DIR BINARY_DIR) + + set_target_properties(libhe_qat PROPERTIES + IMPORTED_LOCATION ${HEQAT_PREFIX}/lib/libhe_qat.a + INCLUDE_DIRECTORIES ${HEQAT_INC_DIR}) +endif() diff --git a/module/heqat/README.md b/module/heqat/README.md index 50f8f9d..d2e706a 100644 --- a/module/heqat/README.md +++ b/module/heqat/README.md @@ -28,9 +28,9 @@ This library currently only offers acceleration of modular exponentiation of mul - Batch Support: The internal buffers are set accommodate up to 1024 requests at a time so that the maximum number of non-blocking API calls is 1024 for each concurrent thread caller. Therefore, only up to 1024 requests can be exercised asynchronously from the application side, be it from a single `for loop` or static code block. Finally, in order to collect the requests, a call to the `getBnModExpRequest()` function must be performed to wait for completion of all submitted asynchronous requests. On multithreaded mode, the blocking function to be called at the end of the code block shall be `release_bnModExp_buffer()`. -- Multithreading Support: This feature permits the API to be called by concurrently threads running on the host. Effective multithreading support relies on a separate buffer that admits outstanding work requests. This buffer is acquired before an API call to submit work requests to the accelerator. This is accomplished by first calling `acquire_bnModExp_buffer()` to reserve an internal buffer to store outstanding requests from the host API caller. + - Multithreading Support: This feature permits the API to be called by concurrently threads running on the host. Effective multithreading support relies on a separate buffer that admits outstanding work requests. This buffer is acquired before an API call to submit work requests to the accelerator. This is accomplished by first calling `acquire_bnModExp_buffer()` to reserve an internal buffer to store outstanding requests from the host API caller. - - Multiple Instances/Devices: The library accesses all logical instances from all visible and configured QAT endpoints at the creation of the QAT runtime context. Therefore, if 8 QAT endpoints are available, it will attempt to use them all, including all the total number of logical instances configured per process. + - Multiple Devices: The library accesses all logical instances from all visible and configured QAT endpoints at the creation of the QAT runtime context. Therefore, if 8 QAT endpoints are available, it will attempt to use them all, including all the total number of logical instances configured per process. >> _**Note**_: Current implementation does not verify if the instance/endpoint has the capabilities needed by the library. For example, the library needs access to the _asym_ capabilities like `CyLnModExp`, therefore if the configuration file of an endpoint happens to be configured to not offer it, the application will exit with an error at some point during execution. From 7e7c28c50090086000fe92ce296379656f4f473f Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 23 Sep 2022 17:33:35 -0700 Subject: [PATCH 254/364] Remove heqat from external dependency. Signed-off-by: Souza, Fillipe --- cmake/heqat/heqat.cmake | 57 ---------------------------------- cmake/heqat/icp/CMakeLists.txt | 33 -------------------- 2 files changed, 90 deletions(-) delete mode 100644 cmake/heqat/heqat.cmake delete mode 100644 cmake/heqat/icp/CMakeLists.txt diff --git a/cmake/heqat/heqat.cmake b/cmake/heqat/heqat.cmake deleted file mode 100644 index 10205b2..0000000 --- a/cmake/heqat/heqat.cmake +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright (C) 2021 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -include(ExternalProject) -MESSAGE(STATUS "Configuring HE QAT") -set(HEQAT_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_he_qat) -set(HEQAT_GIT_REPO_URL git@github.com:intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.project-destiny.git) -set(HEQAT_GIT_LABEL v1.0-pre-release) -set(HEQAT_SRC_DIR ${HEQAT_PREFIX}/src/ext_he_qat/) - -set(HEQAT_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS}") - -ExternalProject_Add( - ext_he_qat - GIT_REPOSITORY ${HEQAT_GIT_REPO_URL} - GIT_TAG ${HEQAT_GIT_LABEL} - PREFIX ${HEQAT_PREFIX} - INSTALL_DIR ${HEQAT_PREFIX} - CMAKE_ARGS ${HEQAT_CXX_FLAGS} - -DCMAKE_INSTALL_PREFIX=${HEQAT_PREFIX} - -DHE_QAT_MISC=OFF - -DIPPCP_PREFIX_PATH=${IPPCRYPTO_PREFIX}/lib/cmake - -DHE_QAT_SHARED=${IPCL_SHARED} - -DCMAKE_BUILD_TYPE=Release - UPDATE_COMMAND "" -) -add_dependencies(ext_he_qat ext_ipp-crypto) - -set(HEQAT_INC_DIR ${HEQAT_PREFIX}/include) - -# Bring up CPA variables -include(${CMAKE_CURRENT_LIST_DIR}/icp/CMakeLists.txt) -list(APPEND HEQAT_INC_DIR ${ICP_INC_DIR}) - -if(IPCL_SHARED) - add_library(libhe_qat INTERFACE) - add_dependencies(libhe_qat ext_he_qat) - - ExternalProject_Get_Property(ext_he_qat SOURCE_DIR BINARY_DIR) - - target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libcpa_sample_utils.so) - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat_debug.so) - else() - target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat.so) - endif() - target_include_directories(libhe_qat SYSTEM INTERFACE ${HEQAT_INC_DIR}) -else() - add_library(libhe_qat STATIC IMPORTED GLOBAL) - add_dependencies(libhe_qat ext_he_qat) - - ExternalProject_Get_Property(ext_he_qat SOURCE_DIR BINARY_DIR) - - set_target_properties(libhe_qat PROPERTIES - IMPORTED_LOCATION ${HEQAT_PREFIX}/lib/libhe_qat.a - INCLUDE_DIRECTORIES ${HEQAT_INC_DIR}) -endif() diff --git a/cmake/heqat/icp/CMakeLists.txt b/cmake/heqat/icp/CMakeLists.txt deleted file mode 100644 index ee0617a..0000000 --- a/cmake/heqat/icp/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ - -if(DEFINED ENV{ICP_ROOT}) - message(STATUS "Environment variable ICP_ROOT is defined as $ENV{ICP_ROOT}.") -else() - message(FATAL_ERROR "Environment variable ICP_ROOT must be defined. Try export ICP_ROOT=") -endif() - -set(ICP_ROOT $ENV{ICP_ROOT}) -set(ICP_BUILDOUTPUT_PATH ${ICP_ROOT}/build) -set(ICP_BUILDSYSTEM_PATH ${ICP_ROOT}/quickassist/build_system) -set(ICP_API_DIR ${ICP_ROOT}/quickassist) -set(ICP_LAC_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer) -set(ICP_OSAL_DIR ${ICP_ROOT}/quickassist/utilities/oasl) -set(ICP_ADF_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/qat_direct) -set(CMN_ROOT ${ICP_ROOT}/quickassist/utilities/libusdm_drv) - -#list(APPEND COMMON_INC_DIR ${ICP_API_DIR}/include -# ${ICP_LAC_DIR}/include -# ${ICP_ADF_DIR}/include -# ${CMN_ROOT} -#) - -set(ICP_INC_DIR ${ICP_API_DIR}/include - ${ICP_LAC_DIR}/include - ${ICP_ADF_DIR}/include - ${CMN_ROOT} - ${ICP_API_DIR}/include/dc - ${ICP_API_DIR}/include/lac) - -#Macros for the test case -add_definitions(-DDO_CRYPTO) -add_definitions(-DUSER_SPACE) -add_compile_options(-fPIC) From bfdf0ab70b1dc3e1b86b8c8210c71737e0623842 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 23 Sep 2022 17:42:18 -0700 Subject: [PATCH 255/364] Remove heqat module as fixed directory. Signed-off-by: Souza, Fillipe --- module/heqat/.clang-format | 9 - module/heqat/.gitignore | 12 - module/heqat/CMakeLists.txt | 209 ----- module/heqat/LICENSE | 201 ----- module/heqat/README.md | 295 ------- .../heqat/cmake/he_qat/HE_QATConfig.cmake.in | 21 - module/heqat/cmake/he_qat/heqat-util.cmake | 31 - module/heqat/common/CMakeLists.txt | 43 - module/heqat/common/cpa_sample_utils.c | 285 ------ module/heqat/config/4xxx_dev0.conf | 182 ---- module/heqat/config/4xxxvf_dev0.conf | 134 --- module/heqat/doc/CMakeLists.txt | 25 - module/heqat/doc/Doxyfile.in | 33 - module/heqat/doc/index.html | 2 - module/heqat/doc/index.rst | 5 - module/heqat/example/CMakeLists.txt | 25 - module/heqat/example/README.md | 7 - module/heqat/example/example.cpp | 143 --- module/heqat/he_qat/CMakeLists.txt | 106 --- module/heqat/he_qat/he_qat_cb.c | 117 --- module/heqat/he_qat/he_qat_context.c | 304 ------- module/heqat/he_qat/he_qat_ctrl.c | 817 ------------------ module/heqat/he_qat/he_qat_ops.c | 566 ------------ module/heqat/he_qat/he_qat_utils.c | 66 -- module/heqat/he_qat/include/he_qat_bn_ops.h | 141 --- module/heqat/he_qat/include/he_qat_context.h | 26 - module/heqat/he_qat/include/he_qat_gconst.h | 17 - module/heqat/he_qat/include/he_qat_types.h | 123 --- module/heqat/he_qat/include/he_qat_utils.h | 20 - module/heqat/icp/CMakeLists.txt | 48 - module/heqat/include/cpa_sample_utils.h | 639 -------------- module/heqat/misc/CMakeLists.txt | 51 -- module/heqat/misc/bignum.cpp | 394 --------- module/heqat/misc/bignum.h | 112 --- module/heqat/misc/he_qat_misc.cpp | 47 - module/heqat/misc/he_qat_misc.h | 33 - module/heqat/misc/utils.cpp | 45 - module/heqat/misc/utils.h | 34 - module/heqat/samples/CMakeLists.txt | 81 -- module/heqat/samples/test_BIGNUMModExp.c | 142 --- module/heqat/samples/test_bnConversion.cpp | 107 --- module/heqat/samples/test_bnModExp.cpp | 231 ----- module/heqat/samples/test_bnModExp_MT.cpp | 297 ------- module/heqat/samples/test_context.c | 28 - module/heqat/scripts/auto_find_qat_install.sh | 1 - .../heqat/scripts/reset_asym_buffer_size.sh | 75 -- module/heqat/scripts/restart_devices.sh | 132 --- module/heqat/scripts/run.sh | 20 - module/heqat/scripts/setup_devices.sh | 156 ---- module/heqat/setup_env.sh | 5 - 50 files changed, 6643 deletions(-) delete mode 100644 module/heqat/.clang-format delete mode 100644 module/heqat/.gitignore delete mode 100644 module/heqat/CMakeLists.txt delete mode 100644 module/heqat/LICENSE delete mode 100644 module/heqat/README.md delete mode 100644 module/heqat/cmake/he_qat/HE_QATConfig.cmake.in delete mode 100644 module/heqat/cmake/he_qat/heqat-util.cmake delete mode 100644 module/heqat/common/CMakeLists.txt delete mode 100644 module/heqat/common/cpa_sample_utils.c delete mode 100755 module/heqat/config/4xxx_dev0.conf delete mode 100755 module/heqat/config/4xxxvf_dev0.conf delete mode 100644 module/heqat/doc/CMakeLists.txt delete mode 100644 module/heqat/doc/Doxyfile.in delete mode 100644 module/heqat/doc/index.html delete mode 100644 module/heqat/doc/index.rst delete mode 100644 module/heqat/example/CMakeLists.txt delete mode 100644 module/heqat/example/README.md delete mode 100644 module/heqat/example/example.cpp delete mode 100644 module/heqat/he_qat/CMakeLists.txt delete mode 100644 module/heqat/he_qat/he_qat_cb.c delete mode 100644 module/heqat/he_qat/he_qat_context.c delete mode 100644 module/heqat/he_qat/he_qat_ctrl.c delete mode 100644 module/heqat/he_qat/he_qat_ops.c delete mode 100644 module/heqat/he_qat/he_qat_utils.c delete mode 100644 module/heqat/he_qat/include/he_qat_bn_ops.h delete mode 100644 module/heqat/he_qat/include/he_qat_context.h delete mode 100644 module/heqat/he_qat/include/he_qat_gconst.h delete mode 100644 module/heqat/he_qat/include/he_qat_types.h delete mode 100644 module/heqat/he_qat/include/he_qat_utils.h delete mode 100644 module/heqat/icp/CMakeLists.txt delete mode 100644 module/heqat/include/cpa_sample_utils.h delete mode 100644 module/heqat/misc/CMakeLists.txt delete mode 100644 module/heqat/misc/bignum.cpp delete mode 100644 module/heqat/misc/bignum.h delete mode 100644 module/heqat/misc/he_qat_misc.cpp delete mode 100644 module/heqat/misc/he_qat_misc.h delete mode 100644 module/heqat/misc/utils.cpp delete mode 100644 module/heqat/misc/utils.h delete mode 100644 module/heqat/samples/CMakeLists.txt delete mode 100644 module/heqat/samples/test_BIGNUMModExp.c delete mode 100644 module/heqat/samples/test_bnConversion.cpp delete mode 100644 module/heqat/samples/test_bnModExp.cpp delete mode 100644 module/heqat/samples/test_bnModExp_MT.cpp delete mode 100644 module/heqat/samples/test_context.c delete mode 100755 module/heqat/scripts/auto_find_qat_install.sh delete mode 100755 module/heqat/scripts/reset_asym_buffer_size.sh delete mode 100755 module/heqat/scripts/restart_devices.sh delete mode 100755 module/heqat/scripts/run.sh delete mode 100755 module/heqat/scripts/setup_devices.sh delete mode 100755 module/heqat/setup_env.sh diff --git a/module/heqat/.clang-format b/module/heqat/.clang-format deleted file mode 100644 index c16dae7..0000000 --- a/module/heqat/.clang-format +++ /dev/null @@ -1,9 +0,0 @@ -BasedOnStyle: Google -Language: Cpp -DerivePointerAlignment: false -PointerAlignment: Left -IndentWidth: 4 -AccessModifierOffset: -4 -IndentCaseLabels: false -SortIncludes: false -ColumnLimit: 80 diff --git a/module/heqat/.gitignore b/module/heqat/.gitignore deleted file mode 100644 index 3b962b7..0000000 --- a/module/heqat/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -.vscode/ -.vs/ - - -build*/ -install - -cmake/he_qat-*.*.*/HE_QATConfig.cmake -*.log -Doxyfile - -**.swp \ No newline at end of file diff --git a/module/heqat/CMakeLists.txt b/module/heqat/CMakeLists.txt deleted file mode 100644 index 9cb6694..0000000 --- a/module/heqat/CMakeLists.txt +++ /dev/null @@ -1,209 +0,0 @@ -cmake_minimum_required(VERSION 3.13) - -# The hekat or heqat (transcribed HqA.t) was an ancient Egyptian volume unit -# used to measure grain, bread, and beer. -project(HE_QAT VERSION 0.1.0 LANGUAGES C CXX) - -include(CheckCCompilerFlag) -include(CheckCXXCompilerFlag) -include(CMakePackageConfigHelpers) - -if(CMAKE_BUILD_TYPE) - set(RELEASE_TYPES - Debug - Release - RelWithDebInfo - MinSizeRel) - list(FIND RELEASE_TYPES ${CMAKE_BUILD_TYPE} INDEX_FOUND) - if(${INDEX_FOUND} EQUAL -1) - message( - FATAL_ERROR - "CMAKE_BUILD_TYPE must be one of Debug, Release, RelWithDebInfo, or MinSizeRel" - ) - endif() -else() - set(CMAKE_BUILD_TYPE Release) -endif() - -set(CMAKE_C_STANDARD 99) -set(CMAKE_C_STANDARD_REQUIRED ON) -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(CMAKE_C_FLAGS "-O2 -Wunused-variable -Wunused-function") -set(CMAKE_CXX_FLAGS "-O2 -Wunused-variable -Wunused-function -fpermissive") - -# What does it do? -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -# When to use it? To build with shared libraries. -set(CMAKE_POSITION_INDEPENDENT_CODE ON) - -# Why? -set(CMAKE_INSTALL_MESSAGE LAZY) - -# Why? -set(CMAKE_INSTALL_RPATH "\$ORIGIN") - -if(NOT CMAKE_INSTALL_PREFIX) - set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_LIST_DIR}/install) -endif() -message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") - -# Which features or functions does it bring? -include(GNUInstallDirs) - -# Location where to unpack and pack static libraries -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) - -# ------------------------------------------------------------------- - -option(HE_QAT_MISC "Enable miscellaneous features" ON) -option(HE_QAT_SYNC "Enable synchronous mode execution" OFF) -option(HE_QAT_MT "Enable interfaces for multithreaded programs" ON) -option(HE_QAT_PERF "Show request performance" OFF) -option(HE_QAT_TEST "Enable testing" OFF) -option(HE_QAT_OMP "Enable tests using OpenMP" ON) -option(HE_QAT_SAMPLES "Enable examples" ON) -option(HE_QAT_BENCHMARK "Enable benchmark" OFF) -option(HE_QAT_DOCS "Enable document building" ON) -option(HE_QAT_SHARED "Build shared library" ON) - -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(HE_QAT_DEBUG ON) - add_definitions(-DHE_QAT_DEBUG) -else() - set(HE_QAT_DEBUG OFF) -endif() - -# Why? -set(HE_QAT_CMAKE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/he_qat") -set(HE_QAT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) -set(HE_QAT_SRC_DIR ${HE_QAT_ROOT_DIR}/he_qat) -set(HE_QAT_INC_DIR ${HE_QAT_ROOT_DIR}/he_qat/include) - -if(HE_QAT_OMP) - find_package(OpenMP REQUIRED) - if(NOT TARGET OpenMP::OpenMP_CXX) - message(FATAL_ERROR "Missing OpenMP::OpenMP_CXX.") - endif() - if(NOT TARGET OpenMP::OpenMP_C) - message(FATAL_ERROR "Missing OpenMP::OpenMP_C.") - endif() -endif() - -if(HE_QAT_MT) - add_definitions(-DHE_QAT_MT) - message(STATUS "Compile with multithreaded interfaces.") -endif() - -if(HE_QAT_MISC) - # IPP Crypto installation - if(IPPCP_PREFIX_PATH) - list(APPEND CMAKE_PREFIX_PATH "${IPPCP_PREFIX_PATH}") - set(IPPCP_DIR "${IPPCP_PREFIX_PATH}/../../../") - message(STATUS "IPPCP_DIR=${IPPCP_DIR}") - else() - # Default to this - set(IPPCP_DIR "/opt/ipp-crypto") - set(IPPCP_PREFIX_PATH "${IPPCP_DIR}/lib/cmake") - list(APPEND CMAKE_PREFIX_PATH "${IPPCP_PREFIX_PATH}") - message(STATUS "Else IPPCP_DIR=${IPPCP_DIR}") - endif() - find_package(IPPCP REQUIRED) - message(STATUS "IPPCP_LIBRARIES ${IPPCP_LIBRARIES}") -endif() - -if(HE_QAT_SYNC) - add_definitions(-DHE_QAT_SYNC_MODE) -endif() - -if(HE_QAT_PERF) - add_definitions(-DHE_QAT_PERF) -endif() - -set(HE_QAT_FORWARD_CMAKE_ARGS - -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} - -DCMAKE_C_STANDARD=${CMAKE_C_STANDARD} - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} - -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} - -DCMAKE_CXX_STANDARD_REQUIRED=${CMAKE_CXX_STANDARD_REQUIRED} - -DCMAKE_CXX_EXTENSIONS=${CMAKE_CXX_EXTENSIONS} - -DCMAKE_EXPORT_COMPILE_COMMANDS=${CMAKE_EXPORT_COMPILE_COMMANDS} - -DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE} - -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -) - - -#OpenSSL installation -if(NOT HE_QAT_SHARED) - set(OPENSSL_USE_STATIC_LIBS TRUE) - message(STATUS "OPENSSL_USE_STATIC_LIBS TRUE") -else() - message(STATUS "OPENSSL_USE_STATIC_LIBS FALSE") -endif() -find_package(OpenSSL REQUIRED) - -# External dependencies -find_package(Threads REQUIRED) -set(CMAKE_THREAD_PREFER_PTHREAD ON) -set(THREADS_PREFER_PTHREAD_FLAG ON) - -set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/he_qat) -include(heqat-util) - -set(COMMON_INC_DIR ${CMAKE_CURRENT_LIST_DIR}/include) -if(NOT CMAKE_INSTALL_PREFIX) - set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_LIST_DIR}/install) -endif() - -# Include QAT lib API support -include(icp/CMakeLists.txt) - -#Common utility functions -add_subdirectory(common) - -# Helper functions for BigNumber -if(HE_QAT_MISC) - add_subdirectory(misc) -endif() - -# HE_QAT Library -add_subdirectory(he_qat) - -if(HE_QAT_TEST) - include(cmake/gtest.cmake) -endif() -if(HE_QAT_BENCHMARK) - include(cmake/gbenchmark.cmake) -endif() - -#Validation test examples -if(HE_QAT_SAMPLES) - add_subdirectory(samples) -endif() - -if(HE_QAT_TEST) - add_subdirectory(test) - add_custom_target(unittest COMMAND $ DEPENDS he_qat_unittest) -endif() - -if(HE_QAT_BENCHMARK) - add_subdirectory(benchmark) - add_custom_target(benchmark COMMAND $ DEPENDS he_qat_bench) -endif() - -if(HE_QAT_DOCS) - # sudo apt-get install doxygen - find_package(Doxygen) - option(BUILD_DOCS "Create and install the HTML based API docs (requires Doxygen)" ${DOXYGEN_FOUND}) - if(BUILD_DOCS) - if(NOT DOXYGEN_FOUND) - message(FATAL_ERROR "Doxygen was not found (Required)") - else() - add_subdirectory(doc) - endif() - endif() -endif() - diff --git a/module/heqat/LICENSE b/module/heqat/LICENSE deleted file mode 100644 index 261eeb9..0000000 --- a/module/heqat/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/module/heqat/README.md b/module/heqat/README.md deleted file mode 100644 index d2e706a..0000000 --- a/module/heqat/README.md +++ /dev/null @@ -1,295 +0,0 @@ -# Intel Homomorphic Encryption (HE) Acceleration Library for Quick Assist Technology (QAT) -Intel Homomorphic Encryption Acceleration Library for QAT (HE QAT Lib) is an open-source library which provides accelerated performance for homomorphic encryption (HE) math functions involving multi-precision numbers and modular arithmetic. This library is written in C99. - -## Contents -- [Intel Homomorphic Encryption Acceleration Library for QAT](#intel-homomorphic-encryption-library-for-qat) - - [Contents](#contents) - - [Introduction](#introduction) - - [Building the Library](#building-the-library) - - [Requirements](#requirements) - - [Dependencies](#dependencies) - - [Instructions](#instructions) - - [Troubleshooting](#troubleshooting) - - [Testing and Benchmarking](#testing-and-benchmarking) - -- [Contributors](#contributors) - -## Introduction - -This library currently only offers acceleration of modular exponentiation of multi-precision numbers, i.e. large numbers whose precision range from 1024 to 8192 bits. Current stage of implementation supports modular exponentiation of big numbers encoded with OpenSSL `BIGNUM` data type, `ippcrypto`'s `BigNumber` class and octet strings encoded with `unsigned char`. More details about the modes of operation and characteristics of the execution flow are described below: - - - Synchronous: API calls will submit requests that will be executed in the order they are first issued by the host caller, i.e. a series of modular exponentiation operation requests will be offloaded for processing by the accelerator in the order they are issued. - - - Asynchronous: API calls will submit requests that will NOT necessarily be executed in the order they are first issued by the host caller, i.e. a sequence of multiple requests for the modular exponentiation operation could be scheduled out of order and executed concurrently by the accelerator; thus, completed out of order. - - - Blocking: API calls will be blocked until work request processing completion. Internally, the next buffered work request waits for completion of the processing of the most recently offloaded request to the accelerator. - - - Non-Blocking: API calls will be non-blocking, it does not wait for completion of the work request to return from call. After multiple non-blocking calls to the API, a blocking function to wait for the requests to complete processing must be called. Internally, non-blocking request submissions are scheduled to the accelerator asynchronously. When there are multiple requests from concurrent API callers, the requests are not guaranteed to be processed in order of arrival. - - - Batch Support: The internal buffers are set accommodate up to 1024 requests at a time so that the maximum number of non-blocking API calls is 1024 for each concurrent thread caller. Therefore, only up to 1024 requests can be exercised asynchronously from the application side, be it from a single `for loop` or static code block. Finally, in order to collect the requests, a call to the `getBnModExpRequest()` function must be performed to wait for completion of all submitted asynchronous requests. On multithreaded mode, the blocking function to be called at the end of the code block shall be `release_bnModExp_buffer()`. - - - Multithreading Support: This feature permits the API to be called by concurrently threads running on the host. Effective multithreading support relies on a separate buffer that admits outstanding work requests. This buffer is acquired before an API call to submit work requests to the accelerator. This is accomplished by first calling `acquire_bnModExp_buffer()` to reserve an internal buffer to store outstanding requests from the host API caller. - - - Multiple Devices: The library accesses all logical instances from all visible and configured QAT endpoints at the creation of the QAT runtime context. Therefore, if 8 QAT endpoints are available, it will attempt to use them all, including all the total number of logical instances configured per process. - ->> _**Note**_: Current implementation does not verify if the instance/endpoint has the capabilities needed by the library. For example, the library needs access to the _asym_ capabilities like `CyLnModExp`, therefore if the configuration file of an endpoint happens to be configured to not offer it, the application will exit with an error at some point during execution. - -## Building the HE QAT Library - -### Requirements -The hardware requirement to use the library is the following: - - Intel 4xxx co-processor - - -As for the operating systems, the library has been tested and confirmed to work on Ubuntu 20.04. - -### Dependencies - -Required dependencies include: - -``` -cmake >=3.15.1 -git -yasm -libboost >= 1.14 -libudev >= 1.47 -pthread -OpenSSL >=1.1.0 -gcc >= 9.1 -QAT20.L.0.8.0-00071.tar.gz (qatlib and QAT drivers) -nasm >= 2.15 -ipp-crypto -``` - -### Instructions - -Before attempting to build the library, please check if the platform has the QAT hardware. - -``` -$ sudo lspci -d 8086:4940 -6b:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) -70:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) -75:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) -7a:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) -e8:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) -ed:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) -f2:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) -f7:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) -``` - -In the example above, the platform is a dual-socket server with Sapphire Rapids (SPR) CPU and it shows 8 QAT endpoints, 4 on each socket. - -#### Installing Dependencies - -``` -sudo apt install yasm zlib1g -sudo apt update -y -sudo apt install -y libsystemd-dev -sudo apt install -y pciutils (tested with version=3.6.4) -sudo apt install -y libudev-dev -sudo apt install -y libreadline-dev -sudo apt install -y libxml2-dev -sudo apt install -y libboost-dev -sudo apt install -y elfutils libelf-dev -sudo apt install -y libnl-3-dev -sudo apt install -y linux-headers-$(uname -r) -sudo apt install -y build-essential -sudo apt install -y libboost-regex-dev -sudo apt install -y pkg-config -``` - -#### Installing OpenSSL - -``` -$ git clone https://github.com/openssl/openssl.git -$ cd openssl/ -$ git checkout OpenSSL_1_1_1-stable -$ ./Configure --prefix=/opt/openssl -$ make -$ sudo make install -``` - -#### Installing QAT Software Stack - -``` -$ cd $HOME -$ mkdir QAT -$ mv QAT20.L.0.8.0-00071.tar.gz QAT/ -$ cd QAT -$ tar zxvf QAT20.L.0.8.0-00071.tar.gz -$ ./configure -$ sudo make -j -$ sudo make install -``` - -Add `$USER` to the `qat` group. Must logout and log back in to take effect. - -``` -$ sudo usermod -aG qat $USER -``` - -> _**Note**_: Please contact the QAT team listed at [https://01.org/intel-quickassist-technology](https://01.org/intel-quickassist-technology) to obtain the latest `QAT20.L.0.8.0-00071.tar.gz` package. - -Verify the QAT installation by checking the QAT service status: - - -``` -sudo service qat_service status -``` - -If all checks out, following the instructions below to build the HE QAT library. - -#### Setup Environment - -This step is required. Note that if the step [Installing QAT Software Stack](#installing-qat-software-stack) has just been performed, then the exact path of the installation is known, i.e. - -``` -$ export ICP_ROOT=$HOME/QAT -``` - -Alternatively, if the system has a ore-built QAT software stack, the script `auto_find_qat_install.sh` can used to help automatically find the path where it was installed (see command below). - -``` -$ export ICP_ROOT=$(./auto_find_qat_install.sh) -``` - -#### Building the Library - -Execute step []() before building the library. - -- How to build without `BigNumber` support - -``` -$ git clone https://github.com/intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.project-destiny.git -$ git checkout development -$ cmake -S . -B build -DHE_QAT_MISC=OFF -$ cmake --build build -$ cmake --install build -``` - -- How to build with `BigNumber` support - -The `cmake` configuration variable `HE_QAT_MISC=ON` enables `BigNumber` resources and samples, requiring IPP Crypto installation as a dependency. If usage of the utility functions that support `BigNumber` data type is needed, follow the building instructions below to install IPP Crypto and then rebuild the library with the cmake flag `HE_QAT_MISC=ON`: - -- Installing `nasm-2.15` - -``` -$ wget -c https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.xz -$ tar -xf nasm-2.15.05.tar.xz -$ cd nasm-2.15.05/ -$ ./configure --prefix=/opt/nasm-2.15 -$ make -j -$ sudo make install -``` - -- Installing `ippcrypto` - -``` -$ cd ~ -$ git clone https://github.com/intel/ipp-crypto.git -$ cd ipp-crypto -$ CC=gcc CXX=g++ cmake CMakeLists.txt -B_build -DARCH=intel64 -DMERGED_BLD:BOOL=ON -DCMAKE_INSTALL_PREFIX=/opt/ipp-crypto -DOPENSSL_INCLUDE_DIR=/opt/openssl/include -DOPENSSL_LIBRARIES=/opt/openssl/lib -DOPENSSL_ROOT_DIR=/opt/openssl -DCMAKE_ASM_NASM_COMPILER=/opt/nasm-2.15/bin/nasm -$ cmake --build _build -j -$ sudo cmake --install _build -``` - -#### Configure QAT endpoints - -Before trying to run any application or example that uses the HE QAT Lib, the QAT endpoints must be configured. -The default configuration provided in this release is the optimal configuration to provide computing acceleration support for IPCL. -The boilerplate configurations can be found in the directory `config`. - -``` -$ ./setup_devices.sh -``` - -#### Configuration Options - -In addition to the standard CMake configuration options, Intel HE Acceleration Library for QAT supports several cmake options to configure the build. For convenience, they are listed below: - -| CMake option | Values | Description | -| ------------------------------| ---------------------- | ------------------------------------------------------- | -| HE_QAT_MISC | ON / OFF (default OFF) | Enable/Disable BigNumber conversion functions. | -| HE_QAT_DEBUG | ON / OFF (default OFF) | Enable/Disable debug log at large runtime penalty. | -| HE_QAT_SAMPLES | ON / OFF (default ON) | Enable/Disable building of samples. | -| HE_QAT_DOCS | ON / OFF (default ON) | Enable/Disable building of documentation. | -| HE_QAT_SYNC | ON / OFF (default OFF) | Enable/Disable synchronous mode execution. | -| HE_QAT_MT | ON / OFF (default ON) | Enable/Disable interfaces for multithreaded programs. | -| HE_QAT_PERF | ON / OFF (default OFF) | Enable/Disable display of measured request performance. | -| HE_QAT_TEST | ON / OFF (default OFF) | Enable/Disable testing. | -| HE_QAT_OMP | ON / OFF (default ON) | Enable/Disable tests using OpenMP. | -| HE_QAT_SHARED | ON / OFF (default ON) | Enable/Disable building shared library. | - -#### Running Samples - -Test showing creation and teardown of the QAT runtime environment: - -``` -./build/samples/test_context -``` - -Test showing functional correctness and performance: - -``` -./build/samples/test_bnModExpPerformOp -``` - -If built with `HE_QAT_MISC=ON`, then the following samples below are also available to try. - -Test showing data conversion between `BigNumber` and `CpaFlatBuffer` formats: - -``` -./build/samples/test_bnConversion -``` - -Test showing functional correctness and performance using `BigNumber` data types: - -``` -./build/samples/test_bnModExp -``` -## Troubleshooting - -- **Issue #1** - -``` -xuser@ubuntu-guest:~/heqat$ cmake -S . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHE_QAT_MISC=ON --- CMAKE_INSTALL_PREFIX: /usr/local --- CMAKE_PREFIX_PATH /home/xuser/ipp-crypto/_build/ --- Missed required Intel IPP Cryptography component: ippcp --- library not found: - /opt/ipp-crypto/lib/intel64/libippcp.a -CMake Error at CMakeLists.txt:93 (find_package): - Found package configuration file: - - /opt/ipp-crypto/lib/cmake/ippcp/ippcp-config.cmake - - but it set IPPCP_FOUND to FALSE so package "IPPCP" is considered to be NOT - FOUND. -``` - -To resolve the error below simply create the symbolic link `/opt/ipp-crypto/lib/intel64/libippcp.a` from the apropriate static ippcp library that was compiled. For example: - -``` -xuser@ubuntu-guest:/opt/ipp-crypto/lib/intel64$ ls -lha -total 7.3M -drwxr-xr-x 2 root root 4.0K Jun 3 16:29 . -drwxr-xr-x 5 root root 4.0K Jun 3 16:29 .. --rw-r--r-- 1 root root 1.6M Jun 3 16:28 libcrypto_mb.a -lrwxrwxrwx 1 root root 18 Jun 3 16:29 libcrypto_mb.so -> libcrypto_mb.so.11 -lrwxrwxrwx 1 root root 20 Jun 3 16:29 libcrypto_mb.so.11 -> libcrypto_mb.so.11.5 --rw-r--r-- 1 root root 1.3M Jun 3 16:28 libcrypto_mb.so.11.5 -lrwxrwxrwx 1 root root 16 Jun 3 16:29 libippcpmx.so -> libippcpmx.so.11 -lrwxrwxrwx 1 root root 18 Jun 3 16:29 libippcpmx.so.11 -> libippcpmx.so.11.5 --rw-r--r-- 1 root root 1.7M Jun 3 16:28 libippcpmx.so.11.5 --rw-r--r-- 1 root root 2.9M Jun 3 16:28 libippcp_s_mx.a -xuser@ubuntu-guest:/opt/ipp-crypto/lib/intel64$ sudo ln -s libippcp_s_mx.a libippcp.a -``` - -## Testing and Benchmarking - -TODO - -# Contributors - -Fillipe D. M. de Souza (Lead) - diff --git a/module/heqat/cmake/he_qat/HE_QATConfig.cmake.in b/module/heqat/cmake/he_qat/HE_QATConfig.cmake.in deleted file mode 100644 index 81dc91c..0000000 --- a/module/heqat/cmake/he_qat/HE_QATConfig.cmake.in +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (C) 2021 Intel Corporation - -@PACKAGE_INIT@ - -include(CMakeFindDependencyMacro) - -include(${CMAKE_CURRENT_LIST_DIR}/he_qatTargets.cmake) - -if(TARGET HE_QAT::he_qat) - set(HE_QAT_FOUND TRUE) - message(STATUS "Intel Homomorphic Encryption Acceleration Library for QAT found") -else() - message(STATUS "Intel Homomorphic Encryption Acceleraiton Library for QAT not found") -endif() - -set(HE_QAT_VERSION "@HE_QAT_VERSION") -set(HE_QAT_VERSION_MAJOR "@HE_QAT_VERSION_MAJOR") -set(HE_QAT_VERSION_MINOR "@HE_QAT_VERSION") -set(HE_QAT_VERSION_PATCH "@HE_QAT_VERSION") - -set(HE_QAT_DEBUG "@HE_QAT_DEBUG") diff --git a/module/heqat/cmake/he_qat/heqat-util.cmake b/module/heqat/cmake/he_qat/heqat-util.cmake deleted file mode 100644 index 0b5ca8a..0000000 --- a/module/heqat/cmake/he_qat/heqat-util.cmake +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (C) 2021 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -# Add dependency to the target archive -function(heqat_create_archive target dependency) - # For proper export of IPCLConfig.cmake / IPCLTargets.cmake, - # we avoid explicitly linking dependencies via target_link_libraries, since - # this would add dependencies to the exported ipcl target. - add_dependencies(${target} ${dependency}) - - if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - add_custom_command(TARGET ${target} POST_BUILD - COMMAND ar -x $ - COMMAND ar -x $ - COMMAND ar -qcs $ *.o - COMMAND rm -f *.o - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS ${target} ${dependency} - ) - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - add_custom_command(TARGET ${target} POST_BUILD - COMMAND lib.exe /OUT:$ - $ - $ - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS ${target} ${dependency} - ) - else() - message(WARNING "Unsupported compiler ${CMAKE_CXX_COMPILER_ID}") - endif() -endfunction() diff --git a/module/heqat/common/CMakeLists.txt b/module/heqat/common/CMakeLists.txt deleted file mode 100644 index eb0ed9b..0000000 --- a/module/heqat/common/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -# Include directories -#list(APPEND COMMON_INC_DIR -# ${ICP_API_DIR}/include/dc -# ${ICP_API_DIR}/include/lac -#) -message(STATUS "COMMON_INC_DIR: ${COMMON_INC_DIR}") -message(STATUS "ICP_INC_DIR: ${ICP_INC_DIR}") - -# Source files -set(COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/cpa_sample_utils.c) - -if(HE_QAT_SHARED) - add_library(cpa_sample_utils SHARED ${COMMON_SRC}) -else() - add_library(cpa_sample_utils STATIC ${COMMON_SRC}) -endif() - -target_include_directories(cpa_sample_utils - PRIVATE $ # Public headers - PRIVATE $ # Public headers - PUBLIC $ # Public headers - PRIVATE ${COMMON_INC_DIR} # Private headers - PRIVATE ${ICP_INC_DIR} # Private headers -) - -target_link_libraries(cpa_sample_utils PRIVATE udev z) - -if(HE_QAT_SHARED) - target_link_libraries(cpa_sample_utils PRIVATE ${ICP_BUILDOUTPUT_PATH}/libqat_s.so) - target_link_libraries(cpa_sample_utils PRIVATE ${ICP_BUILDOUTPUT_PATH}/libusdm_drv_s.so) -else() - heqat_create_archive(cpa_sample_utils libadf_static) - heqat_create_archive(cpa_sample_utils libosal_static) - heqat_create_archive(cpa_sample_utils libqat_static) - heqat_create_archive(cpa_sample_utils libusdm_drv_static) -endif() - -#install(TARGETS cpa_sample_utils DESTINATION ${CMAKE_INSTALL_LIBDIR}) -install(TARGETS cpa_sample_utils EXPORT he_qatTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}) - -set(COMMON_INC_DIR ${COMMON_INC_DIR} PARENT_SCOPE) - - diff --git a/module/heqat/common/cpa_sample_utils.c b/module/heqat/common/cpa_sample_utils.c deleted file mode 100644 index 5949134..0000000 --- a/module/heqat/common/cpa_sample_utils.c +++ /dev/null @@ -1,285 +0,0 @@ -/*************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Corporation - * - * BSD LICENSE - * - * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * version: QAT.L.4.15.0-00011 - * - ***************************************************************************/ - -/** - ***************************************************************************** - * @file cpa_sample_utils.c - * - * @ingroup sampleCode - * - * @description - * Defines functions to get an instance and poll an instance - * - ***************************************************************************/ - -#include "cpa_sample_utils.h" -#include "cpa_dc.h" -#include "icp_sal_poll.h" - -/* - * Maximum number of instances to query from the API - */ -#ifdef USER_SPACE -#define MAX_INSTANCES 1024 -#else -#define MAX_INSTANCES 1 -#endif - -#ifdef DO_CRYPTO -static sampleThread gPollingThread; -static volatile int gPollingCy = 0; -#endif - -static sampleThread gPollingThreadDc; -static volatile int gPollingDc = 0; - -#ifdef SC_ENABLE_DYNAMIC_COMPRESSION -CpaDcHuffType huffmanType_g = CPA_DC_HT_FULL_DYNAMIC; -#else -CpaDcHuffType huffmanType_g = CPA_DC_HT_STATIC; -#endif -/* ************************************************************* - * - * Common instance functions - * - * ************************************************************* - */ - -/* - * This function returns a handle to an instance of the cryptographic - * API. It does this by querying the API for all instances and - * returning the first such instance. - */ -// -#ifdef DO_CRYPTO -void sampleCyGetInstance(CpaInstanceHandle *pCyInstHandle) -{ - CpaInstanceHandle cyInstHandles[MAX_INSTANCES]; - Cpa16U numInstances = 0; - CpaStatus status = CPA_STATUS_SUCCESS; - - *pCyInstHandle = NULL; - status = cpaCyGetNumInstances(&numInstances); - if (numInstances >= MAX_INSTANCES) - { - numInstances = MAX_INSTANCES; - } - if ((status == CPA_STATUS_SUCCESS) && (numInstances > 0)) - { - status = cpaCyGetInstances(numInstances, cyInstHandles); - if (status == CPA_STATUS_SUCCESS) - *pCyInstHandle = cyInstHandles[0]; - } - - if (0 == numInstances) - { - PRINT_ERR("No instances found for 'SSL'\n"); - PRINT_ERR("Please check your section names"); - PRINT_ERR(" in the config file.\n"); - PRINT_ERR("Also make sure to use config file version 2.\n"); - } -} - -void symSessionWaitForInflightReq(CpaCySymSessionCtx pSessionCtx) -{ - -/* Session reuse is available since Cryptographic API version 2.2 */ -#if CY_API_VERSION_AT_LEAST(2, 2) - CpaBoolean sessionInUse = CPA_FALSE; - - do - { - cpaCySymSessionInUse(pSessionCtx, &sessionInUse); - } while (sessionInUse); -#endif - - return; -} -#endif -// - -/* - * This function polls a crypto instance. - * - */ -#ifdef DO_CRYPTO -static void sal_polling(CpaInstanceHandle cyInstHandle) -{ - gPollingCy = 1; - while (gPollingCy) - { - icp_sal_CyPollInstance(cyInstHandle, 0); - OS_SLEEP(10); - } - - sampleThreadExit(); -} -#endif -/* - * This function checks the instance info. If the instance is - * required to be polled then it starts a polling thread. - */ - -#ifdef DO_CRYPTO -void sampleCyStartPolling(CpaInstanceHandle cyInstHandle) -{ - CpaInstanceInfo2 info2 = {0}; - CpaStatus status = CPA_STATUS_SUCCESS; - - status = cpaCyInstanceGetInfo2(cyInstHandle, &info2); - if ((status == CPA_STATUS_SUCCESS) && (info2.isPolled == CPA_TRUE)) - { - /* Start thread to poll instance */ - sampleThreadCreate(&gPollingThread, sal_polling, cyInstHandle); - } -} -#endif -/* - * This function stops the polling of a crypto instance. - */ -#ifdef DO_CRYPTO -void sampleCyStopPolling(void) -{ - gPollingCy = 0; - OS_SLEEP(10); -} -#endif - -/* - * This function returns a handle to an instance of the data - * compression API. It does this by querying the API for all - * instances and returning the first such instance. - */ -// -void sampleDcGetInstance(CpaInstanceHandle *pDcInstHandle) -{ - CpaInstanceHandle dcInstHandles[MAX_INSTANCES]; - Cpa16U numInstances = 0; - CpaStatus status = CPA_STATUS_SUCCESS; - - *pDcInstHandle = NULL; - status = cpaDcGetNumInstances(&numInstances); - if (numInstances >= MAX_INSTANCES) - { - numInstances = MAX_INSTANCES; - } - if ((status == CPA_STATUS_SUCCESS) && (numInstances > 0)) - { - status = cpaDcGetInstances(numInstances, dcInstHandles); - if (status == CPA_STATUS_SUCCESS) - *pDcInstHandle = dcInstHandles[0]; - } - - if (0 == numInstances) - { - PRINT_ERR("No instances found for 'SSL'\n"); - PRINT_ERR("Please check your section names"); - PRINT_ERR(" in the config file.\n"); - PRINT_ERR("Also make sure to use config file version 2.\n"); - } -} -// - -/* - * This function polls a compression instance. - * - */ -static void sal_dc_polling(CpaInstanceHandle dcInstHandle) -{ - - gPollingDc = 1; - while (gPollingDc) - { - icp_sal_DcPollInstance(dcInstHandle, 0); - OS_SLEEP(10); - } - - sampleThreadExit(); -} - -/* - * This function checks the instance info. If the instance is - * required to be polled then it starts a polling thread. - */ -void sampleDcStartPolling(CpaInstanceHandle dcInstHandle) -{ - CpaInstanceInfo2 info2 = {0}; - CpaStatus status = CPA_STATUS_SUCCESS; - - status = cpaDcInstanceGetInfo2(dcInstHandle, &info2); - if ((status == CPA_STATUS_SUCCESS) && (info2.isPolled == CPA_TRUE)) - { - /* Start thread to poll instance */ - sampleThreadCreate(&gPollingThreadDc, sal_dc_polling, dcInstHandle); - } -} - -/* - * This function stops the thread polling the compression instance. - */ -void sampleDcStopPolling(void) -{ - gPollingDc = 0; - OS_SLEEP(10); -} - diff --git a/module/heqat/config/4xxx_dev0.conf b/module/heqat/config/4xxx_dev0.conf deleted file mode 100755 index 870318c..0000000 --- a/module/heqat/config/4xxx_dev0.conf +++ /dev/null @@ -1,182 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default value for FW Auth loading -FirmwareAuthEnabled = 1 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 64 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Default value for power management idle interrrupt delay -PmIdleInterruptDelay = 0 - -# This flag is to enable power management idle support -PmIdleSupport = 1 - -# This flag is to enable key protection technology -KptEnabled = 1 - -# Define the maximum SWK count per function can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerFn = 1 - -# Define the maximum SWK count per pasid can have -# Default value is 1, the maximum value is 128 -KptMaxSWKPerPASID = 1 - -# Define the maximum SWK lifetime in second -# Default value is 0 (eternal of life) -# The maximum value is 31536000 (one year) -KptMaxSWKLifetime = 31536000 - -# Flag to define whether to allow SWK to be shared among processes -# Default value is 0 (shared mode is off) -KptSWKShared = 0 - -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 1 -NumberDcInstances = 0 - -# Crypto - Kernel instance #0 -Cy0Name = "IPSec0" -Cy0IsPolled = 0 -Cy0CoreAffinity = 0 - -# Data Compression - Kernel instance #0 -Dc0Name = "IPComp0" -Dc0IsPolled = 0 -Dc0CoreAffinity = 0 - -############################################## -# ADI Section for Scalable IOV -############################################## -[SIOV] -NumberAdis = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 1 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 1 - -## Crypto - User instance #1 -#Cy1Name = "SSL1" -#Cy1IsPolled = 1 -## List of core affinities -#Cy1CoreAffinity = 2 -# -## Crypto - User instance #2 -#Cy2Name = "SSL2" -#Cy2IsPolled = 1 -## List of core affinities -#Cy2CoreAffinity = 3 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 diff --git a/module/heqat/config/4xxxvf_dev0.conf b/module/heqat/config/4xxxvf_dev0.conf deleted file mode 100755 index 3a7fa18..0000000 --- a/module/heqat/config/4xxxvf_dev0.conf +++ /dev/null @@ -1,134 +0,0 @@ -################################################################ -# This file is provided under a dual BSD/GPLv2 license. When using or -# redistributing this file, you may do so under either license. -# -# GPL LICENSE SUMMARY -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -# The full GNU General Public License is included in this distribution -# in the file called LICENSE.GPL. -# -# Contact Information: -# Intel Corporation -# -# BSD LICENSE -# -# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# version: QAT20.L.0.8.0-00071 -################################################################ -[GENERAL] -ServicesEnabled = asym;dc - -ConfigVersion = 2 - -#Default values for number of concurrent requests*/ -CyNumConcurrentSymRequests = 512 -CyNumConcurrentAsymRequests = 64 - -#Statistics, valid values: 1,0 -statsGeneral = 1 -statsDh = 1 -statsDrbg = 1 -statsDsa = 1 -statsEcc = 1 -statsKeyGen = 1 -statsDc = 1 -statsLn = 1 -statsPrime = 1 -statsRsa = 1 -statsSym = 1 - -# This flag is to enable SSF features (CNV and BnP) -StorageEnabled = 0 - -# Disable public key crypto and prime number -# services by specifying a value of 1 (default is 0) -PkeServiceDisabled = 0 - -# This flag is to enable device auto reset on heartbeat error -AutoResetOnError = 0 - -# Disable Address translation services -ATEnabled = 0 -############################################## -# Kernel Instances Section -############################################## -[KERNEL] -NumberCyInstances = 0 -NumberDcInstances = 0 - -############################################## -# User Process Instance Section -############################################## -[SSL] -NumberCyInstances = 1 -NumberDcInstances = 2 -NumProcesses = 1 -LimitDevAccess = 0 - -# Crypto - User instance #0 -Cy0Name = "SSL0" -Cy0IsPolled = 1 -# List of core affinities -Cy0CoreAffinity = 1 - -## Crypto - User instance #1 -#Cy1Name = "SSL1" -#Cy1IsPolled = 1 -## List of core affinities -#Cy1CoreAffinity = 2 - -# Data Compression - User instance #0 -Dc0Name = "Dc0" -Dc0IsPolled = 1 -# List of core affinities -Dc0CoreAffinity = 1 - -# Data Compression - User instance #1 -Dc1Name = "Dc1" -Dc1IsPolled = 1 -# List of core affinities -Dc1CoreAffinity = 2 - diff --git a/module/heqat/doc/CMakeLists.txt b/module/heqat/doc/CMakeLists.txt deleted file mode 100644 index c3dfd67..0000000 --- a/module/heqat/doc/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2022-2023 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -# Build Doxygen documentation -SET(DOXYGEN_MIN_VERSION "1.8.5") -find_package(Doxygen ${DOXYGEN_MIN_VERSION} REQUIRED) - -set(DOXYGEN_OUTPUT_DIR ${CMAKE_BINARY_DIR}/doxygen) -set(DOXYGEN_INDEX_FILE ${DOXYGEN_OUTPUT_DIR}/xml/indexl.html) -set(DOXYFILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in) -set(DOXYFILE_OUT ${CMAKE_BINARY_DIR}/Doxyfile) - -# Create Doxyfile -configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY) - -add_custom_command(OUTPUT ${DOXYGEN_INDEX_FILE} - COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE_OUT} - MAIN_DEPENDENCY ${DOXYFILE_OUT} ${DOXYFILE_IN} - COMMENT "Generating Doxygen documentation") - -add_custom_target(docs ALL DEPENDS ${DOXYGEN_INDEX_FILE}) - -install(DIRECTORY - ${CMAKE_BINARY_DIR}/doc/doxygen - DESTINATION doc) diff --git a/module/heqat/doc/Doxyfile.in b/module/heqat/doc/Doxyfile.in deleted file mode 100644 index 6bf8078..0000000 --- a/module/heqat/doc/Doxyfile.in +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright (C) 2022-2023 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -PROJECT_NAME = "Intel HE Acceleration Library for QAT" -PROJECT_BRIEF = "Intel Homomorphic Encryption Acceleration Library for QAT, accelerating the modular arithmetic operations used in partial homomorphic encryption on Intel QAT." - -OUTPUT_DIRECTORY = @CMAKE_BINARY_DIR@/doc/doxygen -INPUT = @CMAKE_SOURCE_DIR@/he_qat/include \ - @CMAKE_SOURCE_DIR@/misc \ - @CMAKE_SOURCE_DIR@/icp \ - @CMAKE_SOURCE_DIR@/samples \ - @CMAKE_SOURCE_DIR@/README.md -RECURSIVE = YES -USE_MDFILE_AS_MAINPAGE = @CMAKE_SOURCE_DIR@/README.md -USE_MATHJAX = YES -FULL_PATH_NAMES = NO - -GENERATE_XML = YES -EXTRACT_ALL = YES -EXTRACT_PRIVATE = NO -SHOW_NAMESPACES = YES -GENERATE_LATEX = YES - -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_IF_DOC_ERROR = YES -WARN_NO_PARAMDOC = YES -WARN_AS_ERROR = YES - -QUIET = NO - -SEARCHENGINE = YES -SERVER_BASED_SEARCH = NO diff --git a/module/heqat/doc/index.html b/module/heqat/doc/index.html deleted file mode 100644 index c344624..0000000 --- a/module/heqat/doc/index.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/module/heqat/doc/index.rst b/module/heqat/doc/index.rst deleted file mode 100644 index db1489b..0000000 --- a/module/heqat/doc/index.rst +++ /dev/null @@ -1,5 +0,0 @@ -## Intel HE Acceleration Library for QAT Documentation ## -.. toctree:: - api - -.. mdinclude:: ../README.md diff --git a/module/heqat/example/CMakeLists.txt b/module/heqat/example/CMakeLists.txt deleted file mode 100644 index 388f815..0000000 --- a/module/heqat/example/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -project(he_qat_example LANGUAGES C CXX) - -cmake_minimum_required(VERSION 3.13) - -set(CMAKE_CXX_STANDARD 11) -set(HE_QAT_HINT_DIR ${CMAKE_PREFIX_PATH}) -message(STATUS "CMAKE_PREFIX_PATH ${HE_QAT_HINT_DIR}") -# Example using source -find_package(HE_QAT 0.1.0 - HINTS ${HE_QAT_HINT_DIR} - REQUIRED) -if (NOT TARGET HE_QAT::he_qat) - message(FATAL_ERROR "TARGET HE_QAT::he_qat not found") -endif() - -find_package(OpenSSL REQUIRED) - -include(../icp/CMakeLists.txt) - -add_definitions(-fpermissive) -add_executable(example example.cpp) -target_include_directories(example PRIVATE ${ICP_INC_DIR}) -target_link_libraries(example PRIVATE HE_QAT::he_qat) -target_link_libraries(example PRIVATE qat_s) -target_link_libraries(example PRIVATE OpenSSL::SSL) diff --git a/module/heqat/example/README.md b/module/heqat/example/README.md deleted file mode 100644 index 9bd68d2..0000000 --- a/module/heqat/example/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Building and running - -``` -cmake -S . -B build -DCMAKE_PREFIX_PATH=../install/lib/cmake -cmake --build build -./build/example -``` diff --git a/module/heqat/example/example.cpp b/module/heqat/example/example.cpp deleted file mode 100644 index da19a99..0000000 --- a/module/heqat/example/example.cpp +++ /dev/null @@ -1,143 +0,0 @@ - -#include "he_qat_bn_ops.h" -#include "he_qat_context.h" -#include "he_qat_utils.h" -#include "cpa_sample_utils.h" - -#include -#include -#include -#include - -#define LEN_OF_1024_BITS 128 -#define LEN_OF_2048_BITS 256 -#define msb_CAN_BE_ZERO -1 -#define msb_IS_ONE 0 -#define EVEN_RND_NUM 0 -#define ODD_RND_NUM 1 -#define BATCH_SIZE 1 - -#include -struct timeval start_time, end_time; -double time_taken = 0.0; - -int main(int argc, const char** argv) { - const int bit_length = 4096; // 1024; - const size_t num_trials = 100; - - double avg_speed_up = 0.0; - double ssl_avg_time = 0.0; - double qat_avg_time = 0.0; - - double ssl_elapsed = 0.0; - double qat_elapsed = 0.0; - - HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; - - // Set up QAT runtime context - acquire_qat_devices(); - - // Set up OpenSSL context (as baseline) - BN_CTX* ctx = BN_CTX_new(); - BN_CTX_start(ctx); - - for (size_t mod = 0; mod < num_trials; mod++) { - BIGNUM* bn_mod = generateTestBNData(bit_length); - - if (!bn_mod) continue; - -#ifdef _DESTINY_DEBUG_VERBOSE - char* bn_str = BN_bn2hex(bn_mod); - printf("Generated modulus: %s num_bytes: %d num_bits: %d\n", bn_str, - BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); - OPENSSL_free(bn_str); -#endif - // bn_exponent in [0..bn_mod] - BIGNUM* bn_exponent = BN_new(); - if (!BN_rand_range(bn_exponent, bn_mod)) { - BN_free(bn_mod); - continue; - } - - BIGNUM* bn_base = generateTestBNData(bit_length); - - // Perform OpenSSL ModExp Op - BIGNUM* ssl_res = BN_new(); - gettimeofday(&start_time, NULL); - BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); - gettimeofday(&end_time, NULL); - time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; - time_taken = - (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; - ssl_elapsed = time_taken; - - if (!ERR_get_error()) { -#ifdef _DESTINY_DEBUG_VERBOSE - bn_str = BN_bn2hex(ssl_res); - printf("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", bn_str, - BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); - showHexBN(ssl_res, bit_length); - OPENSSL_free(bn_str); -#endif - } else { - printf("Modular exponentiation failed.\n"); - } - -#ifdef _DESTINY_DEBUG_VERBOSE - PRINT_DBG("\nStarting QAT bnModExp...\n"); -#endif - - // Perform QAT ModExp Op - BIGNUM* qat_res = BN_new(); - gettimeofday(&start_time, NULL); - for (unsigned int j = 0; j < BATCH_SIZE; j++) - status = bnModExpPerformOp(qat_res, bn_base, bn_exponent, bn_mod, - bit_length); - getBnModExpRequest(BATCH_SIZE); - gettimeofday(&end_time, NULL); - time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; - time_taken = - (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; - qat_elapsed = time_taken; - - ssl_avg_time = (mod * ssl_avg_time + ssl_elapsed) / (mod + 1); - qat_avg_time = - (mod * qat_avg_time + qat_elapsed / BATCH_SIZE) / (mod + 1); - avg_speed_up = - (mod * avg_speed_up + - (ssl_elapsed) / (qat_elapsed/BATCH_SIZE)) / (mod + 1); - - printf( - "Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", - (mod + 1), ssl_avg_time, qat_avg_time, avg_speed_up); - - if (HE_QAT_STATUS_SUCCESS != status) { - PRINT_ERR("\nQAT bnModExpOp failed\n"); - } -#ifdef _DESTINY_DEBUG_VERBOSE - else { - PRINT_DBG("\nQAT bnModExpOp finished\n"); - } -#endif - - if (BN_cmp(qat_res, ssl_res) != 0) - printf("\t** FAIL **\n"); - else - printf("\t** PASS **\n"); - - BN_free(ssl_res); - BN_free(qat_res); - - BN_free(bn_mod); - BN_free(bn_base); - BN_free(bn_exponent); - } - - // Tear down OpenSSL context - BN_CTX_end(ctx); - - // Tear down QAT runtime context - release_qat_devices(); - - return (int)status; -} diff --git a/module/heqat/he_qat/CMakeLists.txt b/module/heqat/he_qat/CMakeLists.txt deleted file mode 100644 index 563210b..0000000 --- a/module/heqat/he_qat/CMakeLists.txt +++ /dev/null @@ -1,106 +0,0 @@ - -set(HE_QAT_SRC ${HE_QAT_SRC_DIR}/he_qat_cb.c - ${HE_QAT_SRC_DIR}/he_qat_context.c - ${HE_QAT_SRC_DIR}/he_qat_utils.c -) - -list(APPEND HE_QAT_SRC ${HE_QAT_SRC_DIR}/he_qat_ops.c - ${HE_QAT_SRC_DIR}/he_qat_ctrl.c) - -if(HE_QAT_SHARED) - add_library(he_qat SHARED ${HE_QAT_SRC}) -else() - add_library(he_qat STATIC ${HE_QAT_SRC}) -endif() - -add_library(HE_QAT::he_qat ALIAS he_qat) -#add_library(he_qat SHARED ${HE_QAT_SRC}) - -target_include_directories(he_qat - PUBLIC $ #Public headers - PUBLIC $ #Public headers - PUBLIC $ #Public headers - PRIVATE ${COMMON_INC_DIR} #Private headers - PRIVATE ${ICP_INC_DIR} #Private headers -) - -install(DIRECTORY ${COMMON_INC_DIR}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ - FILES_MATCHING - PATTERN "*.hpp" - PATTERN "*.h") - -install(DIRECTORY ${HE_QAT_INC_DIR}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ - FILES_MATCHING - PATTERN "*.hpp" - PATTERN "*.h") - -target_link_directories(he_qat PUBLIC ${ICP_BUILDOUTPUT_PATH}) -target_link_libraries(he_qat PRIVATE OpenSSL::SSL Threads::Threads) -target_link_libraries(he_qat PRIVATE udev z) - -if(HE_QAT_MISC) - target_link_libraries(he_qat PRIVATE he_qat_misc) -endif() - -if(HE_QAT_SHARED) - target_link_libraries(he_qat PRIVATE qat_s usdm_drv_s) - target_link_libraries(he_qat PRIVATE cpa_sample_utils) -else() - heqat_create_archive(he_qat cpa_sample_utils) -endif() - -set_target_properties(he_qat PROPERTIES POSITION_INDEPENDENT_CODE ON) -set_target_properties(he_qat PROPERTIES VERSION ${HE_QAT_VERSION}) - -if(HE_QAT_DEBUG) - set_target_properties(he_qat PROPERTIES OUTPUT_NAME "he_qat_debug") -else() - set_target_properties(he_qat PROPERTIES OUTPUT_NAME "he_qat") -endif() - - -install(TARGETS he_qat DESTINATION ${CMAKE_INSTALL_LIBDIR}) - -include(CMakePackageConfigHelpers) - -# config cmake config and target file -set(HE_QAT_TARGET_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/cmake/he_qat-${HE_QAT_VERSION}/he_qatTargets.cmake) -set(HE_QAT_CONFIG_IN_FILENAME ${HE_QAT_CMAKE_PATH}/HE_QATConfig.cmake.in) -set(HE_QAT_CONFIG_FILENAME ${HE_QAT_ROOT_DIR}/cmake/he_qat-${HE_QAT_VERSION}/HE_QATConfig.cmake) -set(HE_QAT_CONFIG_VERSION_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/cmake/he_qat-${HE_QAT_VERSION}/HE_QATConfigVersion.cmake) -set(HE_QAT_CONFIG_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/he_qat-${HE_QAT_VERSION}/) - -install( - EXPORT he_qatTargets - NAMESPACE HE_QAT:: - DESTINATION ${HE_QAT_CONFIG_INSTALL_DIR} -) - -write_basic_package_version_file( - ${HE_QAT_CONFIG_VERSION_FILENAME} - VERSION ${HE_QAT_VERSION} - COMPATIBILITY ExactVersion -) - -configure_package_config_file( - ${HE_QAT_CONFIG_IN_FILENAME} ${HE_QAT_CONFIG_FILENAME} - INSTALL_DESTINATION ${HE_QAT_CONFIG_INSTALL_DIR} -) - -install( - TARGETS he_qat - EXPORT he_qatTargets - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - ) - -install(FILES ${HE_QAT_CONFIG_FILENAME} - ${HE_QAT_CONFIG_VERSION_FILENAME} - DESTINATION ${HE_QAT_CONFIG_INSTALL_DIR}) - -export(EXPORT he_qatTargets - FILE ${HE_QAT_TARGET_FILENAME}) - diff --git a/module/heqat/he_qat/he_qat_cb.c b/module/heqat/he_qat/he_qat_cb.c deleted file mode 100644 index 80bae5e..0000000 --- a/module/heqat/he_qat/he_qat_cb.c +++ /dev/null @@ -1,117 +0,0 @@ -/// @file he_qat_cb.c - -// QAT-API headers -#include -#include - -// C support libraries -#include -#include - -// Local headers -#include "he_qat_types.h" - -// Global variables -static pthread_mutex_t response_mutex; ///< It protects against race condition on response_count due to concurrent callback events. -extern volatile unsigned long response_count; ///< It counts the number of requests completed by the accelerator. - -/// @brief Callback implementation for the API HE_QAT_BIGNUMModExp(...) -/// Callback function for the interface HE_QAT_BIGNUMModExp(). It performs -/// any data post-processing required after the modular exponentiation. -/// @param[in] pCallbackTag work request package containing the original input data and other resources for post-processing. -/// @param[in] status CPA_STATUS of the performed operation, e.g. CyLnModExp(). -/// @param[in] pOpData original input data passed to accelerator to perform the target operation (cannot be NULL). -/// @param[out] pOut output returned by the accelerator after executing the target operation. -void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut) -{ - HE_QAT_TaskRequest* request = NULL; - - // Check if input data for the op is available and do something - if (NULL != pCallbackTag) { - // Read request data - request = (HE_QAT_TaskRequest*)pCallbackTag; - - pthread_mutex_lock(&response_mutex); - // Global track of reponses by accelerator - response_count += 1; - pthread_mutex_unlock(&response_mutex); - - pthread_mutex_lock(&request->mutex); - // Collect the device output in pOut - request->op_status = status; - if (CPA_STATUS_SUCCESS == status) { - if (pOpData == request->op_data) { - // Mark request as complete or ready to be used - request->request_status = HE_QAT_STATUS_READY; - - BIGNUM* r = BN_bin2bn(request->op_result.pData, - request->op_result.dataLenInBytes, - (BIGNUM*)request->op_output); - if (NULL == r) - request->request_status = HE_QAT_STATUS_FAIL; -#ifdef HE_QAT_PERF - gettimeofday(&request->end, NULL); -#endif - } else { - request->request_status = HE_QAT_STATUS_FAIL; - } - } - // Make it synchronous and blocking - pthread_cond_signal(&request->ready); - pthread_mutex_unlock(&request->mutex); -#ifdef HE_QAT_SYNC_MODE - COMPLETE((struct COMPLETION_STRUCT*)&request->callback); -#endif - } - - return; -} - -/// @brief Callback implementation for the API HE_QAT_bnModExp(...) -/// Callback function for the interface HE_QAT_bnModExp(). It performs -/// any data post-processing required after the modular exponentiation. -/// @param[in] pCallbackTag work request package containing the original input data and other resources for post-processing. -/// @param[in] status CPA_STATUS of the performed operation, e.g. CyLnModExp(). -/// @param[in] pOpData original input data passed to accelerator to perform the target operation (cannot be NULL). -/// @param[out] pOut output returned by the accelerator after executing the target operation. -void HE_QAT_bnModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut) -{ - HE_QAT_TaskRequest* request = NULL; - - // Check if input data for the op is available and do something - if (NULL != pCallbackTag) { - // Read request data - request = (HE_QAT_TaskRequest*)pCallbackTag; - - pthread_mutex_lock(&response_mutex); - // Global track of reponses by accelerator - response_count += 1; - pthread_mutex_unlock(&response_mutex); - - pthread_mutex_lock(&request->mutex); - // Collect the device output in pOut - request->op_status = status; - if (CPA_STATUS_SUCCESS == status) { - if (pOpData == request->op_data) { - // Mark request as complete or ready to be used - request->request_status = HE_QAT_STATUS_READY; - // Copy compute results to output destination - memcpy(request->op_output, request->op_result.pData, - request->op_result.dataLenInBytes); -#ifdef HE_QAT_PERF - gettimeofday(&request->end, NULL); -#endif - } else { - request->request_status = HE_QAT_STATUS_FAIL; - } - } - // Make it synchronous and blocking - pthread_cond_signal(&request->ready); - pthread_mutex_unlock(&request->mutex); -#ifdef HE_QAT_SYNC_MODE - COMPLETE((struct COMPLETION_STRUCT*)&request->callback); -#endif - } - - return; -} diff --git a/module/heqat/he_qat/he_qat_context.c b/module/heqat/he_qat/he_qat_context.c deleted file mode 100644 index 6d2de68..0000000 --- a/module/heqat/he_qat/he_qat_context.c +++ /dev/null @@ -1,304 +0,0 @@ -/// @file he_qat_context.c - -#define _GNU_SOURCE - -#include "he_qat_types.h" -#include "he_qat_context.h" - -#include - -//#include - -//#include -//#include -//#include -#include -#include - -#include "cpa_sample_utils.h" -#include "icp_sal_user.h" -#include "icp_sal_poll.h" - -#ifdef USER_SPACE -#define MAX_INSTANCES 1024 -#else -#define MAX_INSTANCES 1 -#endif - -static volatile int context_state = 0; - -// Global variable declarations -static pthread_t buffer_manager; -static pthread_t he_qat_runner; -static HE_QAT_Inst he_qat_instances[HE_QAT_NUM_ACTIVE_INSTANCES]; -static pthread_attr_t he_qat_inst_attr[HE_QAT_NUM_ACTIVE_INSTANCES]; -static HE_QAT_InstConfig he_qat_inst_config[HE_QAT_NUM_ACTIVE_INSTANCES]; -static HE_QAT_Config* he_qat_config = NULL; - -extern HE_QAT_RequestBuffer he_qat_buffer; -extern HE_QAT_OutstandingBuffer outstanding; - - -/*********** Internal Services ***********/ -// Start scheduler of work requests (consumer) -extern void* schedule_requests(void* state); -// Activate cpaCyInstances to run on background and poll responses from QAT accelerator -extern void* start_instances(void* _inst_config); -// Stop a running group of cpaCyInstances started with the "start_instances" service -extern void stop_instances(HE_QAT_Config* _config); -// Stop running individual QAT instances from a list of cpaCyInstances (called by "stop_instances") -extern void stop_perform_op(void* _inst_config, unsigned num_inst); -// Activate a cpaCyInstance to run on background and poll responses from QAT accelerator -// WARNING: Deprecated when "start_instances" becomes default. -extern void* start_perform_op(void* _inst_config); - -static CpaInstanceHandle handle = NULL; - -static CpaInstanceHandle get_qat_instance() { - static CpaInstanceHandle cyInstHandles[MAX_INSTANCES]; - static Cpa16U numInstances = 0; - static Cpa16U nextInstance = 0; - CpaStatus status = CPA_STATUS_SUCCESS; - CpaInstanceInfo2 info = {0}; - - if (0 == numInstances) { - //*pCyInstHandle = NULL; - status = cpaCyGetNumInstances(&numInstances); - if (numInstances >= MAX_INSTANCES) { - numInstances = MAX_INSTANCES; - } - if (numInstances >= HE_QAT_NUM_ACTIVE_INSTANCES) { - numInstances = HE_QAT_NUM_ACTIVE_INSTANCES; - } - - printf("Found %d CyInstances.\n", numInstances); - - if ((status == CPA_STATUS_SUCCESS) && (numInstances > 0)) { - status = cpaCyGetInstances(numInstances, cyInstHandles); - // List instances and their characteristics - for (unsigned int i = 0; i < numInstances; i++) { - status = cpaCyInstanceGetInfo2(cyInstHandles[i],&info); - if (CPA_STATUS_SUCCESS == status) { - printf("Vendor Name: %s\n",info.vendorName); - printf("Part Name: %s\n",info.partName); - printf("Inst Name: %s\n",info.instName); - printf("Inst ID: %s\n",info.instID); - printf("Node Affinity: %u\n",info.nodeAffinity); - printf("Physical Instance:\n"); - printf("\tpackageId: %d\n",info.physInstId.packageId); - printf("\tacceleratorId: %d\n",info.physInstId.acceleratorId); - printf("\texecutionEngineId: %d\n",info.physInstId.executionEngineId); - printf("\tbusAddress: %d\n",info.physInstId.busAddress); - printf("\tkptAcHandle: %d\n",info.physInstId.kptAcHandle); - } - } - printf("Next Instance: %d.\n", nextInstance); - if (status == CPA_STATUS_SUCCESS) - return cyInstHandles[nextInstance]; - //*pCyInstHandle = cyInstHandles[0]; - } - - if (0 == numInstances) { - PRINT_ERR("No instances found for 'SSL'\n"); - PRINT_ERR("Please check your section names"); - PRINT_ERR(" in the config file.\n"); - PRINT_ERR("Also make sure to use config file version 2.\n"); - } - - return NULL; - } - - nextInstance = ((nextInstance + 1) % numInstances); - printf("Next Instance: %d.\n", nextInstance); - return cyInstHandles[nextInstance]; -} - -/// @brief -/// Acquire QAT instances and set up QAT execution environment. -HE_QAT_STATUS acquire_qat_devices() { - CpaStatus status = CPA_STATUS_FAIL; - - // Initialize QAT memory pool allocator - status = qaeMemInit(); - if (CPA_STATUS_SUCCESS != status) { - printf("Failed to initialized memory driver.\n"); - return HE_QAT_STATUS_FAIL; // HEQAT_STATUS_ERROR - } -#ifdef _DESTINY_DEBUG_VERBOSE - printf("QAT memory successfully initialized.\n"); -#endif - - // Not sure if for multiple instances the id will need to be specified, e.g. - // "SSL1" - status = icp_sal_userStartMultiProcess("SSL", CPA_FALSE); - if (CPA_STATUS_SUCCESS != status) { - printf("Failed to start SAL user process SSL\n"); - qaeMemDestroy(); - return HE_QAT_STATUS_FAIL; // HEQAT_STATUS_ERROR - } -#ifdef _DESTINY_DEBUG_VERBOSE - printf("SAL user process successfully started.\n"); -#endif - - // Potential out-of-scope hazard for segmentation fault - CpaInstanceHandle _inst_handle[HE_QAT_NUM_ACTIVE_INSTANCES]; // = NULL; - // TODO: @fdiasmor Create a CyGetInstance that retrieves more than one. - // sampleCyGetInstance(&_inst_handle); - for (unsigned int i = 0; i < HE_QAT_NUM_ACTIVE_INSTANCES; i++) { - _inst_handle[i] = get_qat_instance(); - if (_inst_handle[i] == NULL) { - printf("Failed to find QAT endpoints.\n"); - return HE_QAT_STATUS_FAIL; - } - } - - // sampleCyGetInstance(&handle); - // if (handle == NULL) { - // printf("Failed to find QAT endpoints.\n"); - // return HE_QAT_STATUS_FAIL; - //} -#ifdef _DESTINY_DEBUG_VERBOSE - printf("Found QAT endpoints.\n"); -#endif - - // Initialize QAT buffer synchronization attributes - he_qat_buffer.count = 0; - he_qat_buffer.next_free_slot = 0; - he_qat_buffer.next_data_slot = 0; - - // Initialize QAT memory buffer - for (int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { - he_qat_buffer.data[i] = NULL; - } - - // Initialize QAT outstanding buffers - outstanding.busy_count = 0; - outstanding.next_free_buffer = 0; - outstanding.next_ready_buffer = 0; - for (int i = 0; i < HE_QAT_BUFFER_COUNT; i++) { - outstanding.free_buffer[i] = 1; - outstanding.ready_buffer[i] = 0; - outstanding.buffer[i].count = 0; - outstanding.buffer[i].next_free_slot = 0; - outstanding.buffer[i].next_data_slot = 0; - outstanding.buffer[i].next_data_out = 0; - for (int j = 0; j < HE_QAT_BUFFER_SIZE; j++) { - outstanding.buffer[i].data[j] = NULL; - } - pthread_mutex_init(&outstanding.buffer[i].mutex, NULL); - pthread_cond_init(&outstanding.buffer[i].any_more_data, NULL); - pthread_cond_init(&outstanding.buffer[i].any_free_slot, NULL); - } - pthread_mutex_init(&outstanding.mutex, NULL); - pthread_cond_init(&outstanding.any_free_buffer, NULL); - pthread_cond_init(&outstanding.any_ready_buffer, NULL); - - // Creating QAT instances (consumer threads) to process op requests - pthread_attr_t attr; - cpu_set_t cpus; - // for (int i = 0; i < HE_QAT_SYNC; i++) { - for (int i = 0; i < HE_QAT_NUM_ACTIVE_INSTANCES; i++) { - CPU_ZERO(&cpus); - CPU_SET(i, &cpus); - pthread_attr_init(&he_qat_inst_attr[i]); - pthread_attr_setaffinity_np(&he_qat_inst_attr[i], sizeof(cpu_set_t), - &cpus); - - // configure thread - // HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) - // malloc(sizeof(QATInstConfig)); - // if (config == NULL) return HE_QAT_FAIL; - he_qat_inst_config[i].active = 0; // HE_QAT_STATUS_INACTIVE - he_qat_inst_config[i].polling = 0; // HE_QAT_STATUS_INACTIVE - he_qat_inst_config[i].running = 0; - he_qat_inst_config[i].status = CPA_STATUS_FAIL; - // he_qat_inst_config[i].mutex = PTHREAD_MUTEX_INITIALIZER; - pthread_mutex_init(&he_qat_inst_config[i].mutex, NULL); - // he_qat_inst_config[i].ready = PTHREAD_COND_INITIALIZER; - pthread_cond_init(&he_qat_inst_config[i].ready, NULL); - he_qat_inst_config[i].inst_handle = _inst_handle[i]; - he_qat_inst_config[i].inst_id = i; - he_qat_inst_config[i].attr = &he_qat_inst_attr[i]; -// pthread_create(&he_qat_instances[i], he_qat_inst_config[i].attr, -// start_perform_op, (void*)&he_qat_inst_config[i]); - } - - he_qat_config = (HE_QAT_Config *) malloc(sizeof(HE_QAT_Config)); - he_qat_config->inst_config = he_qat_inst_config; - he_qat_config->count = HE_QAT_NUM_ACTIVE_INSTANCES; - he_qat_config->running = 0; - he_qat_config->active = 0; - - // Work on this - // pthread_create(&he_qat_instances[0], NULL, start_instances, (void*)he_qat_config); - pthread_create(&he_qat_runner, NULL, start_instances, (void*)he_qat_config); -#ifdef _DESTINY_DEBUG_VERBOSE - printf("Created processing threads.\n"); -#endif - - // Dispatch the qat instances to run independently in the background -// for (int i = 0; i < HE_QAT_NUM_ACTIVE_INSTANCES; i++) { -// pthread_detach(he_qat_instances[i]); -// } - // Dispatch all QAT instances in a single thread -// pthread_detach(he_qat_instances[0]); - pthread_detach(he_qat_runner); -#ifdef _DESTINY_DEBUG_VERBOSE - printf("Detached processing threads.\n"); -#endif - - // Set context state to active - context_state = 1; - - // Launch buffer manager thread to schedule incoming requests - if (0 != pthread_create(&buffer_manager, NULL, schedule_requests, - (void*)&context_state)) { - release_qat_devices(); - printf( - "Failed to complete QAT initialization while creating buffer " - "manager thread.\n"); - return HE_QAT_STATUS_FAIL; - } - - if (0 != pthread_detach(buffer_manager)) { - release_qat_devices(); - printf( - "Failed to complete QAT initialization while launching buffer " - "manager thread.\n"); - return HE_QAT_STATUS_FAIL; - } - - return HE_QAT_STATUS_SUCCESS; -} - -/// @brief -/// Release QAT instances and tear down QAT execution environment. -HE_QAT_STATUS release_qat_devices() { - CpaStatus status = CPA_STATUS_FAIL; - - if (0 == context_state) return HE_QAT_STATUS_SUCCESS; - - stop_instances(he_qat_config); - //stop_perform_op(he_qat_inst_config, HE_QAT_NUM_ACTIVE_INSTANCES); -#ifdef _DESTINY_DEBUG_VERBOSE - printf("Stopped polling and processing threads.\n"); -#endif - - // Deactivate context (this will cause the buffer manager thread to be - // terminated) - context_state = 0; - - // Stop QAT SSL service - icp_sal_userStop(); -#ifdef _DESTINY_DEBUG_VERBOSE - printf("Stopped SAL user process.\n"); -#endif - - // Release QAT allocated memory - qaeMemDestroy(); -#ifdef _DESTINY_DEBUG_VERBOSE - printf("Release QAT memory.\n"); -#endif - - return HE_QAT_STATUS_SUCCESS; -} diff --git a/module/heqat/he_qat/he_qat_ctrl.c b/module/heqat/he_qat/he_qat_ctrl.c deleted file mode 100644 index 76d60d8..0000000 --- a/module/heqat/he_qat/he_qat_ctrl.c +++ /dev/null @@ -1,817 +0,0 @@ -/// @file he_qat_ctrl.c - -// QAT-API headers -#include "cpa.h" -#include "cpa_cy_im.h" -#include "cpa_cy_ln.h" -#include "icp_sal_poll.h" -#include "cpa_sample_utils.h" - -// Global variables used to hold measured performance numbers. -#ifdef HE_QAT_PERF -#include -struct timeval start_time, end_time; -double time_taken = 0.0; -#endif - -// C support libraries -#include -#include -#include -#include - -// Loca headers -#include "he_qat_types.h" -#include "he_qat_bn_ops.h" -#include "he_qat_gconst.h" - -// Warn user on selected execution mode -#ifdef HE_QAT_SYNC_MODE -#pragma message "Synchronous execution mode." -#else -#pragma message "Asynchronous execution mode." -#endif - -// Global buffer for the runtime environment -HE_QAT_RequestBuffer he_qat_buffer; ///< This the internal buffer that holds and serializes the requests to the accelerator. -HE_QAT_OutstandingBuffer outstanding; ///< This is the data structure that holds outstanding requests from separate active threads calling the API. -volatile unsigned long response_count = 0; ///< Counter of processed requests and it is used to help control throttling. -static volatile unsigned long request_count = 0; ///< Counter of received requests and it is used to help control throttling. -static unsigned long request_latency = 0; ///< Variable used to hold measured averaged latency of requests (currently unused). -static unsigned long restart_threshold = NUM_PKE_SLICES; ///< Number of concurrent requests allowed to be sent to accelerator at once. -static unsigned long max_pending = (NUM_PKE_SLICES * 2 * HE_QAT_NUM_ACTIVE_INSTANCES); ///< Number of requests sent to the accelerator that are pending completion. - -/// @brief Populate internal buffer with incoming requests from API calls. -/// @details This function is called from the main APIs to submit requests to -/// a shared internal buffer for processing on QAT. It is a thread-safe implementation -/// of the producer for the either the internal buffer or the outstanding buffer to -/// host incoming requests. Depending on the buffer type, the submitted request -/// is either ready to be scheduled or to be processed by the accelerator. -/// @param[out] _buffer Either `he_qat_buffer` or `outstanding` buffer. -/// @param[in] args Work request packaged in a custom data structure. -void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { -#ifdef HE_QAT_DEBUG - printf("Lock write request\n"); -#endif - pthread_mutex_lock(&_buffer->mutex); - -#ifdef HE_QAT_DEBUG - printf("Wait lock write request. [buffer size: %d]\n", _buffer->count); -#endif - while (_buffer->count >= HE_QAT_BUFFER_SIZE) - pthread_cond_wait(&_buffer->any_free_slot, &_buffer->mutex); - - assert(_buffer->count < HE_QAT_BUFFER_SIZE); - - _buffer->data[_buffer->next_free_slot++] = args; - - _buffer->next_free_slot %= HE_QAT_BUFFER_SIZE; - _buffer->count++; - - pthread_cond_signal(&_buffer->any_more_data); - pthread_mutex_unlock(&_buffer->mutex); - -#ifdef HE_QAT_DEBUG - printf("Unlocked write request. [buffer size: %d]\n", _buffer->count); -#endif -} - -/// @brief Populates internal buffer with a list of work request. -/// @details This function is called by the request scheduler thread. It is a thread-safe implementation of the producer for the shared internal request buffer. This buffer stores and serializes the offloading of requests that are ready to be processed by the accelerator. -/// @param[out] _buffer reference pointer to the internal buffer `he_qat_buffer`. -/// @param[in] _requests list of requests retrieved from the buffer (`outstanding`) holding outstanding requests. -static void submit_request_list(HE_QAT_RequestBuffer* _buffer, - HE_QAT_TaskRequestList* _requests) { -#ifdef HE_QAT_DEBUG - printf("Lock submit request list\n"); -#endif - if (0 == _requests->count) return; - - pthread_mutex_lock(&_buffer->mutex); - -#ifdef HE_QAT_DEBUG - printf( - "Wait lock submit request list. [internal buffer size: %d] [num " - "requests: %u]\n", - _buffer->count, _requests->count); -#endif - - // Wait until buffer can accomodate the number of input requests - while (_buffer->count >= HE_QAT_BUFFER_SIZE || - (HE_QAT_BUFFER_SIZE - _buffer->count) < _requests->count) - pthread_cond_wait(&_buffer->any_free_slot, &_buffer->mutex); - - assert(_buffer->count < HE_QAT_BUFFER_SIZE); - assert(_requests->count <= (HE_QAT_BUFFER_SIZE - _buffer->count)); - - for (unsigned int i = 0; i < _requests->count; i++) { - _buffer->data[_buffer->next_free_slot++] = _requests->request[i]; - _buffer->next_free_slot %= HE_QAT_BUFFER_SIZE; - _requests->request[i] = NULL; - } - _buffer->count += _requests->count; - _requests->count = 0; - - pthread_cond_signal(&_buffer->any_more_data); - pthread_mutex_unlock(&_buffer->mutex); -#ifdef HE_QAT_DEBUG - printf("Unlocked submit request list. [internal buffer size: %d]\n", - _buffer->count); -#endif -} - - -/// @brief Retrive single request from internal buffer. -/// @details Thread-safe consumer implementation for the shared request buffer. -/// Read request from internal buffer `he_qat_buffer` to finally offload the request to be processed by QAT devices. -/// Supported in single-threaded or multi-threaded mode. -/// @param[in] _buffer buffer of type HE_QAT_RequestBuffer, typically the internal buffer in current implementation. -/// @retval single work request in HE_QAT_TaskRequest data structure. -static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) -{ - void* item = NULL; - static unsigned int counter = 0; - - pthread_mutex_lock(&_buffer->mutex); - -#ifdef HE_QAT_DEBUG - printf("Wait lock read request. [internal buffer size: %d] Request #%u\n", - _buffer->count, counter++); -#endif - // Wait while buffer is empty - while (_buffer->count <= 0) - pthread_cond_wait(&_buffer->any_more_data, &_buffer->mutex); - - assert(_buffer->count > 0); - - item = _buffer->data[_buffer->next_data_slot++]; - - _buffer->next_data_slot %= HE_QAT_BUFFER_SIZE; - _buffer->count--; - - pthread_cond_signal(&_buffer->any_free_slot); - pthread_mutex_unlock(&_buffer->mutex); - -#ifdef HE_QAT_DEBUG - printf("Unlocked read request. [internal buffer count: %d]\n", - _buffer->count); -#endif - - return (HE_QAT_TaskRequest*)(item); -} - -/// @brief Retrieve multiple requests from the outstanding buffer. -/// @details Thread-safe consumer implementation for the outstanding request buffer. -/// Read requests from outstanding buffer (requests ready to be scheduled) to later pass -/// them to the internal buffer `he_qat_buffer`. As those requests move from the outstanding -/// buffer into the internal buffer, their state changes from ready-to-be-scheduled to -/// ready-to-be-processed. This function is supported both in single-threaded or multi-threaded mode. -/// @param[out] _requests list of requests retrieved from internal buffer. -/// @param[in] _buffer buffer of type HE_QAT_RequestBuffer, typically the internal buffer in current implementation. -/// @param[in] max_requests maximum number of requests to retrieve from internal buffer, if available. -static void read_request_list(HE_QAT_TaskRequestList* _requests, - HE_QAT_RequestBuffer* _buffer, unsigned int max_requests) { - if (NULL == _requests) return; - - pthread_mutex_lock(&_buffer->mutex); - - // Wait while buffer is empty - while (_buffer->count <= 0) - pthread_cond_wait(&_buffer->any_more_data, &_buffer->mutex); - - assert(_buffer->count > 0); - // assert(_buffer->count <= HE_QAT_BUFFER_SIZE); - - unsigned int count = (_buffer->count < max_requests) ? _buffer->count : max_requests; - - //for (unsigned int i = 0; i < _buffer->count; i++) { - for (unsigned int i = 0; i < count; i++) { - _requests->request[i] = _buffer->data[_buffer->next_data_slot++]; - _buffer->next_data_slot %= HE_QAT_BUFFER_SIZE; - } - //_requests->count = _buffer->count; - //_buffer->count = 0; - _requests->count = count; - _buffer->count -= count; - - pthread_cond_signal(&_buffer->any_free_slot); - pthread_mutex_unlock(&_buffer->mutex); - - return; -} - -/// @brief Read requests from the outstanding buffer. -/// @details Thread-safe consumer implementation for the outstanding request buffer. -/// Retrieve work requests from outstanding buffer (requests ready to be scheduled) to later on pass them to the internal buffer `he_qat_buffer`. As those requests move from the outstanding buffer into the internal buffer, their state changes from ready-to-be-scheduled to ready-to-be-processed. -/// This function is supported in single-threaded or multi-threaded mode. -/// @param[out] _requests list of work requests retrieved from outstanding buffer. -/// @param[in] _outstanding_buffer outstanding buffer holding requests in ready-to-be-scheduled state. -/// @param[in] max_requests maximum number of requests to retrieve from outstanding buffer if available. -static void pull_outstanding_requests(HE_QAT_TaskRequestList* _requests, HE_QAT_OutstandingBuffer* _outstanding_buffer, unsigned int max_num_requests) -{ - if (NULL == _requests) return; - _requests->count = 0; - - // for now, only one thread can change next_ready_buffer - // so no need for sync tools - - // Select an outstanding buffer to pull requests and add them into the - // processing queue (internal buffer) - pthread_mutex_lock(&_outstanding_buffer->mutex); - // Wait until next outstanding buffer becomes available for use - while (outstanding.busy_count <= 0) - pthread_cond_wait(&_outstanding_buffer->any_ready_buffer, - &_outstanding_buffer->mutex); - - int any_ready = 0; - unsigned int index = _outstanding_buffer->next_ready_buffer; // no fairness - for (unsigned int i = 0; i < HE_QAT_BUFFER_COUNT; i++) { - index = i; // ensure fairness - if (_outstanding_buffer->ready_buffer[index] && - _outstanding_buffer->buffer[index] - .count) { // sync with mutex at interface - any_ready = 1; - break; - } - // index = (index + 1) % HE_QAT_BUFFER_COUNT; - } - // Ensures it gets picked once only - pthread_mutex_unlock(&_outstanding_buffer->mutex); - - if (!any_ready) return; - - // Extract outstanding requests from outstanding buffer - // (this is the only function that reads from outstanding buffer, - // from a single thread) - pthread_mutex_lock(&_outstanding_buffer->buffer[index].mutex); - - // This conditional waiting may not be required - // Wait while buffer is empty - while (_outstanding_buffer->buffer[index].count <= 0) { - pthread_cond_wait(&_outstanding_buffer->buffer[index].any_more_data, - &_outstanding_buffer->buffer[index].mutex); - } - assert(_outstanding_buffer->buffer[index].count > 0); - - unsigned int num_requests = - (_outstanding_buffer->buffer[index].count < max_num_requests) - ? _outstanding_buffer->buffer[index].count - : max_num_requests; - - assert(num_requests <= HE_QAT_BUFFER_SIZE); - - for (unsigned int i = 0; i < num_requests; i++) { - _requests->request[i] = - _outstanding_buffer->buffer[index] - .data[_outstanding_buffer->buffer[index].next_data_slot]; - _outstanding_buffer->buffer[index].count--; - _outstanding_buffer->buffer[index].next_data_slot++; - _outstanding_buffer->buffer[index].next_data_slot %= HE_QAT_BUFFER_SIZE; - } - _requests->count = num_requests; - - pthread_cond_signal(&_outstanding_buffer->buffer[index].any_free_slot); - pthread_mutex_unlock(&_outstanding_buffer->buffer[index].mutex); - - // --------------------------------------------------------------------------- - // Notify there is an outstanding buffer in ready for the processing queue - // pthread_mutex_lock(&_outstanding_buffer->mutex); - // - // _outstanding_buffer->ready_count--; - // _outstanding_buffer->ready_buffer[index] = 0; - // - // pthread_cond_signal(&_outstanding_buffer->any_free_buffer); - // pthread_mutex_unlock(&_outstanding_buffer->mutex); - - return; -} - -/// @brief Schedule outstanding requests to the internal buffer and be ready for processing. -/// @details Schedule outstanding requests from outstanding buffers to the internal buffer, -/// from which requests are ready to be submitted to the device for processing. -/// @param[in] state A volatile integer variable used to activate (val>0) or -/// disactive (val=0) the scheduler. -void* schedule_requests(void* state) { - if (NULL == state) { - printf("Failed at buffer_manager: argument is NULL.\n"); - pthread_exit(NULL); - } - - int* active = (int*)state; - - HE_QAT_TaskRequestList outstanding_requests; - for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { - outstanding_requests.request[i] = NULL; - } - outstanding_requests.count = 0; - - // this thread should receive signal from context to exit - while (*active) { - // Collect a set of requests from the outstanding buffer - pull_outstanding_requests(&outstanding_requests, &outstanding, - HE_QAT_BUFFER_SIZE); - // Submit them to the HE QAT buffer for offloading - submit_request_list(&he_qat_buffer, &outstanding_requests); - } - - pthread_exit(NULL); -} - -/// @brief Poll responses from a specific QAT instance. -/// @param[in] _inst_config Instance configuration containing the parameter -/// values to start and poll responses from the accelerator. -static void* start_inst_polling(void* _inst_config) { - if (NULL == _inst_config) { - printf( - "Failed at start_inst_polling: argument is NULL.\n"); //,__FUNC__); - pthread_exit(NULL); - } - - HE_QAT_InstConfig* config = (HE_QAT_InstConfig*)_inst_config; - - if (NULL == config->inst_handle) return NULL; - -#ifdef HE_QAT_DEBUG - printf("Instance ID %d Polling\n",config->inst_id); -#endif - - // What is harmful for polling without performing any operation? - config->polling = 1; - while (config->polling) { - icp_sal_CyPollInstance(config->inst_handle, 0); - OS_SLEEP(50); - } - - pthread_exit(NULL); -} - -/// @brief -/// Initialize and start multiple instances, their polling thread, -/// and a single processing thread. -/// -/// @details -/// It initializes multiple QAT instances and launches their respective independent -/// polling threads that will listen to responses to requests sent to the accelerators -/// concurrently. Then, it becomes the thread that collect the incoming requests stored -/// in a shared buffer and send them to the accelerator for processing. This is the only -/// processing thread for requests handled by multiple instances -- unlike when using -/// multiple instances with the `start_perform_op` function, in which case each instance -/// has a separate processing thread. The implementation of the multiple instance support -/// using `start_perform_op` is obsolete and slower. The way is using this function, which -/// delivers better performance. The scheduling of request offloads uses a -/// round-robin approach. It collects multiple requests from the internal buffer and then -/// send them to the multiple accelerator instances to process in a round-robin fashion. -/// It was designed to support processing requests of different operation types but -/// currently only supports Modular Exponentiation. -/// -/// @param[in] _config Data structure containing the configuration of multiple instances. -void* start_instances(void* _config) { - static unsigned int instance_count = 0; - static unsigned int next_instance = 0; - - if (NULL == _config) { - printf("Failed in start_instances: _config is NULL.\n"); - pthread_exit(NULL); - } - - HE_QAT_Config* config = (HE_QAT_Config*)_config; - instance_count = config->count; - - printf("Instance Count: %d\n",instance_count); - pthread_t* polling_thread = (pthread_t *) malloc(sizeof(pthread_t)*instance_count); - if (NULL == polling_thread) { - printf("Failed in start_instances: polling_thread is NULL.\n"); - pthread_exit(NULL); - } - unsigned* request_count_per_instance = (unsigned *) malloc(sizeof(unsigned)*instance_count); - if (NULL == request_count_per_instance) { - printf("Failed in start_instances: polling_thread is NULL.\n"); - pthread_exit(NULL); - } - for (unsigned i = 0; i < instance_count; i++) { - request_count_per_instance[i] = 0; - } - - CpaStatus status = CPA_STATUS_FAIL; - - for (unsigned int j = 0; j < config->count; j++) { - // Start from zero or restart after stop_perform_op - pthread_mutex_lock(&config->inst_config[j].mutex); - while (config->inst_config[j].active) - pthread_cond_wait(&config->inst_config[j].ready, - &config->inst_config[j].mutex); - - // assert(0 == config->active); - // assert(NULL == config->inst_handle); - - status = cpaCyStartInstance(config->inst_config[j].inst_handle); - config->inst_config[j].status = status; - if (CPA_STATUS_SUCCESS == status) { - printf("Cpa CyInstance has successfully started.\n"); - status = - cpaCySetAddressTranslation(config->inst_config[j].inst_handle, - sampleVirtToPhys); - } - - pthread_cond_signal(&config->inst_config[j].ready); - pthread_mutex_unlock(&config->inst_config[j].mutex); - - if (CPA_STATUS_SUCCESS != status) pthread_exit(NULL); - - printf("Instance ID: %d\n",config->inst_config[j].inst_id); - - // Start QAT instance and start polling - //pthread_t polling_thread; - if (pthread_create(&polling_thread[j], config->inst_config[j].attr, start_inst_polling, - (void*)&(config->inst_config[j])) != 0) { - printf("Failed at creating and starting polling thread.\n"); - pthread_exit(NULL); - } - - if (pthread_detach(polling_thread[j]) != 0) { - printf("Failed at detaching polling thread.\n"); - pthread_exit(NULL); - } - - config->inst_config[j].active = 1; - config->inst_config[j].running = 1; - - } // for loop - - HE_QAT_TaskRequestList outstanding_requests; - for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { - outstanding_requests.request[i] = NULL; - } - outstanding_requests.count = 0; - - config->running = 1; - config->active = 1; - while (config->running) { -#ifdef HE_QAT_DEBUG - printf("Try reading request from buffer. Inst #%d\n", next_instance); -#endif - unsigned long pending = request_count - response_count; - unsigned long available = max_pending - ((pending < max_pending)?pending:max_pending); -#ifdef HE_QAT_DEBUG - printf("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", - request_count,response_count,pending,available); -#endif - while (available < restart_threshold) { -#ifdef HE_QAT_DEBUG - printf("[WAIT]\n"); -#endif - // argument passed in microseconds - OS_SLEEP(RESTART_LATENCY_MICROSEC); - pending = request_count - response_count; - available = max_pending - ((pending < max_pending)?pending:max_pending); -#ifdef HE_QAT_DEBUG - printf("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", - request_count,response_count,pending,available); -#endif - } -#ifdef HE_QAT_DEBUG - printf("[SUBMIT] request_count: %lu response_count: %lu pending: %lu available: %lu\n", - request_count,response_count,pending,available); -#endif - unsigned int max_requests = available; - - // Try consume maximum amount of data from butter to perform requested operation - read_request_list(&outstanding_requests, &he_qat_buffer, max_requests); - -#ifdef HE_QAT_DEBUG - printf("Offloading %u requests to the accelerator.\n", outstanding_requests.count); -#endif - for (unsigned int i = 0; i < outstanding_requests.count; i++) { - HE_QAT_TaskRequest* request = outstanding_requests.request[i]; -#ifdef HE_QAT_SYNC_MODE - COMPLETION_INIT(&request->callback); -#endif - - unsigned retry = 0; - do { - // Realize the type of operation from data - switch (request->op_type) { - // Select appropriate action - case HE_QAT_OP_MODEXP: -#ifdef HE_QAT_DEBUG - printf("Offload request using instance #%d\n", next_instance); -#endif -#ifdef HE_QAT_PERF - gettimeofday(&request->start, NULL); -#endif - status = cpaCyLnModExp( - config->inst_config[next_instance].inst_handle, - (CpaCyGenFlatBufCbFunc) - request->callback_func, // lnModExpCallback, - (void*)request, (CpaCyLnModExpOpData*)request->op_data, - &request->op_result); - retry++; - break; - case HE_QAT_OP_NONE: - default: -#ifdef HE_QAT_DEBUG - printf("HE_QAT_OP_NONE to instance #%d\n", next_instance); -#endif - retry = HE_QAT_MAX_RETRY; - break; - } - - if (CPA_STATUS_RETRY == status) { - printf("CPA requested RETRY\n"); - printf("RETRY count = %u\n",retry); - pthread_exit(NULL); // halt the whole system - } - - } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); - - // Ensure every call to perform operation is blocking for each endpoint - if (CPA_STATUS_SUCCESS == status) { - // Global tracking of number of requests - request_count += 1; - request_count_per_instance[next_instance] += 1; - next_instance = (next_instance + 1) % instance_count; - - // Wake up any blocked call to stop_perform_op, signaling that now it is - // safe to terminate running instances. Check if this detereorate - // performance. - pthread_cond_signal(&config->inst_config[next_instance].ready); // Prone to the lost wake-up problem - -#ifdef HE_QAT_SYNC_MODE - // Wait until the callback function has been called - if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { - request->op_status = CPA_STATUS_FAIL; - request->request_status = HE_QAT_STATUS_FAIL; // Review it - printf("Failed in COMPLETION WAIT\n"); - } - - // Destroy synchronization object - COMPLETION_DESTROY(&request->callback); -#endif - } else { - request->op_status = CPA_STATUS_FAIL; - request->request_status = HE_QAT_STATUS_FAIL; // Review it - printf("Request Submission FAILED\n"); - } - -#ifdef HE_QAT_DEBUG - printf("Offloading completed by instance #%d\n", next_instance-1); -#endif - - // Reset pointer - outstanding_requests.request[i] = NULL; - request = NULL; - - }// for loop over batch of requests - outstanding_requests.count = 0; - } - pthread_exit(NULL); -} - -/// @brief -/// Start independent processing and polling threads for an instance. -/// -/// @details -/// It initializes a QAT instance and launches its polling thread to listen -/// to responses (request outputs) from the accelerator. It is also reponsible -/// to collect requests from the internal buffer and send them to the accelerator -/// periodiacally. It was designed to extend to receiving and offloading -/// requests of different operation types but currently only supports Modular -/// Exponentiation. -/// -/// @param[in] _inst_config Data structure containing the configuration of a single -/// instance. -void* start_perform_op(void* _inst_config) { - if (NULL == _inst_config) { - printf("Failed in start_perform_op: _inst_config is NULL.\n"); - pthread_exit(NULL); - } - - HE_QAT_InstConfig* config = (HE_QAT_InstConfig*)_inst_config; - - CpaStatus status = CPA_STATUS_FAIL; - - // Start from zero or restart after stop_perform_op - pthread_mutex_lock(&config->mutex); - while (config->active) pthread_cond_wait(&config->ready, &config->mutex); - - // assert(0 == config->active); - // assert(NULL == config->inst_handle); - - status = cpaCyStartInstance(config->inst_handle); - config->status = status; - if (CPA_STATUS_SUCCESS == status) { - printf("Cpa CyInstance has successfully started.\n"); - status = - cpaCySetAddressTranslation(config->inst_handle, sampleVirtToPhys); - } - - pthread_cond_signal(&config->ready); - pthread_mutex_unlock(&config->mutex); - - if (CPA_STATUS_SUCCESS != status) pthread_exit(NULL); - - // Start QAT instance and start polling - pthread_t polling_thread; - if (pthread_create(&polling_thread, config->attr, start_inst_polling, - (void*)config) != 0) { - printf("Failed at creating and starting polling thread.\n"); - pthread_exit(NULL); - } - - if (pthread_detach(polling_thread) != 0) { - printf("Failed at detaching polling thread.\n"); - pthread_exit(NULL); - } - - HE_QAT_TaskRequestList outstanding_requests; - for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { - outstanding_requests.request[i] = NULL; - } - outstanding_requests.count = 0; - - config->running = 1; - config->active = 1; - while (config->running) { -#ifdef HE_QAT_DEBUG - printf("Try reading request from buffer. Inst #%d\n", config->inst_id); -#endif - unsigned long pending = request_count - response_count; - unsigned long available = max_pending - ((pending < max_pending)?pending:max_pending); -#ifdef HE_QAT_DEBUG - printf("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", - request_count,response_count,pending,available); -#endif - while (available < restart_threshold) { -#ifdef HE_QAT_DEBUG - printf("[WAIT]\n"); -#endif - // argument passed in microseconds - OS_SLEEP(650); - pending = request_count - response_count; - available = max_pending - ((pending < max_pending)?pending:max_pending); - } -#ifdef HE_QAT_DEBUG - printf("[SUBMIT] request_count: %lu response_count: %lu pending: %lu available: %lu\n", - request_count,response_count,pending,available); -#endif - unsigned int max_requests = available; - // Try consume maximum amount of data from butter to perform requested operation - read_request_list(&outstanding_requests, &he_qat_buffer, max_requests); - -// // Try consume data from butter to perform requested operation -// HE_QAT_TaskRequest* request = -// (HE_QAT_TaskRequest*)read_request(&he_qat_buffer); -// -// if (NULL == request) { -// pthread_cond_signal(&config->ready); -// continue; -// } -#ifdef HE_QAT_DEBUG - printf("Offloading %u requests to the accelerator.\n", outstanding_requests.count); -#endif - for (unsigned int i = 0; i < outstanding_requests.count; i++) { - HE_QAT_TaskRequest* request = outstanding_requests.request[i]; -#ifdef HE_QAT_SYNC_MODE - COMPLETION_INIT(&request->callback); -#endif - unsigned retry = 0; - do { - // Realize the type of operation from data - switch (request->op_type) { - // Select appropriate action - case HE_QAT_OP_MODEXP: - //if (retry > 0) printf("Try offloading again last request\n"); -#ifdef HE_QAT_DEBUG - printf("Offload request using instance #%d\n", config->inst_id); -#endif -#ifdef HE_QAT_PERF - gettimeofday(&request->start, NULL); -#endif - status = cpaCyLnModExp( - config->inst_handle, - (CpaCyGenFlatBufCbFunc) - request->callback_func, // lnModExpCallback, - (void*)request, (CpaCyLnModExpOpData*)request->op_data, - &request->op_result); - retry++; - break; - case HE_QAT_OP_NONE: - default: -#ifdef HE_QAT_DEBUG - printf("HE_QAT_OP_NONE to instance #%d\n", config->inst_id); -#endif - retry = HE_QAT_MAX_RETRY; - break; - } - - if (CPA_STATUS_RETRY == status) { - printf("CPA requested RETRY\n"); - printf("RETRY count: %u\n",retry); - OS_SLEEP(600); - } - - } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); - - // Ensure every call to perform operation is blocking for each endpoint - if (CPA_STATUS_SUCCESS == status) { - // Global tracking of number of requests - request_count += 1; - //printf("retry_count = %d\n",retry_count); -#ifdef HE_QAT_SYNC_MODE - // Wait until the callback function has been called - if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { - request->op_status = CPA_STATUS_FAIL; - request->request_status = HE_QAT_STATUS_FAIL; // Review it - printf("Failed in COMPLETION WAIT\n"); - } - - // Destroy synchronization object - COMPLETION_DESTROY(&request->callback); -#endif - } else { - request->op_status = CPA_STATUS_FAIL; - request->request_status = HE_QAT_STATUS_FAIL; // Review it - } - - // Reset pointer - outstanding_requests.request[i] = NULL; - request = NULL; - - }// for loop over batch of requests - outstanding_requests.count = 0; - - // Wake up any blocked call to stop_perform_op, signaling that now it is - // safe to terminate running instances. Check if this detereorate - // performance. - pthread_cond_signal( - &config->ready); // Prone to the lost wake-up problem -#ifdef HE_QAT_DEBUG - printf("Offloading completed by instance #%d\n", config->inst_id); -#endif - } - pthread_exit(NULL); -} - -/// @brief -/// Stop specified number of instances from running. -/// -/// @details -/// Stop first 'num_inst' number of cpaCyInstance(s), including their polling -/// and running threads. Stop runnning and polling instances. -/// Release QAT instances handles. -/// -/// @param[in] config List of all created QAT instances and their configurations. -/// @param[in] num_inst Unsigned integer number indicating first number of -/// instances to be terminated. -void stop_perform_op(HE_QAT_InstConfig* config, unsigned num_inst) { - if (NULL == config) return; - - CpaStatus status = CPA_STATUS_FAIL; - for (unsigned i = 0; i < num_inst; i++) { - pthread_mutex_lock(&config[i].mutex); -#ifdef HE_QAT_DEBUG - printf("Try teardown HE QAT instance #%d.\n", i); -#endif - while (0 == config[i].active) { - pthread_cond_wait(&config[i].ready, &config[i].mutex); - } - if (CPA_STATUS_SUCCESS == config[i].status && config[i].active) { -#ifdef HE_QAT_DEBUG - printf("Stop polling and running threads #%d\n", i); -#endif - config[i].polling = 0; - config[i].running = 0; - OS_SLEEP(10); -#ifdef HE_QAT_DEBUG - printf("Stop cpaCyInstance #%d\n", i); -#endif - if (config[i].inst_handle == NULL) continue; -#ifdef HE_QAT_DEBUG - printf("cpaCyStopInstance\n"); -#endif - status = cpaCyStopInstance(config[i].inst_handle); - if (CPA_STATUS_SUCCESS != status) { - printf("Failed to stop QAT instance #%d\n", i); - } - } - pthread_cond_signal(&config[i].ready); - pthread_mutex_unlock(&config[i].mutex); - } - //} - - return; -} - -/// @brief Stop all running instances. -/// @details -/// Stop all running instances after calling `start_instances()`. -/// It will set the states of the instances to terminate gracefully. -/// @param[in] _config All QAT instances configurations holding their states. -void stop_instances(HE_QAT_Config* _config) { - if (NULL == _config) return; - if (_config->active) _config->active = 0; - if (_config->running) _config->running = 0; - stop_perform_op(_config->inst_config, _config->count); - return ; -} - diff --git a/module/heqat/he_qat/he_qat_ops.c b/module/heqat/he_qat/he_qat_ops.c deleted file mode 100644 index 6c6bd02..0000000 --- a/module/heqat/he_qat/he_qat_ops.c +++ /dev/null @@ -1,566 +0,0 @@ -/// @file he_qat_ops.c - -#include "cpa.h" -#include "cpa_cy_im.h" -#include "cpa_cy_ln.h" -#include "icp_sal_poll.h" - -#include "cpa_sample_utils.h" - -#include "he_qat_types.h" -#include "he_qat_bn_ops.h" - -#ifdef HE_QAT_PERF -#include -struct timeval start_time, end_time; -double time_taken = 0.0; -#endif - -#include -#include -#include -#include - -#ifdef HE_QAT_SYNC_MODE -#pragma message "Synchronous execution mode." -#else -#pragma message "Asynchronous execution mode." -#endif - -#include "he_qat_gconst.h" - -// Global buffer for the runtime environment -extern HE_QAT_RequestBuffer he_qat_buffer; -extern HE_QAT_OutstandingBuffer outstanding; - -// Callback functions -extern void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut); -extern void HE_QAT_bnModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut); - -/// @brief Thread-safe producer implementation for the shared request buffer. -/// @details Fill internal or outstanding buffer with incoming work requests. -/// This function is implemented in he_qat_ctrl.c. -extern void submit_request(HE_QAT_RequestBuffer* _buffer, void* args); - - -/* - * ************************************************************************** - * Implementation of Functions for the Single Interface Support - * ************************************************************************** - */ - -HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, - unsigned char* e, unsigned char* m, int nbits) { - static unsigned long long req_count = 0; - - // Unpack data and copy to QAT friendly memory space - int len = (nbits + 7) >> 3; // nbits / 8; - - if (NULL == r) return HE_QAT_STATUS_INVALID_PARAM; - if (NULL == b) return HE_QAT_STATUS_INVALID_PARAM; - if (NULL == e) return HE_QAT_STATUS_INVALID_PARAM; - if (NULL == m) return HE_QAT_STATUS_INVALID_PARAM; - - Cpa8U* pBase = NULL; - Cpa8U* pModulus = NULL; - Cpa8U* pExponent = NULL; - - // TODO(fdiasmor): Try it with 8-byte alignment. - CpaStatus status = CPA_STATUS_FAIL; - // status = PHYS_CONTIG_ALLOC(&pBase, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pBase, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pBase) { - memcpy(pBase, b, len); - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; - } - - // status = PHYS_CONTIG_ALLOC(&pExponent, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pExponent, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { - memcpy(pExponent, e, len); - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; - } - - // status = PHYS_CONTIG_ALLOC(&pModulus, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pModulus, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { - memcpy(pModulus, m, len); - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; - } - - // HE_QAT_TaskRequest request = - // HE_QAT_PACK_MODEXP_REQUEST(pBase, pExponent, pModulus, r) - // Pack it as a QAT Task Request - HE_QAT_TaskRequest* request = - (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); - if (NULL == request) { - printf( - "HE_QAT_TaskRequest memory allocation failed in " - "bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } - - CpaCyLnModExpOpData* op_data = - (CpaCyLnModExpOpData*)calloc(1, sizeof(CpaCyLnModExpOpData)); - if (NULL == op_data) { - printf("Cpa memory allocation failed in bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } - op_data->base.pData = pBase; - op_data->base.dataLenInBytes = len; - op_data->exponent.pData = pExponent; - op_data->exponent.dataLenInBytes = len; - op_data->modulus.pData = pModulus; - op_data->modulus.dataLenInBytes = len; - request->op_data = (void*)op_data; - - // status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&request->op_result.pData, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != request->op_result.pData) { - request->op_result.dataLenInBytes = len; - } else { - printf( - "CpaFlatBuffer.pData memory allocation failed in " - "bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } - - request->op_type = HE_QAT_OP_MODEXP; - request->callback_func = (void*)HE_QAT_bnModExpCallback; - request->op_status = status; - request->op_output = (void*)r; - - request->id = req_count++; - - // Ensure calls are synchronized at exit (blocking) - pthread_mutex_init(&request->mutex, NULL); - pthread_cond_init(&request->ready, NULL); - -#ifdef HE_QAT_DEBUG - printf("BN ModExp interface call for request #%llu\n", req_count); -#endif - - // Submit request using producer function - submit_request(&he_qat_buffer, (void*)request); - - return HE_QAT_STATUS_SUCCESS; -} - -HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int nbits) { - static unsigned long long req_count = 0; - - // Unpack data and copy to QAT friendly memory space - int len = (nbits + 7) >> 3; - - Cpa8U* pBase = NULL; - Cpa8U* pModulus = NULL; - Cpa8U* pExponent = NULL; - - HE_QAT_TaskRequest* request = - (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); - if (NULL == request) { - printf( - "HE_QAT_TaskRequest memory allocation failed in " - "bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } - - // TODO: @fdiasmor Try it with 8-byte alignment. - CpaStatus status = CPA_STATUS_FAIL; - status = PHYS_CONTIG_ALLOC(&pBase, len); - if (CPA_STATUS_SUCCESS == status && NULL != pBase) { - if (!BN_bn2binpad(b, pBase, len)) { - printf("BN_bn2binpad (base) failed in bnModExpPerformOp.\n"); - PHYS_CONTIG_FREE(pBase); - return HE_QAT_STATUS_FAIL; - } - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; - } - - status = PHYS_CONTIG_ALLOC(&pExponent, len); - if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { - if (!BN_bn2binpad(e, pExponent, len)) { - printf("BN_bn2binpad (exponent) failed in bnModExpPerformOp.\n"); - PHYS_CONTIG_FREE(pExponent); - return HE_QAT_STATUS_FAIL; - } - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; - } - - status = PHYS_CONTIG_ALLOC(&pModulus, len); - if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { - if (!BN_bn2binpad(m, pModulus, len)) { - printf("BN_bn2binpad failed in bnModExpPerformOp.\n"); - PHYS_CONTIG_FREE(pModulus); - return HE_QAT_STATUS_FAIL; - } - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; - } - - // Pack it as a QAT Task Request - CpaCyLnModExpOpData* op_data = - (CpaCyLnModExpOpData*)calloc(1, sizeof(CpaCyLnModExpOpData)); - if (NULL == op_data) { - printf("Cpa memory allocation failed in bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } - op_data->base.pData = pBase; - op_data->base.dataLenInBytes = len; - op_data->exponent.pData = pExponent; - op_data->exponent.dataLenInBytes = len; - op_data->modulus.pData = pModulus; - op_data->modulus.dataLenInBytes = len; - request->op_data = (void*)op_data; - - status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); - if (CPA_STATUS_SUCCESS == status && NULL != request->op_result.pData) { - request->op_result.dataLenInBytes = len; - } else { - printf( - "CpaFlatBuffer.pData memory allocation failed in " - "bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } - - request->op_type = HE_QAT_OP_MODEXP; - request->callback_func = (void*)HE_QAT_BIGNUMModExpCallback; - request->op_status = status; - request->op_output = (void*)r; - - request->id = req_count++; - // Ensure calls are synchronized at exit (blocking) - pthread_mutex_init(&request->mutex, NULL); - pthread_cond_init(&request->ready, NULL); - - // Submit request using producer function - submit_request(&he_qat_buffer, (void*)request); - - return HE_QAT_STATUS_SUCCESS; -} - -void getBnModExpRequest(unsigned int batch_size) { - static unsigned long block_at_index = 0; - unsigned int j = 0; - -#ifdef HE_QAT_PERF - gettimeofday(&start_time, NULL); -#endif -// while (j < batch_size) { - do { - // Buffer read may be safe for single-threaded blocking calls only. - // Note: Not tested on multithreaded environment. - HE_QAT_TaskRequest* task = - (HE_QAT_TaskRequest*)he_qat_buffer.data[block_at_index]; - - if (NULL == task) - continue; - - // Block and synchronize: Wait for the most recently offloaded request - // to complete processing - pthread_mutex_lock( - &task->mutex); // mutex only needed for the conditional variable - while (HE_QAT_STATUS_READY != task->request_status) - pthread_cond_wait(&task->ready, &task->mutex); - -#ifdef HE_QAT_PERF - time_taken = (task->end.tv_sec - task->start.tv_sec) * 1e6; - time_taken = - (time_taken + (task->end.tv_usec - task->start.tv_usec)); //*1e-6; - printf("%u time: %.1lfus\n", j, time_taken); -#endif - - // Free up QAT temporary memory - CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; - if (op_data) { - PHYS_CONTIG_FREE(op_data->base.pData); - PHYS_CONTIG_FREE(op_data->exponent.pData); - PHYS_CONTIG_FREE(op_data->modulus.pData); - } - free(task->op_data); - task->op_data = NULL; - if (task->op_result.pData) { - PHYS_CONTIG_FREE(task->op_result.pData); - } - - // Move forward to wait for the next request that will be offloaded - pthread_mutex_unlock(&task->mutex); - - // Fix segmentation fault? - free(he_qat_buffer.data[block_at_index]); - he_qat_buffer.data[block_at_index] = NULL; - - block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; -// j++; -// } - } while (++j < batch_size); // number of null pointers equal batch size ? - -#ifdef HE_QAT_PERF - gettimeofday(&end_time, NULL); - time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; - time_taken = - (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; - printf("Batch Wall Time: %.1lfus\n", time_taken); -#endif - - return; -} - -/* - * ************************************************************************** - * Implementation of Functions for the Multithreading Interface Support - * ************************************************************************** - */ - -HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, - unsigned char* b, unsigned char* e, - unsigned char* m, int nbits) { - static unsigned long long req_count = 0; - - // Unpack data and copy to QAT friendly memory space - int len = (nbits + 7) >> 3; - - if (NULL == r) return HE_QAT_STATUS_INVALID_PARAM; - if (NULL == b) return HE_QAT_STATUS_INVALID_PARAM; - if (NULL == e) return HE_QAT_STATUS_INVALID_PARAM; - if (NULL == m) return HE_QAT_STATUS_INVALID_PARAM; - - Cpa8U* pBase = NULL; - Cpa8U* pModulus = NULL; - Cpa8U* pExponent = NULL; - - // TODO(fdiasmor): Try it with 8-byte alignment. - CpaStatus status = CPA_STATUS_FAIL; - // status = PHYS_CONTIG_ALLOC(&pBase, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pBase, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pBase) { - memcpy(pBase, b, len); - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; - } - - // status = PHYS_CONTIG_ALLOC(&pExponent, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pExponent, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { - memcpy(pExponent, e, len); - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; - } - - // status = PHYS_CONTIG_ALLOC(&pModulus, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pModulus, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { - memcpy(pModulus, m, len); - } else { - printf("Contiguous memory allocation failed for pBase.\n"); - return HE_QAT_STATUS_FAIL; - } - - // HE_QAT_TaskRequest request = - // HE_QAT_PACK_MODEXP_REQUEST(pBase, pExponent, pModulus, r) - // Pack it as a QAT Task Request - HE_QAT_TaskRequest* request = - (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); - if (NULL == request) { - printf( - "HE_QAT_TaskRequest memory allocation failed in " - "bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } - - CpaCyLnModExpOpData* op_data = - (CpaCyLnModExpOpData*)calloc(1, sizeof(CpaCyLnModExpOpData)); - if (NULL == op_data) { - printf("Cpa memory allocation failed in bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } - op_data->base.pData = pBase; - op_data->base.dataLenInBytes = len; - op_data->exponent.pData = pExponent; - op_data->exponent.dataLenInBytes = len; - op_data->modulus.pData = pModulus; - op_data->modulus.dataLenInBytes = len; - request->op_data = (void*)op_data; - - // status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&request->op_result.pData, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != request->op_result.pData) { - request->op_result.dataLenInBytes = len; - } else { - printf( - "CpaFlatBuffer.pData memory allocation failed in " - "bnModExpPerformOp.\n"); - return HE_QAT_STATUS_FAIL; - } - - request->op_type = HE_QAT_OP_MODEXP; - request->callback_func = (void*)HE_QAT_bnModExpCallback; - request->op_status = status; - request->op_output = (void*)r; - - request->id = req_count++; - - // Ensure calls are synchronized at exit (blocking) - pthread_mutex_init(&request->mutex, NULL); - pthread_cond_init(&request->ready, NULL); - -#ifdef HE_QAT_DEBUG - printf("BN ModExp interface call for request #%llu\n", req_count); -#endif - - // Submit request using producer function - submit_request(&outstanding.buffer[_buffer_id], (void*)request); - - return HE_QAT_STATUS_SUCCESS; -} - -/// @brief Frontend for multithreading support. -/// @details Try to acquire an available buffer to store outstanding work requests sent by caller. -/// If none is available, it blocks further processing and waits until another caller's concurrent -/// thread releases one. This function must be called before -/// calling HE_QAT_bnModExp_MT(.). -/// @param[out] Pointer to memory space allocated by caller to hold the buffer ID of the buffer used to store caller's outstanding requests. -HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id) { - if (NULL == _buffer_id) return HE_QAT_STATUS_INVALID_PARAM; - - pthread_mutex_lock(&outstanding.mutex); - - // Wait until next outstanding buffer becomes available for use - while (outstanding.busy_count >= HE_QAT_BUFFER_COUNT) - pthread_cond_wait(&outstanding.any_free_buffer, &outstanding.mutex); - - assert(outstanding.busy_count < HE_QAT_BUFFER_COUNT); - - // Find next outstanding buffer available - unsigned int next_free_buffer = outstanding.next_free_buffer; - for (unsigned int i = 0; i < HE_QAT_BUFFER_COUNT; i++) { - if (outstanding.free_buffer[next_free_buffer]) { - outstanding.free_buffer[next_free_buffer] = 0; - *_buffer_id = next_free_buffer; - break; - } - next_free_buffer = (next_free_buffer + 1) % HE_QAT_BUFFER_COUNT; - } - - outstanding.next_free_buffer = (*_buffer_id + 1) % HE_QAT_BUFFER_COUNT; - outstanding.next_ready_buffer = *_buffer_id; - outstanding.ready_buffer[*_buffer_id] = 1; - outstanding.busy_count++; - // busy meaning: - // taken by a thread, enqueued requests, in processing, waiting results - - pthread_cond_signal(&outstanding.any_ready_buffer); - pthread_mutex_unlock(&outstanding.mutex); - - return HE_QAT_STATUS_SUCCESS; -} - -/// @brief Wait for request processing to complete and release previously acquired buffer. -/// @details Caution: It assumes acquire_bnModExp_buffer(&_buffer_id) to be called first -/// to secure and be assigned an outstanding buffer for the target thread. -/// Equivalent to getBnModExpRequests() for the multithreading support interfaces. -/// param[in] _buffer_id Buffer ID of the buffer to be released/unlock for reuse by the next concurrent thread. -/// param[in] _batch_size Total number of requests to wait for completion before releasing the buffer. -void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size) { - unsigned int next_data_out = outstanding.buffer[_buffer_id].next_data_out; - unsigned int j = 0; - -#ifdef HE_QAT_DEBUG - printf("release_bnModExp_buffer #%u\n", _buffer_id); -#endif - -#ifdef HE_QAT_PERF - gettimeofday(&start_time, NULL); -#endif - - while (j < _batch_size) { - HE_QAT_TaskRequest* task = - (HE_QAT_TaskRequest*)outstanding.buffer[_buffer_id] - .data[next_data_out]; - - if (NULL == task) continue; - -#ifdef HE_QAT_DEBUG - printf("BatchSize %u Buffer #%u Request #%u Waiting\n", _batch_size, - _buffer_id, j); -#endif - - // Block and synchronize: Wait for the most recently offloaded request - // to complete processing. Mutex only needed for the conditional variable. - pthread_mutex_lock(&task->mutex); - while (HE_QAT_STATUS_READY != task->request_status) - pthread_cond_wait(&task->ready, &task->mutex); - -#ifdef HE_QAT_PERF - time_taken = (task->end.tv_sec - task->start.tv_sec) * 1e6; - time_taken = - (time_taken + (task->end.tv_usec - task->start.tv_usec)); //*1e-6; - printf("%u time: %.1lfus\n", j, time_taken); -#endif - - // Free up QAT temporary memory - CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; - if (op_data) { - PHYS_CONTIG_FREE(op_data->base.pData); - PHYS_CONTIG_FREE(op_data->exponent.pData); - PHYS_CONTIG_FREE(op_data->modulus.pData); - } - free(task->op_data); - task->op_data = NULL; - if (task->op_result.pData) { - PHYS_CONTIG_FREE(task->op_result.pData); - } - - // Move forward to wait for the next request that will be offloaded - pthread_mutex_unlock(&task->mutex); - -#ifdef HE_QAT_DEBUG - printf("Buffer #%u Request #%u Completed\n", _buffer_id, j); -#endif - // outstanding.buffer[_buffer_id].count--; - - free(outstanding.buffer[_buffer_id].data[next_data_out]); - outstanding.buffer[_buffer_id].data[next_data_out] = NULL; - - // Update for next thread on the next external iteration - next_data_out = (next_data_out + 1) % HE_QAT_BUFFER_SIZE; - - j++; - } - -#ifdef HE_QAT_PERF - gettimeofday(&end_time, NULL); - time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; - time_taken = - (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; - printf("Batch Wall Time: %.1lfus\n", time_taken); -#endif - - outstanding.buffer[_buffer_id].next_data_out = next_data_out; - - // Release outstanding buffer for usage by another thread - pthread_mutex_lock(&outstanding.mutex); - - outstanding.next_free_buffer = _buffer_id; - outstanding.ready_buffer[_buffer_id] = 0; - outstanding.free_buffer[_buffer_id] = 1; - outstanding.busy_count--; - - pthread_cond_signal(&outstanding.any_free_buffer); - pthread_mutex_unlock(&outstanding.mutex); - - return; -} diff --git a/module/heqat/he_qat/he_qat_utils.c b/module/heqat/he_qat/he_qat_utils.c deleted file mode 100644 index 2677e1b..0000000 --- a/module/heqat/he_qat/he_qat_utils.c +++ /dev/null @@ -1,66 +0,0 @@ -#include "he_qat_utils.h" - -#include -#include - -BIGNUM* generateTestBNData(int nbits) { - if (!RAND_status()) return NULL; -#ifdef _DESTINY_DEBUG_VERBOSE - printf("PRNG properly seeded.\n"); -#endif - - BIGNUM* bn = BN_new(); - - if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { - BN_free(bn); - printf("Error while generating BN random number: %lu\n", - ERR_get_error()); - return NULL; - } - - return bn; -} - -unsigned char* paddingZeros(BIGNUM* bn, int nbits) { - if (!bn) return NULL; - - // Returns same address if it fails - int num_bytes = BN_num_bytes(bn); - int bytes_left = nbits / 8 - num_bytes; - if (bytes_left <= 0) return NULL; - - // Returns same address if it fails - unsigned char* bin = NULL; - int len = bytes_left + num_bytes; - if (!(bin = (unsigned char*)OPENSSL_zalloc(len))) return NULL; - -#ifdef _DESTINY_DEBUG_VERBOSE - printf("Padding bn with %d bytes to total %d bytes\n", bytes_left, len); -#endif - BN_bn2binpad(bn, bin, len); - if (ERR_get_error()) { - OPENSSL_free(bin); - return NULL; - } - - return bin; -} - -void showHexBN(BIGNUM* bn, int nbits) { - int len = nbits / 8; - unsigned char* bin = (unsigned char*)OPENSSL_zalloc(len); - if (!bin) return; - if (BN_bn2binpad(bn, bin, len)) { - for (size_t i = 0; i < len; i++) printf("%2.2x", bin[i]); - printf("\n"); - } - OPENSSL_free(bin); - return; -} - -void showHexBin(unsigned char* bin, int len) { - if (!bin) return; - for (size_t i = 0; i < len; i++) printf("%2.2x", bin[i]); - printf("\n"); - return; -} diff --git a/module/heqat/he_qat/include/he_qat_bn_ops.h b/module/heqat/he_qat/include/he_qat_bn_ops.h deleted file mode 100644 index dd27a00..0000000 --- a/module/heqat/he_qat/include/he_qat_bn_ops.h +++ /dev/null @@ -1,141 +0,0 @@ -/** - * @file he_qat_bn_ops.h - * - * @details - * In this file, functions for Big Number operations accelerated by the - * QuickAssist (QAT) co-processor are specified. - * - * @note - * Unless otherwise specified, Big numbers are represented by octet strings - * and stored in memory as pointers of type unsigned char*. On the QAT API the - * octect string is copied into a data structure of type CpaFlatBuffer. The octet - * strings representing Big Numbers are encoded with compliance to PKCA#1 v2.1, - * section 4, which is consistent with ASN.1 syntax. - * - * The largest number supported here has 4096 bits, i.e. numbers from 0 to - * 2^(4096)-1. The most significant bit is located at index n-1. If the number is - * N, then the bit length is defined by n = floor(log2(N))+1. The memory buffer b to - * hold such number N needs to have at least M = ceiling(n/8) bytes allocated. In - * general, it will be larger and a power of 2, e.g. total bytes allocated is T=128 - * for numbers having up to n=1024 bits, total bytes allocated is T=256 for numbers - * having up to n=2048 bits, and so forth. Finally, the big number N is stored in - * `big endian` format, i.e. the least significant byte (LSB) is located at index [T-1], - * whereas the most significant byte is stored at [T-M]. - * - * The API client is responsible for allocation and release of their memory spaces of - * the function arguments. Allocated memory spaces must be contiguous. Once a function - * is called, the ownership of the memory spaces is transfered to the function until - * their completion such that concurrent usage by the client during excution may result - * in undefined behavior. - */ - -// New compilers -#pragma once - -// Legacy compilers -#ifndef _HE_QAT_BN_OPS_H_ -#define _HE_QAT_BN_OPS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "he_qat_types.h" - -/// @brief Performs modular exponentiation using BIGNUM data structure. -/// -/// @details -/// Perform big number modular exponentiation operation accelerated with QAT for input data -/// using OpenSSL BIGNUM data structure. Create QAT contiguous memory space. -/// Copy BIGNUM binary data and package it into a request (HE_QAT_Request data structure) and -/// call producer function to submit request to the internal buffer. -/// -/// @param[out] r Remainder number of the modular exponentiation operation. -/// @param[in] b Base number of the modular exponentiation operation. -/// @param[in] e Exponent number of the modular exponentiation operation. -/// @param[in] m Modulus number of the modular exponentiation operation. -/// @param[in] nbits Number of bits (bit precision) of input/output big numbers. -HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int nbits); - -/// @brief Performs big number modular exponentiation for input data (an octet string) -/// in primitive type format (unsigned char *). -/// -/// @details -/// Perform big number modular exponentiation operation accelerated with QAT for -/// input data as an octet string of unsigned chars. Create QAT contiguous memory -/// space. Upon call it copies input data and package it into a request, then calls -/// producer function to submit request to internal buffer. -/// -/// @param[out] r Remainder number of the modular exponentiation operation. -/// @param[in] b Base number of the modular exponentiation operation. -/// @param[in] e Exponent number of the modular exponentiation operation. -/// @param[in] m Modulus number of the modular exponentiation operation. -/// @param[in] nbits Number of bits (bit precision) of input/output big numbers. -HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, - unsigned char* e, unsigned char* m, int nbits); - -/// @brief -/// It waits for number of requests sent by HE_QAT_bnModExp or HE_QAT_BIGNUMModExp -/// to complete. -/// -/// @details -/// This function is blocking and works as a barrier. The purpose of this function -/// is to wait for all outstanding requests to complete processing. It will also -/// release all temporary memory allocated used to support the submission and -/// processing of the requests. It monitors outstanding requests to be completed -/// and then it deallocates buffer holding outstanding request. -/// -/// @param[in] num_requests Number of requests to wait for processing completion. -void getBnModExpRequest(unsigned int num_requests); - -/** - * - * Interfaces for the Multithreading Support - * - **/ - -/// @brief Performs big number modular exponentiation for input data (an octet string) -/// in primitive type format (unsigned char *). Same as HE_QAT_bnModExp with -/// multithreading support. -/// -/// @details -/// Perform big number modular exponentiation operation accelerated with QAT for -/// input data as an octet string of unsigned chars. Create QAT contiguous memory -/// space. Upon call it copies input data and package it into a request, then calls -/// producer function to submit request to internal buffer. -/// -/// @param[in] _buffer_id Buffer ID of the reserved buffer for the caller's thread. -/// @param[out] r Remainder number of the modular exponentiation operation. -/// @param[in] b Base number of the modular exponentiation operation. -/// @param[in] e Exponent number of the modular exponentiation operation. -/// @param[in] m Modulus number of the modular exponentiation operation. -/// @param[in] nbits Number of bits (bit precision) of input/output big numbers. -HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, - unsigned char* b, unsigned char* e, unsigned char* m, int nbits); - -/// @brief Reserve/acquire buffer for multithreading support. -/// -/// @details Try to acquire an available buffer to store outstanding work requests sent by caller. -/// If none is available, it blocks further processing and waits until another caller's concurrent -/// thread releases one. This function must be called before -/// calling HE_QAT_bnModExp_MT(.). -/// -/// @param[out] _buffer_id Pointer to memory space allocated by caller to hold the buffer ID of the buffer used to store caller's outstanding requests. -HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id); - -/// @brief Wait for request processing to complete and release previously acquired buffer. -/// -/// @details Caution: It assumes acquire_bnModExp_buffer(&_buffer_id) to be called first -/// to secure and be assigned an outstanding buffer for the target thread. -/// Equivalent to getBnModExpRequests() for the multithreading support interfaces. -/// -/// param[in] _buffer_id Buffer ID of the buffer to be released/unlock for reuse by the next concurrent thread. -/// param[in] _batch_size Total number of requests to wait for completion before releasing the buffer. -void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size); - -#ifdef __cplusplus -} // extern "C" { -#endif - -#endif diff --git a/module/heqat/he_qat/include/he_qat_context.h b/module/heqat/he_qat/include/he_qat_context.h deleted file mode 100644 index e260793..0000000 --- a/module/heqat/he_qat/include/he_qat_context.h +++ /dev/null @@ -1,26 +0,0 @@ -/// @file he_qat_context.h - -#pragma once - -#ifndef _HE_QAT_CONTEXT_H_ -#define _HE_QAT_CONTEXT_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "he_qat_types.h" - -/// @brief -/// Configure and initialize QAT runtime environment. -HE_QAT_STATUS acquire_qat_devices(); - -/// @brief -/// Release and free resources of the QAT runtime environment. -HE_QAT_STATUS release_qat_devices(); - -#ifdef __cplusplus -} // extern "C" { -#endif - -#endif diff --git a/module/heqat/he_qat/include/he_qat_gconst.h b/module/heqat/he_qat/include/he_qat_gconst.h deleted file mode 100644 index 1883577..0000000 --- a/module/heqat/he_qat/include/he_qat_gconst.h +++ /dev/null @@ -1,17 +0,0 @@ -/// @file he_qat_gconst.h - -#pragma once - -#ifndef _HE_QAT_CONST_H_ -#define _HE_QAT_CONST_H_ - -// Local Constants -#define HE_QAT_NUM_ACTIVE_INSTANCES 8 -#define HE_QAT_BUFFER_SIZE 1024 -#define HE_QAT_BUFFER_COUNT HE_QAT_NUM_ACTIVE_INSTANCES -#define HE_QAT_MAX_RETRY 100 -#define RESTART_LATENCY_MICROSEC 600 -#define NUM_PKE_SLICES 6 - -#endif // _HE_QAT_CONST_H_ - diff --git a/module/heqat/he_qat/include/he_qat_types.h b/module/heqat/he_qat/include/he_qat_types.h deleted file mode 100644 index b20d910..0000000 --- a/module/heqat/he_qat/include/he_qat_types.h +++ /dev/null @@ -1,123 +0,0 @@ -/// @file he_qat_types.h - -#pragma once - -#ifndef _HE_QAT_TYPES_H_ -#define _HE_QAT_TYPES_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -// QATLib Headers -#include "cpa.h" -#include "cpa_cy_im.h" -#include "cpa_cy_ln.h" -#include "cpa_sample_utils.h" - -// C Libraries -#include -#ifdef HE_QAT_PERF -#include -#endif - -#include "he_qat_gconst.h" - -// Type definitions -typedef enum { - HE_QAT_SYNC = 1, - HE_QAT_ASYNC = 2 -} HE_QAT_EXEC_MODE; - -typedef enum { - HE_QAT_STATUS_INVALID_PARAM = 2, - HE_QAT_STATUS_READY = 1, - HE_QAT_STATUS_SUCCESS = 0, - HE_QAT_STATUS_FAIL = -1 -} HE_QAT_STATUS; - -typedef enum { - HE_QAT_OP_NONE = 0, ///< No Operation (NO OP) - HE_QAT_OP_MODEXP = 1 ///< QAT Modular Exponentiation -} HE_QAT_OP; - -typedef pthread_t HE_QAT_Inst; - -typedef struct { - void* data[HE_QAT_BUFFER_SIZE]; ///< Stores work requests ready to be sent to the accelerator. - volatile unsigned int count; ///< Tracks the number of occupied entries/slots in the data[] buffer. - // nextin index of the next free slot for a request - unsigned int next_free_slot; ///< Index of the next slot available to store a new request. - // nextout index of next request to be processed - unsigned int next_data_slot; ///< Index of the next slot containing request ready to be consumed for processing. - // index of next output data to be read by a thread waiting - // for all the request to complete processing - unsigned int next_data_out; ///< Index of the next slot containing request whose processing has been completed and its output is ready to be consumed by the caller. - pthread_mutex_t mutex; ///< Synchronization object used to control access to the buffer. - pthread_cond_t any_more_data; ///< Conditional variable used to synchronize the consumption of data in buffer (wait until more data is available to be consumed). - pthread_cond_t any_free_slot; ///< Conditional variable used to synchronize the provision of free slots in buffer (wait until enough slots are available to add more data in buffer). -} HE_QAT_RequestBuffer; - -typedef struct { - HE_QAT_RequestBuffer buffer[HE_QAT_BUFFER_COUNT]; ///< Buffers to support concurrent threads with less sync overhead. Stores incoming request from different threads. - unsigned int busy_count; ///< Counts number of currently occupied buffers. - unsigned int next_free_buffer; ///< Next in: index of the next free slot for a request. - int free_buffer[HE_QAT_BUFFER_COUNT]; ///< Keeps track of buffers that are available (any value > 0 means the buffer at index i is available). The next_free_buffer does not necessarily mean that the buffer is already released from usage. - unsigned int next_ready_buffer; ///< Next out: index of next request to be processed. - int ready_buffer[HE_QAT_BUFFER_COUNT]; ///< Keeps track of buffers that are ready (any value > 0 means the buffer at index i is ready). The next_ready_buffer does not necessarily mean that the buffer is not busy at any time instance. - pthread_mutex_t mutex; ///< Used for synchronization of concurrent access of an object of the type - pthread_cond_t any_ready_buffer; ///< Conditional variable used to synchronize the consumption of the contents in the buffers storing outstanding requests and ready to be scheduled to move to the internal buffer. - pthread_cond_t any_free_buffer; ///< Conditional variable used to synchronize the provisioning of buffers to store incoming requests from concurrent threads. -} HE_QAT_OutstandingBuffer; - -typedef struct { - int inst_id; ///< QAT instance ID. - CpaInstanceHandle inst_handle; ///< Handle of this QAT instance. - pthread_attr_t* attr; ///< Unused member. - HE_QAT_RequestBuffer* he_qat_buffer; ///< Unused member. - pthread_mutex_t mutex; - pthread_cond_t ready; - volatile int active; ///< State of this QAT instance. - volatile int polling; ///< State of this QAT instance's polling thread (any value different from 0 indicates that it is running). - volatile int running; ///< State of this QAT instance's processing thread (any value different from 0 indicates that it is running). - CpaStatus status; ///< Status of the latest activity by this QAT instance. -} HE_QAT_InstConfig; - -typedef struct { - HE_QAT_InstConfig *inst_config; ///< List of the QAT instance's configurations. - volatile int active; ///< Value different from 0 indicates all QAT instances are created and active. - volatile int running; ///< Value different from 0 indicates all created QAT instances are running. - unsigned int count; ///< Total number of created QAT instances. -} HE_QAT_Config; - -// One for each consumer -typedef struct { - unsigned long long id; ///< Work request ID. - // sem_t callback; - struct COMPLETION_STRUCT callback; ///< Synchronization object. - HE_QAT_OP op_type; ///< Work type: type of operation to be offloaded to QAT. - CpaStatus op_status; ///< Status of the operation after completion. - CpaFlatBuffer op_result; ///< Output of the operation in contiguous memory. - // CpaCyLnModExpOpData op_data; - void* op_data; ///< Input data packaged in QAT's data structure for the target type of operation. - void* op_output; ///< Pointer to the memory space where to store the output for the caller. - void* callback_func; ///< Pointer to the callback function. - volatile HE_QAT_STATUS request_status; - pthread_mutex_t mutex; - pthread_cond_t ready; -#ifdef HE_QAT_PERF - struct timeval start; ///< Time when the request was first received from the caller. - struct timeval end; ///< Time when the request completed processing and callback function was triggered. -#endif -} HE_QAT_TaskRequest; - -typedef struct { - HE_QAT_TaskRequest* request[HE_QAT_BUFFER_SIZE]; - unsigned int count; -} HE_QAT_TaskRequestList; - -#ifdef __cplusplus -} // close the extern "C" { -#endif - -#endif // _HE_QAT_TYPES_H_ diff --git a/module/heqat/he_qat/include/he_qat_utils.h b/module/heqat/he_qat/include/he_qat_utils.h deleted file mode 100644 index ce43fb0..0000000 --- a/module/heqat/he_qat/include/he_qat_utils.h +++ /dev/null @@ -1,20 +0,0 @@ - -#ifndef HE_QAT_UTILS_H_ -#define HE_QAT_UTILS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -BIGNUM* generateTestBNData(int nbits); -unsigned char* paddingZeros(BIGNUM* bn, int nbits); -void showHexBN(BIGNUM* bn, int nbits); -void showHexBin(unsigned char* bin, int len); - -#ifdef __cplusplus -} // extern "C" { -#endif - -#endif // HE_QAT_UTILS_H_ diff --git a/module/heqat/icp/CMakeLists.txt b/module/heqat/icp/CMakeLists.txt deleted file mode 100644 index 8bae5b4..0000000 --- a/module/heqat/icp/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ - -if(DEFINED ENV{ICP_ROOT}) - message(STATUS "Environment variable ICP_ROOT is defined as $ENV{ICP_ROOT}.") -else() - message(FATAL_ERROR "Environment variable ICP_ROOT must be defined. Try export ICP_ROOT=") -endif() - -set(ICP_ROOT $ENV{ICP_ROOT}) -set(ICP_BUILDOUTPUT_PATH ${ICP_ROOT}/build) -set(ICP_BUILDSYSTEM_PATH ${ICP_ROOT}/quickassist/build_system) -set(ICP_API_DIR ${ICP_ROOT}/quickassist) -set(ICP_LAC_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer) -set(ICP_OSAL_DIR ${ICP_ROOT}/quickassist/utilities/oasl) -set(ICP_ADF_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/qat_direct) -set(CMN_ROOT ${ICP_ROOT}/quickassist/utilities/libusdm_drv) - -set(ICP_INC_DIR ${ICP_API_DIR}/include - ${ICP_LAC_DIR}/include - ${ICP_ADF_DIR}/include - ${CMN_ROOT} - ${ICP_API_DIR}/include/dc - ${ICP_API_DIR}/include/lac) - -# Macros for the test case -add_definitions(-DDO_CRYPTO) -add_definitions(-DUSER_SPACE) -add_compile_options(-fPIC) - -add_library(libadf_static STATIC IMPORTED GLOBAL) -add_library(libosal_static STATIC IMPORTED GLOBAL) -add_library(libqat_static STATIC IMPORTED GLOBAL) -add_library(libusdm_drv_static STATIC IMPORTED GLOBAL) - -set_target_properties(libadf_static PROPERTIES - IMPORTED_LOCATION ${ICP_BUILDOUTPUT_PATH}/libadf.a -) - -set_target_properties(libosal_static PROPERTIES - IMPORTED_LOCATION ${ICP_BUILDOUTPUT_PATH}/libosal.a -) - -set_target_properties(libqat_static PROPERTIES - IMPORTED_LOCATION ${ICP_BUILDOUTPUT_PATH}/libqat.a -) - -set_target_properties(libusdm_drv_static PROPERTIES - IMPORTED_LOCATION ${ICP_BUILDOUTPUT_PATH}/libusdm_drv.a -) diff --git a/module/heqat/include/cpa_sample_utils.h b/module/heqat/include/cpa_sample_utils.h deleted file mode 100644 index a35b557..0000000 --- a/module/heqat/include/cpa_sample_utils.h +++ /dev/null @@ -1,639 +0,0 @@ -/*************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Corporation - * - * BSD LICENSE - * - * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * version: QAT.L.4.15.0-00011 - * - ***************************************************************************/ - -/** - ***************************************************************************** - * @file cpa_sample_utils.h - * - * @defgroup sampleUtils Macro and inline function definitions - * - * @ingroup sampleCode - * - * @description - * Defines macros for printing and debugging, inline functions for memory - * allocating and freeing and thread creation - * - ***************************************************************************/ - -#ifndef CPA_SAMPLE_UTILS_H -#define CPA_SAMPLE_UTILS_H - -#ifdef __cplusplus -#define HE_QAT_RESTRICT __restrict__ -#else -#define HE_QAT_RESTRICT restrict -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#include "cpa.h" -#include "cpa_cy_im.h" -#include "cpa_dc.h" - - -#ifdef DO_CRYPTO -#include "cpa_cy_sym.h" -#endif -#include "cpa_sample_cnv_utils.h" - -#ifdef USER_SPACE -/* User space utils */ -#include -#include -#include -#include -#include -#include -/* Performance sample code mem utils */ - -#include "qae_mem.h" - -extern CpaDcHuffType huffmanType_g; -extern CpaStatus qaeMemInit(void); -extern void qaeMemDestroy(void); -/* Threads */ -typedef pthread_t sampleThread; - -/* Check for CY API version */ -#define CY_API_VERSION_AT_LEAST(major, minor) \ - (CPA_CY_API_VERSION_NUM_MAJOR > major || \ - (CPA_CY_API_VERSION_NUM_MAJOR == major && \ - CPA_CY_API_VERSION_NUM_MINOR >= minor)) - -/* Printing */ -/**< Prints the name of the function and the arguments only if gDebugParam is - * CPA_TRUE. - */ -#define PRINT_DBG(args...) \ - do \ - { \ - if (CPA_TRUE == gDebugParam) \ - { \ - printf("%s(): ", __func__); \ - printf(args); \ - fflush(stdout); \ - } \ - } while (0) - -/**< Prints the arguments */ -#ifndef PRINT -#define PRINT(args...) \ - do \ - { \ - printf(args); \ - } while (0) -#endif - -/**< Prints the name of the function and the arguments */ -#ifndef PRINT_ERR -#define PRINT_ERR(args...) \ - do \ - { \ - printf("%s(): ", __func__); \ - printf(args); \ - } while (0) -#endif -/** - ******************************************************************************* - * @ingroup sampleUtils - * Completion definitions - * - ******************************************************************************/ -struct completion_struct -{ - sem_t semaphore; -}; -/* Use semaphores to signal completion of events */ -#define COMPLETION_STRUCT completion_struct - -#define COMPLETION_INIT(s) sem_init(&((s)->semaphore), 0, 0); - -#define COMPLETION_WAIT(s, timeout) (sem_wait(&((s)->semaphore)) == 0) - -#define COMPLETE(s) sem_post(&((s)->semaphore)) - -#define COMPLETION_DESTROY(s) sem_destroy(&((s)->semaphore)) - -#else -/* Kernel space utils */ -#include -#include -#include -#include -#include -#include -#include - -#ifdef __x86_64__ -#define SAMPLE_ADDR_LEN uint64_t -#else -#define SAMPLE_ADDR_LEN uint32_t -#endif - -extern CpaDcHuffType huffmanType_g; - -/* Threads */ -typedef struct task_struct *sampleThread; - -/* Check for CY API version */ -#define CY_API_VERSION_AT_LEAST(major, minor) \ - (CPA_CY_API_VERSION_NUM_MAJOR > major || \ - (CPA_CY_API_VERSION_NUM_MAJOR == major && \ - CPA_CY_API_VERSION_NUM_MINOR >= minor)) - -/* Printing */ -/**< Prints the name of the function and the arguments only if gDebugParam is - * CPA_TRUE. - */ -#define PRINT_DBG(args...) \ - do \ - { \ - if (CPA_TRUE == gDebugParam) \ - { \ - printk("%s(): ", __func__); \ - printk(KERN_CONT args); \ - } \ - } while (0) - -/**< Regular prints */ -#ifndef PRINT -#define PRINT(args...) \ - do \ - { \ - printk(KERN_CONT args); \ - } while (0) -#endif - -/**< Prints the name of the function and the arguments */ -#ifndef PRINT_ERR -#define PRINT_ERR(args...) \ - do \ - { \ - printk("%s(): ", __func__); \ - printk(KERN_CONT args); \ - } while (0) -#endif -/** - ******************************************************************************* - * @ingroup sampleUtils - * Completion definitions - * - ******************************************************************************/ -#define COMPLETION_STRUCT completion - -#define COMPLETION_INIT(c) init_completion(c) - -#define COMPLETION_WAIT(c, timeout) \ - wait_for_completion_interruptible_timeout(c, timeout) - -#define COMPLETE(c) complete(c) - -#define COMPLETION_DESTROY(s) - -#endif - -#ifndef BYTE_ALIGNMENT_8 -#define BYTE_ALIGNMENT_8 (8) -#endif -#ifndef BYTE_ALIGNMENT_64 -#define BYTE_ALIGNMENT_64 (64) -#endif - -/** - ***************************************************************************** - * @ingroup fipsSampleCodeUtils - * displayHexArray - * - * @description - * Display the contents of a buffer - * - * @param[in] pLabel String to giving a short description of the printed - * value - * @param[in] pBuff pointer to the data to be printed - * @param[in] len len of the data to be printed - * - * @retval none - * - * @pre - * none - * @post - * none - *****************************************************************************/ -static inline void displayHexArray(const char *HE_QAT_RESTRICT pLabel, - const Cpa8U *HE_QAT_RESTRICT pBuff, - Cpa32U len) -{ - - int i = 0; - PRINT("%s(%d)", pLabel, len); - if (NULL == pBuff) - { - PRINT("%s(%d) Buff is NULL!!\n", __FUNCTION__, __LINE__); - return; - } - for (i = 0; i < len; i++) - { - PRINT("%02x", pBuff[i]); - } - PRINT("\n"); -} -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function and associated macro sleeps for ms milliseconds - * - * @param[in] ms sleep time in ms - * - * @retval none - * - ******************************************************************************/ -static __inline CpaStatus sampleSleep(Cpa32U ms) -{ -#ifdef USER_SPACE - int ret = 0; - struct timespec resTime, remTime; - //resTime.tv_sec = ms / 1000; - //resTime.tv_nsec = (ms % 1000) * 1000000; - // microseconds - resTime.tv_sec = ms / 1000000; - resTime.tv_nsec = (ms % 1000000) * 1000; - do - { - ret = nanosleep(&resTime, &remTime); - resTime = remTime; - } while ((ret != 0) && (errno == EINTR)); - - if (ret != 0) - { - PRINT_ERR("nanoSleep failed with code %d\n", ret); - return CPA_STATUS_FAIL; - } - else - { - return CPA_STATUS_SUCCESS; - } -#else - if (ms != 0) - { - set_current_state((long)TASK_INTERRUPTIBLE); - schedule_timeout((ms * HZ) / 1000); - } - else - { - schedule(); - } - - return CPA_STATUS_SUCCESS; -#endif -} -/** - ******************************************************************************* - * @ingroup sampleUtils - * Macro from the sampleSleep function - * - ******************************************************************************/ -#define OS_SLEEP(ms) sampleSleep((ms)) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function and associated macro allocates the memory for the given - * size and stores the address of the memory allocated in the pointer. - * Memory allocated by this function is NOT guaranteed to be physically - * contiguous. - * - * @param[out] ppMemAddr address of pointer where address will be stored - * @param[in] sizeBytes the size of the memory to be allocated - * - * @retval CPA_STATUS_RESOURCE Macro failed to allocate Memory - * @retval CPA_STATUS_SUCCESS Macro executed successfully - * - ******************************************************************************/ -static __inline CpaStatus Mem_OsMemAlloc(void **ppMemAddr, Cpa32U sizeBytes) -{ -#ifdef USER_SPACE - *ppMemAddr = malloc(sizeBytes); - if (NULL == *ppMemAddr) - { - return CPA_STATUS_RESOURCE; - } - return CPA_STATUS_SUCCESS; -#else - *ppMemAddr = kmalloc(sizeBytes, GFP_KERNEL); - if (NULL == *ppMemAddr) - { - return CPA_STATUS_RESOURCE; - } - return CPA_STATUS_SUCCESS; -#endif -} - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function and associated macro allocates the memory for the given - * size for the given alignment and stores the address of the memory - * allocated in the pointer. Memory allocated by this function is - * guaranteed to be physically contiguous. - * - * @param[out] ppMemAddr address of pointer where address will be stored - * @param[in] sizeBytes the size of the memory to be allocated - * @param[in] alignement the alignment of the memory to be allocated - *(non-zero) - * - * @retval CPA_STATUS_RESOURCE Macro failed to allocate Memory - * @retval CPA_STATUS_SUCCESS Macro executed successfully - * - ******************************************************************************/ -static __inline CpaStatus Mem_Alloc_Contig(void **ppMemAddr, - Cpa32U sizeBytes, - Cpa32U alignment) -{ -#ifdef USER_SPACE - /* Use perf sample code memory allocator */ - - /* In this sample all allocations are done from node=0 - * This might not be optimal in a dual processor system. - */ - *ppMemAddr = qaeMemAllocNUMA(sizeBytes, 0, alignment); - if (NULL == *ppMemAddr) - { - return CPA_STATUS_RESOURCE; - } - return CPA_STATUS_SUCCESS; -#else - void *pAlloc = NULL; - uint32_t align = 0; - - pAlloc = - kmalloc_node((sizeBytes + alignment + sizeof(void *)), GFP_KERNEL, 0); - if (NULL == pAlloc) - { - return CPA_STATUS_RESOURCE; - } - - *ppMemAddr = pAlloc + sizeof(void *); - - align = ((SAMPLE_ADDR_LEN)(*ppMemAddr)) % alignment; - - *ppMemAddr += (alignment - align); - *(SAMPLE_ADDR_LEN *)(*ppMemAddr - sizeof(void *)) = (SAMPLE_ADDR_LEN)pAlloc; - - return CPA_STATUS_SUCCESS; -#endif -} - -/** - ******************************************************************************* - * @ingroup sampleUtils - * Macro from the Mem_OsMemAlloc function - * - ******************************************************************************/ -#define OS_MALLOC(ppMemAddr, sizeBytes) \ - Mem_OsMemAlloc((void *)(ppMemAddr), (sizeBytes)) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * Macro from the Mem_Alloc_Contig function - * - ******************************************************************************/ -#define PHYS_CONTIG_ALLOC(ppMemAddr, sizeBytes) \ - Mem_Alloc_Contig((void *)(ppMemAddr), (sizeBytes), 1) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * Algined version of PHYS_CONTIG_ALLOC() macro - * - ******************************************************************************/ -#define PHYS_CONTIG_ALLOC_ALIGNED(ppMemAddr, sizeBytes, alignment) \ - Mem_Alloc_Contig((void *)(ppMemAddr), (sizeBytes), (alignment)) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function and associated macro frees the memory at the given address - * and resets the pointer to NULL. The memory must have been allocated by - * the function Mem_OsMemAlloc() - * - * @param[out] ppMemAddr address of pointer where mem address is stored. - * If pointer is NULL, the function will exit silently - * - * @retval void - * - ******************************************************************************/ -static __inline void Mem_OsMemFree(void **ppMemAddr) -{ -#ifdef USER_SPACE - if (NULL != *ppMemAddr) - { - free(*ppMemAddr); - *ppMemAddr = NULL; - } -#else - if (NULL != *ppMemAddr) - { - kfree(*ppMemAddr); - *ppMemAddr = NULL; - } -#endif -} - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function and associated macro frees the memory at the given address - * and resets the pointer to NULL. The memory must have been allocated by - * the function Mem_Alloc_Contig(). - * - * @param[out] ppMemAddr address of pointer where mem address is stored. - * If pointer is NULL, the function will exit silently - * - * @retval void - * - ******************************************************************************/ -static __inline void Mem_Free_Contig(void **ppMemAddr) -{ -#ifdef USER_SPACE - if (NULL != *ppMemAddr) - { - qaeMemFreeNUMA(ppMemAddr); - *ppMemAddr = NULL; - } -#else - void *pAlloc = NULL; - - if (NULL != *ppMemAddr) - { - pAlloc = (void *)(*((SAMPLE_ADDR_LEN *)(*ppMemAddr - sizeof(void *)))); - kfree(pAlloc); - *ppMemAddr = NULL; - } -#endif -} - -/** - ******************************************************************************* - * @ingroup sampleUtils - * Macro from the Mem_OsMemFree function - * - ******************************************************************************/ -#define OS_FREE(pMemAddr) Mem_OsMemFree((void *)&pMemAddr) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * Macro from the Mem_Free_Contig function - * - ******************************************************************************/ -#define PHYS_CONTIG_FREE(pMemAddr) Mem_Free_Contig((void *)&pMemAddr) - -#define _4K_PAGE_SIZE (4 * 1024) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function returns the physical address for a given virtual address. - * In case of error 0 is returned. - * - * @param[in] virtAddr Virtual address - * - * @retval CpaPhysicalAddr Physical address or 0 in case of error - * - ******************************************************************************/ - -static __inline CpaPhysicalAddr sampleVirtToPhys(void *virtAddr) -{ -#ifdef USER_SPACE - return (CpaPhysicalAddr)qaeVirtToPhysNUMA(virtAddr); -#else - return (CpaPhysicalAddr)virt_to_phys(virtAddr); -#endif -} - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function creates a thread - * - ******************************************************************************/ - -static __inline CpaStatus sampleThreadCreate(sampleThread *thread, - void *funct, - void *args) -{ -#ifdef USER_SPACE -#ifdef __cplusplus - if (pthread_create(thread, NULL, (void* (*)(void*)) funct, args) != 0) -#else - if (pthread_create(thread, NULL, funct, args) != 0) -#endif - { - PRINT_ERR("Failed create thread\n"); - return CPA_STATUS_FAIL; - } - else - { - pthread_detach(*thread); - return CPA_STATUS_SUCCESS; - } -#else - *thread = kthread_create(funct, args, "SAMPLE_THREAD"); - wake_up_process(*thread); - return CPA_STATUS_SUCCESS; -#endif -} - -static __inline void sampleThreadExit(void) -{ -#ifdef USER_SPACE - pthread_exit(NULL); -#endif -} - -#ifdef DO_CRYPTO -void sampleCyGetInstance(CpaInstanceHandle *pCyInstHandle); - -void sampleCyStartPolling(CpaInstanceHandle cyInstHandle); - -void sampleCyStopPolling(void); - -void symSessionWaitForInflightReq(CpaCySymSessionCtx pSessionCtx); -#endif // DO_CRYPTO - -void sampleDcGetInstance(CpaInstanceHandle *pDcInstHandle); - -void sampleDcStartPolling(CpaInstanceHandle dcInstHandle); - -void sampleDcStopPolling(void); - -#ifdef __cplusplus -} //extern "C" { -#endif - - -#endif - diff --git a/module/heqat/misc/CMakeLists.txt b/module/heqat/misc/CMakeLists.txt deleted file mode 100644 index f37b8db..0000000 --- a/module/heqat/misc/CMakeLists.txt +++ /dev/null @@ -1,51 +0,0 @@ - -#Include directories -#list(APPEND HE_QAT_MISC_INC_DIR -set(HE_QAT_MISC_INC_DIR ${COMMON_INC_DIR} - ${HE_QAT_INC_DIR} - ${CMAKE_CURRENT_LIST_DIR} - # ${IPPCP_DIR}/include -) - -message(STATUS "HE_QAT_MISC_INC_DIR: ${HE_QAT_MISC_INC_DIR}") - -#Source files -#list(APPEND HE_QAT_MISC_SRC ${CMAKE_CURRENT_LIST_DIR} / utils.cpp -set(HE_QAT_MISC_SRC - ${CMAKE_CURRENT_LIST_DIR}/he_qat_misc.cpp - ${CMAKE_CURRENT_LIST_DIR}/utils.cpp - ${CMAKE_CURRENT_LIST_DIR}/bignum.cpp) - -if(HE_QAT_SHARED) - add_library(he_qat_misc SHARED ${HE_QAT_MISC_SRC}) -else() - add_library(he_qat_misc STATIC ${HE_QAT_MISC_SRC}) -endif() - -message(STATUS "IPPCP Headers Directory ${IPPCP_DIR}/include") -target_include_directories(he_qat_misc #PUBLIC $ #Public headers - #PUBLIC $ #Public headers - PRIVATE ${IPPCP_DIR}/../../../include - PRIVATE ${HE_QAT_MISC_INC_DIR} #Private headers - PRIVATE ${ICP_INC_DIR} #Private headers - -) -#target_link_directories(he_qat_misc PUBLIC ${IPPCP_DIR}/lib/intel64) -#target_link_libraries(he_qat_misc PRIVATE ippcpmx crypto_mb) - -if(HE_QAT_SHARED) - target_link_libraries(he_qat_misc PRIVATE IPPCP::ippcp IPPCP::crypto_mb) -else() - heqat_create_archive(he_qat_misc IPPCP::ippcp) - heqat_create_archive(he_qat_misc IPPCP::crypto_mb) -endif() - -install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ - FILES_MATCHING - PATTERN "*.hpp" - PATTERN "*.h") -#install(TARGETS he_qat_misc DESTINATION ${CMAKE_INSTALL_LIBDIR}) -install(TARGETS he_qat_misc EXPORT he_qatTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}) - -set(HE_QAT_MISC_INC_DIR ${HE_QAT_MISC_INC_DIR} PARENT_SCOPE) diff --git a/module/heqat/misc/bignum.cpp b/module/heqat/misc/bignum.cpp deleted file mode 100644 index 1e88859..0000000 --- a/module/heqat/misc/bignum.cpp +++ /dev/null @@ -1,394 +0,0 @@ -/******************************************************************************* - * Copyright 2019-2021 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ - -#include "bignum.h" -#include -#include -#include "utils.h" - -////////////////////////////////////////////////////////////////////// -// -// BigNumber -// -////////////////////////////////////////////////////////////////////// -BigNumber::~BigNumber() { delete[](Ipp8u*) m_pBN; } - -bool BigNumber::create(const Ipp32u* pData, int length, IppsBigNumSGN sgn) { - int size; - ippsBigNumGetSize(length, &size); - m_pBN = (IppsBigNumState*)(new Ipp8u[size]); - if (!m_pBN) return false; - ippsBigNumInit(length, m_pBN); - if (pData) ippsSet_BN(sgn, length, pData, m_pBN); - return true; -} - -// -// constructors -// -BigNumber::BigNumber(Ipp32u value) { create(&value, 1, IppsBigNumPOS); } - -BigNumber::BigNumber(Ipp32s value) { - Ipp32s avalue = abs(value); - create((Ipp32u*)&avalue, 1, (value < 0) ? IppsBigNumNEG : IppsBigNumPOS); -} - -BigNumber::BigNumber(const IppsBigNumState* pBN) { - IppsBigNumSGN bnSgn; - int bnBitLen; - Ipp32u* bnData; - ippsRef_BN(&bnSgn, &bnBitLen, &bnData, pBN); - - create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); -} - -BigNumber::BigNumber(const Ipp32u* pData, int length, IppsBigNumSGN sgn) { - create(pData, length, sgn); -} - -static char HexDigitList[] = "0123456789ABCDEF"; - -BigNumber::BigNumber(const char* s) { - bool neg = '-' == s[0]; - if (neg) s++; - bool hex = ('0' == s[0]) && (('x' == s[1]) || ('X' == s[1])); - - int dataLen; - Ipp32u base; - if (hex) { - s += 2; - base = 0x10; - dataLen = (int)(strlen_safe(s) + 7) / 8; - } else { - base = 10; - dataLen = (int)(strlen_safe(s) + 9) / 10; - } - - create(0, dataLen); - *(this) = Zero(); - while (*s) { - char tmp[2] = {s[0], 0}; - Ipp32u digit = (Ipp32u)strcspn(HexDigitList, tmp); - *this = (*this) * base + BigNumber(digit); - s++; - } - - if (neg) (*this) = Zero() - (*this); -} - -BigNumber::BigNumber(const BigNumber& bn) { - IppsBigNumSGN bnSgn; - int bnBitLen; - Ipp32u* bnData; - ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); - - create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); -} - -// -// set value -// -void BigNumber::Set(const Ipp32u* pData, int length, IppsBigNumSGN sgn) { - ippsSet_BN(sgn, length, pData, BN(*this)); -} - -// -// constants -// -const BigNumber& BigNumber::Zero() { - static const BigNumber zero(0); - return zero; -} - -const BigNumber& BigNumber::One() { - static const BigNumber one(1); - return one; -} - -const BigNumber& BigNumber::Two() { - static const BigNumber two(2); - return two; -} - -// -// arithmetic operators -// -BigNumber& BigNumber::operator=(const BigNumber& bn) { - if (this != &bn) { // prevent self copy - IppsBigNumSGN bnSgn; - int bnBitLen; - Ipp32u* bnData; - ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); - - delete[](Ipp8u*) m_pBN; - create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); - } - return *this; -} - -BigNumber& BigNumber::operator+=(const BigNumber& bn) { - int aBitLen; - ippsRef_BN(NULL, &aBitLen, NULL, *this); - int bBitLen; - ippsRef_BN(NULL, &bBitLen, NULL, bn); - int rBitLen = IPP_MAX(aBitLen, bBitLen) + 1; - - BigNumber result(0, BITSIZE_WORD(rBitLen)); - ippsAdd_BN(*this, bn, result); - *this = result; - return *this; -} - -BigNumber& BigNumber::operator-=(const BigNumber& bn) { - int aBitLen; - ippsRef_BN(NULL, &aBitLen, NULL, *this); - int bBitLen; - ippsRef_BN(NULL, &bBitLen, NULL, bn); - int rBitLen = IPP_MAX(aBitLen, bBitLen); - - BigNumber result(0, BITSIZE_WORD(rBitLen)); - ippsSub_BN(*this, bn, result); - *this = result; - return *this; -} - -BigNumber& BigNumber::operator*=(const BigNumber& bn) { - int aBitLen; - ippsRef_BN(NULL, &aBitLen, NULL, *this); - int bBitLen; - ippsRef_BN(NULL, &bBitLen, NULL, bn); - int rBitLen = aBitLen + bBitLen; - - BigNumber result(0, BITSIZE_WORD(rBitLen)); - ippsMul_BN(*this, bn, result); - *this = result; - return *this; -} - -BigNumber& BigNumber::operator*=(Ipp32u n) { - int aBitLen; - ippsRef_BN(NULL, &aBitLen, NULL, *this); - - BigNumber result(0, BITSIZE_WORD(aBitLen + 32)); - BigNumber bn(n); - ippsMul_BN(*this, bn, result); - *this = result; - return *this; -} - -BigNumber& BigNumber::operator%=(const BigNumber& bn) { - BigNumber remainder(bn); - ippsMod_BN(BN(*this), BN(bn), BN(remainder)); - *this = remainder; - return *this; -} - -BigNumber& BigNumber::operator/=(const BigNumber& bn) { - BigNumber quotient(*this); - BigNumber remainder(bn); - ippsDiv_BN(BN(*this), BN(bn), BN(quotient), BN(remainder)); - *this = quotient; - return *this; -} - -BigNumber operator+(const BigNumber& a, const BigNumber& b) { - BigNumber r(a); - return r += b; -} - -BigNumber operator-(const BigNumber& a, const BigNumber& b) { - BigNumber r(a); - return r -= b; -} - -BigNumber operator*(const BigNumber& a, const BigNumber& b) { - BigNumber r(a); - return r *= b; -} - -BigNumber operator*(const BigNumber& a, Ipp32u n) { - BigNumber r(a); - return r *= n; -} - -BigNumber operator/(const BigNumber& a, const BigNumber& b) { - BigNumber q(a); - return q /= b; -} - -BigNumber operator%(const BigNumber& a, const BigNumber& b) { - BigNumber r(b); - ippsMod_BN(BN(a), BN(b), BN(r)); - return r; -} - -// -// modulo arithmetic -// -BigNumber BigNumber::Modulo(const BigNumber& a) const { return a % *this; } - -BigNumber BigNumber::InverseAdd(const BigNumber& a) const { - BigNumber t = Modulo(a); - if (t == BigNumber::Zero()) - return t; - else - return *this - t; -} - -BigNumber BigNumber::InverseMul(const BigNumber& a) const { - BigNumber r(*this); - ippsModInv_BN(BN(a), BN(*this), BN(r)); - return r; -} - -BigNumber BigNumber::ModAdd(const BigNumber& a, const BigNumber& b) const { - BigNumber r = this->Modulo(a + b); - return r; -} - -BigNumber BigNumber::ModSub(const BigNumber& a, const BigNumber& b) const { - BigNumber r = this->Modulo(a + this->InverseAdd(b)); - return r; -} - -BigNumber BigNumber::ModMul(const BigNumber& a, const BigNumber& b) const { - BigNumber r = this->Modulo(a * b); - return r; -} - -// -// comparison -// -int BigNumber::compare(const BigNumber& bn) const { - Ipp32u result; - BigNumber tmp = *this - bn; - ippsCmpZero_BN(BN(tmp), &result); - return (result == IS_ZERO) ? 0 : (result == GREATER_THAN_ZERO) ? 1 : -1; -} - -bool operator<(const BigNumber& a, const BigNumber& b) { - return a.compare(b) < 0; -} -bool operator>(const BigNumber& a, const BigNumber& b) { - return a.compare(b) > 0; -} -bool operator==(const BigNumber& a, const BigNumber& b) { - return 0 == a.compare(b); -} -bool operator!=(const BigNumber& a, const BigNumber& b) { - return 0 != a.compare(b); -} - -// easy tests -// -bool BigNumber::IsOdd() const { - Ipp32u* bnData; - ippsRef_BN(NULL, NULL, &bnData, *this); - return bnData[0] & 1; -} - -// -// size of BigNumber -// -int BigNumber::LSB() const { - if (*this == BigNumber::Zero()) return 0; - - vector v; - num2vec(v); - - int lsb = 0; - vector::iterator i; - for (i = v.begin(); i != v.end(); i++) { - Ipp32u x = *i; - if (0 == x) - lsb += 32; - else { - while (0 == (x & 1)) { - lsb++; - x >>= 1; - } - break; - } - } - return lsb; -} - -int BigNumber::MSB() const { - if (*this == BigNumber::Zero()) return 0; - - vector v; - num2vec(v); - - int msb = (int)v.size() * 32 - 1; - vector::reverse_iterator i; - for (i = v.rbegin(); i != v.rend(); i++) { - Ipp32u x = *i; - if (0 == x) - msb -= 32; - else { - while (!(x & 0x80000000)) { - msb--; - x <<= 1; - } - break; - } - } - return msb; -} - -int Bit(const vector& v, int n) { - return 0 != (v[n >> 5] & (1 << (n & 0x1F))); -} - -// -// conversions and output -// -void BigNumber::num2vec(vector& v) const { - int bnBitLen; - Ipp32u* bnData; - ippsRef_BN(NULL, &bnBitLen, &bnData, *this); - - int len = BITSIZE_WORD(bnBitLen); - ; - for (int n = 0; n < len; n++) v.push_back(bnData[n]); -} - -void BigNumber::num2hex(string& s) const { - IppsBigNumSGN bnSgn; - int bnBitLen; - Ipp32u* bnData; - ippsRef_BN(&bnSgn, &bnBitLen, &bnData, *this); - - int len = BITSIZE_WORD(bnBitLen); - - s.append(1, (bnSgn == ippBigNumNEG) ? '-' : ' '); - s.append(1, '0'); - s.append(1, 'x'); - for (int n = len; n > 0; n--) { - Ipp32u x = bnData[n - 1]; - for (int nd = 8; nd > 0; nd--) { - char c = HexDigitList[(x >> (nd - 1) * 4) & 0xF]; - s.append(1, c); - } - } -} - -ostream& operator<<(ostream& os, const BigNumber& a) { - string s; - a.num2hex(s); - os << s.c_str(); - return os; -} diff --git a/module/heqat/misc/bignum.h b/module/heqat/misc/bignum.h deleted file mode 100644 index 68c3e4d..0000000 --- a/module/heqat/misc/bignum.h +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* - * Copyright 2019-2021 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ - -#if !defined _BIGNUMBER_H_ -#define _BIGNUMBER_H_ - -#include "ippcp.h" - -#include -#include -#include - -using namespace std; - -class BigNumber { -public: - BigNumber(Ipp32u value = 0); - BigNumber(Ipp32s value); - BigNumber(const IppsBigNumState* pBN); - BigNumber(const Ipp32u* pData, int length = 1, - IppsBigNumSGN sgn = IppsBigNumPOS); - BigNumber(const BigNumber& bn); - BigNumber(const char* s); - virtual ~BigNumber(); - - // set value - void Set(const Ipp32u* pData, int length = 1, - IppsBigNumSGN sgn = IppsBigNumPOS); - // conversion to IppsBigNumState - friend IppsBigNumState* BN(const BigNumber& bn) { return bn.m_pBN; } - operator IppsBigNumState*() const { return m_pBN; } - - // some useful constatns - static const BigNumber& Zero(); - static const BigNumber& One(); - static const BigNumber& Two(); - - // arithmetic operators probably need - BigNumber& operator=(const BigNumber& bn); - BigNumber& operator+=(const BigNumber& bn); - BigNumber& operator-=(const BigNumber& bn); - BigNumber& operator*=(Ipp32u n); - BigNumber& operator*=(const BigNumber& bn); - BigNumber& operator/=(const BigNumber& bn); - BigNumber& operator%=(const BigNumber& bn); - friend BigNumber operator+(const BigNumber& a, const BigNumber& b); - friend BigNumber operator-(const BigNumber& a, const BigNumber& b); - friend BigNumber operator*(const BigNumber& a, const BigNumber& b); - friend BigNumber operator*(const BigNumber& a, Ipp32u); - friend BigNumber operator%(const BigNumber& a, const BigNumber& b); - friend BigNumber operator/(const BigNumber& a, const BigNumber& b); - - // modulo arithmetic - BigNumber Modulo(const BigNumber& a) const; - BigNumber ModAdd(const BigNumber& a, const BigNumber& b) const; - BigNumber ModSub(const BigNumber& a, const BigNumber& b) const; - BigNumber ModMul(const BigNumber& a, const BigNumber& b) const; - BigNumber InverseAdd(const BigNumber& a) const; - BigNumber InverseMul(const BigNumber& a) const; - - // comparisons - friend bool operator<(const BigNumber& a, const BigNumber& b); - friend bool operator>(const BigNumber& a, const BigNumber& b); - friend bool operator==(const BigNumber& a, const BigNumber& b); - friend bool operator!=(const BigNumber& a, const BigNumber& b); - friend bool operator<=(const BigNumber& a, const BigNumber& b) { - return !(a > b); - } - friend bool operator>=(const BigNumber& a, const BigNumber& b) { - return !(a < b); - } - - // easy tests - bool IsOdd() const; - bool IsEven() const { return !IsOdd(); } - - // size of BigNumber - int MSB() const; - int LSB() const; - int BitSize() const { return MSB() + 1; } - int DwordSize() const { return (BitSize() + 31) >> 5; } - friend int Bit(const vector& v, int n); - - // conversion and output - void num2hex(string& s) const; // convert to hex string - void num2vec(vector& v) const; // convert to 32-bit word vector - friend ostream& operator<<(ostream& os, const BigNumber& a); - -protected: - bool create(const Ipp32u* pData, int length, - IppsBigNumSGN sgn = IppsBigNumPOS); - int compare(const BigNumber&) const; - IppsBigNumState* m_pBN; -}; - -// convert bit size into 32-bit words -#define BITSIZE_WORD(n) ((((n) + 31) >> 5)) - -#endif // _BIGNUMBER_H_ diff --git a/module/heqat/misc/he_qat_misc.cpp b/module/heqat/misc/he_qat_misc.cpp deleted file mode 100644 index efee2e2..0000000 --- a/module/heqat/misc/he_qat_misc.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/// @file he_qat_misc.cpp - -#include "he_qat_misc.h" - -//#ifdef __cplusplus -//#include "bignum.h" -//#endif - -#include -#include - -//#ifdef __cplusplus -HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, - int nbits) { - if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; - int len_ = (nbits + 7) >> 3; // nbits/8; - - // Create BigNumber containg input data passed as argument - bn = BigNumber(reinterpret_cast(data), BITSIZE_WORD(nbits)); - Ipp32u* ref_bn_data_ = NULL; - ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); - - // Convert it to little endian format - unsigned char* data_ = reinterpret_cast(ref_bn_data_); - for (int i = 0; i < len_; i++) data_[i] = data[len_ - 1 - i]; - - return HE_QAT_STATUS_SUCCESS; -} - -HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, - const BigNumber& bn) { - if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; - int len_ = (nbits + 7) >> 3; // nbits/8; - - // Extract raw vector of data in little endian format - Ipp32u* ref_bn_data_ = NULL; - ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); - - // Revert it to big endian format - unsigned char* data_ = reinterpret_cast(ref_bn_data_); - for (int i = 0; i < len_; i++) data[i] = data_[len_ - 1 - i]; - - return HE_QAT_STATUS_SUCCESS; -} - -//} // extern "C" { -//#endif diff --git a/module/heqat/misc/he_qat_misc.h b/module/heqat/misc/he_qat_misc.h deleted file mode 100644 index 459d5e0..0000000 --- a/module/heqat/misc/he_qat_misc.h +++ /dev/null @@ -1,33 +0,0 @@ -/// @file he_qat_misc.h - -#ifndef HE_QAT_MISC_H_ -#define HE_QAT_MISC_H_ - -#pragma once - -#include "he_qat_gconst.h" -#include "he_qat_types.h" -#include "bignum.h" -#include - -/// @brief -/// Convert QAT large number into little endian format and encapsulate it into a -/// BigNumber object. -/// @param[out] bn BigNumber object representing multi-precision number in -/// little endian format. -/// @param[in] data Large number of nbits precision in big endian format. -/// @param[in] nbits Number of bits. Has to be power of 2, e.g. 1024, 2048, -/// 4096, etc. -HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, - int nbits); -/// @brief -/// Convert BigNumber object into raw data compatible with QAT. -/// @param[out] data BigNumber object's raw data in big endian format. -/// @param[in] nbits Number of bits. Has to be power of 2, e.g. 1024, 2048, -/// 4096, etc. -/// @param[in] bn BigNumber object holding a multi-precision that can be -/// represented in nbits. -HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, - const BigNumber& bn); - -#endif // HE_QAT_MISC_H_ diff --git a/module/heqat/misc/utils.cpp b/module/heqat/misc/utils.cpp deleted file mode 100644 index 1bf189b..0000000 --- a/module/heqat/misc/utils.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * Copyright 2021 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ - -#include "utils.h" - -size_t strlen_safe(const char* dest, size_t dmax) { - size_t count; - - /* check null pointer */ - if (NULL == dest) { - return 0UL; - } - - /* check max equal zero */ - if (0UL == dmax) { - return 0UL; - } - - /* check dmax > 4Kb */ - if (dmax > RSIZE_MAX_STR) { - return 0UL; - } - - count = 0UL; - while (*dest && dmax) { - ++count; - --dmax; - ++dest; - } - - return count; -} diff --git a/module/heqat/misc/utils.h b/module/heqat/misc/utils.h deleted file mode 100644 index bc06bff..0000000 --- a/module/heqat/misc/utils.h +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - * Copyright 2021 Intel Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -#ifndef _UTILS_H_ -#define _UTILS_H_ - -#include - -#define RSIZE_MAX_STR (4UL << 10) /* 4Kb */ - -/** - * \brief - * The strnlen_s function computes the length of the string pointed to by dest. - * \param[in] dest pointer to string - * \param[in] dmax restricted maximum length. (default 4Kb) - * \return size_t - * The function returns the string length, excluding the terminating - * null character. If dest is NULL, then strnlen_s returns 0. - */ -size_t strlen_safe(const char* dest, size_t dmax = RSIZE_MAX_STR); - -#endif // _UTILS_H_ diff --git a/module/heqat/samples/CMakeLists.txt b/module/heqat/samples/CMakeLists.txt deleted file mode 100644 index 2a62889..0000000 --- a/module/heqat/samples/CMakeLists.txt +++ /dev/null @@ -1,81 +0,0 @@ - -if(HE_QAT_DEBUG) - add_definitions(-D_DESTINY_DEBUG_VERBOSE) -endif() - -# ------------------------------------------------------------------------------------------- - -add_executable(test_context test_context.c) - -target_include_directories(test_context PUBLIC ${COMMON_INC_DIR}) -#target_include_directories(test_context PUBLIC ${HE_QAT_INC_DIR}) -target_include_directories(test_context PUBLIC ${ICP_INC_DIR}) - -target_link_libraries(test_context PUBLIC he_qat) - -install(TARGETS test_context RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) - -# ------------------------------------------------------------------------------------------- - -add_executable(test_BIGNUMModExp test_BIGNUMModExp.c) - -target_include_directories(test_BIGNUMModExp PUBLIC ${COMMON_INC_DIR}) # ${HE_QAT_UTILS_INC_DIR}) -#target_include_directories(test_BIGNUMModExp PUBLIC ${HE_QAT_INC_DIR}) -target_include_directories(test_BIGNUMModExp PUBLIC ${ICP_INC_DIR}) - -target_link_libraries(test_BIGNUMModExp PUBLIC he_qat) -target_link_libraries(test_BIGNUMModExp PUBLIC OpenSSL::SSL) # OpenSSL::Crypto) -#target_link_libraries(test_BIGNUMModExp PUBLIC IPPCP::ippcp) - -install(TARGETS test_BIGNUMModExp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) - -# ------------------------------------------------------------------------------------------- - -if(HE_QAT_MISC) - add_compile_options(-fpermissive) - - # Sample showing how to convert from/to BigNumber to/from CpaFlatBuffer - add_executable(test_bnConversion test_bnConversion.cpp) - - target_include_directories(test_bnConversion PUBLIC ${COMMON_INC_DIR}) - target_include_directories(test_bnConversion PUBLIC ${ICP_INC_DIR}) - target_include_directories(test_bnConversion PUBLIC ${HE_QAT_MISC_INC_DIR}) - - target_link_libraries(test_bnConversion PUBLIC he_qat) - target_link_libraries(test_bnConversion PUBLIC he_qat_misc) - target_link_libraries(test_bnConversion PUBLIC IPPCP::ippcp) # IPPCP::crypto_mb) - target_link_libraries(test_bnConversion PUBLIC OpenSSL::SSL) # OpenSSL::Crypto) - - install(TARGETS test_bnConversion RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) - - # Sample demonstrating how to use bnModExp - add_executable(test_bnModExp test_bnModExp.cpp) - - target_include_directories(test_bnModExp PUBLIC ${COMMON_INC_DIR}) - target_include_directories(test_bnModExp PUBLIC ${ICP_INC_DIR}) - target_include_directories(test_bnModExp PUBLIC ${HE_QAT_MISC_INC_DIR}) - - target_link_libraries(test_bnModExp PUBLIC he_qat) - target_link_libraries(test_bnModExp PUBLIC he_qat_misc) - target_link_libraries(test_bnModExp PUBLIC IPPCP::ippcp) # IPPCP::crypto_mb) - target_link_libraries(test_bnModExp PUBLIC OpenSSL::SSL) # OpenSSL::Crypto) - - install(TARGETS test_bnModExp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) - - if(OpenMP_CXX_FOUND) - # Sample demonstrating how to use multithread-supported interface bnModExp_MT - add_executable(test_bnModExp_MT test_bnModExp_MT.cpp) - - target_include_directories(test_bnModExp_MT PUBLIC ${COMMON_INC_DIR}) - target_include_directories(test_bnModExp_MT PUBLIC ${ICP_INC_DIR}) - target_include_directories(test_bnModExp_MT PUBLIC ${HE_QAT_MISC_INC_DIR}) - - target_link_libraries(test_bnModExp_MT PUBLIC he_qat) - target_link_libraries(test_bnModExp_MT PUBLIC he_qat_misc) - target_link_libraries(test_bnModExp_MT PUBLIC OpenMP::OpenMP_CXX) - target_link_libraries(test_bnModExp_MT PUBLIC IPPCP::ippcp) # IPPCP::crypto_mb) - target_link_libraries(test_bnModExp_MT PUBLIC OpenSSL::SSL) # OpenSSL::Crypto) - - install(TARGETS test_bnModExp_MT RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) - endif() -endif() diff --git a/module/heqat/samples/test_BIGNUMModExp.c b/module/heqat/samples/test_BIGNUMModExp.c deleted file mode 100644 index 9a91a98..0000000 --- a/module/heqat/samples/test_BIGNUMModExp.c +++ /dev/null @@ -1,142 +0,0 @@ - -#include "cpa_sample_utils.h" -#include "he_qat_utils.h" -#include "he_qat_bn_ops.h" -#include "he_qat_context.h" - -#include -#include -#include -#include - -#include -struct timeval start_time, end_time; -double time_taken = 0.0; - -int gDebugParam = 1; // Active in Debug mode -const unsigned int BATCH_SIZE = 1; - -int main(int argc, const char** argv) { - const int bit_length = 4096; // 1024; - const size_t num_trials = 100; - - double avg_speed_up = 0.0; - double ssl_avg_time = 0.0; - double qat_avg_time = 0.0; - - double ssl_elapsed = 0.0 ; - double qat_elapsed = 0.0 ; - - HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; - - // Set up QAT runtime context - acquire_qat_devices(); - - // Set up OpenSSL context (as baseline) - BN_CTX* ctx = BN_CTX_new(); - BN_CTX_start(ctx); - - for (size_t mod = 0; mod < num_trials; mod++) { - BIGNUM* bn_mod = generateTestBNData(bit_length); - - if (!bn_mod) continue; - -#ifdef _DESTINY_DEBUG_VERBOSE - char* bn_str = BN_bn2hex(bn_mod); - printf("Generated modulus: %s num_bytes: %d num_bits: %d\n", bn_str, - BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); - OPENSSL_free(bn_str); -#endif - // bn_exponent in [0..bn_mod] - BIGNUM* bn_exponent = BN_new(); - if (!BN_rand_range(bn_exponent, bn_mod)) { - BN_free(bn_mod); - continue; - } - - BIGNUM* bn_base = generateTestBNData(bit_length); - - // Perform OpenSSL ModExp Op - BIGNUM* ssl_res = BN_new(); - //start = clock(); - gettimeofday(&start_time, NULL); - BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); - //ssl_elapsed = clock() - start; - gettimeofday(&end_time, NULL); - time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; - time_taken = - (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; - ssl_elapsed = time_taken; - - if (!ERR_get_error()) { -#ifdef _DESTINY_DEBUG_VERBOSE - bn_str = BN_bn2hex(ssl_res); - printf("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", bn_str, - BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); - showHexBN(ssl_res, bit_length); - OPENSSL_free(bn_str); -#endif - } else { - printf("Modular exponentiation failed.\n"); - } - -#ifdef _DESTINY_DEBUG_VERBOSE - PRINT_DBG("\nStarting QAT bnModExp...\n"); -#endif - - // Perform QAT ModExp Op - BIGNUM* qat_res = BN_new(); - //start = clock(); - gettimeofday(&start_time, NULL); - for (unsigned int j = 0; j < BATCH_SIZE; j++) - status = HE_QAT_BIGNUMModExp(qat_res, bn_base, bn_exponent, bn_mod, - bit_length); - getBnModExpRequest(BATCH_SIZE); - //qat_elapsed = clock() - start; - gettimeofday(&end_time, NULL); - time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; - time_taken = - (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; - qat_elapsed = time_taken; - - ssl_avg_time = (mod * ssl_avg_time + ssl_elapsed) / (mod + 1); - qat_avg_time = - (mod * qat_avg_time + qat_elapsed / BATCH_SIZE) / (mod + 1); - avg_speed_up = - (mod * avg_speed_up + - (ssl_elapsed) / (qat_elapsed/BATCH_SIZE)) / (mod + 1); - - printf( - "Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", - (mod + 1), ssl_avg_time, qat_avg_time, avg_speed_up); - - if (HE_QAT_STATUS_SUCCESS != status) { - PRINT_ERR("\nQAT bnModExpOp failed\n"); - } -#ifdef _DESTINY_DEBUG_VERBOSE - else { - PRINT_DBG("\nQAT bnModExpOp finished\n"); - } -#endif - - if (BN_cmp(qat_res, ssl_res) != 0) - printf("\t** FAIL **\n"); - else - printf("\t** PASS **\n"); - - BN_free(ssl_res); - BN_free(qat_res); - - BN_free(bn_mod); - BN_free(bn_base); - BN_free(bn_exponent); - } - - // Tear down OpenSSL context - BN_CTX_end(ctx); - - // Tear down QAT runtime context - release_qat_devices(); - - return (int)status; -} diff --git a/module/heqat/samples/test_bnConversion.cpp b/module/heqat/samples/test_bnConversion.cpp deleted file mode 100644 index 2e51b30..0000000 --- a/module/heqat/samples/test_bnConversion.cpp +++ /dev/null @@ -1,107 +0,0 @@ - -#include "he_qat_misc.h" -#include "he_qat_utils.h" - -#include -#include -#include -#include - -#include - -#include - -#include -struct timeval start_time, end_time; -double time_taken = 0.0; - -int main(int argc, const char** argv) { - const int bit_length = 1024; - const size_t num_trials = 4; - - double ssl_elapsed = 0.0 ; - double qat_elapsed = 0.0 ; - - HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; - - // Set up OpenSSL context (as baseline) - BN_CTX* ctx = BN_CTX_new(); - BN_CTX_start(ctx); - - for (unsigned int mod = 0; mod < num_trials; mod++) { - BIGNUM* bn_mod = generateTestBNData(bit_length); - - if (!bn_mod) continue; - - char* bn_str = BN_bn2hex(bn_mod); - printf("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, - BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); - OPENSSL_free(bn_str); - - int len_ = (bit_length + 7) >> 3; - - unsigned char* bn_mod_data_ = - (unsigned char*)calloc(len_, sizeof(unsigned char)); - if (NULL == bn_mod_data_) exit(1); - BN_bn2binpad(bn_mod, bn_mod_data_, len_); - - BN_free(bn_mod); - - BigNumber big_num((Ipp32u)0); - - gettimeofday(&start_time, NULL); - status = binToBigNumber(big_num, bn_mod_data_, bit_length); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("Failed at binToBigNumber()\n"); - exit(1); - } - gettimeofday(&end_time, NULL); - time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; - time_taken = - (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; - ssl_elapsed = time_taken; - printf("Conversion to BigNumber has completed in %.1lfus.\n", - (ssl_elapsed)); - - int bit_len = 0; - ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); - std::string str; - big_num.num2hex(str); - printf("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, - bit_len); - - gettimeofday(&start_time, NULL); - unsigned char* ref_bn_data_ = - (unsigned char*)calloc(len_, sizeof(unsigned char)); - if (NULL == ref_bn_data_) exit(1); - status = bigNumberToBin(ref_bn_data_, bit_length, big_num); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("Failed at bigNumberToBin()\n"); - exit(1); - } - gettimeofday(&end_time, NULL); - time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; - time_taken = - (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; - qat_elapsed = time_taken; - printf("Conversion from BigNumber has completed %.1lfus.\n", - (qat_elapsed)); - - BIGNUM* ref_bin_ = BN_new(); - BN_bin2bn(ref_bn_data_, len_, ref_bin_); - bn_str = BN_bn2hex(ref_bin_); - printf("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, - BN_num_bytes(ref_bin_), BN_num_bits(ref_bin_)); - printf("-----------------------\n"); - - OPENSSL_free(bn_str); - free(bn_mod_data_); - free(ref_bn_data_); - BN_free(ref_bin_); - } - - // Tear down OpenSSL context - BN_CTX_end(ctx); - - return (int)status; -} diff --git a/module/heqat/samples/test_bnModExp.cpp b/module/heqat/samples/test_bnModExp.cpp deleted file mode 100644 index 7499445..0000000 --- a/module/heqat/samples/test_bnModExp.cpp +++ /dev/null @@ -1,231 +0,0 @@ - -#include "he_qat_misc.h" -#include "he_qat_utils.h" -#include "he_qat_bn_ops.h" -#include "he_qat_context.h" -#include "cpa_sample_utils.h" - -#include -#include -#include -#include -#include - -#include -#include - -#ifdef _DESTINY_DEBUG_VERBOSE -int gDebugParam = 1; -#endif - -const unsigned int BATCH_SIZE = 48; - -using namespace std::chrono; - -int main(int argc, const char** argv) { - const int bit_length = 4096; - const size_t num_trials = 100; - - double avg_speed_up = 0.0; - double ssl_avg_time = 0.0; - double qat_avg_time = 0.0; - - HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; - - // Set up QAT runtime context - acquire_qat_devices(); - - // Set up OpenSSL context (as baseline) - BN_CTX* ctx = BN_CTX_new(); - BN_CTX_start(ctx); - - for (unsigned int mod = 0; mod < num_trials; mod++) { - // Generate modulus number - BIGNUM* bn_mod = generateTestBNData(bit_length); - - if (!bn_mod) continue; - - char* bn_str = BN_bn2hex(bn_mod); -#ifdef _DESTINY_DEBUG_VERBOSE - printf("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, - BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); -#endif - OPENSSL_free(bn_str); - - // Generate exponent in [0..bn_mod] - BIGNUM* bn_exponent = BN_new(); - if (!BN_rand_range(bn_exponent, bn_mod)) { - BN_free(bn_mod); - continue; - } - - // Generate base number - BIGNUM* bn_base = generateTestBNData(bit_length); - - // Perform OpenSSL ModExp Op - BIGNUM* ssl_res = BN_new(); - auto start = high_resolution_clock::now(); - BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); - auto stop = high_resolution_clock::now(); - auto ssl_duration = duration_cast(stop - start); - - int len_ = (bit_length + 7) >> 3; - - // Start QAT timer (including data conversion overhead) - start = high_resolution_clock::now(); - unsigned char* bn_base_data_ = - (unsigned char*)calloc(len_, sizeof(unsigned char)); - if (NULL == bn_base_data_) exit(1); - BN_bn2binpad(bn_base, bn_base_data_, len_); - unsigned char* bn_mod_data_ = - (unsigned char*)calloc(len_, sizeof(unsigned char)); - if (NULL == bn_mod_data_) exit(1); - BN_bn2binpad(bn_mod, bn_mod_data_, len_); - unsigned char* bn_exponent_data_ = - (unsigned char*)calloc(len_, sizeof(unsigned char)); - if (NULL == bn_exponent_data_) exit(1); - BN_bn2binpad(bn_exponent, bn_exponent_data_, len_); - unsigned char* bn_remainder_data_ = - (unsigned char*)calloc(len_, sizeof(unsigned char)); - if (NULL == bn_remainder_data_) exit(1); - stop = high_resolution_clock::now(); - auto cvt_duration = duration_cast(stop - start); - - // Simulate input number in BigNumber representation - BigNumber big_num_base((Ipp32u)0); - BigNumber big_num_mod((Ipp32u)0); - BigNumber big_num_exponent((Ipp32u)0); - status = binToBigNumber(big_num_base, bn_base_data_, bit_length); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("Failed at binToBigNumber()\n"); - exit(1); - } - status = binToBigNumber(big_num_mod, bn_mod_data_, bit_length); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("Failed at binToBigNumber()\n"); - exit(1); - } - status = - binToBigNumber(big_num_exponent, bn_exponent_data_, bit_length); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("Failed at binToBigNumber()\n"); - exit(1); - } - - // Reset numbers to 0 - memset(bn_base_data_, 0, len_); - memset(bn_mod_data_, 0, len_); - memset(bn_exponent_data_, 0, len_); - // Make sure variables are reset - if (memcmp(bn_base_data_, bn_mod_data_, len_) || - memcmp(bn_base_data_, bn_exponent_data_, len_)) { - PRINT_ERR("Pointers are not reset to zero!"); - exit(1); - } - - start = high_resolution_clock::now(); - status = bigNumberToBin(bn_base_data_, bit_length, big_num_base); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("bn_base_data_: failed at bignumbertobin()\n"); - exit(1); - } - status = bigNumberToBin(bn_mod_data_, bit_length, big_num_mod); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("bn_base_data_: failed at bignumbertobin()\n"); - exit(1); - } - status = - bigNumberToBin(bn_exponent_data_, bit_length, big_num_exponent); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("bn_base_data_: failed at bignumbertobin()\n"); - exit(1); - } - cvt_duration += - duration_cast(high_resolution_clock::now() - start); - - // Perform BigNumber modular exponentiation on QAT - start = high_resolution_clock::now(); - for (unsigned int b = 0; b < BATCH_SIZE; b++) - status = - HE_QAT_bnModExp(bn_remainder_data_, bn_base_data_, - bn_exponent_data_, bn_mod_data_, bit_length); - getBnModExpRequest(BATCH_SIZE); - stop = high_resolution_clock::now(); - auto qat_duration = duration_cast(stop - start); - - ssl_avg_time = - (mod * ssl_avg_time + ((double)(ssl_duration.count()))) / (mod + 1); - qat_avg_time = (mod * qat_avg_time + - ((double)(qat_duration.count())) / BATCH_SIZE) / - (mod + 1); - avg_speed_up = (mod * avg_speed_up + - (ssl_duration.count() / - (double)(qat_duration.count() / BATCH_SIZE))) / - (mod + 1); - printf("Request #%u\t", mod + 1); - printf("Overhead: %.1luus", cvt_duration.count()); - printf("\tOpenSSL: %.1lfus", ssl_avg_time); - printf("\tQAT: %.1lfus", qat_avg_time); - printf("\tSpeed-up: %.1lfx", avg_speed_up); - - BIGNUM* qat_res = BN_new(); - BN_bin2bn(bn_remainder_data_, len_, qat_res); - - if (HE_QAT_STATUS_SUCCESS != status) { - PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); - } -#ifdef _DESTINY_DEBUG_VERBOSE - else { - PRINT_DBG("\nQAT bnModExpOp finished\n"); - } -#endif - - BigNumber big_num((Ipp32u)0); - status = binToBigNumber(big_num, bn_remainder_data_, bit_length); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("bn_remainder_data_: Failed at bigNumberToBin()\n"); - exit(1); - } - -#ifdef _DESTINY_DEBUG_VERBOSE - bn_str = BN_bn2hex(qat_res); - printf("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, - BN_num_bytes(qat_res), BN_num_bits(qat_res)); -#endif - -#ifdef _DESTINY_DEBUG_VERBOSE - int bit_len = 0; - ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); - std::string str; - big_num.num2hex(str); - printf("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, - bit_len); - printf( - "---------------------################-----------------------\n"); -#endif - - if (BN_cmp(qat_res, ssl_res) != 0) - printf("\t** FAIL **\n"); - else - printf("\t** PASS **\n"); - - BN_free(bn_mod); - BN_free(bn_base); - BN_free(bn_exponent); - BN_free(qat_res); - BN_free(ssl_res); - - free(bn_mod_data_); - free(bn_base_data_); - free(bn_exponent_data_); - free(bn_remainder_data_); - } - - // Tear down OpenSSL context - BN_CTX_end(ctx); - - // Tear down QAT runtime context - release_qat_devices(); - - return (int)status; -} diff --git a/module/heqat/samples/test_bnModExp_MT.cpp b/module/heqat/samples/test_bnModExp_MT.cpp deleted file mode 100644 index e3ef33c..0000000 --- a/module/heqat/samples/test_bnModExp_MT.cpp +++ /dev/null @@ -1,297 +0,0 @@ - -#include "he_qat_misc.h" -#include "he_qat_utils.h" -#include "he_qat_bn_ops.h" -#include "he_qat_context.h" -#include "cpa_sample_utils.h" - -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifdef _DESTINY_DEBUG_VERBOSE -int gDebugParam = 1; -#endif - -const unsigned int BATCH_SIZE = 4096; - -using namespace std::chrono; - -int main(int argc, const char** argv) { - const int bit_length = 4096; - const size_t num_trials = 10000; - - double avg_speed_up = 0.0; - double ssl_avg_time = 0.0; - double qat_avg_time = 0.0; - - // clock_t start = CLOCKS_PER_SEC; - // clock_t ssl_elapsed = CLOCKS_PER_SEC; - // clock_t qat_elapsed = CLOCKS_PER_SEC; - - HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; - - // Set up QAT runtime context - acquire_qat_devices(); - - // Set up OpenSSL context (as baseline) - BN_CTX* ctx = BN_CTX_new(); - BN_CTX_start(ctx); - - int nthreads = 4; - for (unsigned int mod = 0; mod < num_trials; mod++) { - // Generate modulus number - BIGNUM* bn_mod = generateTestBNData(bit_length); - - if (!bn_mod) continue; - - char* bn_str = BN_bn2hex(bn_mod); -#ifdef _DESTINY_DEBUG_VERBOSE - printf("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, - BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); -#endif - OPENSSL_free(bn_str); - - // Generate exponent in [0..bn_mod] - BIGNUM* bn_exponent = BN_new(); - if (!BN_rand_range(bn_exponent, bn_mod)) { - BN_free(bn_mod); - continue; - } - - // Generate base number - BIGNUM* bn_base = generateTestBNData(bit_length); - - // Perform OpenSSL ModExp Op - BIGNUM* ssl_res = BN_new(); - auto start = high_resolution_clock::now(); - // start = clock(); - BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); - auto stop = high_resolution_clock::now(); - auto ssl_duration = duration_cast(stop - start); - // ssl_elapsed = clock() - start; - - int len_ = (bit_length + 7) >> 3; - - // Start QAT timer (including data conversion overhead) - // start = clock(); - start = high_resolution_clock::now(); - unsigned char* bn_base_data_ = - (unsigned char*)calloc(len_, sizeof(unsigned char)); - if (NULL == bn_base_data_) exit(1); - BN_bn2binpad(bn_base, bn_base_data_, len_); - unsigned char* bn_mod_data_ = - (unsigned char*)calloc(len_, sizeof(unsigned char)); - if (NULL == bn_mod_data_) exit(1); - BN_bn2binpad(bn_mod, bn_mod_data_, len_); - unsigned char* bn_exponent_data_ = - (unsigned char*)calloc(len_, sizeof(unsigned char)); - if (NULL == bn_exponent_data_) exit(1); - BN_bn2binpad(bn_exponent, bn_exponent_data_, len_); - unsigned char* bn_remainder_data_ = - (unsigned char*)calloc(nthreads * len_, sizeof(unsigned char)); - if (NULL == bn_remainder_data_) exit(1); - stop = high_resolution_clock::now(); - auto cvt_duration = duration_cast(stop - start); - // clock_t cvt_elapsed = clock() - start; - - // Simulate input number in BigNumber representation - BigNumber big_num_base((Ipp32u)0); - BigNumber big_num_mod((Ipp32u)0); - BigNumber big_num_exponent((Ipp32u)0); - status = binToBigNumber(big_num_base, bn_base_data_, bit_length); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("Failed at binToBigNumber()\n"); - exit(1); - } - status = binToBigNumber(big_num_mod, bn_mod_data_, bit_length); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("Failed at binToBigNumber()\n"); - exit(1); - } - status = - binToBigNumber(big_num_exponent, bn_exponent_data_, bit_length); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("Failed at binToBigNumber()\n"); - exit(1); - } - - // Reset numbers to 0 - memset(bn_base_data_, 0, len_); - memset(bn_mod_data_, 0, len_); - memset(bn_exponent_data_, 0, len_); - // Make sure variables are reset - if (memcmp(bn_base_data_, bn_mod_data_, len_) || - memcmp(bn_base_data_, bn_exponent_data_, len_)) { - PRINT_ERR("Pointers are not reset to zero!"); - exit(1); - } - - // start = clock(); - start = high_resolution_clock::now(); - status = bigNumberToBin(bn_base_data_, bit_length, big_num_base); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("bn_base_data_: failed at bignumbertobin()\n"); - exit(1); - } - status = bigNumberToBin(bn_mod_data_, bit_length, big_num_mod); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("bn_base_data_: failed at bignumbertobin()\n"); - exit(1); - } - status = - bigNumberToBin(bn_exponent_data_, bit_length, big_num_exponent); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("bn_base_data_: failed at bignumbertobin()\n"); - exit(1); - } - // cvt_elapsed += (clock() - start); - cvt_duration += - duration_cast(high_resolution_clock::now() - start); - - omp_set_num_threads(nthreads); - - // Perform BigNumber modular exponentiation on QAT - start = high_resolution_clock::now(); - -#pragma omp parallel private(status) -{ - int thread_id = omp_get_thread_num(); - unsigned int buffer_id = thread_id; - - // Secure one of the distributed outstanding buffers - status = acquire_bnModExp_buffer(&buffer_id); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("Error: acquire_bnModExp_buffer()\n"); - exit(1); - } -#ifdef HE_QAT_DEBUG - printf("Thread #%d HE QAT ACQUIRED BUFFER ID: %u\n",thread_id,buffer_id); -#endif - // Divide work among threads - unsigned int worksize = BATCH_SIZE/nthreads; - unsigned int begin = thread_id*worksize; - unsigned int end = begin + worksize; - -#ifdef HE_QAT_DEBUG - printf("Thread #%d Begin: %u End: %u\n",thread_id,begin,end); -#endif - - // For local thread, schedule work execution - for (unsigned int b = begin; b < end; b++) - status = HE_QAT_bnModExp_MT(buffer_id, bn_remainder_data_ + thread_id*len_, - bn_base_data_, bn_exponent_data_, bn_mod_data_, bit_length); - -#ifdef HE_QAT_DEBUG - printf("Thread #%d Waiting\n",thread_id); -#endif - - // Wait for the request to complete - release_bnModExp_buffer(buffer_id, BATCH_SIZE/nthreads); - -#ifdef HE_QAT_DEBUG - printf("Thread #%d Completed\n",thread_id); -#endif -} // pragma omp parallel - - stop = high_resolution_clock::now(); - auto qat_duration = duration_cast(stop - start); - - ssl_avg_time = - (mod * ssl_avg_time + ((double)(ssl_duration.count()))) / (mod + 1); - qat_avg_time = (mod * qat_avg_time + - ((double)(qat_duration.count())) / BATCH_SIZE) / - (mod + 1); - avg_speed_up = (mod * avg_speed_up + - (ssl_duration.count() / - (double)(qat_duration.count() / BATCH_SIZE))) / - (mod + 1); - // qat_elapsed = clock() - start; - - // printf("BigNumber data conversion overhead: %.1lfus.\n", - // (cvt_elapsed / (CLOCKS_PER_SEC / 1000000.0))); - // printf("BigNumber modular exponentiation on QAT: %.1lfus.\n", - // (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); - // qat_elapsed += cvt_elapsed; - printf("Request #%u\t", mod + 1); - printf("Overhead: %.1luus", cvt_duration.count()); - printf("\tOpenSSL: %.1lfus", ssl_avg_time); - printf("\tQAT: %.1lfus", qat_avg_time); - printf("\tSpeed-up: %.1lfx", avg_speed_up); - // qat_elapsed += cvt_elapsed; - - BIGNUM* qat_res = BN_new(); - BN_bin2bn(bn_remainder_data_, len_, qat_res); - - if (HE_QAT_STATUS_SUCCESS != status) { - PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); - } -#ifdef _DESTINY_DEBUG_VERBOSE - else { - PRINT_DBG("\nQAT bnModExpOp finished\n"); - } -#endif - - // start = clock(); - BigNumber big_num((Ipp32u)0); - status = binToBigNumber(big_num, bn_remainder_data_, bit_length); - if (HE_QAT_STATUS_SUCCESS != status) { - printf("bn_remainder_data_: Failed at bigNumberToBin()\n"); - exit(1); - } - // qat_elapsed += (clock() - start); - // printf("BigNumber ModExp total time: %.1lfus.\n", - // (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); - -#ifdef _DESTINY_DEBUG_VERBOSE - bn_str = BN_bn2hex(qat_res); - printf("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, - BN_num_bytes(qat_res), BN_num_bits(qat_res)); -#endif - -#ifdef _DESTINY_DEBUG_VERBOSE - int bit_len = 0; - ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); - std::string str; - big_num.num2hex(str); - printf("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, - bit_len); - printf( - "---------------------################-----------------------\n"); -#endif - - if (BN_cmp(qat_res, ssl_res) != 0) - printf("\t** FAIL **\n"); - else - printf("\t** PASS **\n"); - - BN_free(bn_mod); - BN_free(bn_base); - BN_free(bn_exponent); - BN_free(qat_res); - BN_free(ssl_res); - - // OPENSSL_free(bn_str); - - free(bn_mod_data_); - free(bn_base_data_); - free(bn_exponent_data_); - free(bn_remainder_data_); - -// break; - } - - // Tear down OpenSSL context - BN_CTX_end(ctx); - - // Tear down QAT runtime context - release_qat_devices(); - - return (int)status; -} diff --git a/module/heqat/samples/test_context.c b/module/heqat/samples/test_context.c deleted file mode 100644 index e640e8b..0000000 --- a/module/heqat/samples/test_context.c +++ /dev/null @@ -1,28 +0,0 @@ - -#include -#include "cpa_sample_utils.h" -#include "he_qat_context.h" - -int main() { - HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; - - status = acquire_qat_devices(); - if (HE_QAT_STATUS_SUCCESS == status) { - printf("Completed acquire_qat_devices() successfully.\n"); - } else { - printf("acquire_qat_devices() failed.\n"); - exit(1); - } - - OS_SLEEP(5000); - - status = release_qat_devices(); - if (HE_QAT_STATUS_SUCCESS == status) { - printf("Completed release_qat_devices() successfully.\n"); - } else { - printf("release_qat_devices() failed.\n"); - exit(1); - } - - return 0; -} diff --git a/module/heqat/scripts/auto_find_qat_install.sh b/module/heqat/scripts/auto_find_qat_install.sh deleted file mode 100755 index 4150685..0000000 --- a/module/heqat/scripts/auto_find_qat_install.sh +++ /dev/null @@ -1 +0,0 @@ -for item in $(locate QAT/build); do [ -d $item ] && [ $(echo $item | grep $HOME) ] && echo ${item%/*}; done diff --git a/module/heqat/scripts/reset_asym_buffer_size.sh b/module/heqat/scripts/reset_asym_buffer_size.sh deleted file mode 100755 index 80b591e..0000000 --- a/module/heqat/scripts/reset_asym_buffer_size.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash - -if [[ -z "${@}" ]]; then - echo "Usage: ./reset_asym_buffer_size " - exit -fi - -OLD_BUFFER_SIZE=$1 - -if [[ -z ${2} ]]; then - echo "Error: second parameter missing" - echo "Usage: ./reset_asym_buffer_size " - exit -fi - -NEW_BUFFER_SIZE=$2 - -num_phys_dev=$(lspci -d 8086:4940 | wc -l) -num_virt_dev=$(lspci -d 8086:4941 | wc -l) - -# Update physical device configuration files -i=0; -while [ $i -lt $num_phys_dev ]; -do - sudo sed -i /etc/4xxx_dev$i.conf -e "s/CyNumConcurrentAsymRequests = $OLD_BUFFER_SIZE/CyNumConcurrentAsymRequests = $NEW_BUFFER_SIZE/g"; - i=`expr $i + 1`; -done - -# Update virtual function configuration files -i=0; -while [ $i -lt $num_virt_dev ]; -do - sudo sed -i /etc/4xxxvf_dev$i.conf -e "s/CyNumConcurrentAsymRequests = $OLD_BUFFER_SIZE/CyNumConcurrentAsymRequests = $NEW_BUFFER_SIZE/g"; - i=`expr $i + 1`; -done - -## Power Off PFs -#i=0; -#while [ $i -lt $num_phys_dev ]; -#do -# sudo adf_ctl qat_dev$i down; -# i=`expr $i + 1`; -#done -# -## Power On PFs -#i=0; -#while [ $i -lt $num_phys_dev ]; -#do -# sudo adf_ctl qat_dev$i up; -# i=`expr $i + 1`; -#done -# -## Restart QAT service (This will bring up PFs and VFs) -#echo "sudo service qat_service restart" -#sudo service qat_service restart -# -## Power Off All VFs -#i=$num_phys_dev; -#vf_per_pf=`expr $num_virt_dev / $num_phys_dev` -#n=`expr $vf_per_pf \\* $num_phys_dev` -#n=`expr $n + $num_phys_dev` -#while [ $i -lt $n ]; -#do -# sudo adf_ctl qat_dev$i down; -# i=`expr $i + 1`; -#done -# -## Power On One QAT VF per QAT PF -#i=$num_phys_dev; -#while [ $i -lt $n ]; -#do -# sudo adf_ctl qat_dev$i up; -# i=`expr $i + $vf_per_pf`; -#done - diff --git a/module/heqat/scripts/restart_devices.sh b/module/heqat/scripts/restart_devices.sh deleted file mode 100755 index fc26b0e..0000000 --- a/module/heqat/scripts/restart_devices.sh +++ /dev/null @@ -1,132 +0,0 @@ -#!/bin/bash - -# Refresh -echo "sudo service restart qat_service" -sudo service qat_service restart - -num_phys_dev=$(lspci -d 8086:4940 | wc -l) -if [ $num_phys_dev -eq 0 ]; then - echo "No QAT Device Found !" - exit -else - echo "$num_phys_dev QAT Devices Found !" -fi - -total_virt_func=$(lspci -d 8086:4941 | wc -l) -num_virt_func=`expr $total_virt_func / $num_phys_dev` -dev_step=1 - -if [ $# -eq 0 ]; then - echo "Usage: ./setup_devices " - echo " Parameters:" - echo " -- num_phys_dev: Number of physical devices to be active. (default: auto)" - echo " -- conf_virt_func: Number of configured virtual functions per device. (default: 0)" - echo " -- num_virt_func: Number of virtual functions to be active per device. (default: 0)" -fi - -nphysdev=$num_phys_dev -if [ -n "$1" ]; then - nphysdev=$1 - if [ $nphysdev -gt $num_phys_dev ]; then - nphysdev=$num_phys_dev - fi -fi - -conf_virt_func=0 -# Check if virtual function is enabled -if [ $num_virt_func -gt 0 ]; then - conf_virt_func=1 -fi - -if [ -n "$2" ]; then - conf_virt_func=$2 - # if user attempts to request higher than available - if [ $conf_virt_func -gt $num_virt_func ]; then - conf_virt_func=$num_virt_func - fi -fi - -# Shutdown QAT PFs -i=0 -while [ $i -lt $num_phys_dev ]; -do - echo "sudo adf_ctl qat_dev$i down"; - sudo adf_ctl qat_dev$i down; - i=`expr $i + 1`; -done - -# Reconfigure Target QAT PFs -i=0 -n=$nphysdev -while [ $i -lt $n ]; -do - echo "sudo adf_ctl qat_dev$i up"; - sudo adf_ctl qat_dev$i up; - i=`expr $i + 1`; -done - -# Refresh -echo "sudo service restart qat_service" -sudo service qat_service restart - -# If Virtualization Mode Enabled -start=0 -if [ $num_virt_func -gt 0 ]; then - if [ $conf_virt_func -gt 0 ]; then - start=$num_phys_dev - dev_step=$num_virt_func - fi -fi - -# Shutdown QAT VFs -i=$start -stop=`expr $num_phys_dev \\* $num_virt_func` -stop=`expr $start + $stop` -step=$dev_step -while [ $i -lt $stop ]; -do - echo "sudo adf_ctl qat_dev$i down"; - sudo adf_ctl qat_dev$i down; - i=`expr $i + 1`; -done - -i=0 -while [ $i -lt $nphysdev ]; -do - # Start QAT PF - echo "sudo adf_ctl qat_dev$i up"; - sudo adf_ctl qat_dev$i up; - i=`expr $i + 1`; -done - -start=$num_phys_dev -i=$start -stop=`expr $nphysdev \\* $num_virt_func` -stop=`expr $start + $stop` -step=$dev_step -while [ $i -lt $stop ]; -do - # Start QAT VF - echo "adf_ctl qat_dev$i up" - sudo adf_ctl qat_dev$i up; - # Start up additional instances mapped to the same physical device - j=1; - while [ $j -lt $conf_virt_func ]; - do - dev_id=`expr $i + $j`; - # Start QAT VF - echo "adf_ctl qat_dev$dev_id up" - sudo adf_ctl qat_dev$dev_id up; - j=`expr $j + 1`; - done - i=`expr $i + $dev_step` -done - -# Shutdown Unused QAT PFs -i=$nphysdev -while [ $i -lt $num_phys_dev ]; -do - echo "sudo adf_ctl qat_dev$i down"; - sudo adf_ctl qat_dev$i down; - i=`expr $i + 1`; -done diff --git a/module/heqat/scripts/run.sh b/module/heqat/scripts/run.sh deleted file mode 100755 index aa451dd..0000000 --- a/module/heqat/scripts/run.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -export HEQATLIB_INSTALL_DIR=$HEQATLIB_ROOT_DIR/install -export ICP_ROOT=$($HEQATLIB_ROOT_DIR/scripts/auto_find_qat_install.sh) -export LD_LIBRARY_PATH=$HEQATLIB_INSTALL_DIR/lib:$ICP_ROOT/build:$LD_LIBRARY_PATH - -pushd $HEQATLIB_INSTALL_DIR/bin - -for app in $(ls test_*) -do - echo "*****************************************************************" - echo "* [START] RUNNING TEST SAMPLE $app *" - echo "*****************************************************************" - ./$app - echo "*****************************************************************" - echo "* [STOP] RUNNING TEST SAMPLE $app *" - echo "*****************************************************************" -done - -popd diff --git a/module/heqat/scripts/setup_devices.sh b/module/heqat/scripts/setup_devices.sh deleted file mode 100755 index 2cc3bb6..0000000 --- a/module/heqat/scripts/setup_devices.sh +++ /dev/null @@ -1,156 +0,0 @@ -# Copyright (C) 2022-2023 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -#!/bin/bash - -# Refresh -echo "sudo service restart qat_service" -sudo service qat_service restart - -num_phys_dev=$(lspci -d 8086:4940 | wc -l) -if [ $num_phys_dev -eq 0 ]; then - echo "No QAT Device Found !" - exit -else - echo "$num_phys_dev QAT Devices Found !" -fi - -total_virt_func=$(lspci -d 8086:4941 | wc -l) -num_virt_func=`expr $total_virt_func / $num_phys_dev` -dev_step=1 - -if [ $# -eq 0 ]; then - echo "Usage: ./setup_devices " - echo " Parameters:" - echo " -- num_phys_dev: Number of physical devices to be active. (default: auto)" - echo " -- conf_virt_func: Number of configured virtual functions per device. (default: 0)" - echo " -- num_virt_func: Number of virtual functions to be active per device. (default: 0)" -fi - -nphysdev=$num_phys_dev -if [ -n "$1" ]; then - nphysdev=$1 - if [ $nphysdev -gt $num_phys_dev ]; then - nphysdev=$num_phys_dev - fi -fi - -conf_virt_func=0 -# Check if virtual function is enabled -if [ $num_virt_func -gt 0 ]; then - conf_virt_func=1 -fi - -if [ -n "$2" ]; then - conf_virt_func=$2 - # if user attempts to request higher than available - if [ $conf_virt_func -gt $num_virt_func ]; then - conf_virt_func=$num_virt_func - fi -fi - -# Shutdown QAT PFs -i=0 -while [ $i -lt $num_phys_dev ]; -do - echo "sudo adf_ctl qat_dev$i down"; - sudo adf_ctl qat_dev$i down; - i=`expr $i + 1`; -done - -# Reconfigure Target QAT PFs -i=0 -n=$nphysdev -while [ $i -lt $n ]; -do - echo "sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf"; - sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf; - echo "sudo adf_ctl qat_dev$i up"; - sudo adf_ctl qat_dev$i up; - i=`expr $i + 1`; -done - -# Refresh -echo "sudo service restart qat_service" -sudo service qat_service restart - -# If Virtualization Mode Enabled -start=0 -if [ $num_virt_func -gt 0 ]; then - if [ $conf_virt_func -gt 0 ]; then - start=$num_phys_dev - dev_step=$num_virt_func - fi -fi - -# Shutdown QAT VFs -i=$start -stop=`expr $num_phys_dev \\* $num_virt_func` -stop=`expr $start + $stop` -step=$dev_step -while [ $i -lt $stop ]; -do - echo "sudo adf_ctl qat_dev$i down"; - sudo adf_ctl qat_dev$i down; - i=`expr $i + 1`; -done - -#i=0 -#while [ $i -lt $total_virt_func ]; -#do -# echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$i.conf"; -# sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$i.conf; -# i=`expr $i + 1`; -#done - -i=0 -while [ $i -lt $nphysdev ]; -do - # Reconfigure QAT PF - echo "sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf"; - sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf; - # Start QAT PF - echo "sudo adf_ctl qat_dev$i up"; - sudo adf_ctl qat_dev$i up; - i=`expr $i + 1`; -done - -start=$num_phys_dev -i=$start -stop=`expr $nphysdev \\* $num_virt_func` -stop=`expr $start + $stop` -step=$dev_step -while [ $i -lt $stop ]; -do - k=`expr $i - $start` - # Reconfigure QAT VF (must match PF's config) - echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf"; - sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf; - # Start QAT VF - echo "adf_ctl qat_dev$i up" - sudo adf_ctl qat_dev$i up; - # Start up additional instances mapped to the same physical device - j=1; - while [ $j -lt $conf_virt_func ]; - do - dev_id=`expr $i + $j`; - k=`expr $dev_id - $start`; - # Reconfigure QAT VF (must match PF's config) - echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf"; - sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf; - # Start QAT VF - echo "adf_ctl qat_dev$dev_id up" - sudo adf_ctl qat_dev$dev_id up; - j=`expr $j + 1`; - done - i=`expr $i + $dev_step` -done - -# Shutdown Unused QAT PFs -i=$nphysdev -while [ $i -lt $num_phys_dev ]; -do - echo "sudo adf_ctl qat_dev$i down"; - sudo adf_ctl qat_dev$i down; - i=`expr $i + 1`; -done diff --git a/module/heqat/setup_env.sh b/module/heqat/setup_env.sh deleted file mode 100755 index 27dffda..0000000 --- a/module/heqat/setup_env.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -export HEQATLIB_ROOT_DIR=$(pwd) -export ICP_ROOT=$($PWD/scripts/auto_find_qat_install.sh) - From 51f227c6663860df5f6444cf6da6d9833340378b Mon Sep 17 00:00:00 2001 From: Fillipe Souza Date: Fri, 23 Sep 2022 17:45:20 -0700 Subject: [PATCH 256/364] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 50f8f9d..9c56c3c 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ This library currently only offers acceleration of modular exponentiation of mul - Multithreading Support: This feature permits the API to be called by concurrently threads running on the host. Effective multithreading support relies on a separate buffer that admits outstanding work requests. This buffer is acquired before an API call to submit work requests to the accelerator. This is accomplished by first calling `acquire_bnModExp_buffer()` to reserve an internal buffer to store outstanding requests from the host API caller. - - Multiple Instances/Devices: The library accesses all logical instances from all visible and configured QAT endpoints at the creation of the QAT runtime context. Therefore, if 8 QAT endpoints are available, it will attempt to use them all, including all the total number of logical instances configured per process. + - Multiple Instances: The library accesses all logical instances from all visible and configured QAT endpoints at the creation of the QAT runtime context. Therefore, if 8 QAT endpoints are available, it will attempt to use them all, including all the total number of logical instances configured per process. >> _**Note**_: Current implementation does not verify if the instance/endpoint has the capabilities needed by the library. For example, the library needs access to the _asym_ capabilities like `CyLnModExp`, therefore if the configuration file of an endpoint happens to be configured to not offer it, the application will exit with an error at some point during execution. From a17947454b6a3a39869993572109113abea37a00 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 23 Sep 2022 17:57:00 -0700 Subject: [PATCH 257/364] Add heqat as a git submodule. Signed-off-by: Souza, Fillipe --- .gitmodules | 4 ++++ module/heqat | 1 + 2 files changed, 5 insertions(+) create mode 100644 .gitmodules create mode 160000 module/heqat diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..dc5f7b8 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "module/heqat"] + path = module/heqat + url = https://github.com/intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.project-destiny.git + branch = main diff --git a/module/heqat b/module/heqat new file mode 160000 index 0000000..51f227c --- /dev/null +++ b/module/heqat @@ -0,0 +1 @@ +Subproject commit 51f227c6663860df5f6444cf6da6d9833340378b From adb9a24d2d078e16d60a8923499653e5dc8333ea Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 23 Sep 2022 18:16:01 -0700 Subject: [PATCH 258/364] Update download instructions. Signed-off-by: Souza, Fillipe --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a37c07d..8e8109f 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ Intel Paillier Cryptosystem Library is an open-source library which provides acc - [Building the Library](#building-the-library) - [Prerequisites](#prerequisites) - [Dependencies](#dependencies) + - [Downloading](#downloading) - [Instructions](#instructions) - [Testing and Benchmarking](#testing-and-benchmarking) - [Python Extension](#python-extension) @@ -71,7 +72,13 @@ For RHEL, ```OpenSSL``` needs to be built and installed from source as the stati ``` sudo yum install numactl-devel ``` - +### Downloading +Pull source code from git repository with all submodules. +``` +git clone --recursive https://github.com/intel/pailliercryptolib.git +cd pailliercryptolib +git submodule update --init +``` ### Instructions The library can be built using the following commands: ```bash From 2b03bd7273fd33a1a8e99799c3cfce4c8dc072d0 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 23 Sep 2022 18:26:13 -0700 Subject: [PATCH 259/364] Update downloading instructions. Signed-off-by: Souza, Fillipe --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8e8109f..1f80d7c 100644 --- a/README.md +++ b/README.md @@ -73,10 +73,16 @@ For RHEL, ```OpenSSL``` needs to be built and installed from source as the stati sudo yum install numactl-devel ``` ### Downloading -Pull source code from git repository with all submodules. +Pull source code from git repository with all submodules. There are two ways to do it: +- Clone source code with all submodules at once ``` git clone --recursive https://github.com/intel/pailliercryptolib.git cd pailliercryptolib +``` +- Clone source code, then pull submodules +``` +git clone https://github.com/intel/pailliercryptolib.git +cd pailliercryptolib git submodule update --init ``` ### Instructions From 72e38700d4619768486e3a1dad1cbdea709ee919 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 26 Sep 2022 15:11:51 -0700 Subject: [PATCH 260/364] Update documentation. Signed-off-by: Souza, Fillipe --- README.md | 2 +- he_qat/include/he_qat_bn_ops.h | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 9c56c3c..c8f7050 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ This library currently only offers acceleration of modular exponentiation of mul - Batch Support: The internal buffers are set accommodate up to 1024 requests at a time so that the maximum number of non-blocking API calls is 1024 for each concurrent thread caller. Therefore, only up to 1024 requests can be exercised asynchronously from the application side, be it from a single `for loop` or static code block. Finally, in order to collect the requests, a call to the `getBnModExpRequest()` function must be performed to wait for completion of all submitted asynchronous requests. On multithreaded mode, the blocking function to be called at the end of the code block shall be `release_bnModExp_buffer()`. -- Multithreading Support: This feature permits the API to be called by concurrently threads running on the host. Effective multithreading support relies on a separate buffer that admits outstanding work requests. This buffer is acquired before an API call to submit work requests to the accelerator. This is accomplished by first calling `acquire_bnModExp_buffer()` to reserve an internal buffer to store outstanding requests from the host API caller. + - Multithreading Support: This feature permits the API to be called by concurrently threads running on the host. Effective multithreading support relies on a separate buffer that admits outstanding work requests. This buffer is acquired before an API call to submit work requests to the accelerator. This is accomplished by first calling `acquire_bnModExp_buffer()` to reserve an internal buffer to store outstanding requests from the host API caller. - Multiple Instances: The library accesses all logical instances from all visible and configured QAT endpoints at the creation of the QAT runtime context. Therefore, if 8 QAT endpoints are available, it will attempt to use them all, including all the total number of logical instances configured per process. diff --git a/he_qat/include/he_qat_bn_ops.h b/he_qat/include/he_qat_bn_ops.h index dd27a00..11c2259 100644 --- a/he_qat/include/he_qat_bn_ops.h +++ b/he_qat/include/he_qat_bn_ops.h @@ -12,15 +12,14 @@ * strings representing Big Numbers are encoded with compliance to PKCA#1 v2.1, * section 4, which is consistent with ASN.1 syntax. * - * The largest number supported here has 4096 bits, i.e. numbers from 0 to - * 2^(4096)-1. The most significant bit is located at index n-1. If the number is - * N, then the bit length is defined by n = floor(log2(N))+1. The memory buffer b to - * hold such number N needs to have at least M = ceiling(n/8) bytes allocated. In - * general, it will be larger and a power of 2, e.g. total bytes allocated is T=128 - * for numbers having up to n=1024 bits, total bytes allocated is T=256 for numbers - * having up to n=2048 bits, and so forth. Finally, the big number N is stored in - * `big endian` format, i.e. the least significant byte (LSB) is located at index [T-1], - * whereas the most significant byte is stored at [T-M]. + * The largest number supported here has 8192 bits, i.e. numbers from 0 to + * 2^(8192)-1. If the number is N, then the bit length is defined by n = floor(log2(N))+1. + * The memory buffer b to hold such number N needs to have at least M = ceiling(n/8) + * bytes allocated. In general, it will be larger and a power of 2, e.g. total bytes + * allocated is T=128 for numbers having up to n=1024 bits, total bytes allocated is + * T=256 for numbers having up to n=2048 bits, and so forth. Finally, the big number N + * is stored in `big endian` format, i.e. the least significant byte (LSB) is located + * at index [T-1], whereas the most significant byte is stored at [T-M]. * * The API client is responsible for allocation and release of their memory spaces of * the function arguments. Allocated memory spaces must be contiguous. Once a function From a8acc9c0861e1ee4dcaf5cc37b5b76d7e5247659 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Wed, 5 Oct 2022 22:46:50 -0700 Subject: [PATCH 261/364] Apply IPCL v1.1.4 to internal development branch (#131) * initial release * Update CODEOWNERS (#1) * Minor updates (#4) * Minor updates - Updated contributors - Added code of conduct - Updated CI/CD * ModExp function: remove padding & code clean (#6) - Remove padding operation in ippsModExp function - Let ippsMBModExp function support modulus of different bit size(in one vector) - Code clean * ippsModExp & unittests: corner case fix (#7) * Improve RNG security (#9) * Fix insecure prng (#3) - Add RDSEED and RDRAND instruction check in compile time - Prioritize RDSEED/RDRAND based RNG to produce random big number * Add RNG support for non-RDRAND, non-RDSEED systems (#5) - Use IPP-Crypto pseudo random number generator if none of those instructions are supported * Removing seed setup and replacing rng function for PrimeGen_BN (#8) - Remove seed setup for prime number generator - Add support to TRNGen_RDSEED and PRNGen_RDRAND for prime number generator Co-authored-by: Pengfei Zhao * Refactor apply obfuscator (#10) - Refactor apply_obfuscator - minor typo fix * Update ipp-crypto version to use ippcp_2021.6 (#12) - Minor update to use IPP-Crypto v2021.6 * 13 errors building installing questions about docs (#15) * Minor fixes - Fix gbenchmark build error on other platforms - Fixed IPCLTargets typo - Update version to 1.1.4 * Update to 1.1.4 (#17) (#20) * Improve RNG security (#9) * Fix insecure prng (#3) - Add RDSEED and RDRAND instruction check in compile time - Prioritize RDSEED/RDRAND based RNG to produce random big number * Add RNG support for non-RDRAND, non-RDSEED systems (#5) - Use IPP-Crypto pseudo random number generator if none of those instructions are supported * Removing seed setup and replacing rng function for PrimeGen_BN (#8) - Remove seed setup for prime number generator - Add support to TRNGen_RDSEED and PRNGen_RDRAND for prime number generator * Refactor apply obfuscator (#10) - Refactor apply_obfuscator - minor typo fix * Update version for 1.1.4 * Update ipp-crypto version to use ippcp_2021.6 (#12) - Minor update to use IPP-Crypto v2021.6 * 13 errors building installing questions about docs (#15) * Minor fixes - Fix gbenchmark build error on other platforms - Fixed IPCLTargets typo - Update version to 1.1.4 Co-authored-by: Pengfei Zhao * Add ipcl.hpp public header & cleanup ipcl/CMakeLists.txt (#22) * Cleanup ipcl/CMakeLists.txt * Refactor header - rename keygen.hpp with ipcl.hpp, use it as public header * Unit test & benchmark: replace header files with public header - ipcl.hpp * Improve installation and support runtime IFMA detection (#23) * Add option to determine AVX512IFMA during runtime (#18) - Add CMake flag to enable runtime version (```IPCL_DETECT_IFMA_RUNTIME```) - Add ```cpu_features``` dependency - Add manual IFMA disabling with environment variable (```IPCL_DISABLE_AVX512IFMA=ON```) - Updated README to include AVX512IFMA runtime detection option * Fixed shared library build - Refactor cmake configurations - Added example code * Added build and usage documentation - Fixed minor typos and updated flag names to be more consistent - Cleaned up example CMake file * Added examples documentation - Build and install instruction - Linking and compiling instruction - Usage examples * Fixed typo in root README (#24) Co-authored-by: Pengfei Zhao --- .github/workflows/github-ci.yml | 5 +- .pre-commit-config.yaml | 2 +- CMakeLists.txt | 44 ++++++---- CODE_OF_CONDUCT.md | 128 ++++++++++++++++++++++++++++ README.md | 44 +++++----- benchmark/bench_cryptography.cpp | 2 +- benchmark/bench_ops.cpp | 2 +- cmake/cpufeatures.cmake | 53 ++++++++++++ cmake/gbenchmark.cmake | 11 +-- cmake/gtest.cmake | 16 +++- cmake/ipcl/IPCLConfig.cmake.in | 5 +- cmake/ippcrypto.cmake | 27 ++++-- example/CMakeLists.txt | 15 ++++ example/README.md | 141 +++++++++++++++++++++++++++++++ example/test.cpp | 40 +++++++++ ipcl/CMakeLists.txt | 38 ++++++--- ipcl/include/ipcl/ipcl.hpp | 37 ++++++++ ipcl/include/ipcl/util.hpp | 13 +++ ipcl/keygen.cpp | 4 +- ipcl/mod_exp.cpp | 57 +++++++++++++ test/test_cryptography.cpp | 4 +- test/test_ops.cpp | 4 +- 22 files changed, 612 insertions(+), 80 deletions(-) create mode 100644 CODE_OF_CONDUCT.md create mode 100644 cmake/cpufeatures.cmake create mode 100644 example/CMakeLists.txt create mode 100644 example/README.md create mode 100644 example/test.cpp create mode 100644 ipcl/include/ipcl/ipcl.hpp diff --git a/.github/workflows/github-ci.yml b/.github/workflows/github-ci.yml index 846f840..6c29546 100644 --- a/.github/workflows/github-ci.yml +++ b/.github/workflows/github-ci.yml @@ -1,7 +1,7 @@ # Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -name: ipcl_internal +name: Build and Test on: # By default this will run when the activity type is "opened", "synchronize", # or "reopened". @@ -9,9 +9,12 @@ on: branches: - main - development + - "[0-9]+.[0-9]+.[0-9]+" push: branches: + - main - development + - "[0-9]+.[0-9]+.[0-9]+" # Manually run this workflow on any specified branch. workflow_dispatch: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e13a70f..2f41239 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -43,7 +43,7 @@ repos: entry: cpplint language: system files: \.(c|cc|cxx|cpp|h|hpp|hxx)$ - exclude: ipcl/bignum.cpp|ipcl/include/ipcl/bignum.h + exclude: ipcl/bignum.cpp|ipcl/include/ipcl/bignum.h|example/test.cpp args: - --recursive - --filter=-runtime/references,-whitespace/comments,-whitespace/indent diff --git a/CMakeLists.txt b/CMakeLists.txt index 92aab59..7d26427 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,10 +4,12 @@ cmake_minimum_required(VERSION 3.15.1) project(IPCL VERSION 1.1.3 LANGUAGES C CXX) +project(IPCL VERSION 1.1.4 LANGUAGES C CXX) include(CMakePackageConfigHelpers) include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) +include(GNUInstallDirs) if(CMAKE_BUILD_TYPE) set(RELEASE_TYPES @@ -34,16 +36,14 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_INSTALL_MESSAGE LAZY) -set(CMAKE_INSTALL_RPATH "\$ORIGIN") - -set(CMAKE_C_FLAGS "-O2 -Wno-error=deprecated-declarations") -set(CMAKE_CXX_FLAGS "-O2 -fpermissive -Wno-error=deprecated-declarations") -if(NOT CMAKE_INSTALL_PREFIX) - set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "/opt/intel/ipcl") endif() -include(GNUInstallDirs) +set(CMAKE_C_FLAGS "-O2 -Wno-error=deprecated-declarations") +set(CMAKE_CXX_FLAGS "-O2 -fpermissive -Wno-error=deprecated-declarations") +set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR};${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ippcrypto") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) @@ -54,6 +54,7 @@ option(IPCL_ENABLE_OMP "Enable OpenMP testing/benchmarking" ON) option(IPCL_THREAD_COUNT "The max number of threads used by OpenMP(If the value is OFF/0, it is determined at runtime)" OFF) option(IPCL_DOCS "Enable document building" OFF) option(IPCL_SHARED "Build shared library" ON) +option(IPCL_DETECT_IFMA_RUNTIME "Detect AVX512/IFMA instructions during runtime" OFF) option(IPCL_DEBUG_DISABLE_AVX512IFMA "(Debugging) Disable usage of AVX512IFMA instructions" OFF) if(IPCL_ENABLE_OMP) add_compile_definitions(IPCL_USE_OMP) @@ -84,6 +85,7 @@ else() endif() message(STATUS "IPCL_DOCS: ${IPCL_DOCS}") message(STATUS "IPCL_SHARED: ${IPCL_SHARED}") +message(STATUS "IPCL_DETECT_IFMA_RUNTIME: ${IPCL_DETECT_IFMA_RUNTIME}") set(IPCL_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) set(IPCL_SRC_DIR ${IPCL_ROOT_DIR}/ipcl) @@ -101,17 +103,22 @@ set(IPCL_FORWARD_CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ) -# check whether cpu support avx512 flag -if(IPCL_DEBUG_DISABLE_AVX512IFMA) - message(STATUS "Support AVX512IFMA: False") +if(IPCL_DETECT_IFMA_RUNTIME) + add_compile_definitions(IPCL_RUNTIME_MOD_EXP) + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cpufeatures") else() - set(CPU_AVX512_FLAG "avx512ifma") - execute_process(COMMAND lscpu COMMAND grep ${CPU_AVX512_FLAG} OUTPUT_VARIABLE CPU_ENABLE_AVX512) - if("${CPU_ENABLE_AVX512}" STREQUAL "") + # check whether cpu support avx512 flag + if(IPCL_DEBUG_DISABLE_AVX512IFMA) message(STATUS "Support AVX512IFMA: False") else() - message(STATUS "Support AVX512IFMA: True") - add_compile_definitions(IPCL_CRYPTO_MB_MOD_EXP) + set(CPU_AVX512_FLAG "avx512ifma") + execute_process(COMMAND lscpu COMMAND grep ${CPU_AVX512_FLAG} OUTPUT_VARIABLE CPU_ENABLE_AVX512) + if("${CPU_ENABLE_AVX512}" STREQUAL "") + message(STATUS "Support AVX512IFMA: False") + else() + message(STATUS "Support AVX512IFMA: True") + add_compile_definitions(IPCL_CRYPTO_MB_MOD_EXP) + endif() endif() endif() @@ -133,7 +140,7 @@ else() endif() # find package for OpenSSL and Threads -set(OPENSSL_USE_STATIC_LIBS TRUE) +# set(OPENSSL_USE_STATIC_LIBS TRUE) find_package(Threads REQUIRED) find_package(OpenSSL REQUIRED) @@ -145,6 +152,9 @@ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ipcl) include(ipcl-util) include(cmake/ippcrypto.cmake) +if(IPCL_DETECT_IFMA_RUNTIME) + include(cmake/cpufeatures.cmake) +endif() if(IPCL_TEST) include(cmake/gtest.cmake) @@ -153,6 +163,8 @@ if(IPCL_BENCHMARK) include(cmake/gbenchmark.cmake) endif() + + add_subdirectory(ipcl) # unit-test and benchmarks diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..dfb54fc --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +webadmin@linux.intel.com. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/README.md b/README.md index 0bdf06f..e90903f 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ # Intel Paillier Cryptosystem Library -Intel Paillier Cryptosystem Library is an open-source library which provides accelerated performance of a partial homomorphic encryption (HE), named Paillier cryptosystem, by utilizing IntelĀ® [Integrated Performance Primitives Cryptography](https://github.com/intel/ipp-crypto) technologies on Intel CPUs supporting the AVX512IFMA instructions. The library is written in modern standard C++ and provides the essential API for the Paillier cryptosystem scheme. +Intel Paillier Cryptosystem Library is an open-source library which provides accelerated performance of a partial homomorphic encryption (HE), named Paillier cryptosystem, by utilizing IntelĀ® [Integrated Performance Primitives Cryptography](https://github.com/intel/ipp-crypto) technologies on Intel CPUs supporting the AVX512IFMA instructions. The library is written in modern standard C++ and provides the essential API for the Paillier cryptosystem scheme. Intel Paillier Cryptosystem Library is certified for ISO compliance. ## Contents - [Intel Paillier Cryptosystem Library](#intel-paillier-cryptosystem-library) - [Contents](#contents) - [Introduction](#introduction) - - [Performance](#performance) - [Building the Library](#building-the-library) - [Prerequisites](#prerequisites) - [Dependencies](#dependencies) - [Instructions](#instructions) + - [Installing and Using Example](#installing-and-using-example) - [Testing and Benchmarking](#testing-and-benchmarking) - [Python Extension](#python-extension) - [Standardization](#standardization) @@ -28,8 +28,6 @@ As a public key encryption scheme, Paillier cryptosystem has three stages: For increased security, typically the key length is at least 1024 bits, but recommendation is 2048 bits or larger. To handle such large size integers, conventional implementations of the Paillier cryptosystem utilizes the GNU Multiple Precision Arithmetic Library (GMP). The essential computation of the scheme relies on the modular exponentiation, and our library takes advantage of the multi-buffer modular exponentiation function (```mbx_exp_mb8```) of IPP-Crypto library, which is enabled in AVX512IFMA instruction sets supporting SKUs, such as Intel Icelake Xeon CPUs. -### Performance -To be added after P2CA review ## Building the Library ### Prerequisites For best performance, especially due to the multi-buffer modular exponentiation function, the library is to be used on AVX512IFMA enabled systems, as listed below in Intel CPU codenames: @@ -75,21 +73,27 @@ sudo yum install numactl-devel ### Instructions The library can be built using the following commands: ```bash -export IPCL_DIR=$(pwd) +export IPCL_ROOT=$(pwd) cmake -S . -B build -DCMAKE_BUILD_TYPE=Release cmake --build build -j ``` It is possible to pass additional options to enable more features. The following table contains the current CMake options, default values are in bold. -| CMake options | Values | Default | Comments | -|-------------------------|-----------|---------|-------------------------------------| -|`IPCL_TEST` | ON/OFF | ON | unit-test | -|`IPCL_BENCHMARK` | ON/OFF | ON | benchmark | -|`IPCL_ENABLE_OMP` | ON/OFF | ON | enables OpenMP functionalities | -|`IPCL_THREAD_COUNT` | Integer | OFF | The max number of threads | -|`IPCL_DOCS` | ON/OFF | OFF | build doxygen documentation | -|`IPCL_SHARED` | ON/OFF | ON | build shared library | +| CMake options | Values | Default | Comments | +|--------------------------|-----------|---------|-------------------------------------| +|`IPCL_TEST` | ON/OFF | ON | unit-test | +|`IPCL_BENCHMARK` | ON/OFF | ON | benchmark | +|`IPCL_ENABLE_OMP` | ON/OFF | ON | enables OpenMP functionalities | +|`IPCL_THREAD_COUNT` | Integer | OFF | explicitly set max number of threads| +|`IPCL_DOCS` | ON/OFF | OFF | build doxygen documentation | +|`IPCL_SHARED` | ON/OFF | ON | build shared library | +|`IPCL_DETECT_IFMA_RUNTIME`| ON/OFF | OFF | detects AVX512IFMA during runtime | + +If ```IPCL_DETECT_IFMA_RUNTIME``` flag is set to ```ON```, it will determine whether the system supports the AVX512IFMA instructions on runtime. It is still possible to disable IFMA exclusive feature (multi-buffer modular exponentiation) during runtime by setting up the environment variable ```IPCL_DISABLE_AVX512IFMA=1```. + +### Installing and Using Example +For installing and using the library externally, see [example/README.md](./example/README.md). ## Testing and Benchmarking To run a set of unit tests via [Googletest](https://github.com/google/googletest), configure and build library with `-DIPCL_TEST=ON` (see [Instructions](#instructions)). @@ -105,21 +109,23 @@ cmake --build build --target benchmark ``` Setting the CMake flag ```-DIPCL_ENABLE_OMP=ON``` during configuration will use OpenMP for acceleration. Setting the value of `-DIPCL_THREAD_COUNT` will limit the maximum number of threads used by OpenMP (If set to OFF or 0, its actual value will be determined at run time). -The executables are located at `${IPCL_DIR}/build/test/unittest_ipcl` and `${IPCL_DIR}/build/benchmark/bench_ipcl`. +The executables are located at `${IPCL_ROOT}/build/test/unittest_ipcl` and `${IPCL_ROOT}/build/benchmark/bench_ipcl`. # Python Extension -Alongside the Intel Paillier Cryptosystem Library, we provide a Python extension package utilizing this library as a backend. For installation and usage detail, refer to [Intel Paillier Cryptosystem Library - Python](https://github.com/intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.pailliercryptolib-python). +Alongside the Intel Paillier Cryptosystem Library, we provide a Python extension package utilizing this library as a backend. For installation and usage detail, refer to [Intel Paillier Cryptosystem Library - Python](https://github.com/intel/pailliercryptolib_python). # Standardization -This library is in compliance with the homomorphic encryption standards [ISO/IEC 18033-6](https://www.iso.org/standard/67740.html). -The compliance test is included in the [unit-test](https://github.com/intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.pailliercryptolib/blob/main/test/test_cryptography.cpp#L112-L256). +This library is certified for ISO compliance with the homomorphic encryption standards [ISO/IEC 18033-6](https://www.iso.org/standard/67740.html) by Dekra. # Contributors Main contributors to this project, sorted by alphabetical order of last name are: + - [Flavio Bergamaschi](https://www.linkedin.com/in/flavio-bergamaschi) - [Xiaoran Fang](https://github.com/fangxiaoran) - [Hengrui Hu](https://github.com/hhr293) - [Xiaojun Huang](https://github.com/xhuan28) - - [Hamish Hunt](https://github.com/hamishun) - - [Sejun Kim](https://github.com/skmono) (lead) + - [Hamish Hunt](https://www.linkedin.com/in/hamish-hunt) + - [Jingyi Jin](https://www.linkedin.com/in/jingyi-jin-655735) + - [Sejun Kim](https://www.linkedin.com/in/sejun-kim-2b1b4866) (lead) + - [Fillipe D.M. de Souza](https://www.linkedin.com/in/fillipe-d-m-de-souza-a8281820) - [Bin Wang](https://github.com/bwang30) - [Pengfei Zhao](https://github.com/justalittlenoob) diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index 84d45cd..9f30a53 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -5,7 +5,7 @@ #include -#include "ipcl/keygen.hpp" +#include "ipcl/ipcl.hpp" #define ADD_SAMPLE_KEY_LENGTH_ARGS Args({1024})->Args({2048}) #define ADD_SAMPLE_VECTOR_SIZE_ARGS \ diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index d57acd3..48fe76c 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -6,7 +6,7 @@ #include #include -#include "ipcl/keygen.hpp" +#include "ipcl/ipcl.hpp" #define ADD_SAMPLE_KEY_LENGTH_ARGS Args({1024})->Args({2048}) #define ADD_SAMPLE_VECTOR_SIZE_ARGS \ diff --git a/cmake/cpufeatures.cmake b/cmake/cpufeatures.cmake new file mode 100644 index 0000000..6df3c12 --- /dev/null +++ b/cmake/cpufeatures.cmake @@ -0,0 +1,53 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +include(ExternalProject) +include(GNUInstallDirs) + +message(STATUS "configuring cpu_features") +set(CPUFEATURES_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_cpufeatures) +set(CPUFEATURES_DESTDIR ${CPUFEATURES_PREFIX}/cpufeatures_install) +set(CPUFEATURES_GIT_REPO_URL https://github.com/google/cpu_features.git) +set(CPUFEATURES_GIT_LABEL v0.7.0) +set(CPUFEATURES_C_FLAGS "${IPCL_FORWARD_CMAKE_ARGS} -fPIC") + +ExternalProject_Add( + ext_cpufeatures + PREFIX ${CPUFEATURES_PREFIX} + GIT_REPOSITORY ${CPUFEATURES_GIT_REPO_URL} + GIT_TAG ${CPUFEATURES_GIT_LABEL} + CMAKE_ARGS ${CPUFEATURES_C_FLAGS} + -DCMAKE_BUILD_TYPE=Release + -DBUILD_TESTING=OFF + -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + UPDATE_COMMAND "" + EXCLUDE_FROM_ALL TRUE + INSTALL_COMMAND make DESTDIR=${CPUFEATURES_DESTDIR} install + ) + + +set(CPUFEATURES_INC_DIR ${CPUFEATURES_DESTDIR}/${CMAKE_INSTALL_PREFIX}/include) +set(CPUFEATURES_LIB_DIR ${CPUFEATURES_DESTDIR}/${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) + +if(IPCL_SHARED) + add_library(libcpu_features INTERFACE) + add_dependencies(libcpu_features ext_cpufeatures) + + target_include_directories(libcpu_features SYSTEM + INTERFACE ${CPUFEATURES_INC_DIR}) + target_link_libraries(libcpu_features + INTERFACE ${CPUFEATURES_LIB_DIR}/libcpu_features.a) + + install( + DIRECTORY ${CPUFEATURES_LIB_DIR}/ + DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cpufeatures" + USE_SOURCE_PERMISSIONS + ) +else() + add_library(libcpu_features STATIC IMPORTED GLOBAL) + add_dependencies(libcpu_features ext_cpufeatures) + + set_target_properties(libcpu_features PROPERTIES + IMPORTED_LOCATION ${CPUFEATURES_LIB_DIR}/libcpu_features.a + INCLUDE_DIRECTORIES ${CPUFEATURES_INC_DIR}) +endif() diff --git a/cmake/gbenchmark.cmake b/cmake/gbenchmark.cmake index efd03fb..8c3e8c6 100644 --- a/cmake/gbenchmark.cmake +++ b/cmake/gbenchmark.cmake @@ -2,6 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 include(ExternalProject) +include(GNUInstallDirs) set(GBENCHMARK_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_gbenchmark) @@ -32,15 +33,7 @@ ExternalProject_Add( add_library(libgbenchmark INTERFACE) add_dependencies(libgbenchmark ext_gbenchmark) -ExternalProject_Get_Property(ext_gbenchmark SOURCE_DIR BINARY_DIR) -file(STRINGS /etc/os-release LINUX_ID REGEX "^ID=") -string(REGEX REPLACE "ID=\(.*)" "\\1" LINUX_ID "${LINUX_ID}") -if(${LINUX_ID} STREQUAL "ubuntu") - target_link_libraries(libgbenchmark INTERFACE ${GBENCHMARK_PREFIX}/lib/libbenchmark.a) -else() - # non debian systems install gbenchmark lib under lib64 - target_link_libraries(libgbenchmark INTERFACE ${GBENCHMARK_PREFIX}/lib64/libbenchmark.a) -endif() +target_link_libraries(libgbenchmark INTERFACE ${GBENCHMARK_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libbenchmark.a) target_include_directories(libgbenchmark SYSTEM INTERFACE ${GBENCHMARK_PREFIX}/include) diff --git a/cmake/gtest.cmake b/cmake/gtest.cmake index 7678d59..24b80a7 100644 --- a/cmake/gtest.cmake +++ b/cmake/gtest.cmake @@ -2,20 +2,30 @@ # SPDX-License-Identifier: Apache-2.0 include(ExternalProject) +include(GNUInstallDirs) +set(GTEST_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_gtest) set(GTEST_GIT_REPO_URL https://github.com/google/googletest.git) set(GTEST_GIT_LABEL release-1.10.0) set(GTEST_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS} -fPIC") ExternalProject_Add( ext_gtest - PREFIX ext_gtest + PREFIX ${GTEST_PREFIX} GIT_REPOSITORY ${GTEST_GIT_REPO_URL} GIT_TAG ${GTEST_GIT_LABEL} CMAKE_ARGS ${GTEST_CXX_FLAGS} -DCMAKE_BUILD_TYPE=Release - INSTALL_COMMAND "" + -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} UPDATE_COMMAND "" - EXCLUDE_FROM_ALL TRUE) + EXCLUDE_FROM_ALL TRUE + INSTALL_COMMAND "" +) + +# install( +# DIRECTORY ${GTEST_DESTDIR}/${CMAKE_INSTALL_PREFIX}/ +# DESTINATION "." +# USE_SOURCE_PERMISSIONS +# ) ExternalProject_Get_Property(ext_gtest SOURCE_DIR BINARY_DIR) diff --git a/cmake/ipcl/IPCLConfig.cmake.in b/cmake/ipcl/IPCLConfig.cmake.in index be0c1d8..340a5c4 100644 --- a/cmake/ipcl/IPCLConfig.cmake.in +++ b/cmake/ipcl/IPCLConfig.cmake.in @@ -4,11 +4,14 @@ include(CMakeFindDependencyMacro) -include(${CMAKE_CURRENT_LIST_DIR}/ipclTargets.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/IPCLTargets.cmake) if(TARGET IPCL::ipcl) set(IPCL_FOUND TRUE) message(STATUS "Intel Paillier Cryptosystem Library found") + find_package(OpenSSL REQUIRED) + find_package(Threads REQUIRED) + find_package(OpenMP REQUIRED) else() message(STATUS "Intel Paillier Cryptosystem Library not found") endif() diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake index a12ad08..3650b9a 100644 --- a/cmake/ippcrypto.cmake +++ b/cmake/ippcrypto.cmake @@ -2,10 +2,12 @@ # SPDX-License-Identifier: Apache-2.0 include(ExternalProject) -MESSAGE(STATUS "Configuring ipp-crypto") +message(STATUS "Configuring ipp-crypto") + set(IPPCRYPTO_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_ipp-crypto) +set(IPPCRYPTO_DESTDIR ${IPPCRYPTO_PREFIX}/ippcrypto_install) set(IPPCRYPTO_GIT_REPO_URL https://github.com/intel/ipp-crypto.git) -set(IPPCRYPTO_GIT_LABEL ipp-crypto_2021_4) +set(IPPCRYPTO_GIT_LABEL ippcp_2021.6) set(IPPCRYPTO_SRC_DIR ${IPPCRYPTO_PREFIX}/src/ext_ipp-crypto/) set(IPPCRYPTO_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS} -DNONPIC_LIB:BOOL=off -DMERGED_BLD:BOOL=on") @@ -29,20 +31,29 @@ ExternalProject_Add( -DARCH=${IPPCRYPTO_ARCH} -DCMAKE_ASM_NASM_COMPILER=nasm -DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} UPDATE_COMMAND "" + INSTALL_COMMAND make DESTDIR=${IPPCRYPTO_DESTDIR} install ) -set(IPPCRYPTO_INC_DIR ${IPPCRYPTO_PREFIX}/include) - +set(IPPCRYPTO_INC_DIR ${IPPCRYPTO_DESTDIR}/${CMAKE_INSTALL_PREFIX}/include) +set(IPPCRYPTO_LIB_DIR ${IPPCRYPTO_DESTDIR}/${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${IPPCRYPTO_ARCH}) if(IPCL_SHARED) add_library(libippcrypto INTERFACE) add_dependencies(libippcrypto ext_ipp-crypto) ExternalProject_Get_Property(ext_ipp-crypto SOURCE_DIR BINARY_DIR) - target_link_libraries(libippcrypto INTERFACE ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libippcp.a ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libcrypto_mb.a) - target_include_directories(libippcrypto SYSTEM INTERFACE ${IPPCRYPTO_PREFIX}/include) + target_link_libraries(libippcrypto INTERFACE + ${IPPCRYPTO_LIB_DIR}/libippcp.so + ${IPPCRYPTO_LIB_DIR}/libcrypto_mb.so) + target_include_directories(libippcrypto SYSTEM INTERFACE ${IPPCRYPTO_INC_DIR}) + install( + DIRECTORY ${IPPCRYPTO_LIB_DIR}/ + DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ippcrypto" + USE_SOURCE_PERMISSIONS + ) else() add_library(libippcrypto::ippcp STATIC IMPORTED GLOBAL) @@ -54,12 +65,12 @@ else() find_package(OpenSSL REQUIRED) set_target_properties(libippcrypto::ippcp PROPERTIES - IMPORTED_LOCATION ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libippcp.a + IMPORTED_LOCATION ${IPPCRYPTO_LIB_DIR}/libippcp.a INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} ) set_target_properties(libippcrypto::crypto_mb PROPERTIES - IMPORTED_LOCATION ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libcrypto_mb.a + IMPORTED_LOCATION ${IPPCRYPTO_LIB_DIR}/libcrypto_mb.a INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} ) endif() diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt new file mode 100644 index 0000000..cb66be8 --- /dev/null +++ b/example/CMakeLists.txt @@ -0,0 +1,15 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.15.1) + +project(ipcl_example LANGUAGES C CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +find_package(IPCL 1.1.4 REQUIRED HINTS ${IPCL_HINT_DIR}) + +add_executable(test test.cpp) +target_link_libraries(test PRIVATE IPCL::ipcl) diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..0bfe98c --- /dev/null +++ b/example/README.md @@ -0,0 +1,141 @@ +# Example using Intel Paillier Cryptosystem Library +This document provides an example program for using the Intel Paillier Cryptosystem Library in an external application. + +## Contents +- [Example using Intel Paillier Cryptosystem Library](#example-using-intel-paillier-cryptosystem-library) + - [Contents](#contents) + - [Installation](#installation) + - [Linking and Running Applications](#linking-and-running-applications) + - [Building with CMake](#building-with-cmake) + - [Manually Compiling](#manually-compiling) + - [Using Intel Paillier Cryptosystem Library](#using-intel-paillier-cryptosystem-library) + - [Data handling](#data-handling) + - [```ipcl::PlainText``` Constructor](#ipclplaintext-constructor) + - [Accessing data](#accessing-data) + - [Key Generation](#key-generation) + - [Encryption and Decryption](#encryption-and-decryption) + - [HE Operations](#he-operations) + + + +## Installation +To install the library, +```bash +cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/path/to/install/ -DCMAKE_BUILD_TYPE=Release -DIPCL_TEST=OFF -DIPCL_BENCHMARK=OFF +cmake --build build -j +cmake --build build --target install +``` + +If ```CMAKE_INSTALL_PREFIX``` is not explicitly set, the library will automatically set to ```/opt/intel/ipcl``` by default. + +For more details about the build configuration options, please refer to the build instructions provided in the [README.md](../README.md). + +## Linking and Running Applications + +Before proceeding after the library is installed, it is useful to setup an environment variable to point to the installation location. +```bash +export IPCL_DIR=/path/to/install/ +``` + +### Building with CMake +A more convenient way to use the library is via the `find_package` functionality in `CMake`. +In your external applications, add the following lines to your `CMakeLists.txt`. + +```bash +find_package(IPCL 1.1.4 + HINTS ${IPCL_HINT_DIR} + REQUIRED) +target_link_libraries(${TARGET} IPCL::ipcl) +``` + +If the library is installed globally, `IPCL_DIR` or `IPCL_HINT_DIR` flag is not needed. If `IPCL_DIR` is properly set, `IPCL_HINT_DIR` is not needed as well. Otherwise `IPCL_HINT_DIR` should be the directory containing `IPCLCOnfig.cmake`, under `${CMAKE_INSTALL_PREFIX}/lib/cmake/ipcl-1.1.4/` + +### Manually Compiling +In order to directly use `g++` or `clang++` to compile an example code, it can be done by: +```bash +# gcc +g++ test.cpp -o test -L${IPCL_DIR}/lib -I${IPCL_DIR}/include -lipcl -fopenmp -lnuma -lcrypto + +# clang +clang++ test.cpp -o test -L${IPCL_DIR}/lib -I${IPCL_DIR}/include -lipcl -fopenmp -lnuma -lcrypto +``` + + +## Using Intel Paillier Cryptosystem Library + +### Data handling +The library uses a container - ```ipcl::PlainText``` for encryption inputs and decryption outputs as well as plaintext HE operations. + +#### ```ipcl::PlainText``` Constructor + +```C++ +// construct w/ unsigned int32 +uint32_t val1; +ipcl::PlainText pt1(val1); + +// construct w/ unsigned int32 vector +std::vector val2; +ipcl::PlainText pt2(val2); + +// construct w/ IPP-Crypto BigNumber +BigNumber val3; +ipcl::PlainText pt3(val3); + +// construct w/ IPP-Crypto BigNumber vector +std::vector val4; +ipcl::PlainText pt4(val4); +``` +For more details about the IPP-Crypto ```BigNumber``` class, please refer to [Intel IPP Developer Reference](https://www.intel.com/content/www/us/en/develop/documentation/ipp-crypto-reference/top/appendix-a-support-functions-and-classes/classes-and-functions-used-in-examples/bignumber-class.html). + +#### Accessing data +The library provides several methods to handle and access the data included in the ```ipcl::PlainText``` container. +```C++ +ipcl::PlainText pt(raw_data); + +BigNumber ret1 = pt[1]; // idx +std::vector ret2 = pt; // convert +pt.insert(pos, val); // insert BigNumber to position +pt.remove(pos, length); // remove element (default length=1) +ipcl::PlainText pt_copy = pt; // copy +pt_copy.clear(); // empty the container +``` +FOr more details, please refer to the [```base_text.hpp```](../ipcl/include/ipcl/base_text.hpp) and [```plaintext.hpp```](../ipcl/include/ipcl/plaintext.hpp). + +### Key Generation +The public key and private key pair can be generated by using the ```ipcl::generateKeypair``` function. +```C++ +// key.pub_key, key.priv_key +ipcl::keyPair key = ipcl::generateKeypair(2048, true); +// After computation, need to delete the key objects +delete key.pub_key; +delete key.priv_key; +``` + +### Encryption and Decryption +The public key is used to encrypt ```ipcl::PlainText``` objects for ```ipcl::CipherText``` outputs. +In the same way, the private key is used to decrypt ```ipcl::CipherText``` objects for ```ipcl::PlainText``` outputs. +```C++ +ipcl::PlainText pt(raw_data); +ipcl::CipherText ct = key.pub_key->encrypt(pt); +ipcl::PlainText dec_pt = key.priv_key->decrypt(ct); +``` + +### HE Operations +Since the Intel Paillier Cryptosystem Library being a partially homomorphic encryption scheme, while addition is supports both ciphertext operands, multiplication only supports single ciphertext operand. + +```C++ +// setup +ipcl::PlainText a, b; + +ipcl::CipherText ct_a = key.pub_key->encrypt(a); +ipcl::CipherText ct_b = key.pub_key->encrypt(b); + +// Addition (all three end up being same values after decryption) +ipcl::CipherText ct_c1 = ct_a + ct_b; // ciphertext + ciphertext +ipcl::CipherText ct_c2 = ct_a + b; // ciphertext + plaintext +ipcl::CipherText ct_c3 = ct_b + a; // ciphertext + plaintext + +// Multiplication +ipcl::CipherText ct_d1 = ct_a * b; // ciphertext * plaintext +ipcl::CipherText ct_d2 = ct_b * a; +``` diff --git a/example/test.cpp b/example/test.cpp new file mode 100644 index 0000000..5ac7a31 --- /dev/null +++ b/example/test.cpp @@ -0,0 +1,40 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include + +int main() { + const uint32_t num_values = 9; + + ipcl::keyPair key = ipcl::generateKeypair(2048, true); + + std::vector exp_value(num_values); + ipcl::PlainText pt; + ipcl::CipherText ct; + ipcl::PlainText dt; + + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < num_values; i++) { + exp_value[i] = dist(rng); + } + + pt = ipcl::PlainText(exp_value); + ct = key.pub_key->encrypt(pt); + dt = key.priv_key->decrypt(ct); + + for (int i = 0; i < num_values; i++) { + std::vector v = dt.getElementVec(i); + bool chk = v[0] == exp_value[i]; + std::cout << (chk ? "pass" : "fail") << std::endl; + } + + delete key.pub_key; + delete key.priv_key; +} diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index b1388b2..e645d38 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -35,31 +35,55 @@ target_include_directories(ipcl PUBLIC $ ) +if(IPCL_DETECT_IFMA_RUNTIME) + target_include_directories(ipcl + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PUBLIC $ + PUBLIC $ + ) + install(DIRECTORY ${CPUFEATURES_INC_DIR}/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING + PATTERN "*.hpp" + PATTERN "*.h") + +endif() + install(DIRECTORY ${IPCL_INC_DIR}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h") install(DIRECTORY ${IPPCRYPTO_INC_DIR}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h") +find_package(OpenSSL REQUIRED) +find_package(Threads REQUIRED) target_link_libraries(ipcl PUBLIC OpenSSL::SSL OpenSSL::Crypto Threads::Threads -lnuma) if(IPCL_ENABLE_OMP) find_package(OpenMP REQUIRED) - target_link_libraries(ipcl PRIVATE OpenMP::OpenMP_CXX) + target_link_libraries(ipcl PUBLIC OpenMP::OpenMP_CXX) endif() if(IPCL_SHARED) target_link_libraries(ipcl PRIVATE libippcrypto) + if(IPCL_DETECT_IFMA_RUNTIME) + target_link_libraries(ipcl PRIVATE libcpu_features) + target_include_directories(ipcl PRIVATE ${CPUFEATURES_INC_DIR}) + endif() target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) else() ipcl_create_archive(ipcl libippcrypto::ippcp) ipcl_create_archive(ipcl libippcrypto::crypto_mb) + if(IPCL_DETECT_IFMA_RUNTIME) + ipcl_create_archive(ipcl libcpu_features) + target_include_directories(ipcl PRIVATE ${CPUFEATURES_INC_DIR}) + endif() target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) endif() @@ -71,14 +95,6 @@ else() set_target_properties(ipcl PROPERTIES OUTPUT_NAME "ipcl") endif() - -install(DIRECTORY ${IPCL_INC_DIR}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ - FILES_MATCHING - PATTERN "*.hpp" - PATTERN "*.h" -) - install(TARGETS ipcl DESTINATION ${CMAKE_INSTALL_LIBDIR}) # config cmake config and target file diff --git a/ipcl/include/ipcl/ipcl.hpp b/ipcl/include/ipcl/ipcl.hpp new file mode 100644 index 0000000..f82ad31 --- /dev/null +++ b/ipcl/include/ipcl/ipcl.hpp @@ -0,0 +1,37 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IPCL_INCLUDE_IPCL_IPCL_HPP_ +#define IPCL_INCLUDE_IPCL_IPCL_HPP_ + +#include "ipcl/pri_key.hpp" + +namespace ipcl { + +/** + * Paillier key structure contains a public key and private key + * pub_key: paillier public key + * priv_key: paillier private key + */ +struct keyPair { + PublicKey* pub_key; + PrivateKey* priv_key; +}; + +/** + * Generate prime number + * @param[in] maxBitSize Maximum bit length of to be generated prime number + * @return The function return a prime big number + */ +BigNumber getPrimeBN(int maxBitSize); + +/** + * Generate a public/private key pair + * @param[in] n_length Bit length of key size + * @param[in] enable_DJN Enable DJN (default=true) + * @return The function return the public and private key pair + */ +keyPair generateKeypair(int64_t n_length, bool enable_DJN = true); + +} // namespace ipcl +#endif // IPCL_INCLUDE_IPCL_IPCL_HPP_ diff --git a/ipcl/include/ipcl/util.hpp b/ipcl/include/ipcl/util.hpp index b264816..202e277 100644 --- a/ipcl/include/ipcl/util.hpp +++ b/ipcl/include/ipcl/util.hpp @@ -4,6 +4,11 @@ #ifndef IPCL_INCLUDE_IPCL_UTIL_HPP_ #define IPCL_INCLUDE_IPCL_UTIL_HPP_ +#ifdef IPCL_RUNTIME_MOD_EXP +#include +#endif // IPCL_RUNTIME_MOD_EXP + +#include #include #include #include @@ -66,6 +71,14 @@ class OMPUtilities { #endif // IPCL_USE_OMP +#ifdef IPCL_RUNTIME_MOD_EXP +static const bool disable_avx512ifma = + (std::getenv("IPCL_DISABLE_AVX512IFMA") != nullptr); +static const cpu_features::X86Features features = + cpu_features::GetX86Info().features; +static const bool has_avx512ifma = features.avx512ifma && !disable_avx512ifma; +#endif // IPCL_RUNTIME_MOD_EXP + } // namespace ipcl #endif // IPCL_INCLUDE_IPCL_UTIL_HPP_ diff --git a/ipcl/keygen.cpp b/ipcl/keygen.cpp index 290e502..f2d712e 100644 --- a/ipcl/keygen.cpp +++ b/ipcl/keygen.cpp @@ -1,11 +1,9 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include "ipcl/keygen.hpp" - #include -#include "ipcl/util.hpp" +#include "ipcl/ipcl.hpp" namespace ipcl { diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index cdb729d..1f885a4 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -160,6 +160,61 @@ std::vector ippModExp(const std::vector& base, std::size_t v_size = base.size(); std::vector res(v_size); +#ifdef IPCL_RUNTIME_MOD_EXP + + // If there is only 1 big number, we don't need to use MBModExp + if (v_size == 1) { + res[0] = ippSBModExp(base[0], exp[0], mod[0]); + return res; + } + + if (has_avx512ifma) { + std::size_t remainder = v_size % IPCL_CRYPTO_MB_SIZE; + std::size_t num_chunk = + (v_size + IPCL_CRYPTO_MB_SIZE - 1) / IPCL_CRYPTO_MB_SIZE; +#ifdef IPCL_USE_OMP + int omp_remaining_threads = OMPUtilities::MaxThreads; +#pragma omp parallel for num_threads( \ + OMPUtilities::assignOMPThreads(omp_remaining_threads, num_chunk)) +#endif // IPCL_USE_OMP + for (std::size_t i = 0; i < num_chunk; i++) { + std::size_t chunk_size = IPCL_CRYPTO_MB_SIZE; + if ((i == (num_chunk - 1)) && (remainder > 0)) chunk_size = remainder; + + std::size_t chunk_offset = i * IPCL_CRYPTO_MB_SIZE; + + auto base_start = base.begin() + chunk_offset; + auto base_end = base_start + chunk_size; + + auto exp_start = exp.begin() + chunk_offset; + auto exp_end = exp_start + chunk_size; + + auto mod_start = mod.begin() + chunk_offset; + auto mod_end = mod_start + chunk_size; + + auto base_chunk = std::vector(base_start, base_end); + auto exp_chunk = std::vector(exp_start, exp_end); + auto mod_chunk = std::vector(mod_start, mod_end); + + auto tmp = ippMBModExp(base_chunk, exp_chunk, mod_chunk); + std::copy(tmp.begin(), tmp.end(), res.begin() + chunk_offset); + } + + return res; + + } else { +#ifdef IPCL_USE_OMP + int omp_remaining_threads = OMPUtilities::MaxThreads; +#pragma omp parallel for num_threads( \ + OMPUtilities::assignOMPThreads(omp_remaining_threads, v_size)) +#endif // IPCL_USE_OMP + for (int i = 0; i < v_size; i++) + res[i] = ippSBModExp(base[i], exp[i], mod[i]); + return res; + } + +#else + #ifdef IPCL_CRYPTO_MB_MOD_EXP // If there is only 1 big number, we don't need to use MBModExp @@ -214,6 +269,8 @@ std::vector ippModExp(const std::vector& base, return res; #endif // IPCL_CRYPTO_MB_MOD_EXP + +#endif // IPCL_RUNTIME_MOD_EXP } BigNumber ippModExp(const BigNumber& base, const BigNumber& exp, diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index abe0928..bac47db 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -7,9 +7,7 @@ #include #include "gtest/gtest.h" -#include "ipcl/ciphertext.hpp" -#include "ipcl/keygen.hpp" -#include "ipcl/plaintext.hpp" +#include "ipcl/ipcl.hpp" constexpr int SELF_DEF_NUM_VALUES = 9; diff --git a/test/test_ops.cpp b/test/test_ops.cpp index 862f1f4..74064fe 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -7,9 +7,7 @@ #include #include "gtest/gtest.h" -#include "ipcl/ciphertext.hpp" -#include "ipcl/keygen.hpp" -#include "ipcl/plaintext.hpp" +#include "ipcl/ipcl.hpp" constexpr int SELF_DEF_NUM_VALUES = 7; From 7fef48421dff75f90e6709b1f1928fed12c7300b Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 7 Oct 2022 15:40:02 -0700 Subject: [PATCH 262/364] Remove dangling header. Signed-off-by: Souza, Fillipe --- include/cpa_sample_utils.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/cpa_sample_utils.h b/include/cpa_sample_utils.h index a35b557..56a206f 100644 --- a/include/cpa_sample_utils.h +++ b/include/cpa_sample_utils.h @@ -96,7 +96,6 @@ extern "C" { #ifdef DO_CRYPTO #include "cpa_cy_sym.h" #endif -#include "cpa_sample_cnv_utils.h" #ifdef USER_SPACE /* User space utils */ From 5b2b2b8453238f667d6c6f1a1c479d51434d8786 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 7 Oct 2022 15:40:54 -0700 Subject: [PATCH 263/364] Adjust optimization params. Signed-off-by: Souza, Fillipe --- he_qat/he_qat_ctrl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/he_qat/he_qat_ctrl.c b/he_qat/he_qat_ctrl.c index 76d60d8..d48998c 100644 --- a/he_qat/he_qat_ctrl.c +++ b/he_qat/he_qat_ctrl.c @@ -38,8 +38,8 @@ HE_QAT_OutstandingBuffer outstanding; ///< This is the data structure that holds volatile unsigned long response_count = 0; ///< Counter of processed requests and it is used to help control throttling. static volatile unsigned long request_count = 0; ///< Counter of received requests and it is used to help control throttling. static unsigned long request_latency = 0; ///< Variable used to hold measured averaged latency of requests (currently unused). -static unsigned long restart_threshold = NUM_PKE_SLICES; ///< Number of concurrent requests allowed to be sent to accelerator at once. -static unsigned long max_pending = (NUM_PKE_SLICES * 2 * HE_QAT_NUM_ACTIVE_INSTANCES); ///< Number of requests sent to the accelerator that are pending completion. +static unsigned long restart_threshold = NUM_PKE_SLICES * HE_QAT_NUM_ACTIVE_INSTANCES; ///< Number of concurrent requests allowed to be sent to accelerator at once. +static unsigned long max_pending = (2 * NUM_PKE_SLICES * HE_QAT_NUM_ACTIVE_INSTANCES); ///< Number of requests sent to the accelerator that are pending completion. /// @brief Populate internal buffer with incoming requests from API calls. /// @details This function is called from the main APIs to submit requests to From 5a1b3cd018aaf6e84574f7145eb436a4f87bce99 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 7 Oct 2022 15:41:27 -0700 Subject: [PATCH 264/364] Fix compilation error for HE_QAT_PERF=ON. Signed-off-by: Souza, Fillipe --- he_qat/he_qat_ops.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/he_qat/he_qat_ops.c b/he_qat/he_qat_ops.c index 6c6bd02..ba8d942 100644 --- a/he_qat/he_qat_ops.c +++ b/he_qat/he_qat_ops.c @@ -12,8 +12,6 @@ #ifdef HE_QAT_PERF #include -struct timeval start_time, end_time; -double time_taken = 0.0; #endif #include @@ -255,6 +253,8 @@ void getBnModExpRequest(unsigned int batch_size) { unsigned int j = 0; #ifdef HE_QAT_PERF + struct timeval start_time, end_time; + double time_taken = 0.0; gettimeofday(&start_time, NULL); #endif // while (j < batch_size) { @@ -477,12 +477,14 @@ HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id) { void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size) { unsigned int next_data_out = outstanding.buffer[_buffer_id].next_data_out; unsigned int j = 0; - + #ifdef HE_QAT_DEBUG printf("release_bnModExp_buffer #%u\n", _buffer_id); #endif #ifdef HE_QAT_PERF + struct timeval start_time, end_time; + double time_taken = 0.0; gettimeofday(&start_time, NULL); #endif From 86437b6e009cc9ffba0a576498e566a4d65a4861 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Fri, 7 Oct 2022 15:48:44 -0700 Subject: [PATCH 265/364] Use main branch instead of v1.1-rc --- module/heqat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/heqat b/module/heqat index 51f227c..5a1b3cd 160000 --- a/module/heqat +++ b/module/heqat @@ -1 +1 @@ -Subproject commit 51f227c6663860df5f6444cf6da6d9833340378b +Subproject commit 5a1b3cd018aaf6e84574f7145eb436a4f87bce99 From 9536741cf1cb5e5107446492d978e390236c62a5 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 11 Oct 2022 18:02:18 -0700 Subject: [PATCH 266/364] Add context interface to configure device runtime. Signed-off-by: Souza, Fillipe --- benchmark/main.cpp | 15 ++++----- ipcl/CMakeLists.txt | 17 +++++----- ipcl/context.cpp | 59 +++++++++++++++++++++++++++++++++++ ipcl/include/ipcl/context.hpp | 28 +++++++++++++++++ test/main.cpp | 15 +++------ 5 files changed, 107 insertions(+), 27 deletions(-) create mode 100644 ipcl/context.cpp create mode 100644 ipcl/include/ipcl/context.hpp diff --git a/benchmark/main.cpp b/benchmark/main.cpp index 63ecedd..a08e372 100644 --- a/benchmark/main.cpp +++ b/benchmark/main.cpp @@ -1,23 +1,20 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#ifdef IPCL_USE_QAT -#include -#endif // IPCL_USE_QAT - +#include #include int main(int argc, char** argv) { #ifdef IPCL_USE_QAT - acquire_qat_devices(); + ipcl::initializeContext("QAT"); +#else + ipcl::initializeContext("default"); #endif // IPCL_USE_QAT benchmark::Initialize(&argc, argv); benchmark::RunSpecifiedBenchmarks(); - -#ifdef IPCL_USE_QAT - release_qat_devices(); -#endif + + ipcl::terminateContext(); return 0; } diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 3c931db..0afbef9 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -2,14 +2,15 @@ # SPDX-License-Identifier: Apache-2.0 set(IPCL_SRCS pri_key.cpp - pub_key.cpp - keygen.cpp - bignum.cpp - mod_exp.cpp - base_text.cpp - plaintext.cpp - ciphertext.cpp - util.cpp + pub_key.cpp + keygen.cpp + bignum.cpp + mod_exp.cpp + context.cpp + base_text.cpp + plaintext.cpp + ciphertext.cpp + util.cpp ) diff --git a/ipcl/context.cpp b/ipcl/context.cpp new file mode 100644 index 0000000..07fa350 --- /dev/null +++ b/ipcl/context.cpp @@ -0,0 +1,59 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/context.hpp" + +#include +#include + +#ifdef IPCL_USE_QAT +#include +#endif + +namespace ipcl { + + ///> Default behavior is selected at runtime and implementation dependent + enum class RuntimeValue { DEFAULT, CPU, QAT, HYBRID }; + std::map runtimeMap = { + {"DEFAULT",RuntimeValue::DEFAULT}, {"default",RuntimeValue::DEFAULT}, + {"CPU",RuntimeValue::CPU}, {"cpu",RuntimeValue::CPU}, + {"QAT",RuntimeValue::QAT}, {"qat",RuntimeValue::QAT}, + {"HYBRID",RuntimeValue::HYBRID}, {"hybrid",RuntimeValue::HYBRID} + }; + + static bool isUsingQAT = false; + static bool initializeQATContext() { + if (HE_QAT_STATUS_SUCCESS == acquire_qat_devices()) + return (isUsingQAT = true); + return false; + } + + bool initializeContext(std::string runtime_choice) { +#ifdef IPCL_USE_QAT + switch (runtimeMap[runtime_choice]) { + case RuntimeValue::QAT: + return initializeQATContext(); + case RuntimeValue::CPU: + case RuntimeValue::HYBRID: + case RuntimeValue::DEFAULT: + default: + return true; + } +#else // Default behavior: CPU choice + return true; +#endif // IPCL_USE_QAT + } + + bool terminateContext() { +#ifdef IPCL_USE_QAT + if (isUsingQAT) { + if (HE_QAT_STATUS_SUCCESS == release_qat_devices()) + return true; + return false; + } return true; +#else // Default behavior: CPU choice + return true; +#endif // IPCL_USE_QAT + } + +} // namespace ipcl diff --git a/ipcl/include/ipcl/context.hpp b/ipcl/include/ipcl/context.hpp new file mode 100644 index 0000000..5c3b004 --- /dev/null +++ b/ipcl/include/ipcl/context.hpp @@ -0,0 +1,28 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#ifndef IPCL_INCLUDE_IPCL_CONTEXT_HPP_ +#define IPCL_INCLUDE_IPCL_CONTEXT_HPP_ + +#include + +namespace ipcl { + +/** + * Initialize device (CPU, QAT, or both) runtime context for the Paillier crypto services. + * @details It must be called if there is intent of using QAT devices for compute acceleration. + * @param[in] runtime_choice Acceptable values are "CPU", "cpu", "QAT", "qat", "HYBRID", "hybrid", "DEFAULT", "default". Anything other than the accepted values, including typos and absence thereof, will default to the "DEFAULT" runtime choice. + * @return true if runtime context has been properly initialized, false otherwise. + */ +bool initializeContext(std::string runtime_choice); + +/** + * Terminate runtime context. + * @return true if runtime context has been properly terminated, false otherwise. + */ +bool terminateContext(void); + +} // namespace ipcl +#endif // IPCL_INCLUDE_IPCL_CONTEXT_HPP_ diff --git a/test/main.cpp b/test/main.cpp index 29d68fd..6c19ea9 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -1,18 +1,16 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#ifdef IPCL_USE_QAT -#include "he_qat_context.h" -#endif // IPCL_USE_QAT - +#include #include #include int main(int argc, char** argv) { #ifdef IPCL_USE_QAT - // Initialize QAT context - acquire_qat_devices(); + ipcl::initializeContext("QAT"); +#else + ipcl::initializeContext("default"); #endif // IPCL_USE_QAT // Use system clock for seed @@ -20,10 +18,7 @@ int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); int status = RUN_ALL_TESTS(); -#ifdef IPCL_USE_QAT - // Destroy QAT context - release_qat_devices(); -#endif + ipcl::terminateContext(); return status; } From acb71a40fc6135841bd107a2cdb75b1f23aa8f44 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 11 Oct 2022 18:03:17 -0700 Subject: [PATCH 267/364] Update heqat.cmake Signed-off-by: Souza, Fillipe --- module/heqat.cmake | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/module/heqat.cmake b/module/heqat.cmake index d572db6..fbb5625 100644 --- a/module/heqat.cmake +++ b/module/heqat.cmake @@ -4,26 +4,36 @@ include(ExternalProject) MESSAGE(STATUS "Configuring HE QAT") set(HEQAT_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_he_qat) +set(HEQAT_DESTDIR ${HEQAT_PREFIX}/heqat_install) set(HEQAT_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/module/heqat) set(HEQAT_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS}") +set(HEQAT_BUILD_TYPE Release) +if (CMAKE_BUILD_TYPE STREQUAL "Debug") + set(HEQAT_BUILD_TYPE Debug) +endif() + ExternalProject_Add( ext_he_qat SOURCE_DIR ${HEQAT_SRC_DIR} PREFIX ${HEQAT_PREFIX} - INSTALL_DIR ${HEQAT_PREFIX} + INSTALL_DIR ${HEQAT_DESTDIR} CMAKE_ARGS ${HEQAT_CXX_FLAGS} - -DCMAKE_INSTALL_PREFIX=${HEQAT_PREFIX} + -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DHE_QAT_MISC=OFF -DHE_QAT_DOCS=${IPCL_DOCS} - -DIPPCP_PREFIX_PATH=${IPPCRYPTO_PREFIX}/lib/cmake + # REVIEW IPPCP_PREFIX_PATH (DEPS ON LOCAL INSTALL) + -DIPPCP_PREFIX_PATH=${IPPCRYPTO_DESTDIR}/lib/cmake -DHE_QAT_SHARED=${IPCL_SHARED} - -DCMAKE_BUILD_TYPE=Release + -DCMAKE_BUILD_TYPE=${HEQAT_BUILD_TYPE} UPDATE_COMMAND "" + EXCLUDE_FROM_ALL TRUE + INSTALL_COMMAND make DESTDIR=${HEQAT_DESTDIR} install ) add_dependencies(ext_he_qat ext_ipp-crypto) -set(HEQAT_INC_DIR ${HEQAT_PREFIX}/include) +set(HEQAT_INC_DIR ${HEQAT_DESTDIR}/${CMAKE_INSTALL_PREFIX}/include) +set(HEQAT_LIB_DIR ${HEQAT_DESTDIR}/${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) # Bring up CPA variables include(${HEQAT_SRC_DIR}/icp/CMakeLists.txt) @@ -35,11 +45,11 @@ if(IPCL_SHARED) ExternalProject_Get_Property(ext_he_qat SOURCE_DIR BINARY_DIR) - target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libcpa_sample_utils.so) + target_link_libraries(libhe_qat INTERFACE ${HEQAT_LIB_DIR}/libcpa_sample_utils.so) if(CMAKE_BUILD_TYPE STREQUAL "Debug") - target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat_debug.so) + target_link_libraries(libhe_qat INTERFACE ${HEQAT_LIB_DIR}/libhe_qat_debug.so) else() - target_link_libraries(libhe_qat INTERFACE ${HEQAT_PREFIX}/lib/libhe_qat.so) + target_link_libraries(libhe_qat INTERFACE ${HEQAT_LIB_DIR}/libhe_qat.so) endif() target_include_directories(libhe_qat SYSTEM INTERFACE ${HEQAT_INC_DIR}) else() @@ -48,7 +58,13 @@ else() ExternalProject_Get_Property(ext_he_qat SOURCE_DIR BINARY_DIR) - set_target_properties(libhe_qat PROPERTIES - IMPORTED_LOCATION ${HEQAT_PREFIX}/lib/libhe_qat.a - INCLUDE_DIRECTORIES ${HEQAT_INC_DIR}) + if (CMAKE_BUILD_TYPE STREQUAL "Debug") + set_target_properties(libhe_qat PROPERTIES + IMPORTED_LOCATION ${HEQAT_LIB_DIR}/libhe_qat_debug.a + INCLUDE_DIRECTORIES ${HEQAT_INC_DIR}) + else() + set_target_properties(libhe_qat PROPERTIES + IMPORTED_LOCATION ${HEQAT_LIB_DIR}/libhe_qat.a + INCLUDE_DIRECTORIES ${HEQAT_INC_DIR}) + endif() endif() From 77a206cd65ffb0b3096a3c752dedef3386468980 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 12 Oct 2022 16:43:51 -0700 Subject: [PATCH 268/364] Remove commented line Signed-off-by: Souza, Fillipe --- he_qat/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/he_qat/CMakeLists.txt b/he_qat/CMakeLists.txt index 563210b..f6a8e76 100644 --- a/he_qat/CMakeLists.txt +++ b/he_qat/CMakeLists.txt @@ -14,7 +14,6 @@ else() endif() add_library(HE_QAT::he_qat ALIAS he_qat) -#add_library(he_qat SHARED ${HE_QAT_SRC}) target_include_directories(he_qat PUBLIC $ #Public headers From 56251ed6a16e307b689471b2d6b93821b8229701 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 12 Oct 2022 16:46:43 -0700 Subject: [PATCH 269/364] Expose context status interface. Signed-off-by: Souza, Fillipe --- he_qat/he_qat_context.c | 22 +++++++++++----------- he_qat/he_qat_ctrl.c | 7 ++++--- he_qat/include/he_qat_context.h | 4 ++++ he_qat/include/he_qat_types.h | 5 ++++- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/he_qat/he_qat_context.c b/he_qat/he_qat_context.c index 6d2de68..7ffe390 100644 --- a/he_qat/he_qat_context.c +++ b/he_qat/he_qat_context.c @@ -6,12 +6,6 @@ #include "he_qat_context.h" #include - -//#include - -//#include -//#include -//#include #include #include @@ -25,7 +19,7 @@ #define MAX_INSTANCES 1 #endif -static volatile int context_state = 0; +static volatile HE_QAT_STATUS context_state = HE_QAT_STATUS_INACTIVE; // Global variable declarations static pthread_t buffer_manager; @@ -35,10 +29,10 @@ static pthread_attr_t he_qat_inst_attr[HE_QAT_NUM_ACTIVE_INSTANCES]; static HE_QAT_InstConfig he_qat_inst_config[HE_QAT_NUM_ACTIVE_INSTANCES]; static HE_QAT_Config* he_qat_config = NULL; +// External global variables extern HE_QAT_RequestBuffer he_qat_buffer; extern HE_QAT_OutstandingBuffer outstanding; - /*********** Internal Services ***********/ // Start scheduler of work requests (consumer) extern void* schedule_requests(void* state); @@ -248,7 +242,7 @@ HE_QAT_STATUS acquire_qat_devices() { #endif // Set context state to active - context_state = 1; + context_state = HE_QAT_STATUS_ACTIVE; // Launch buffer manager thread to schedule incoming requests if (0 != pthread_create(&buffer_manager, NULL, schedule_requests, @@ -276,7 +270,8 @@ HE_QAT_STATUS acquire_qat_devices() { HE_QAT_STATUS release_qat_devices() { CpaStatus status = CPA_STATUS_FAIL; - if (0 == context_state) return HE_QAT_STATUS_SUCCESS; + if (HE_QAT_STATUS_INACTIVE == context_state) + return HE_QAT_STATUS_SUCCESS; stop_instances(he_qat_config); //stop_perform_op(he_qat_inst_config, HE_QAT_NUM_ACTIVE_INSTANCES); @@ -286,7 +281,7 @@ HE_QAT_STATUS release_qat_devices() { // Deactivate context (this will cause the buffer manager thread to be // terminated) - context_state = 0; + context_state = HE_QAT_STATUS_INACTIVE; // Stop QAT SSL service icp_sal_userStop(); @@ -302,3 +297,8 @@ HE_QAT_STATUS release_qat_devices() { return HE_QAT_STATUS_SUCCESS; } + +HE_QAT_STATUS get_qat_context_state() { + return context_state; +} + diff --git a/he_qat/he_qat_ctrl.c b/he_qat/he_qat_ctrl.c index d48998c..35ce5a7 100644 --- a/he_qat/he_qat_ctrl.c +++ b/he_qat/he_qat_ctrl.c @@ -291,13 +291,13 @@ static void pull_outstanding_requests(HE_QAT_TaskRequestList* _requests, HE_QAT_ /// from which requests are ready to be submitted to the device for processing. /// @param[in] state A volatile integer variable used to activate (val>0) or /// disactive (val=0) the scheduler. -void* schedule_requests(void* state) { +void* schedule_requests(void* context_state) { if (NULL == state) { printf("Failed at buffer_manager: argument is NULL.\n"); pthread_exit(NULL); } - int* active = (int*)state; + HE_QAT_STATUS* active = (HE_QAT_STATUS*)context_state; HE_QAT_TaskRequestList outstanding_requests; for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { @@ -306,7 +306,8 @@ void* schedule_requests(void* state) { outstanding_requests.count = 0; // this thread should receive signal from context to exit - while (*active) { + *active = HE_QAT_STATUS_RUNNING; + while (HE_QAT_STATUS_INACTIVE != *active) { // Collect a set of requests from the outstanding buffer pull_outstanding_requests(&outstanding_requests, &outstanding, HE_QAT_BUFFER_SIZE); diff --git a/he_qat/include/he_qat_context.h b/he_qat/include/he_qat_context.h index e260793..86fbc8b 100644 --- a/he_qat/include/he_qat_context.h +++ b/he_qat/include/he_qat_context.h @@ -19,6 +19,10 @@ HE_QAT_STATUS acquire_qat_devices(); /// Release and free resources of the QAT runtime environment. HE_QAT_STATUS release_qat_devices(); +/// @brief +/// Probe context status of the QAT runtime environment. +HE_QAT_STATUS get_qat_context_state(); + #ifdef __cplusplus } // extern "C" { #endif diff --git a/he_qat/include/he_qat_types.h b/he_qat/include/he_qat_types.h index b20d910..71c4671 100644 --- a/he_qat/include/he_qat_types.h +++ b/he_qat/include/he_qat_types.h @@ -30,10 +30,13 @@ typedef enum { } HE_QAT_EXEC_MODE; typedef enum { + HE_QAT_STATUS_ACTIVE = 3, + HE_QAT_STATUS_RUNNING = 4, HE_QAT_STATUS_INVALID_PARAM = 2, HE_QAT_STATUS_READY = 1, HE_QAT_STATUS_SUCCESS = 0, - HE_QAT_STATUS_FAIL = -1 + HE_QAT_STATUS_FAIL = -1, + HE_QAT_STATUS_INACTIVE = -2 } HE_QAT_STATUS; typedef enum { From 8bca333d02d5c115676de40646e68b4c8c30f572 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 12 Oct 2022 16:51:25 -0700 Subject: [PATCH 270/364] Fix compilation Signed-off-by: Souza, Fillipe --- he_qat/he_qat_ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/he_qat/he_qat_ctrl.c b/he_qat/he_qat_ctrl.c index 35ce5a7..8a95aa6 100644 --- a/he_qat/he_qat_ctrl.c +++ b/he_qat/he_qat_ctrl.c @@ -292,7 +292,7 @@ static void pull_outstanding_requests(HE_QAT_TaskRequestList* _requests, HE_QAT_ /// @param[in] state A volatile integer variable used to activate (val>0) or /// disactive (val=0) the scheduler. void* schedule_requests(void* context_state) { - if (NULL == state) { + if (NULL == context_state) { printf("Failed at buffer_manager: argument is NULL.\n"); pthread_exit(NULL); } From d898473147d5989f61d5e141853cf2ae30dcb1a1 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 12 Oct 2022 17:12:18 -0700 Subject: [PATCH 271/364] Add interfaces to probe QAT context state. Signed-off-by: Souza, Fillipe --- ipcl/context.cpp | 17 +++++++++++++++++ ipcl/include/ipcl/context.hpp | 13 +++++++++++++ 2 files changed, 30 insertions(+) diff --git a/ipcl/context.cpp b/ipcl/context.cpp index 07fa350..be2c32c 100644 --- a/ipcl/context.cpp +++ b/ipcl/context.cpp @@ -21,6 +21,13 @@ namespace ipcl { {"HYBRID",RuntimeValue::HYBRID}, {"hybrid",RuntimeValue::HYBRID} }; + enum class FeatureValue { AVX512IFMA, QAT4XXX }; + std::map hasFeatureMap = { + {"avx512",FeatureValue::AVX512IFMA}, {"avx512ifma",FeatureValue::AVX512IFMA}, + {"4xxx",FeatureValue::QAT4XXX}, {"qat_4xxx",FeatureValue::QAT4XXX} + } + + bool hasQAT = false; static bool isUsingQAT = false; static bool initializeQATContext() { if (HE_QAT_STATUS_SUCCESS == acquire_qat_devices()) @@ -30,6 +37,8 @@ namespace ipcl { bool initializeContext(std::string runtime_choice) { #ifdef IPCL_USE_QAT + hasQAT = true; + switch (runtimeMap[runtime_choice]) { case RuntimeValue::QAT: return initializeQATContext(); @@ -56,4 +65,12 @@ namespace ipcl { #endif // IPCL_USE_QAT } + bool isQATRunning() { + return (HE_QAT_STATUS_RUNNING == get_qat_context_state()); + } + + bool isQATActive() { + return (HE_QAT_STATUS_ACTIVE == get_qat_context_state()); + } + } // namespace ipcl diff --git a/ipcl/include/ipcl/context.hpp b/ipcl/include/ipcl/context.hpp index 5c3b004..c9492e2 100644 --- a/ipcl/include/ipcl/context.hpp +++ b/ipcl/include/ipcl/context.hpp @@ -24,5 +24,18 @@ bool initializeContext(std::string runtime_choice); */ bool terminateContext(void); + +/** + * Determine if QAT instances are running for IPCL. + * @return true if QAT instances are active and running, false otherwise. + */ +bool isQATRunning(void); + +/** + * Determine if QAT instances are active for IPCL. + * @return true if QAT instances are active, false otherwise. + */ +bool isQATActive(void); + } // namespace ipcl #endif // IPCL_INCLUDE_IPCL_CONTEXT_HPP_ From 715f93223f19075a674b9618ffffbd50b59c1b04 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 12 Oct 2022 18:25:54 -0700 Subject: [PATCH 272/364] Fix compilation. Signed-off-by: Souza, Fillipe --- ipcl/context.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipcl/context.cpp b/ipcl/context.cpp index be2c32c..44377ae 100644 --- a/ipcl/context.cpp +++ b/ipcl/context.cpp @@ -25,7 +25,7 @@ namespace ipcl { std::map hasFeatureMap = { {"avx512",FeatureValue::AVX512IFMA}, {"avx512ifma",FeatureValue::AVX512IFMA}, {"4xxx",FeatureValue::QAT4XXX}, {"qat_4xxx",FeatureValue::QAT4XXX} - } + }; bool hasQAT = false; static bool isUsingQAT = false; From d3afb258d2dd040400f9621f815ad219dd8fb3c3 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 12 Oct 2022 18:26:47 -0700 Subject: [PATCH 273/364] Update heqat module. Signed-off-by: Souza, Fillipe --- module/heqat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/heqat b/module/heqat index 5a1b3cd..8bca333 160000 --- a/module/heqat +++ b/module/heqat @@ -1 +1 @@ -Subproject commit 5a1b3cd018aaf6e84574f7145eb436a4f87bce99 +Subproject commit 8bca333d02d5c115676de40646e68b4c8c30f572 From 8f2754056beec2a171f2a273aae65d7b39c5cd33 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 12 Oct 2022 18:28:04 -0700 Subject: [PATCH 274/364] Test QAT context status interface. Signed-off-by: Souza, Fillipe --- test/main.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/main.cpp b/test/main.cpp index 6c19ea9..d3782c0 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -9,6 +9,16 @@ int main(int argc, char** argv) { #ifdef IPCL_USE_QAT ipcl::initializeContext("QAT"); + + if (ipcl::isQATActive()) + std::cout << "QAT Context: ACTIVE" << std::endl; + else + std::cout << "Error: QAT Context INACTIVE." << std::endl; + + if (ipcl::isQATRunning()) + std::cout << "QAT Instances: RUNNING" << std::endl; + else + std::cout << "Error: QAT Instances NOT RUNNING." << std::endl; #else ipcl::initializeContext("default"); #endif // IPCL_USE_QAT @@ -20,5 +30,16 @@ int main(int argc, char** argv) { ipcl::terminateContext(); +#ifdef IPCL_USE_QAT + if (!ipcl::isQATActive()) + std::cout << "QAT Context: INACTIVE" << std::endl; + else + std::cout << "Error: QAT Context ACTIVE." << std::endl; + if (!ipcl::isQATRunning()) + std::cout << "QAT Instances: NOT RUNNING" << std::endl; + else + std::cout << "Error: QAT Instances STILL RUNNING." << std::endl; +#endif + return status; } From da2e4df6be3d003c07d52aea0340f1fbc52c8b8f Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Sat, 15 Oct 2022 03:10:14 +0800 Subject: [PATCH 275/364] Apply changes on dev branch to qat_integration (#132) * Major changes - Apply public repo changes to internal repo (#124) - benchmark with same inputs (#119) - PubKey: Add support for fixed hs & r in obfuscator when DJN is enabled - ModExp function: Let ippsMBModExp function support modulus of different bit size and removed padding - Improve RNG security (#126) - unittests: corner case fix * Minor typo fixes - Updated contributors and CODEOWNERS - Added code of conduct - Updated CI/CD Co-authored-by: sejunkim --- .github/workflows/github-ci.yml | 5 +- .pre-commit-config.yaml | 2 +- CMakeLists.txt | 60 ++++++- CODE_OF_CONDUCT.md | 128 +++++++++++++++ README.md | 46 +++--- benchmark/bench_cryptography.cpp | 90 +++++++++-- benchmark/bench_ops.cpp | 135 ++++++++++++---- cmake/cpufeatures.cmake | 53 +++++++ cmake/gbenchmark.cmake | 11 +- cmake/gtest.cmake | 16 +- cmake/ipcl/IPCLConfig.cmake.in | 5 +- cmake/ippcrypto.cmake | 25 ++- example/CMakeLists.txt | 15 ++ example/README.md | 141 ++++++++++++++++ example/test.cpp | 40 +++++ ipcl/CMakeLists.txt | 55 ++++--- ipcl/common.cpp | 56 +++++++ ipcl/include/ipcl/common.hpp | 29 ++++ ipcl/include/ipcl/ipcl.hpp | 37 +++++ ipcl/include/ipcl/mod_exp.hpp | 16 +- ipcl/include/ipcl/pub_key.hpp | 20 +-- ipcl/include/ipcl/util.hpp | 13 ++ ipcl/keygen.cpp | 66 +++----- ipcl/mod_exp.cpp | 265 ++++++++++++++++++------------- ipcl/pub_key.cpp | 101 +++++------- test/test_cryptography.cpp | 10 +- test/test_ops.cpp | 6 +- 27 files changed, 1079 insertions(+), 367 deletions(-) create mode 100644 CODE_OF_CONDUCT.md create mode 100644 cmake/cpufeatures.cmake create mode 100644 example/CMakeLists.txt create mode 100644 example/README.md create mode 100644 example/test.cpp create mode 100644 ipcl/common.cpp create mode 100644 ipcl/include/ipcl/ipcl.hpp diff --git a/.github/workflows/github-ci.yml b/.github/workflows/github-ci.yml index 846f840..6c29546 100644 --- a/.github/workflows/github-ci.yml +++ b/.github/workflows/github-ci.yml @@ -1,7 +1,7 @@ # Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -name: ipcl_internal +name: Build and Test on: # By default this will run when the activity type is "opened", "synchronize", # or "reopened". @@ -9,9 +9,12 @@ on: branches: - main - development + - "[0-9]+.[0-9]+.[0-9]+" push: branches: + - main - development + - "[0-9]+.[0-9]+.[0-9]+" # Manually run this workflow on any specified branch. workflow_dispatch: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e13a70f..2f41239 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -43,7 +43,7 @@ repos: entry: cpplint language: system files: \.(c|cc|cxx|cpp|h|hpp|hxx)$ - exclude: ipcl/bignum.cpp|ipcl/include/ipcl/bignum.h + exclude: ipcl/bignum.cpp|ipcl/include/ipcl/bignum.h|example/test.cpp args: - --recursive - --filter=-runtime/references,-whitespace/comments,-whitespace/indent diff --git a/CMakeLists.txt b/CMakeLists.txt index 74e6117..a91d374 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,7 @@ project(IPCL VERSION 2.0.0 LANGUAGES C CXX) include(CMakePackageConfigHelpers) include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) +include(GNUInstallDirs) if(CMAKE_BUILD_TYPE) set(RELEASE_TYPES @@ -34,16 +35,14 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_INSTALL_MESSAGE LAZY) -set(CMAKE_INSTALL_RPATH "\$ORIGIN") - -set(CMAKE_C_FLAGS "-O2 -Wno-error=deprecated-declarations") -set(CMAKE_CXX_FLAGS "-O2 -fpermissive -Wno-error=deprecated-declarations") -if(NOT CMAKE_INSTALL_PREFIX) - set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "/opt/intel/ipcl") endif() -include(GNUInstallDirs) +set(CMAKE_C_FLAGS "-O2 -Wno-error=deprecated-declarations") +set(CMAKE_CXX_FLAGS "-O2 -fpermissive -Wno-error=deprecated-declarations") +set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR};${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ippcrypto") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) @@ -69,6 +68,9 @@ if(IPCL_ENABLE_QAT) endif() endif() +option(IPCL_DETECT_IFMA_RUNTIME "Detect AVX512/IFMA instructions during runtime" OFF) +option(IPCL_DEBUG_DISABLE_AVX512IFMA "(Debugging) Disable usage of AVX512IFMA instructions" OFF) + if(IPCL_ENABLE_OMP) add_compile_definitions(IPCL_USE_OMP) if(IPCL_THREAD_COUNT) @@ -100,6 +102,7 @@ else() endif() message(STATUS "IPCL_DOCS: ${IPCL_DOCS}") message(STATUS "IPCL_SHARED: ${IPCL_SHARED}") +message(STATUS "IPCL_DETECT_IFMA_RUNTIME: ${IPCL_DETECT_IFMA_RUNTIME}") set(IPCL_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) set(IPCL_SRC_DIR ${IPCL_ROOT_DIR}/ipcl) @@ -117,9 +120,47 @@ set(IPCL_FORWARD_CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ) +if(IPCL_DETECT_IFMA_RUNTIME) + add_compile_definitions(IPCL_RUNTIME_MOD_EXP) + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cpufeatures") +else() + # check whether cpu support avx512 flag + if(IPCL_DEBUG_DISABLE_AVX512IFMA) + message(STATUS "Support AVX512IFMA: False") + else() + set(CPU_AVX512_FLAG "avx512ifma") + execute_process(COMMAND lscpu COMMAND grep ${CPU_AVX512_FLAG} OUTPUT_VARIABLE CPU_ENABLE_AVX512) + if("${CPU_ENABLE_AVX512}" STREQUAL "") + message(STATUS "Support AVX512IFMA: False") + else() + message(STATUS "Support AVX512IFMA: True") + add_compile_definitions(IPCL_CRYPTO_MB_MOD_EXP) + endif() + endif() +endif() + +# check whether cpu support rdseed or rdrand instruction +set(CPU_RDSEED_FLAG "rdseed") +execute_process(COMMAND lscpu COMMAND grep ${CPU_RDSEED_FLAG} OUTPUT_VARIABLE CPU_ENABLE_RDSEED) +if("${CPU_ENABLE_RDSEED}" STREQUAL "") + set(CPU_RDRAND_FLAG "rdrand") + execute_process(COMMAND lscpu COMMAND grep ${CPU_RDRAND_FLAG} OUTPUT_VARIABLE CPU_ENABLE_RDRAND) + if("${CPU_ENABLE_RDRAND}" STREQUAL "") + message(WARNING "CPU doesn't support RDSEED and RDRAND instruction, using random generator will cause errors.") + else () + message(STATUS "Support RDRAND instruction: True") + add_compile_definitions(IPCL_RNG_INSTR_RDRAND) + endif() +else() + message(STATUS "Support RDSEED instruction: True") + add_compile_definitions(IPCL_RNG_INSTR_RDSEED) +endif() + # find package for OpenSSL and Threads set(CMAKE_THREAD_PREFER_PTHREAD ON) # set(THREADS_PREFER_PTHREAD_FLAG ON) +# set(OPENSSL_USE_STATIC_LIBS TRUE) + find_package(Threads REQUIRED) set(OPENSSL_USE_STATIC_LIBS TRUE) find_package(OpenSSL REQUIRED) @@ -129,6 +170,9 @@ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ipcl) include(ipcl-util) include(cmake/ippcrypto.cmake) +if(IPCL_DETECT_IFMA_RUNTIME) + include(cmake/cpufeatures.cmake) +endif() if(IPCL_ENABLE_QAT) include(module/heqat.cmake) @@ -141,6 +185,8 @@ if(IPCL_BENCHMARK) include(cmake/gbenchmark.cmake) endif() + + add_subdirectory(ipcl) # unit-test and benchmarks diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..dfb54fc --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +webadmin@linux.intel.com. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/README.md b/README.md index 1f80d7c..47c0993 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ # Intel Paillier Cryptosystem Library -Intel Paillier Cryptosystem Library is an open-source library which provides accelerated performance of a partial homomorphic encryption (HE), named Paillier cryptosystem, by utilizing IntelĀ® [Integrated Performance Primitives Cryptography](https://github.com/intel/ipp-crypto) technologies on Intel CPUs supporting the AVX512IFMA instructions. The library is written in modern standard C++ and provides the essential API for the Paillier cryptosystem scheme. +Intel Paillier Cryptosystem Library is an open-source library which provides accelerated performance of a partial homomorphic encryption (HE), named Paillier cryptosystem, by utilizing IntelĀ® [Integrated Performance Primitives Cryptography](https://github.com/intel/ipp-crypto) technologies on Intel CPUs supporting the AVX512IFMA instructions. The library is written in modern standard C++ and provides the essential API for the Paillier cryptosystem scheme. Intel Paillier Cryptosystem Library is certified for ISO compliance. ## Contents - [Intel Paillier Cryptosystem Library](#intel-paillier-cryptosystem-library) - [Contents](#contents) - [Introduction](#introduction) - - [Performance](#performance) - [Building the Library](#building-the-library) - [Prerequisites](#prerequisites) - [Dependencies](#dependencies) - [Downloading](#downloading) - [Instructions](#instructions) + - [Installing and Using Example](#installing-and-using-example) - [Testing and Benchmarking](#testing-and-benchmarking) - [Python Extension](#python-extension) - [Standardization](#standardization) @@ -29,8 +29,6 @@ As a public key encryption scheme, Paillier cryptosystem has three stages: For increased security, typically the key length is at least 1024 bits, but recommendation is 2048 bits or larger. To handle such large size integers, conventional implementations of the Paillier cryptosystem utilizes the GNU Multiple Precision Arithmetic Library (GMP). The essential computation of the scheme relies on the modular exponentiation, and our library takes advantage of the multi-buffer modular exponentiation function (```mbx_exp_mb8```) of IPP-Crypto library, which is enabled in AVX512IFMA instruction sets supporting SKUs, such as Intel Icelake Xeon CPUs. -### Performance -To be added after P2CA review ## Building the Library ### Prerequisites For best performance, especially due to the multi-buffer modular exponentiation function, the library is to be used on AVX512IFMA enabled systems, as listed below in Intel CPU codenames: @@ -88,22 +86,28 @@ git submodule update --init ### Instructions The library can be built using the following commands: ```bash -export IPCL_DIR=$(pwd) +export IPCL_ROOT=$(pwd) cmake -S . -B build -DCMAKE_BUILD_TYPE=Release cmake --build build -j ``` It is possible to pass additional options to enable more features. The following table contains the current CMake options, default values are in bold. -| CMake options | Values | Default | Comments | -|-------------------------|-----------|---------|-------------------------------------| -|`IPCL_TEST` | ON/OFF | ON | unit-test | -|`IPCL_BENCHMARK` | ON/OFF | ON | benchmark | -|`IPCL_ENABLE_QAT` | ON/OFF | OFF | enables QAT functionalities | -|`IPCL_ENABLE_OMP` | ON/OFF | ON | enables OpenMP functionalities | -|`IPCL_THREAD_COUNT` | Integer | OFF | The max number of threads | -|`IPCL_DOCS` | ON/OFF | OFF | build doxygen documentation | -|`IPCL_SHARED` | ON/OFF | ON | build shared library | +| CMake options | Values | Default | Comments | +|--------------------------|-----------|---------|-------------------------------------| +|`IPCL_TEST` | ON/OFF | ON | unit-test | +|`IPCL_BENCHMARK` | ON/OFF | ON | benchmark | +|`IPCL_ENABLE_QAT` | ON/OFF | OFF | enables QAT functionalities | +|`IPCL_ENABLE_OMP` | ON/OFF | ON | enables OpenMP functionalities | +|`IPCL_THREAD_COUNT` | Integer | OFF | explicitly set max number of threads| +|`IPCL_DOCS` | ON/OFF | OFF | build doxygen documentation | +|`IPCL_SHARED` | ON/OFF | ON | build shared library | +|`IPCL_DETECT_IFMA_RUNTIME`| ON/OFF | OFF | detects AVX512IFMA during runtime | + +If ```IPCL_DETECT_IFMA_RUNTIME``` flag is set to ```ON```, it will determine whether the system supports the AVX512IFMA instructions on runtime. It is still possible to disable IFMA exclusive feature (multi-buffer modular exponentiation) during runtime by setting up the environment variable ```IPCL_DISABLE_AVX512IFMA=1```. + +### Installing and Using Example +For installing and using the library externally, see [example/README.md](./example/README.md). ## Compiling for QAT @@ -130,21 +134,23 @@ cmake --build build --target benchmark ``` Setting the CMake flag ```-DIPCL_ENABLE_OMP=ON``` during configuration will use OpenMP for acceleration. Setting the value of `-DIPCL_THREAD_COUNT` will limit the maximum number of threads used by OpenMP (If set to OFF or 0, its actual value will be determined at run time). -The executables are located at `${IPCL_DIR}/build/test/unittest_ipcl` and `${IPCL_DIR}/build/benchmark/bench_ipcl`. +The executables are located at `${IPCL_ROOT}/build/test/unittest_ipcl` and `${IPCL_ROOT}/build/benchmark/bench_ipcl`. # Python Extension -Alongside the Intel Paillier Cryptosystem Library, we provide a Python extension package utilizing this library as a backend. For installation and usage detail, refer to [Intel Paillier Cryptosystem Library - Python](https://github.com/intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.pailliercryptolib-python). +Alongside the Intel Paillier Cryptosystem Library, we provide a Python extension package utilizing this library as a backend. For installation and usage detail, refer to [Intel Paillier Cryptosystem Library - Python](https://github.com/intel/pailliercryptolib_python). # Standardization -This library is in compliance with the homomorphic encryption standards [ISO/IEC 18033-6](https://www.iso.org/standard/67740.html). -The compliance test is included in the [unit-test](https://github.com/intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.pailliercryptolib/blob/main/test/test_cryptography.cpp#L112-L256). +This library is certified for ISO compliance with the homomorphic encryption standards [ISO/IEC 18033-6](https://www.iso.org/standard/67740.html) by Dekra. # Contributors Main contributors to this project, sorted by alphabetical order of last name are: + - [Flavio Bergamaschi](https://www.linkedin.com/in/flavio-bergamaschi) - [Xiaoran Fang](https://github.com/fangxiaoran) - [Hengrui Hu](https://github.com/hhr293) - [Xiaojun Huang](https://github.com/xhuan28) - - [Hamish Hunt](https://github.com/hamishun) - - [Sejun Kim](https://github.com/skmono) (lead) + - [Hamish Hunt](https://www.linkedin.com/in/hamish-hunt) + - [Jingyi Jin](https://www.linkedin.com/in/jingyi-jin-655735) + - [Sejun Kim](https://www.linkedin.com/in/sejun-kim-2b1b4866) (lead) + - [Fillipe D.M. de Souza](https://www.linkedin.com/in/fillipe-d-m-de-souza-a8281820) - [Bin Wang](https://github.com/bwang30) - [Pengfei Zhao](https://github.com/justalittlenoob) diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index 4d740c4..49d983b 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -3,10 +3,9 @@ #include -#include #include -#include "ipcl/keygen.hpp" +#include "ipcl/ipcl.hpp" #define ADD_SAMPLE_KEY_LENGTH_ARGS Args({1024})->Args({2048}) #define ADD_SAMPLE_VECTOR_SIZE_ARGS \ @@ -19,27 +18,81 @@ ->Args({2048}) \ ->Args({2100}) +constexpr bool Enable_DJN = true; + +// P_BN comes from ISO_IEC_18033_6_Compliance +const BigNumber P_BN = + "0xff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c" + "8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b4" + "0a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff76" + "4dd8b091f11a0943a2dd2b983b0df02f4c4d00b413"; + +// Q_BN comes from ISO_IEC_18033_6_Compliance +const BigNumber Q_BN = + "0xdacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d" + "9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de70" + "72a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49b" + "aa0f610bad100cdf47cc86e5034e2a0b2179e04ec7"; + +// R_BN comes from ISO_IEC_18033_6_Compliance +const BigNumber R_BN = + "0x57fb19590c31dc7c034b2a889cf4037ce3db799909c1eb0adb6199d8e96791daca9018" + "891f34309daff32dced4af7d793d16734d055e28023acab7295956bfbfdf62bf0ccb2ed3" + "1d5d176ca8b404e93007565fb6b72c33a512b4dc4f719231d62e27e34c3733929af32247" + "f88c20d1ee77096cc80d3d642464054c815b35878ba812349c8bdc3c6b645daf1a0de609" + "65f44dcf705681032480f1eeba82243196b96903becdc0df0801d4120cbd6db1c4b2841a" + "27991c44a43750c24ed0825718ad14cfb9c6b40b78ff3d25f71741f2def1c9d420d4b0fa" + "1e0a02e7851b5ec6a81133a368b80d1500b0f28fc653d2e6ff4366236dbf80ae3b4beae3" + "5e04579f2c"; + +const BigNumber HS_BN = + "0x7788f6e8f57d3488cf9e0c7f4c19521de9aa172bf35924c7827a1189d6c688ac078f77" + "7efcfc230e34f1fa5ae8d9d2ed5b062257618e0a0a485b0084b3fd39080031ea739bb48c" + "dcce4ad41704ed930d40f53a1cc5d7f70bcb379f17a912b0ad14fabe8fc10213dcd1eabd" + "9175ee9bf66c31e9af9703c9d92fa5c8d36279459631ba7e9d4571a10960f8e8d031b267" + "22f6ae6f618895b9ce4fce926c8f54169168f6bb3e033861e08c2eca2161198481bc7c52" + "3a38310be22f4dd7d028dc6b774e5cb8e6f33b24168697743b7deff411510e27694bf2e8" + "0258b325fd97370f5110f54d8d7580b45ae3db26da4e3b0409f0cfbc56d9d9856b66d8bf" + "46e727dc3148f70362d05faea743621e3841c94c78d53ee7e7fdef61022dd56922368991" + "f843ca0aebf8436e5ec7e737c7ce72ac58f138bb11a3035fe96cc5a7b1aa9d565cb8a317" + "f42564482dd3c842c5ee9fb523c165a8507ecee1ac4f185bdbcb7a51095c4c46bfe15aec" + "3dfd77e1fd2b0003596df83bbb0d5521f16e2301ec2d4aafe25e4479ee965d8bb30a689a" + "6f38ba710222fff7cf359d0f317b8e268f40f576c04262a595cdfc9a07b72978b9564ace" + "699208291da7024e86b6eeb1458658852f10794c677b53db8577af272233722ad4579d7a" + "074e57217e1c57d11862f74486c7f2987e4d09cd6fb2923569b577de50e89e6965a27e18" + "7a8a341a7282b385ef"; + static void BM_KeyGen(benchmark::State& state) { int64_t n_length = state.range(0); for (auto _ : state) { - ipcl::keyPair key = ipcl::generateKeypair(n_length, true); + ipcl::keyPair key = ipcl::generateKeypair(n_length, Enable_DJN); } } BENCHMARK(BM_KeyGen)->Unit(benchmark::kMicrosecond)->ADD_SAMPLE_KEY_LENGTH_ARGS; static void BM_Encrypt(benchmark::State& state) { size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector exp_value_v(dsize); + BigNumber n = P_BN * Q_BN; + int n_length = n.BitSize(); + ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); + ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + + std::vector r_bn_v(dsize, R_BN); + pub_key->setRandom(r_bn_v); + pub_key->setHS(HS_BN); + std::vector exp_bn_v(dsize); for (size_t i = 0; i < dsize; i++) - exp_value_v[i] = (unsigned int)(i * 1024) + 999; + exp_bn_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); - ipcl::PlainText pt(exp_value_v); + ipcl::PlainText pt(exp_bn_v); ipcl::CipherText ct; - for (auto _ : state) ct = key.pub_key->encrypt(pt); + for (auto _ : state) ct = pub_key->encrypt(pt); + + delete pub_key; + delete priv_key; } BENCHMARK(BM_Encrypt) @@ -48,17 +101,26 @@ BENCHMARK(BM_Encrypt) static void BM_Decrypt(benchmark::State& state) { size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector exp_value_v(dsize); + BigNumber n = P_BN * Q_BN; + int n_length = n.BitSize(); + ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); + ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + + std::vector r_bn_v(dsize, R_BN); + pub_key->setRandom(r_bn_v); + pub_key->setHS(HS_BN); + std::vector exp_bn_v(dsize); for (size_t i = 0; i < dsize; i++) - exp_value_v[i] = (unsigned int)(i * 1024) + 999; + exp_bn_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); - ipcl::PlainText pt(exp_value_v), dt; - ipcl::CipherText ct = key.pub_key->encrypt(pt); + ipcl::PlainText pt(exp_bn_v), dt; + ipcl::CipherText ct = pub_key->encrypt(pt); + for (auto _ : state) dt = priv_key->decrypt(ct); - for (auto _ : state) dt = key.priv_key->decrypt(ct); + delete pub_key; + delete priv_key; } BENCHMARK(BM_Decrypt) diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index 42311ec..dc26354 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -6,10 +6,9 @@ #include #include -#include "ipcl/ciphertext.hpp" -#include "ipcl/keygen.hpp" -#include "ipcl/plaintext.hpp" +#include "ipcl/ipcl.hpp" +#define ADD_SAMPLE_KEY_LENGTH_ARGS Args({1024})->Args({2048}) #define ADD_SAMPLE_VECTOR_SIZE_ARGS \ Args({16}) \ ->Args({64}) \ @@ -20,75 +19,145 @@ ->Args({2048}) \ ->Args({2100}) +constexpr bool Enable_DJN = true; + +// P_BN comes from ISO_IEC_18033_6_Compliance +const BigNumber P_BN = + "0xff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c" + "8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b4" + "0a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff76" + "4dd8b091f11a0943a2dd2b983b0df02f4c4d00b413"; + +// Q_BN comes from ISO_IEC_18033_6_Compliance +const BigNumber Q_BN = + "0xdacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d" + "9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de70" + "72a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49b" + "aa0f610bad100cdf47cc86e5034e2a0b2179e04ec7"; + +// R_BN comes from ISO_IEC_18033_6_Compliance +const BigNumber R_BN = + "0x57fb19590c31dc7c034b2a889cf4037ce3db799909c1eb0adb6199d8e96791daca9018" + "891f34309daff32dced4af7d793d16734d055e28023acab7295956bfbfdf62bf0ccb2ed3" + "1d5d176ca8b404e93007565fb6b72c33a512b4dc4f719231d62e27e34c3733929af32247" + "f88c20d1ee77096cc80d3d642464054c815b35878ba812349c8bdc3c6b645daf1a0de609" + "65f44dcf705681032480f1eeba82243196b96903becdc0df0801d4120cbd6db1c4b2841a" + "27991c44a43750c24ed0825718ad14cfb9c6b40b78ff3d25f71741f2def1c9d420d4b0fa" + "1e0a02e7851b5ec6a81133a368b80d1500b0f28fc653d2e6ff4366236dbf80ae3b4beae3" + "5e04579f2c"; + +const BigNumber HS_BN = + "0x7788f6e8f57d3488cf9e0c7f4c19521de9aa172bf35924c7827a1189d6c688ac078f77" + "7efcfc230e34f1fa5ae8d9d2ed5b062257618e0a0a485b0084b3fd39080031ea739bb48c" + "dcce4ad41704ed930d40f53a1cc5d7f70bcb379f17a912b0ad14fabe8fc10213dcd1eabd" + "9175ee9bf66c31e9af9703c9d92fa5c8d36279459631ba7e9d4571a10960f8e8d031b267" + "22f6ae6f618895b9ce4fce926c8f54169168f6bb3e033861e08c2eca2161198481bc7c52" + "3a38310be22f4dd7d028dc6b774e5cb8e6f33b24168697743b7deff411510e27694bf2e8" + "0258b325fd97370f5110f54d8d7580b45ae3db26da4e3b0409f0cfbc56d9d9856b66d8bf" + "46e727dc3148f70362d05faea743621e3841c94c78d53ee7e7fdef61022dd56922368991" + "f843ca0aebf8436e5ec7e737c7ce72ac58f138bb11a3035fe96cc5a7b1aa9d565cb8a317" + "f42564482dd3c842c5ee9fb523c165a8507ecee1ac4f185bdbcb7a51095c4c46bfe15aec" + "3dfd77e1fd2b0003596df83bbb0d5521f16e2301ec2d4aafe25e4479ee965d8bb30a689a" + "6f38ba710222fff7cf359d0f317b8e268f40f576c04262a595cdfc9a07b72978b9564ace" + "699208291da7024e86b6eeb1458658852f10794c677b53db8577af272233722ad4579d7a" + "074e57217e1c57d11862f74486c7f2987e4d09cd6fb2923569b577de50e89e6965a27e18" + "7a8a341a7282b385ef"; + static void BM_Add_CTCT(benchmark::State& state) { size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector exp_value1_v(dsize, 65535), exp_value2_v(dsize, 65535); + BigNumber n = P_BN * Q_BN; + int n_length = n.BitSize(); + ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); + ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + + std::vector r_bn_v(dsize, R_BN); + pub_key->setRandom(r_bn_v); + pub_key->setHS(HS_BN); - ipcl::PlainText pt1, pt2; + std::vector exp_bn1_v(dsize), exp_bn2_v(dsize); for (int i = 0; i < dsize; i++) { - exp_value1_v[i] += (unsigned int)(i * 1024); - exp_value2_v[i] += (unsigned int)(i * 1024); + exp_bn1_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); + exp_bn2_v[i] = Q_BN + BigNumber((unsigned int)(i * 1024)); } - pt1 = ipcl::PlainText(exp_value1_v); - pt2 = ipcl::PlainText(exp_value2_v); - ipcl::CipherText ct1 = key.pub_key->encrypt(pt1); - ipcl::CipherText ct2 = key.pub_key->encrypt(pt2); + ipcl::PlainText pt1(exp_bn1_v); + ipcl::PlainText pt2(exp_bn2_v); + + ipcl::CipherText ct1 = pub_key->encrypt(pt1); + ipcl::CipherText ct2 = pub_key->encrypt(pt2); ipcl::CipherText sum; for (auto _ : state) sum = ct1 + ct2; -} + delete pub_key; + delete priv_key; +} BENCHMARK(BM_Add_CTCT) ->Unit(benchmark::kMicrosecond) ->ADD_SAMPLE_VECTOR_SIZE_ARGS; static void BM_Add_CTPT(benchmark::State& state) { size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector exp_value1_v(dsize, 65535), exp_value2_v(dsize, 65535); + BigNumber n = P_BN * Q_BN; + int n_length = n.BitSize(); + ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); + ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + + std::vector r_bn_v(dsize, R_BN); + pub_key->setRandom(r_bn_v); + pub_key->setHS(HS_BN); - ipcl::PlainText pt1, pt2; + std::vector exp_bn1_v(dsize), exp_bn2_v(dsize); for (int i = 0; i < dsize; i++) { - exp_value1_v[i] += (unsigned int)(i * 1024); - exp_value2_v[i] += (unsigned int)(i * 1024); + exp_bn1_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); + exp_bn2_v[i] = Q_BN + BigNumber((unsigned int)(i * 1024)); } - pt1 = ipcl::PlainText(exp_value1_v); - pt2 = ipcl::PlainText(exp_value2_v); - ipcl::CipherText ct1 = key.pub_key->encrypt(pt1); - ipcl::CipherText sum; + ipcl::PlainText pt1(exp_bn1_v); + ipcl::PlainText pt2(exp_bn2_v); + + ipcl::CipherText ct1 = pub_key->encrypt(pt1); + ipcl::CipherText sum; for (auto _ : state) sum = ct1 + pt2; -} + delete pub_key; + delete priv_key; +} BENCHMARK(BM_Add_CTPT) ->Unit(benchmark::kMicrosecond) ->ADD_SAMPLE_VECTOR_SIZE_ARGS; static void BM_Mul_CTPT(benchmark::State& state) { size_t dsize = state.range(0); - ipcl::keyPair key = ipcl::generateKeypair(2048, true); + BigNumber n = P_BN * Q_BN; + int n_length = n.BitSize(); + ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); + ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); - std::vector exp_value1_v(dsize, 65535), exp_value2_v(dsize, 65535); + std::vector r_bn_v(dsize, R_BN); + pub_key->setRandom(r_bn_v); + pub_key->setHS(HS_BN); - ipcl::PlainText pt1, pt2; + std::vector exp_bn1_v(dsize), exp_bn2_v(dsize); for (int i = 0; i < dsize; i++) { - exp_value1_v[i] += (unsigned int)(i * 1024); - exp_value2_v[i] += (unsigned int)(i * 1024); + exp_bn1_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); + exp_bn2_v[i] = Q_BN + BigNumber((unsigned int)(i * 1024)); } - pt1 = ipcl::PlainText(exp_value1_v); - pt2 = ipcl::PlainText(exp_value2_v); - ipcl::CipherText ct1 = key.pub_key->encrypt(pt1); - ipcl::CipherText product; + ipcl::PlainText pt1(exp_bn1_v); + ipcl::PlainText pt2(exp_bn2_v); + ipcl::CipherText ct1 = pub_key->encrypt(pt1); + + ipcl::CipherText product; for (auto _ : state) product = ct1 * pt2; -} + delete pub_key; + delete priv_key; +} BENCHMARK(BM_Mul_CTPT) ->Unit(benchmark::kMicrosecond) ->ADD_SAMPLE_VECTOR_SIZE_ARGS; diff --git a/cmake/cpufeatures.cmake b/cmake/cpufeatures.cmake new file mode 100644 index 0000000..6df3c12 --- /dev/null +++ b/cmake/cpufeatures.cmake @@ -0,0 +1,53 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +include(ExternalProject) +include(GNUInstallDirs) + +message(STATUS "configuring cpu_features") +set(CPUFEATURES_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_cpufeatures) +set(CPUFEATURES_DESTDIR ${CPUFEATURES_PREFIX}/cpufeatures_install) +set(CPUFEATURES_GIT_REPO_URL https://github.com/google/cpu_features.git) +set(CPUFEATURES_GIT_LABEL v0.7.0) +set(CPUFEATURES_C_FLAGS "${IPCL_FORWARD_CMAKE_ARGS} -fPIC") + +ExternalProject_Add( + ext_cpufeatures + PREFIX ${CPUFEATURES_PREFIX} + GIT_REPOSITORY ${CPUFEATURES_GIT_REPO_URL} + GIT_TAG ${CPUFEATURES_GIT_LABEL} + CMAKE_ARGS ${CPUFEATURES_C_FLAGS} + -DCMAKE_BUILD_TYPE=Release + -DBUILD_TESTING=OFF + -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + UPDATE_COMMAND "" + EXCLUDE_FROM_ALL TRUE + INSTALL_COMMAND make DESTDIR=${CPUFEATURES_DESTDIR} install + ) + + +set(CPUFEATURES_INC_DIR ${CPUFEATURES_DESTDIR}/${CMAKE_INSTALL_PREFIX}/include) +set(CPUFEATURES_LIB_DIR ${CPUFEATURES_DESTDIR}/${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) + +if(IPCL_SHARED) + add_library(libcpu_features INTERFACE) + add_dependencies(libcpu_features ext_cpufeatures) + + target_include_directories(libcpu_features SYSTEM + INTERFACE ${CPUFEATURES_INC_DIR}) + target_link_libraries(libcpu_features + INTERFACE ${CPUFEATURES_LIB_DIR}/libcpu_features.a) + + install( + DIRECTORY ${CPUFEATURES_LIB_DIR}/ + DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cpufeatures" + USE_SOURCE_PERMISSIONS + ) +else() + add_library(libcpu_features STATIC IMPORTED GLOBAL) + add_dependencies(libcpu_features ext_cpufeatures) + + set_target_properties(libcpu_features PROPERTIES + IMPORTED_LOCATION ${CPUFEATURES_LIB_DIR}/libcpu_features.a + INCLUDE_DIRECTORIES ${CPUFEATURES_INC_DIR}) +endif() diff --git a/cmake/gbenchmark.cmake b/cmake/gbenchmark.cmake index efd03fb..8c3e8c6 100644 --- a/cmake/gbenchmark.cmake +++ b/cmake/gbenchmark.cmake @@ -2,6 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 include(ExternalProject) +include(GNUInstallDirs) set(GBENCHMARK_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_gbenchmark) @@ -32,15 +33,7 @@ ExternalProject_Add( add_library(libgbenchmark INTERFACE) add_dependencies(libgbenchmark ext_gbenchmark) -ExternalProject_Get_Property(ext_gbenchmark SOURCE_DIR BINARY_DIR) -file(STRINGS /etc/os-release LINUX_ID REGEX "^ID=") -string(REGEX REPLACE "ID=\(.*)" "\\1" LINUX_ID "${LINUX_ID}") -if(${LINUX_ID} STREQUAL "ubuntu") - target_link_libraries(libgbenchmark INTERFACE ${GBENCHMARK_PREFIX}/lib/libbenchmark.a) -else() - # non debian systems install gbenchmark lib under lib64 - target_link_libraries(libgbenchmark INTERFACE ${GBENCHMARK_PREFIX}/lib64/libbenchmark.a) -endif() +target_link_libraries(libgbenchmark INTERFACE ${GBENCHMARK_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libbenchmark.a) target_include_directories(libgbenchmark SYSTEM INTERFACE ${GBENCHMARK_PREFIX}/include) diff --git a/cmake/gtest.cmake b/cmake/gtest.cmake index 7678d59..24b80a7 100644 --- a/cmake/gtest.cmake +++ b/cmake/gtest.cmake @@ -2,20 +2,30 @@ # SPDX-License-Identifier: Apache-2.0 include(ExternalProject) +include(GNUInstallDirs) +set(GTEST_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_gtest) set(GTEST_GIT_REPO_URL https://github.com/google/googletest.git) set(GTEST_GIT_LABEL release-1.10.0) set(GTEST_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS} -fPIC") ExternalProject_Add( ext_gtest - PREFIX ext_gtest + PREFIX ${GTEST_PREFIX} GIT_REPOSITORY ${GTEST_GIT_REPO_URL} GIT_TAG ${GTEST_GIT_LABEL} CMAKE_ARGS ${GTEST_CXX_FLAGS} -DCMAKE_BUILD_TYPE=Release - INSTALL_COMMAND "" + -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} UPDATE_COMMAND "" - EXCLUDE_FROM_ALL TRUE) + EXCLUDE_FROM_ALL TRUE + INSTALL_COMMAND "" +) + +# install( +# DIRECTORY ${GTEST_DESTDIR}/${CMAKE_INSTALL_PREFIX}/ +# DESTINATION "." +# USE_SOURCE_PERMISSIONS +# ) ExternalProject_Get_Property(ext_gtest SOURCE_DIR BINARY_DIR) diff --git a/cmake/ipcl/IPCLConfig.cmake.in b/cmake/ipcl/IPCLConfig.cmake.in index be0c1d8..340a5c4 100644 --- a/cmake/ipcl/IPCLConfig.cmake.in +++ b/cmake/ipcl/IPCLConfig.cmake.in @@ -4,11 +4,14 @@ include(CMakeFindDependencyMacro) -include(${CMAKE_CURRENT_LIST_DIR}/ipclTargets.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/IPCLTargets.cmake) if(TARGET IPCL::ipcl) set(IPCL_FOUND TRUE) message(STATUS "Intel Paillier Cryptosystem Library found") + find_package(OpenSSL REQUIRED) + find_package(Threads REQUIRED) + find_package(OpenMP REQUIRED) else() message(STATUS "Intel Paillier Cryptosystem Library not found") endif() diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake index 69b27de..497bad7 100644 --- a/cmake/ippcrypto.cmake +++ b/cmake/ippcrypto.cmake @@ -2,10 +2,12 @@ # SPDX-License-Identifier: Apache-2.0 include(ExternalProject) -MESSAGE(STATUS "Configuring ipp-crypto") +message(STATUS "Configuring ipp-crypto") + set(IPPCRYPTO_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_ipp-crypto) +set(IPPCRYPTO_DESTDIR ${IPPCRYPTO_PREFIX}/ippcrypto_install) set(IPPCRYPTO_GIT_REPO_URL https://github.com/intel/ipp-crypto.git) -set(IPPCRYPTO_GIT_LABEL ipp-crypto_2021_4) +set(IPPCRYPTO_GIT_LABEL ippcp_2021.6) set(IPPCRYPTO_SRC_DIR ${IPPCRYPTO_PREFIX}/src/ext_ipp-crypto/) set(IPPCRYPTO_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS} -DNONPIC_LIB:BOOL=off -DMERGED_BLD:BOOL=on") @@ -29,20 +31,27 @@ ExternalProject_Add( -DARCH=${IPPCRYPTO_ARCH} -DCMAKE_ASM_NASM_COMPILER=nasm -DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} UPDATE_COMMAND "" + INSTALL_COMMAND make DESTDIR=${IPPCRYPTO_DESTDIR} install ) -set(IPPCRYPTO_INC_DIR ${IPPCRYPTO_PREFIX}/include) - +set(IPPCRYPTO_INC_DIR ${IPPCRYPTO_DESTDIR}/${CMAKE_INSTALL_PREFIX}/include) +set(IPPCRYPTO_LIB_DIR ${IPPCRYPTO_DESTDIR}/${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${IPPCRYPTO_ARCH}) if(IPCL_SHARED) add_library(libippcrypto INTERFACE) add_dependencies(libippcrypto ext_ipp-crypto) ExternalProject_Get_Property(ext_ipp-crypto SOURCE_DIR BINARY_DIR) - target_link_libraries(libippcrypto INTERFACE ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libippcp.so ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libcrypto_mb.so) - target_include_directories(libippcrypto SYSTEM INTERFACE ${IPPCRYPTO_PREFIX}/include) + target_link_libraries(libippcrypto INTERFACE ${IPPCRYPTO_LIB_DIR}/libippcp.so ${IPPCRYPTO_LIB_DIR}/libcrypto_mb.so) + target_include_directories(libippcrypto SYSTEM INTERFACE ${IPPCRYPTO_INC_DIR}) + install( + DIRECTORY ${IPPCRYPTO_LIB_DIR}/ + DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ippcrypto" + USE_SOURCE_PERMISSIONS + ) else() add_library(libippcrypto::ippcp STATIC IMPORTED GLOBAL) @@ -54,12 +63,12 @@ else() find_package(OpenSSL REQUIRED) set_target_properties(libippcrypto::ippcp PROPERTIES - IMPORTED_LOCATION ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libippcp.a + IMPORTED_LOCATION ${IPPCRYPTO_LIB_DIR}/libippcp.a INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} ) set_target_properties(libippcrypto::crypto_mb PROPERTIES - IMPORTED_LOCATION ${IPPCRYPTO_PREFIX}/lib/${IPPCRYPTO_ARCH}/libcrypto_mb.a + IMPORTED_LOCATION ${IPPCRYPTO_LIB_DIR}/libcrypto_mb.a INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} ) endif() diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt new file mode 100644 index 0000000..cb66be8 --- /dev/null +++ b/example/CMakeLists.txt @@ -0,0 +1,15 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.15.1) + +project(ipcl_example LANGUAGES C CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +find_package(IPCL 1.1.4 REQUIRED HINTS ${IPCL_HINT_DIR}) + +add_executable(test test.cpp) +target_link_libraries(test PRIVATE IPCL::ipcl) diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..0bfe98c --- /dev/null +++ b/example/README.md @@ -0,0 +1,141 @@ +# Example using Intel Paillier Cryptosystem Library +This document provides an example program for using the Intel Paillier Cryptosystem Library in an external application. + +## Contents +- [Example using Intel Paillier Cryptosystem Library](#example-using-intel-paillier-cryptosystem-library) + - [Contents](#contents) + - [Installation](#installation) + - [Linking and Running Applications](#linking-and-running-applications) + - [Building with CMake](#building-with-cmake) + - [Manually Compiling](#manually-compiling) + - [Using Intel Paillier Cryptosystem Library](#using-intel-paillier-cryptosystem-library) + - [Data handling](#data-handling) + - [```ipcl::PlainText``` Constructor](#ipclplaintext-constructor) + - [Accessing data](#accessing-data) + - [Key Generation](#key-generation) + - [Encryption and Decryption](#encryption-and-decryption) + - [HE Operations](#he-operations) + + + +## Installation +To install the library, +```bash +cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/path/to/install/ -DCMAKE_BUILD_TYPE=Release -DIPCL_TEST=OFF -DIPCL_BENCHMARK=OFF +cmake --build build -j +cmake --build build --target install +``` + +If ```CMAKE_INSTALL_PREFIX``` is not explicitly set, the library will automatically set to ```/opt/intel/ipcl``` by default. + +For more details about the build configuration options, please refer to the build instructions provided in the [README.md](../README.md). + +## Linking and Running Applications + +Before proceeding after the library is installed, it is useful to setup an environment variable to point to the installation location. +```bash +export IPCL_DIR=/path/to/install/ +``` + +### Building with CMake +A more convenient way to use the library is via the `find_package` functionality in `CMake`. +In your external applications, add the following lines to your `CMakeLists.txt`. + +```bash +find_package(IPCL 1.1.4 + HINTS ${IPCL_HINT_DIR} + REQUIRED) +target_link_libraries(${TARGET} IPCL::ipcl) +``` + +If the library is installed globally, `IPCL_DIR` or `IPCL_HINT_DIR` flag is not needed. If `IPCL_DIR` is properly set, `IPCL_HINT_DIR` is not needed as well. Otherwise `IPCL_HINT_DIR` should be the directory containing `IPCLCOnfig.cmake`, under `${CMAKE_INSTALL_PREFIX}/lib/cmake/ipcl-1.1.4/` + +### Manually Compiling +In order to directly use `g++` or `clang++` to compile an example code, it can be done by: +```bash +# gcc +g++ test.cpp -o test -L${IPCL_DIR}/lib -I${IPCL_DIR}/include -lipcl -fopenmp -lnuma -lcrypto + +# clang +clang++ test.cpp -o test -L${IPCL_DIR}/lib -I${IPCL_DIR}/include -lipcl -fopenmp -lnuma -lcrypto +``` + + +## Using Intel Paillier Cryptosystem Library + +### Data handling +The library uses a container - ```ipcl::PlainText``` for encryption inputs and decryption outputs as well as plaintext HE operations. + +#### ```ipcl::PlainText``` Constructor + +```C++ +// construct w/ unsigned int32 +uint32_t val1; +ipcl::PlainText pt1(val1); + +// construct w/ unsigned int32 vector +std::vector val2; +ipcl::PlainText pt2(val2); + +// construct w/ IPP-Crypto BigNumber +BigNumber val3; +ipcl::PlainText pt3(val3); + +// construct w/ IPP-Crypto BigNumber vector +std::vector val4; +ipcl::PlainText pt4(val4); +``` +For more details about the IPP-Crypto ```BigNumber``` class, please refer to [Intel IPP Developer Reference](https://www.intel.com/content/www/us/en/develop/documentation/ipp-crypto-reference/top/appendix-a-support-functions-and-classes/classes-and-functions-used-in-examples/bignumber-class.html). + +#### Accessing data +The library provides several methods to handle and access the data included in the ```ipcl::PlainText``` container. +```C++ +ipcl::PlainText pt(raw_data); + +BigNumber ret1 = pt[1]; // idx +std::vector ret2 = pt; // convert +pt.insert(pos, val); // insert BigNumber to position +pt.remove(pos, length); // remove element (default length=1) +ipcl::PlainText pt_copy = pt; // copy +pt_copy.clear(); // empty the container +``` +FOr more details, please refer to the [```base_text.hpp```](../ipcl/include/ipcl/base_text.hpp) and [```plaintext.hpp```](../ipcl/include/ipcl/plaintext.hpp). + +### Key Generation +The public key and private key pair can be generated by using the ```ipcl::generateKeypair``` function. +```C++ +// key.pub_key, key.priv_key +ipcl::keyPair key = ipcl::generateKeypair(2048, true); +// After computation, need to delete the key objects +delete key.pub_key; +delete key.priv_key; +``` + +### Encryption and Decryption +The public key is used to encrypt ```ipcl::PlainText``` objects for ```ipcl::CipherText``` outputs. +In the same way, the private key is used to decrypt ```ipcl::CipherText``` objects for ```ipcl::PlainText``` outputs. +```C++ +ipcl::PlainText pt(raw_data); +ipcl::CipherText ct = key.pub_key->encrypt(pt); +ipcl::PlainText dec_pt = key.priv_key->decrypt(ct); +``` + +### HE Operations +Since the Intel Paillier Cryptosystem Library being a partially homomorphic encryption scheme, while addition is supports both ciphertext operands, multiplication only supports single ciphertext operand. + +```C++ +// setup +ipcl::PlainText a, b; + +ipcl::CipherText ct_a = key.pub_key->encrypt(a); +ipcl::CipherText ct_b = key.pub_key->encrypt(b); + +// Addition (all three end up being same values after decryption) +ipcl::CipherText ct_c1 = ct_a + ct_b; // ciphertext + ciphertext +ipcl::CipherText ct_c2 = ct_a + b; // ciphertext + plaintext +ipcl::CipherText ct_c3 = ct_b + a; // ciphertext + plaintext + +// Multiplication +ipcl::CipherText ct_d1 = ct_a * b; // ciphertext * plaintext +ipcl::CipherText ct_d2 = ct_b * a; +``` diff --git a/example/test.cpp b/example/test.cpp new file mode 100644 index 0000000..5ac7a31 --- /dev/null +++ b/example/test.cpp @@ -0,0 +1,40 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include + +int main() { + const uint32_t num_values = 9; + + ipcl::keyPair key = ipcl::generateKeypair(2048, true); + + std::vector exp_value(num_values); + ipcl::PlainText pt; + ipcl::CipherText ct; + ipcl::PlainText dt; + + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < num_values; i++) { + exp_value[i] = dist(rng); + } + + pt = ipcl::PlainText(exp_value); + ct = key.pub_key->encrypt(pt); + dt = key.priv_key->decrypt(ct); + + for (int i = 0; i < num_values; i++) { + std::vector v = dt.getElementVec(i); + bool chk = v[0] == exp_value[i]; + std::cout << (chk ? "pass" : "fail") << std::endl; + } + + delete key.pub_key; + delete key.priv_key; +} diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 0afbef9..38eeaf8 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -6,11 +6,12 @@ set(IPCL_SRCS pri_key.cpp keygen.cpp bignum.cpp mod_exp.cpp - context.cpp + context.cpp base_text.cpp plaintext.cpp ciphertext.cpp util.cpp + common.cpp ) @@ -34,27 +35,47 @@ target_include_directories(ipcl PUBLIC $ ) +if(IPCL_DETECT_IFMA_RUNTIME) + target_include_directories(ipcl + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PUBLIC $ + PUBLIC $ + ) + install(DIRECTORY ${CPUFEATURES_INC_DIR}/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING + PATTERN "*.hpp" + PATTERN "*.h") + +endif() + install(DIRECTORY ${IPCL_INC_DIR}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h") install(DIRECTORY ${IPPCRYPTO_INC_DIR}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h") +find_package(OpenSSL REQUIRED) +find_package(Threads REQUIRED) target_link_libraries(ipcl PUBLIC OpenSSL::SSL OpenSSL::Crypto Threads::Threads -lnuma) if(IPCL_ENABLE_OMP) find_package(OpenMP REQUIRED) - target_link_libraries(ipcl PRIVATE OpenMP::OpenMP_CXX) + target_link_libraries(ipcl PUBLIC OpenMP::OpenMP_CXX) endif() if(IPCL_SHARED) target_link_libraries(ipcl PRIVATE libippcrypto) + if(IPCL_DETECT_IFMA_RUNTIME) + target_link_libraries(ipcl PRIVATE libcpu_features) + target_include_directories(ipcl PRIVATE ${CPUFEATURES_INC_DIR}) + endif() target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) if(IPCL_ENABLE_QAT) target_link_libraries(ipcl PRIVATE libhe_qat udev z) @@ -64,25 +85,21 @@ else() ipcl_create_archive(ipcl libippcrypto::ippcp) ipcl_create_archive(ipcl libippcrypto::crypto_mb) + if(IPCL_ENABLE_QAT) ipcl_create_archive(ipcl libhe_qat) message(STATUS "HEQAT_PREFIX_INCLUDE : ${HEQAT_PREFIX}/include") message(STATUS "HEQAT_INC_DIR : ${HEQAT_INC_DIR}") target_include_directories(ipcl PRIVATE "$") target_link_libraries(ipcl PRIVATE udev z) - endif() - target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) -endif() + endif() + if(IPCL_DETECT_IFMA_RUNTIME) + ipcl_create_archive(ipcl libcpu_features) + target_include_directories(ipcl PRIVATE ${CPUFEATURES_INC_DIR}) + endif() -# check whether cpu support avx512 flag -set(CPU_AVX512_FLAG "avx512ifma") -execute_process(COMMAND lscpu COMMAND grep ${CPU_AVX512_FLAG} OUTPUT_VARIABLE CPU_ENABLE_AVX512) -if("${CPU_ENABLE_AVX512}" STREQUAL "") - message(STATUS "Support AVX512IFMA: False") -else() - message(STATUS "Support AVX512IFMA: True") - add_compile_definitions(IPCL_CRYPTO_MB_MOD_EXP) + target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) endif() set_target_properties(ipcl PROPERTIES POSITION_INDEPENDENT_CODE ON) @@ -93,14 +110,6 @@ else() set_target_properties(ipcl PROPERTIES OUTPUT_NAME "ipcl") endif() - -install(DIRECTORY ${IPCL_INC_DIR}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ - FILES_MATCHING - PATTERN "*.hpp" - PATTERN "*.h" -) - install(TARGETS ipcl DESTINATION ${CMAKE_INSTALL_LIBDIR}) # config cmake config and target file diff --git a/ipcl/common.cpp b/ipcl/common.cpp new file mode 100644 index 0000000..90209eb --- /dev/null +++ b/ipcl/common.cpp @@ -0,0 +1,56 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/common.hpp" + +#include + +#include "ipcl/util.hpp" + +namespace ipcl { + +IppStatus ippGenRandom(Ipp32u* rand, int bits, void* ctx) { +#ifdef IPCL_RNG_INSTR_RDSEED + return ippsTRNGenRDSEED(rand, bits, ctx); +#elif defined(IPCL_RNG_INSTR_RDRAND) + return ippsPRNGenRDRAND(rand, bits, ctx); +#else + return ippsPRNGen(rand, bits, ctx); +#endif +} + +IppStatus ippGenRandomBN(IppsBigNumState* rand, int bits, void* ctx) { +#ifdef IPCL_RNG_INSTR_RDSEED + return ippsTRNGenRDSEED_BN(rand, bits, ctx); +#elif defined(IPCL_RNG_INSTR_RDRAND) + return ippsPRNGenRDRAND_BN(rand, bits, ctx); +#else + return ippsPRNGen_BN(rand, bits, ctx); +#endif +} + +BigNumber getRandomBN(int bits) { + IppStatus stat; + int bn_buf_size; + + int bn_len = BITSIZE_WORD(bits); + stat = ippsBigNumGetSize(bn_len, &bn_buf_size); + ERROR_CHECK(stat == ippStsNoErr, + "getRandomBN: get IppsBigNumState context error."); + + IppsBigNumState* pBN = + reinterpret_cast(alloca(bn_buf_size)); + ERROR_CHECK(pBN != nullptr, "getRandomBN: big number alloca error"); + + stat = ippsBigNumInit(bn_len, pBN); + ERROR_CHECK(stat == ippStsNoErr, + "getRandomBN: init big number context error."); + + stat = ippGenRandomBN(pBN, bits, NULL); + ERROR_CHECK(stat == ippStsNoErr, + "getRandomBN: generate random big number error."); + + return BigNumber{pBN}; +} + +} // namespace ipcl diff --git a/ipcl/include/ipcl/common.hpp b/ipcl/include/ipcl/common.hpp index f954026..e15d44e 100644 --- a/ipcl/include/ipcl/common.hpp +++ b/ipcl/include/ipcl/common.hpp @@ -4,9 +4,38 @@ #ifndef IPCL_INCLUDE_IPCL_COMMON_HPP_ #define IPCL_INCLUDE_IPCL_COMMON_HPP_ +#include "ipcl/bignum.h" + namespace ipcl { constexpr int IPCL_CRYPTO_MB_SIZE = 8; +/** + * Random generator wrapper.Generates a random unsigned Big Number of the + * specified bit length + * @param[in] rand Pointer to the output unsigned integer big number + * @param[in] bits The number of generated bits + * @param[in] ctx Pointer to the IppsPRNGState context. + * @return Error code + */ +IppStatus ippGenRandom(Ipp32u* rand, int bits, void* ctx); + +/** + * Random generator wrapper.Generates a random positive Big Number of the + * specified bit length + * @param[in] rand Pointer to the output Big Number + * @param[in] bits The number of generated bits + * @param[in] ctx Pointer to the IppsPRNGState context. + * @return Error code + */ +IppStatus ippGenRandomBN(IppsBigNumState* rand, int bits, void* ctx); + +/** + * Get random value + * @param[in] bits The number of Big Number bits + * @return The random value of type Big Number + */ +BigNumber getRandomBN(int bits); + } // namespace ipcl #endif // IPCL_INCLUDE_IPCL_COMMON_HPP_ diff --git a/ipcl/include/ipcl/ipcl.hpp b/ipcl/include/ipcl/ipcl.hpp new file mode 100644 index 0000000..f82ad31 --- /dev/null +++ b/ipcl/include/ipcl/ipcl.hpp @@ -0,0 +1,37 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IPCL_INCLUDE_IPCL_IPCL_HPP_ +#define IPCL_INCLUDE_IPCL_IPCL_HPP_ + +#include "ipcl/pri_key.hpp" + +namespace ipcl { + +/** + * Paillier key structure contains a public key and private key + * pub_key: paillier public key + * priv_key: paillier private key + */ +struct keyPair { + PublicKey* pub_key; + PrivateKey* priv_key; +}; + +/** + * Generate prime number + * @param[in] maxBitSize Maximum bit length of to be generated prime number + * @return The function return a prime big number + */ +BigNumber getPrimeBN(int maxBitSize); + +/** + * Generate a public/private key pair + * @param[in] n_length Bit length of key size + * @param[in] enable_DJN Enable DJN (default=true) + * @return The function return the public and private key pair + */ +keyPair generateKeypair(int64_t n_length, bool enable_DJN = true); + +} // namespace ipcl +#endif // IPCL_INCLUDE_IPCL_IPCL_HPP_ diff --git a/ipcl/include/ipcl/mod_exp.hpp b/ipcl/include/ipcl/mod_exp.hpp index 810ff27..0419e60 100644 --- a/ipcl/include/ipcl/mod_exp.hpp +++ b/ipcl/include/ipcl/mod_exp.hpp @@ -12,23 +12,23 @@ namespace ipcl { /** * Modular exponentiation for multi buffer * @param[in] base base of the exponentiation - * @param[in] pow pow of the exponentiation - * @param[in] m modular + * @param[in] exp pow of the exponentiation + * @param[in] mod modular * @return the modular exponentiation result of type BigNumber */ std::vector ippModExp(const std::vector& base, - const std::vector& pow, - const std::vector& m); + const std::vector& exp, + const std::vector& mod); /** * Modular exponentiation for single buffer * @param[in] base base of the exponentiation - * @param[in] pow pow of the exponentiation - * @param[in] m modular + * @param[in] exp pow of the exponentiation + * @param[in] mod modular * @return the modular exponentiation result of type BigNumber */ -BigNumber ippModExp(const BigNumber& base, const BigNumber& pow, - const BigNumber& m); +BigNumber ippModExp(const BigNumber& base, const BigNumber& exp, + const BigNumber& mod); } // namespace ipcl #endif // IPCL_INCLUDE_IPCL_MOD_EXP_HPP_ diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp index b40b7fd..130c5bd 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -82,7 +82,7 @@ class PublicKey { * Apply obfuscator for ciphertext * @param[out] obfuscator output of obfuscator with random value */ - void applyObfuscator(std::vector& obfuscator) const; + void applyObfuscator(std::vector& ciphertext) const; /** * Set the Random object for ISO/IEC 18033-6 compliance check @@ -90,6 +90,8 @@ class PublicKey { */ void setRandom(const std::vector& r); + void setHS(const BigNumber& hs); + /** * Check if using DJN scheme */ @@ -126,13 +128,6 @@ class PublicKey { std::vector m_r; bool m_testv; - /** - * Get random value - * @param[in] size size of random - * @return addr of random of type Ipp32u vector - */ - std::vector randIpp32u(int size) const; - /** * Big number vector multi buffer encryption * @param[in] pt plaintext of BigNumber vector type @@ -142,12 +137,9 @@ class PublicKey { std::vector raw_encrypt(const std::vector& pt, bool make_secure = true) const; - /** - * Get random value - * @param[in] length bit length - * @return the random value of type BigNumber - */ - BigNumber getRandom(int length) const; + std::vector getDJNObfuscator(std::size_t sz) const; + + std::vector getNormalObfuscator(std::size_t sz) const; }; } // namespace ipcl diff --git a/ipcl/include/ipcl/util.hpp b/ipcl/include/ipcl/util.hpp index b264816..202e277 100644 --- a/ipcl/include/ipcl/util.hpp +++ b/ipcl/include/ipcl/util.hpp @@ -4,6 +4,11 @@ #ifndef IPCL_INCLUDE_IPCL_UTIL_HPP_ #define IPCL_INCLUDE_IPCL_UTIL_HPP_ +#ifdef IPCL_RUNTIME_MOD_EXP +#include +#endif // IPCL_RUNTIME_MOD_EXP + +#include #include #include #include @@ -66,6 +71,14 @@ class OMPUtilities { #endif // IPCL_USE_OMP +#ifdef IPCL_RUNTIME_MOD_EXP +static const bool disable_avx512ifma = + (std::getenv("IPCL_DISABLE_AVX512IFMA") != nullptr); +static const cpu_features::X86Features features = + cpu_features::GetX86Info().features; +static const bool has_avx512ifma = features.avx512ifma && !disable_avx512ifma; +#endif // IPCL_RUNTIME_MOD_EXP + } // namespace ipcl #endif // IPCL_INCLUDE_IPCL_UTIL_HPP_ diff --git a/ipcl/keygen.cpp b/ipcl/keygen.cpp index efbf1d6..f2d712e 100644 --- a/ipcl/keygen.cpp +++ b/ipcl/keygen.cpp @@ -1,56 +1,38 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include "ipcl/keygen.hpp" - -#include -#include #include -#include "ipcl/util.hpp" +#include "ipcl/ipcl.hpp" namespace ipcl { constexpr int N_BIT_SIZE_MAX = 2048; -constexpr int N_BIT_SIZE_MIN = 16; - -static void rand32u(std::vector& addr) { - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - for (auto& x : addr) x = (dist(rng) << 16) + dist(rng); -} - -BigNumber getPrimeBN(int maxBitSize) { - int PrimeSize; - ippsPrimeGetSize(maxBitSize, &PrimeSize); - auto primeGen = std::vector(PrimeSize); - ippsPrimeInit(maxBitSize, reinterpret_cast(primeGen.data())); - - // define Pseudo Random Generator (default settings) - constexpr int seedBitSize = 160; - constexpr int seedSize = BITSIZE_WORD(seedBitSize); - - ippsPRNGGetSize(&PrimeSize); - auto rand = std::vector(PrimeSize); - ippsPRNGInit(seedBitSize, reinterpret_cast(rand.data())); - - auto seed = std::vector(seedSize); - rand32u(seed); - BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); - - ippsPRNGSetSeed(BN(bseed), reinterpret_cast(rand.data())); - - // generate maxBit prime - BigNumber pBN(0, maxBitSize / 8); +constexpr int N_BIT_SIZE_MIN = 200; + +BigNumber getPrimeBN(int max_bits) { + int prime_size; + ippsPrimeGetSize(max_bits, &prime_size); + auto prime_ctx = std::vector(prime_size); + ippsPrimeInit(max_bits, reinterpret_cast(prime_ctx.data())); + +#if defined(IPCL_RNG_INSTR_RDSEED) || defined(IPCL_RNG_INSTR_RDRAND) + bool rand_param = NULL; +#else + auto buff = std::vector(prime_size); + auto rand_param = buff.data(); + ippsPRNGInit(160, reinterpret_cast(rand_param)); +#endif + + BigNumber prime_bn(0, max_bits / 8); while (ippStsNoErr != - ippsPrimeGen_BN(pBN, maxBitSize, 10, - reinterpret_cast(primeGen.data()), - ippsPRNGen, - reinterpret_cast(rand.data()))) { + ippsPrimeGen_BN(prime_bn, max_bits, 10, + reinterpret_cast(prime_ctx.data()), + ippGenRandom, + reinterpret_cast(rand_param))) { } - return pBN; + return prime_bn; } static BigNumber getPrimeDistance(int64_t key_size) { @@ -111,7 +93,7 @@ keyPair generateKeypair(int64_t n_length, bool enable_DJN) { "generateKeyPair: modulus size in bits should belong to either 1Kb, 2Kb, " "3Kb or 4Kb range only, key size exceed the range!!!"); ERROR_CHECK((n_length >= N_BIT_SIZE_MIN) && (n_length % 4 == 0), - "generateKeyPair: key size should >=16, and divisible by 4"); + "generateKeyPair: key size should >=200, and divisible by 4"); BigNumber ref_dist = getPrimeDistance(n_length); diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index 327ea0c..b628ee4 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -455,124 +455,131 @@ static BigNumber heQatBnModExp(const BigNumber& base, const BigNumber& exponent, #endif // IPCL_USE_QAT static std::vector ippMBModExp(const std::vector& base, - const std::vector& pow, - const std::vector& m) { - VEC_SIZE_CHECK(base); - VEC_SIZE_CHECK(pow); - VEC_SIZE_CHECK(m); + const std::vector& exp, + const std::vector& mod) { + std::size_t real_v_size = base.size(); + std::size_t pow_v_size = exp.size(); + std::size_t mod_v_size = mod.size(); + ERROR_CHECK((real_v_size == pow_v_size) && (pow_v_size == mod_v_size) && + (real_v_size <= IPCL_CRYPTO_MB_SIZE), + "ippMBModExp: input vector size error"); mbx_status st = MBX_STATUS_OK; - int bits = m.front().BitSize(); - int dwords = BITSIZE_DWORD(bits); - int bufferLen = mbx_exp_BufferSize(bits); - auto buffer = std::vector(bufferLen); - - std::vector out_x(IPCL_CRYPTO_MB_SIZE); - std::vector b_array(IPCL_CRYPTO_MB_SIZE); - std::vector p_array(IPCL_CRYPTO_MB_SIZE); - - int mem_pool_size = IPCL_CRYPTO_MB_SIZE * dwords; - std::vector out_mem_pool(mem_pool_size); - std::vector base_mem_pool(mem_pool_size); - std::vector pow_mem_pool(mem_pool_size); - - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - out_x[i] = &out_mem_pool[i * dwords]; - b_array[i] = &base_mem_pool[i * dwords]; - p_array[i] = &pow_mem_pool[i * dwords]; - } - /* - * These two intermediate variables pow_b & pow_p are necessary + * These two intermediate variables base_data & exp_data are necessary * because if they are not used, the length returned from ippsRef_BN - * will be inconsistent with the length allocated by b_array/p_array, + * will be inconsistent with the length allocated by base_pa/exp_pa, * resulting in data errors. */ - std::vector pow_b(IPCL_CRYPTO_MB_SIZE); - std::vector pow_p(IPCL_CRYPTO_MB_SIZE); - std::vector pow_nsquare(IPCL_CRYPTO_MB_SIZE); - std::vector b_size_v(IPCL_CRYPTO_MB_SIZE); - std::vector p_size_v(IPCL_CRYPTO_MB_SIZE); - std::vector n_size_v(IPCL_CRYPTO_MB_SIZE); + std::vector base_data(IPCL_CRYPTO_MB_SIZE); + std::vector exp_data(IPCL_CRYPTO_MB_SIZE); + std::vector mod_data(IPCL_CRYPTO_MB_SIZE); + std::vector base_bits_v(IPCL_CRYPTO_MB_SIZE); + std::vector exp_bits_v(IPCL_CRYPTO_MB_SIZE); + std::vector mod_bits_v(IPCL_CRYPTO_MB_SIZE); + + for (int i = 0; i < real_v_size; i++) { + ippsRef_BN(nullptr, &base_bits_v[i], + reinterpret_cast(&base_data[i]), base[i]); + ippsRef_BN(nullptr, &exp_bits_v[i], + reinterpret_cast(&exp_data[i]), exp[i]); + ippsRef_BN(nullptr, &mod_bits_v[i], &mod_data[i], mod[i]); + } + + // Find the longest size of module and power + auto longest_mod_it = std::max_element(mod_bits_v.begin(), mod_bits_v.end()); + auto longest_mod_idx = std::distance(mod_bits_v.begin(), longest_mod_it); + BigNumber longest_mod = mod[longest_mod_idx]; + int mod_bits = *longest_mod_it; + int exp_bits = *std::max_element(exp_bits_v.begin(), exp_bits_v.end()); + + std::vector out_pa(IPCL_CRYPTO_MB_SIZE); + std::vector base_pa(IPCL_CRYPTO_MB_SIZE); + std::vector exp_pa(IPCL_CRYPTO_MB_SIZE); + + int mod_dwords = BITSIZE_DWORD(mod_bits); + int num_buff = IPCL_CRYPTO_MB_SIZE * mod_dwords; + std::vector out_buff(num_buff); + std::vector base_buff(num_buff); + std::vector exp_buff(num_buff); for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - ippsRef_BN(nullptr, &b_size_v[i], reinterpret_cast(&pow_b[i]), - base[i]); - ippsRef_BN(nullptr, &p_size_v[i], reinterpret_cast(&pow_p[i]), - pow[i]); - ippsRef_BN(nullptr, &n_size_v[i], &pow_nsquare[i], m[i]); - - memcpy(b_array[i], pow_b[i], BITSIZE_WORD(b_size_v[i]) * 4); - memcpy(p_array[i], pow_p[i], BITSIZE_WORD(p_size_v[i]) * 4); + auto idx = i * mod_dwords; + out_pa[i] = &out_buff[idx]; + base_pa[i] = &base_buff[idx]; + exp_pa[i] = &exp_buff[idx]; } - // Find the biggest size of module and exp - int nsqBitLen = *std::max_element(n_size_v.begin(), n_size_v.end()); - int expBitLen = *std::max_element(p_size_v.begin(), p_size_v.end()); + for (int i = 0; i < real_v_size; i++) { + memcpy(base_pa[i], base_data[i], BITSIZE_WORD(base_bits_v[i]) * 4); + memcpy(exp_pa[i], exp_data[i], BITSIZE_WORD(exp_bits_v[i]) * 4); + } + int work_buff_size = mbx_exp_BufferSize(mod_bits); + auto work_buff = std::vector(work_buff_size); // If actual sizes of modules are different, // set the mod_bits parameter equal to maximum size of the actual module in // bit size and extend all the modules with zero bits to the mod_bits value. // The same is applicable for the exp_bits parameter and actual exponents. - st = mbx_exp_mb8(out_x.data(), b_array.data(), p_array.data(), expBitLen, - reinterpret_cast(pow_nsquare.data()), nsqBitLen, - reinterpret_cast(buffer.data()), bufferLen); + st = mbx_exp_mb8(out_pa.data(), base_pa.data(), exp_pa.data(), exp_bits, + reinterpret_cast(mod_data.data()), mod_bits, + reinterpret_cast(work_buff.data()), work_buff_size); - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { + for (int i = 0; i < real_v_size; i++) { ERROR_CHECK(MBX_STATUS_OK == MBX_GET_STS(st, i), std::string("ippMultiBuffExp: error multi buffered exp " "modules, error code = ") + std::to_string(MBX_GET_STS(st, i))); } - // It is important to hold a copy of nsquare for thread-safe purpose - std::vector res(IPCL_CRYPTO_MB_SIZE, m.front()); - - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - res[i].Set(reinterpret_cast(out_x[i]), BITSIZE_WORD(nsqBitLen), + // Init res with longest mod value to ensure each + // Big number has enough space. + std::vector res(real_v_size, longest_mod); + for (int i = 0; i < real_v_size; i++) { + res[i].Set(reinterpret_cast(out_pa[i]), BITSIZE_WORD(mod_bits), IppsBigNumPOS); } return res; } -static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, - const BigNumber& m) { +static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& exp, + const BigNumber& mod) { IppStatus stat = ippStsNoErr; // It is important to declare res * bform bit length refer to ipp-crypto spec: // R should not be less than the data length of the modulus m - BigNumber res(m); + BigNumber res(mod); - int bnBitLen; - Ipp32u* pow_m; - ippsRef_BN(nullptr, &bnBitLen, &pow_m, BN(m)); - int nlen = BITSIZE_WORD(bnBitLen); + int mod_bits; + Ipp32u* mod_data; + ippsRef_BN(nullptr, &mod_bits, &mod_data, BN(mod)); + int mod_words = BITSIZE_WORD(mod_bits); int size; // define and initialize Montgomery Engine over Modulus N - stat = ippsMontGetSize(IppsBinaryMethod, nlen, &size); + stat = ippsMontGetSize(IppsBinaryMethod, mod_words, &size); ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: get the size of IppsMontState context error."); auto pMont = std::vector(size); - stat = ippsMontInit(IppsBinaryMethod, nlen, + stat = ippsMontInit(IppsBinaryMethod, mod_words, reinterpret_cast(pMont.data())); ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: init Mont context error."); - stat = - ippsMontSet(pow_m, nlen, reinterpret_cast(pMont.data())); + stat = ippsMontSet(mod_data, mod_words, + reinterpret_cast(pMont.data())); ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: set Mont input error."); // encode base into Montgomery form - BigNumber bform(m); + BigNumber bform(mod); stat = ippsMontForm(BN(base), reinterpret_cast(pMont.data()), BN(bform)); ERROR_CHECK(stat == ippStsNoErr, "ippMontExp: convert big number into Mont form error."); // compute R = base^pow mod N - stat = ippsMontExp(BN(bform), BN(pow), + stat = ippsMontExp(BN(bform), BN(exp), reinterpret_cast(pMont.data()), BN(res)); ERROR_CHECK(stat == ippStsNoErr, std::string("ippsMontExp: error code = ") + std::to_string(stat)); @@ -589,80 +596,112 @@ static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& pow, } std::vector ippModExp(const std::vector& base, - const std::vector& pow, - const std::vector& m) { + const std::vector& exp, + const std::vector& mod) { #ifdef IPCL_USE_QAT // TODO(fdiasmor): Slice with custom batches, test OMP std::size_t worksize = base.size(); std::vector remainder(worksize); // remainder = heQatBnModExp(base, pow, m); - remainder = heQatBnModExp(base, pow, m, 1024); + remainder = heQatBnModExp(base, exp, mod, 1024); return remainder; #else std::size_t v_size = base.size(); std::vector res(v_size); -#ifdef IPCL_CRYPTO_MB_MOD_EXP +#ifdef IPCL_RUNTIME_MOD_EXP // If there is only 1 big number, we don't need to use MBModExp if (v_size == 1) { - res[0] = ippSBModExp(base[0], pow[0], m[0]); + res[0] = ippSBModExp(base[0], exp[0], mod[0]); return res; } - std::size_t offset = 0; - std::size_t num_chunk = v_size / IPCL_CRYPTO_MB_SIZE; - std::size_t remainder = v_size % IPCL_CRYPTO_MB_SIZE; - + if (has_avx512ifma) { + std::size_t remainder = v_size % IPCL_CRYPTO_MB_SIZE; + std::size_t num_chunk = + (v_size + IPCL_CRYPTO_MB_SIZE - 1) / IPCL_CRYPTO_MB_SIZE; #ifdef IPCL_USE_OMP - int omp_remaining_threads = OMPUtilities::MaxThreads; + int omp_remaining_threads = OMPUtilities::MaxThreads; #pragma omp parallel for num_threads( \ OMPUtilities::assignOMPThreads(omp_remaining_threads, num_chunk)) #endif // IPCL_USE_OMP - for (std::size_t i = 0; i < num_chunk; i++) { - auto base_start = base.begin() + i * IPCL_CRYPTO_MB_SIZE; - auto base_end = base_start + IPCL_CRYPTO_MB_SIZE; + for (std::size_t i = 0; i < num_chunk; i++) { + std::size_t chunk_size = IPCL_CRYPTO_MB_SIZE; + if ((i == (num_chunk - 1)) && (remainder > 0)) chunk_size = remainder; - auto pow_start = pow.begin() + i * IPCL_CRYPTO_MB_SIZE; - auto pow_end = pow_start + IPCL_CRYPTO_MB_SIZE; + std::size_t chunk_offset = i * IPCL_CRYPTO_MB_SIZE; - auto m_start = m.begin() + i * IPCL_CRYPTO_MB_SIZE; - auto m_end = m_start + IPCL_CRYPTO_MB_SIZE; + auto base_start = base.begin() + chunk_offset; + auto base_end = base_start + chunk_size; - auto base_chunk = std::vector(base_start, base_end); - auto pow_chunk = std::vector(pow_start, pow_end); - auto m_chunk = std::vector(m_start, m_end); + auto exp_start = exp.begin() + chunk_offset; + auto exp_end = exp_start + chunk_size; + + auto mod_start = mod.begin() + chunk_offset; + auto mod_end = mod_start + chunk_size; + + auto base_chunk = std::vector(base_start, base_end); + auto exp_chunk = std::vector(exp_start, exp_end); + auto mod_chunk = std::vector(mod_start, mod_end); - auto tmp = ippMBModExp(base_chunk, pow_chunk, m_chunk); - std::copy(tmp.begin(), tmp.end(), res.begin() + i * IPCL_CRYPTO_MB_SIZE); + auto tmp = ippMBModExp(base_chunk, exp_chunk, mod_chunk); + std::copy(tmp.begin(), tmp.end(), res.begin() + chunk_offset); + } + + return res; + + } else { +#ifdef IPCL_USE_OMP + int omp_remaining_threads = OMPUtilities::MaxThreads; +#pragma omp parallel for num_threads( \ + OMPUtilities::assignOMPThreads(omp_remaining_threads, v_size)) +#endif // IPCL_USE_OMP + for (int i = 0; i < v_size; i++) + res[i] = ippSBModExp(base[i], exp[i], mod[i]); + return res; + } + +#else + +#ifdef IPCL_CRYPTO_MB_MOD_EXP + + // If there is only 1 big number, we don't need to use MBModExp + if (v_size == 1) { + res[0] = ippSBModExp(base[0], exp[0], mod[0]); + return res; } - offset = num_chunk * IPCL_CRYPTO_MB_SIZE; - // If only 1 big number left, we don't need to make padding - if (remainder == 1) - res[offset] = ippSBModExp(base[offset], pow[offset], m[offset]); + std::size_t remainder = v_size % IPCL_CRYPTO_MB_SIZE; + std::size_t num_chunk = + (v_size + IPCL_CRYPTO_MB_SIZE - 1) / IPCL_CRYPTO_MB_SIZE; + +#ifdef IPCL_USE_OMP + int omp_remaining_threads = OMPUtilities::MaxThreads; +#pragma omp parallel for num_threads( \ + OMPUtilities::assignOMPThreads(omp_remaining_threads, num_chunk)) +#endif // IPCL_USE_OMP + for (std::size_t i = 0; i < num_chunk; i++) { + std::size_t chunk_size = IPCL_CRYPTO_MB_SIZE; + if ((i == (num_chunk - 1)) && (remainder > 0)) chunk_size = remainder; - // If the 1 < remainder < IPCL_CRYPTO_MB_SIZE, we need to make padding - if (remainder > 1) { - auto base_start = base.begin() + offset; - auto base_end = base_start + remainder; + std::size_t chunk_offset = i * IPCL_CRYPTO_MB_SIZE; - auto pow_start = pow.begin() + offset; - auto pow_end = pow_start + remainder; + auto base_start = base.begin() + chunk_offset; + auto base_end = base_start + chunk_size; - auto m_start = m.begin() + offset; - auto m_end = m_start + remainder; + auto exp_start = exp.begin() + chunk_offset; + auto exp_end = exp_start + chunk_size; - std::vector base_chunk(IPCL_CRYPTO_MB_SIZE, 0); - std::vector pow_chunk(IPCL_CRYPTO_MB_SIZE, 0); - std::vector m_chunk(IPCL_CRYPTO_MB_SIZE, 0); + auto mod_start = mod.begin() + chunk_offset; + auto mod_end = mod_start + chunk_size; - std::copy(base_start, base_end, base_chunk.begin()); - std::copy(pow_start, pow_end, pow_chunk.begin()); - std::copy(m_start, m_end, m_chunk.begin()); + auto base_chunk = std::vector(base_start, base_end); + auto exp_chunk = std::vector(exp_start, exp_end); + auto mod_chunk = std::vector(mod_start, mod_end); - auto tmp = ippMBModExp(base_chunk, pow_chunk, m_chunk); - std::copy(tmp.begin(), tmp.begin() + remainder, res.begin() + offset); + auto tmp = ippMBModExp(base_chunk, exp_chunk, mod_chunk); + std::copy(tmp.begin(), tmp.end(), res.begin() + chunk_offset); } return res; @@ -674,16 +713,18 @@ std::vector ippModExp(const std::vector& base, #pragma omp parallel for num_threads( \ OMPUtilities::assignOMPThreads(omp_remaining_threads, v_size)) #endif // IPCL_USE_OMP - for (int i = 0; i < v_size; i++) res[i] = ippSBModExp(base[i], pow[i], m[i]); + for (int i = 0; i < v_size; i++) + res[i] = ippSBModExp(base[i], exp[i], mod[i]); return res; #endif // IPCL_CRYPTO_MB_MOD_EXP +#endif // IPCL_RUNTIME_MOD_EXP #endif // IPCL_USE_QAT } -BigNumber ippModExp(const BigNumber& base, const BigNumber& pow, - const BigNumber& m) { - return ippSBModExp(base, pow, m); +BigNumber ippModExp(const BigNumber& base, const BigNumber& exp, + const BigNumber& mod) { + return ippSBModExp(base, exp, mod); } } // namespace ipcl diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index b4fe94f..01f8124 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -35,44 +35,12 @@ PublicKey::PublicKey(const BigNumber& n, int bits, bool enableDJN_) if (enableDJN_) this->enableDJN(); // sets m_enable_DJN } -// array of 32-bit random, using rand() from stdlib -std::vector PublicKey::randIpp32u(int size) const { - std::vector addr(size); - // TODO(skmono): check if copy of m_init_seed is needed for const - unsigned int init_seed = m_init_seed; - for (auto& a : addr) a = (rand_r(&init_seed) << 16) + rand_r(&init_seed); - return addr; -} - -// length is arbitrary -BigNumber PublicKey::getRandom(int bit_len) const { - IppStatus stat; - int bn_buf_size; - - // define length Big Numbers - int bn_len = BITSIZE_WORD(bit_len); - stat = ippsBigNumGetSize(bn_len, &bn_buf_size); - ERROR_CHECK(stat == ippStsNoErr, - "getRandom: get IppsBigNumState context error."); - - IppsBigNumState* pBN = - reinterpret_cast(alloca(bn_buf_size)); - ERROR_CHECK(pBN != nullptr, "getRandom: big number alloca error"); - - stat = ippsBigNumInit(bn_len, pBN); - ERROR_CHECK(stat == ippStsNoErr, "getRandom: init big number context error."); - - ippsPRNGenRDRAND_BN(pBN, bit_len, NULL); - - return BigNumber{pBN}; -} - void PublicKey::enableDJN() { BigNumber gcd; BigNumber rmod; do { int rand_bit = m_n.BitSize(); - BigNumber rand = getRandom(rand_bit + 128); + BigNumber rand = getRandomBN(rand_bit + 128); rmod = rand % m_n; gcd = rand.gcd(m_n); } while (gcd.compare(1)); @@ -86,31 +54,45 @@ void PublicKey::enableDJN() { m_enable_DJN = true; } -void PublicKey::applyObfuscator(std::vector& obfuscator) const { - std::size_t obf_size = obfuscator.size(); - std::vector r(obf_size); - std::vector pown(obf_size, m_n); - std::vector base(obf_size, m_hs); - std::vector sq(obf_size, m_nsquare); +std::vector PublicKey::getDJNObfuscator(std::size_t sz) const { + std::vector r(sz); + std::vector base(sz, m_hs); + std::vector sq(sz, m_nsquare); - if (m_enable_DJN) { + if (m_testv) { + r = m_r; + } else { for (auto& r_ : r) { - r_ = getRandom(m_randbits); + r_ = getRandomBN(m_randbits); } - obfuscator = ipcl::ippModExp(base, r, sq); + } + return ipcl::ippModExp(base, r, sq); +} + +std::vector PublicKey::getNormalObfuscator(std::size_t sz) const { + std::vector r(sz); + std::vector sq(sz, m_nsquare); + std::vector pown(sz, m_n); + + if (m_testv) { + r = m_r; } else { - for (int i = 0; i < obf_size; i++) { - if (m_testv) { - r[i] = m_r[i]; - } else { - r[i] = getRandom(m_bits); - r[i] = r[i] % (m_n - 1) + 1; - } - pown[i] = m_n; - sq[i] = m_nsquare; + for (int i = 0; i < sz; i++) { + r[i] = getRandomBN(m_bits); + r[i] = r[i] % (m_n - 1) + 1; } - obfuscator = ipcl::ippModExp(r, pown, sq); } + return ipcl::ippModExp(r, pown, sq); +} + +void PublicKey::applyObfuscator(std::vector& ciphertext) const { + std::size_t sz = ciphertext.size(); + std::vector obfuscator = + m_enable_DJN ? getDJNObfuscator(sz) : getNormalObfuscator(sz); + BigNumber sq = m_nsquare; + + for (std::size_t i = 0; i < sz; ++i) + ciphertext[i] = sq.ModMul(ciphertext[i], obfuscator[i]); } void PublicKey::setRandom(const std::vector& r) { @@ -118,30 +100,25 @@ void PublicKey::setRandom(const std::vector& r) { m_testv = true; } +void PublicKey::setHS(const BigNumber& hs) { m_hs = hs; } + std::vector PublicKey::raw_encrypt(const std::vector& pt, bool make_secure) const { std::size_t pt_size = pt.size(); std::vector ct(pt_size); - BigNumber sq = m_nsquare; - for (std::size_t i = 0; i < pt_size; i++) { + for (std::size_t i = 0; i < pt_size; i++) ct[i] = (m_n * pt[i] + 1) % m_nsquare; - } - if (make_secure) { - std::vector obfuscator(pt_size); - applyObfuscator(obfuscator); + if (make_secure) applyObfuscator(ct); - for (std::size_t i = 0; i < pt_size; i++) - ct[i] = sq.ModMul(ct[i], obfuscator[i]); - } return ct; } CipherText PublicKey::encrypt(const PlainText& pt, bool make_secure) const { std::size_t pt_size = pt.getSize(); - ERROR_CHECK(pt_size > 0, "encrypt: Cannot encrypt emtpy PlainText"); + ERROR_CHECK(pt_size > 0, "encrypt: Cannot encrypt empty PlainText"); std::vector ct_bn_v(pt_size); ct_bn_v = raw_encrypt(pt.getTexts(), make_secure); diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index eaaf3e3..bac47db 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -7,11 +7,9 @@ #include #include "gtest/gtest.h" -#include "ipcl/ciphertext.hpp" -#include "ipcl/keygen.hpp" -#include "ipcl/plaintext.hpp" +#include "ipcl/ipcl.hpp" -constexpr int SELF_DEF_NUM_VALUES = 20; +constexpr int SELF_DEF_NUM_VALUES = 9; TEST(CryptoTest, CryptoTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; @@ -45,7 +43,9 @@ TEST(CryptoTest, CryptoTest) { } TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { - const uint32_t num_values = SELF_DEF_NUM_VALUES; + // Ensure that at least 2 different numbers are encrypted + // Because ir_bn_v[1] will set to a specific value + const uint32_t num_values = SELF_DEF_NUM_VALUES + 1; BigNumber p = "0xff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c" diff --git a/test/test_ops.cpp b/test/test_ops.cpp index 30ad188..74064fe 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -7,11 +7,9 @@ #include #include "gtest/gtest.h" -#include "ipcl/ciphertext.hpp" -#include "ipcl/keygen.hpp" -#include "ipcl/plaintext.hpp" +#include "ipcl/ipcl.hpp" -constexpr int SELF_DEF_NUM_VALUES = 20; +constexpr int SELF_DEF_NUM_VALUES = 7; void CtPlusCt(ipcl::CipherText& res, const ipcl::CipherText& ct1, const ipcl::CipherText& ct2, const ipcl::keyPair key) { From b417e2ede5105fcd8b80a57b2362c525c9c75f38 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Fri, 14 Oct 2022 12:53:13 -0700 Subject: [PATCH 276/364] Add context header to public header --- ipcl/include/ipcl/ipcl.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/ipcl/include/ipcl/ipcl.hpp b/ipcl/include/ipcl/ipcl.hpp index f82ad31..98b9a37 100644 --- a/ipcl/include/ipcl/ipcl.hpp +++ b/ipcl/include/ipcl/ipcl.hpp @@ -4,6 +4,7 @@ #ifndef IPCL_INCLUDE_IPCL_IPCL_HPP_ #define IPCL_INCLUDE_IPCL_IPCL_HPP_ +#include "ipcl/context.hpp" #include "ipcl/pri_key.hpp" namespace ipcl { From 801e491dbdb60261bd830fac307d5d5c7c9b61c5 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 14 Oct 2022 16:53:50 -0700 Subject: [PATCH 277/364] Fail-proof context setup and teardown. Signed-off-by: Souza, Fillipe --- he_qat/he_qat_context.c | 90 +++++++++++++++++++++++++++++------------ samples/test_context.c | 24 +++++++++++ 2 files changed, 88 insertions(+), 26 deletions(-) diff --git a/he_qat/he_qat_context.c b/he_qat/he_qat_context.c index 7ffe390..d740e30 100644 --- a/he_qat/he_qat_context.c +++ b/he_qat/he_qat_context.c @@ -20,6 +20,7 @@ #endif static volatile HE_QAT_STATUS context_state = HE_QAT_STATUS_INACTIVE; +static pthread_mutex_t context_lock; // Global variable declarations static pthread_t buffer_manager; @@ -47,11 +48,11 @@ extern void stop_perform_op(void* _inst_config, unsigned num_inst); extern void* start_perform_op(void* _inst_config); static CpaInstanceHandle handle = NULL; +static Cpa16U numInstances = 0; +static Cpa16U nextInstance = 0; static CpaInstanceHandle get_qat_instance() { static CpaInstanceHandle cyInstHandles[MAX_INSTANCES]; - static Cpa16U numInstances = 0; - static Cpa16U nextInstance = 0; CpaStatus status = CPA_STATUS_SUCCESS; CpaInstanceInfo2 info = {0}; @@ -65,28 +66,39 @@ static CpaInstanceHandle get_qat_instance() { numInstances = HE_QAT_NUM_ACTIVE_INSTANCES; } + if (CPA_STATUS_SUCCESS != status) { +#ifdef HE_QAT_DEBUG + printf("No CyInstances Found.\n", numInstances); +#endif + return NULL; + } +#ifdef HE_QAT_DEBUG printf("Found %d CyInstances.\n", numInstances); - +#endif if ((status == CPA_STATUS_SUCCESS) && (numInstances > 0)) { status = cpaCyGetInstances(numInstances, cyInstHandles); // List instances and their characteristics for (unsigned int i = 0; i < numInstances; i++) { status = cpaCyInstanceGetInfo2(cyInstHandles[i],&info); - if (CPA_STATUS_SUCCESS == status) { - printf("Vendor Name: %s\n",info.vendorName); - printf("Part Name: %s\n",info.partName); - printf("Inst Name: %s\n",info.instName); - printf("Inst ID: %s\n",info.instID); - printf("Node Affinity: %u\n",info.nodeAffinity); - printf("Physical Instance:\n"); - printf("\tpackageId: %d\n",info.physInstId.packageId); - printf("\tacceleratorId: %d\n",info.physInstId.acceleratorId); - printf("\texecutionEngineId: %d\n",info.physInstId.executionEngineId); - printf("\tbusAddress: %d\n",info.physInstId.busAddress); - printf("\tkptAcHandle: %d\n",info.physInstId.kptAcHandle); - } + if (CPA_STATUS_SUCCESS != status) + return NULL; +#ifdef HE_QAT_DEBUG + printf("Vendor Name: %s\n",info.vendorName); + printf("Part Name: %s\n",info.partName); + printf("Inst Name: %s\n",info.instName); + printf("Inst ID: %s\n",info.instID); + printf("Node Affinity: %u\n",info.nodeAffinity); + printf("Physical Instance:\n"); + printf("\tpackageId: %d\n",info.physInstId.packageId); + printf("\tacceleratorId: %d\n",info.physInstId.acceleratorId); + printf("\texecutionEngineId: %d\n",info.physInstId.executionEngineId); + printf("\tbusAddress: %d\n",info.physInstId.busAddress); + printf("\tkptAcHandle: %d\n",info.physInstId.kptAcHandle); +#endif } +#ifdef HE_QAT_DEBUG printf("Next Instance: %d.\n", nextInstance); +#endif if (status == CPA_STATUS_SUCCESS) return cyInstHandles[nextInstance]; //*pCyInstHandle = cyInstHandles[0]; @@ -103,7 +115,9 @@ static CpaInstanceHandle get_qat_instance() { } nextInstance = ((nextInstance + 1) % numInstances); +#ifdef HE_QAT_DEBUG printf("Next Instance: %d.\n", nextInstance); +#endif return cyInstHandles[nextInstance]; } @@ -112,13 +126,22 @@ static CpaInstanceHandle get_qat_instance() { HE_QAT_STATUS acquire_qat_devices() { CpaStatus status = CPA_STATUS_FAIL; + pthread_mutex_lock(&context_lock); + + // Handle cases where acquire_qat_devices() is called when already active and running + if (HE_QAT_STATUS_ACTIVE == context_state) { + pthread_mutex_unlock(&context_lock); + return HE_QAT_STATUS_SUCCESS; + } + // Initialize QAT memory pool allocator status = qaeMemInit(); if (CPA_STATUS_SUCCESS != status) { + pthread_mutex_unlock(&context_lock); printf("Failed to initialized memory driver.\n"); return HE_QAT_STATUS_FAIL; // HEQAT_STATUS_ERROR } -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG printf("QAT memory successfully initialized.\n"); #endif @@ -126,11 +149,12 @@ HE_QAT_STATUS acquire_qat_devices() { // "SSL1" status = icp_sal_userStartMultiProcess("SSL", CPA_FALSE); if (CPA_STATUS_SUCCESS != status) { + pthread_mutex_unlock(&context_lock); printf("Failed to start SAL user process SSL\n"); qaeMemDestroy(); return HE_QAT_STATUS_FAIL; // HEQAT_STATUS_ERROR } -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG printf("SAL user process successfully started.\n"); #endif @@ -141,6 +165,7 @@ HE_QAT_STATUS acquire_qat_devices() { for (unsigned int i = 0; i < HE_QAT_NUM_ACTIVE_INSTANCES; i++) { _inst_handle[i] = get_qat_instance(); if (_inst_handle[i] == NULL) { + pthread_mutex_unlock(&context_lock); printf("Failed to find QAT endpoints.\n"); return HE_QAT_STATUS_FAIL; } @@ -151,7 +176,7 @@ HE_QAT_STATUS acquire_qat_devices() { // printf("Failed to find QAT endpoints.\n"); // return HE_QAT_STATUS_FAIL; //} -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG printf("Found QAT endpoints.\n"); #endif @@ -226,7 +251,7 @@ HE_QAT_STATUS acquire_qat_devices() { // Work on this // pthread_create(&he_qat_instances[0], NULL, start_instances, (void*)he_qat_config); pthread_create(&he_qat_runner, NULL, start_instances, (void*)he_qat_config); -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG printf("Created processing threads.\n"); #endif @@ -237,7 +262,7 @@ HE_QAT_STATUS acquire_qat_devices() { // Dispatch all QAT instances in a single thread // pthread_detach(he_qat_instances[0]); pthread_detach(he_qat_runner); -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG printf("Detached processing threads.\n"); #endif @@ -247,6 +272,7 @@ HE_QAT_STATUS acquire_qat_devices() { // Launch buffer manager thread to schedule incoming requests if (0 != pthread_create(&buffer_manager, NULL, schedule_requests, (void*)&context_state)) { + pthread_mutex_unlock(&context_lock); release_qat_devices(); printf( "Failed to complete QAT initialization while creating buffer " @@ -255,12 +281,15 @@ HE_QAT_STATUS acquire_qat_devices() { } if (0 != pthread_detach(buffer_manager)) { + pthread_mutex_unlock(&context_lock); release_qat_devices(); printf( "Failed to complete QAT initialization while launching buffer " "manager thread.\n"); return HE_QAT_STATUS_FAIL; } + + pthread_mutex_unlock(&context_lock); return HE_QAT_STATUS_SUCCESS; } @@ -270,12 +299,16 @@ HE_QAT_STATUS acquire_qat_devices() { HE_QAT_STATUS release_qat_devices() { CpaStatus status = CPA_STATUS_FAIL; - if (HE_QAT_STATUS_INACTIVE == context_state) - return HE_QAT_STATUS_SUCCESS; + pthread_mutex_lock(&context_lock); + + if (HE_QAT_STATUS_INACTIVE == context_state) { + pthread_mutex_unlock(&context_lock); + return HE_QAT_STATUS_SUCCESS; + } stop_instances(he_qat_config); //stop_perform_op(he_qat_inst_config, HE_QAT_NUM_ACTIVE_INSTANCES); -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG printf("Stopped polling and processing threads.\n"); #endif @@ -285,16 +318,21 @@ HE_QAT_STATUS release_qat_devices() { // Stop QAT SSL service icp_sal_userStop(); -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG printf("Stopped SAL user process.\n"); #endif // Release QAT allocated memory qaeMemDestroy(); -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG printf("Release QAT memory.\n"); #endif + numInstances = 0; + nextInstance = 0; + + pthread_mutex_unlock(&context_lock); + return HE_QAT_STATUS_SUCCESS; } diff --git a/samples/test_context.c b/samples/test_context.c index e640e8b..8cbc1f0 100644 --- a/samples/test_context.c +++ b/samples/test_context.c @@ -5,6 +5,14 @@ int main() { HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + status = release_qat_devices(); + if (HE_QAT_STATUS_SUCCESS == status) { + printf("Nothing to do by release_qat_devices().\n"); + } else { + printf("release_qat_devices() failed.\n"); + exit(1); + } status = acquire_qat_devices(); if (HE_QAT_STATUS_SUCCESS == status) { @@ -13,6 +21,14 @@ int main() { printf("acquire_qat_devices() failed.\n"); exit(1); } + + status = acquire_qat_devices(); + if (HE_QAT_STATUS_SUCCESS == status) { + printf("QAT context already exists.\n"); + } else { + printf("acquire_qat_devices() failed.\n"); + exit(1); + } OS_SLEEP(5000); @@ -23,6 +39,14 @@ int main() { printf("release_qat_devices() failed.\n"); exit(1); } + + status = release_qat_devices(); + if (HE_QAT_STATUS_SUCCESS == status) { + printf("Nothing to do by release_qat_devices().\n"); + } else { + printf("release_qat_devices() failed.\n"); + exit(1); + } return 0; } From 6bd6cd86d70f5c3219fab118ef204f27a5a2ec68 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 14 Oct 2022 17:32:52 -0700 Subject: [PATCH 278/364] Update heqat module. Signed-off-by: Souza, Fillipe --- module/heqat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/heqat b/module/heqat index 8bca333..801e491 160000 --- a/module/heqat +++ b/module/heqat @@ -1 +1 @@ -Subproject commit 8bca333d02d5c115676de40646e68b4c8c30f572 +Subproject commit 801e491dbdb60261bd830fac307d5d5c7c9b61c5 From 9311518df0675a28e97982a6ed6e50d1bad990d7 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 14 Oct 2022 17:38:24 -0700 Subject: [PATCH 279/364] Update context. Signed-off-by: Souza, Fillipe --- ipcl/context.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ipcl/context.cpp b/ipcl/context.cpp index 44377ae..24db392 100644 --- a/ipcl/context.cpp +++ b/ipcl/context.cpp @@ -27,6 +27,7 @@ namespace ipcl { {"4xxx",FeatureValue::QAT4XXX}, {"qat_4xxx",FeatureValue::QAT4XXX} }; +#ifdef IPCL_USE_QAT bool hasQAT = false; static bool isUsingQAT = false; static bool initializeQATContext() { @@ -34,6 +35,7 @@ namespace ipcl { return (isUsingQAT = true); return false; } +#endif bool initializeContext(std::string runtime_choice) { #ifdef IPCL_USE_QAT @@ -66,11 +68,19 @@ namespace ipcl { } bool isQATRunning() { +#ifdef IPCL_USE_QAT return (HE_QAT_STATUS_RUNNING == get_qat_context_state()); +#else + return false; +#endif } bool isQATActive() { +#ifdef IPCL_USE_QAT return (HE_QAT_STATUS_ACTIVE == get_qat_context_state()); +#else + return false; +#endif } } // namespace ipcl From 5111cff3a416871b63b9c9582ea139690c59383a Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 14 Oct 2022 17:54:32 -0700 Subject: [PATCH 280/364] Update context. Signed-off-by: Souza, Fillipe --- ipcl/context.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ipcl/context.cpp b/ipcl/context.cpp index 24db392..14262a5 100644 --- a/ipcl/context.cpp +++ b/ipcl/context.cpp @@ -31,7 +31,8 @@ namespace ipcl { bool hasQAT = false; static bool isUsingQAT = false; static bool initializeQATContext() { - if (HE_QAT_STATUS_SUCCESS == acquire_qat_devices()) + if (!isUsingQAT && + HE_QAT_STATUS_SUCCESS == acquire_qat_devices()) return (isUsingQAT = true); return false; } @@ -40,7 +41,6 @@ namespace ipcl { bool initializeContext(std::string runtime_choice) { #ifdef IPCL_USE_QAT hasQAT = true; - switch (runtimeMap[runtime_choice]) { case RuntimeValue::QAT: return initializeQATContext(); @@ -58,8 +58,10 @@ namespace ipcl { bool terminateContext() { #ifdef IPCL_USE_QAT if (isUsingQAT) { - if (HE_QAT_STATUS_SUCCESS == release_qat_devices()) - return true; + if (HE_QAT_STATUS_SUCCESS == release_qat_devices()) { + isUsingQAT = false; + return true; + } return false; } return true; #else // Default behavior: CPU choice From da1aab433d177ea301b3897444ebb0ae2979d69b Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 17 Oct 2022 14:59:53 -0700 Subject: [PATCH 281/364] Rename Debug Macro. Signed-off-by: Souza, Fillipe --- he_qat/he_qat_utils.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/he_qat/he_qat_utils.c b/he_qat/he_qat_utils.c index 2677e1b..d16475d 100644 --- a/he_qat/he_qat_utils.c +++ b/he_qat/he_qat_utils.c @@ -5,7 +5,8 @@ BIGNUM* generateTestBNData(int nbits) { if (!RAND_status()) return NULL; -#ifdef _DESTINY_DEBUG_VERBOSE + +#ifdef HE_QAT_DEBUG printf("PRNG properly seeded.\n"); #endif @@ -34,9 +35,10 @@ unsigned char* paddingZeros(BIGNUM* bn, int nbits) { int len = bytes_left + num_bytes; if (!(bin = (unsigned char*)OPENSSL_zalloc(len))) return NULL; -#ifdef _DESTINY_DEBUG_VERBOSE - printf("Padding bn with %d bytes to total %d bytes\n", bytes_left, len); +#ifdef HE_QAT_DEBUG + PRINT("Padding bn with %d bytes to total %d bytes\n", bytes_left, len); #endif + BN_bn2binpad(bn, bin, len); if (ERR_get_error()) { OPENSSL_free(bin); From 6a254b5bc9eea825e59ccd25fd8a8725566ddb2c Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Mon, 17 Oct 2022 16:10:05 -0700 Subject: [PATCH 282/364] Refactor to HE_QAT_PRINT_DBG and PRINT. Signed-off-by: Souza, Fillipe --- he_qat/he_qat_utils.c | 1 + he_qat/include/he_qat_utils.h | 6 ++++++ include/cpa_sample_utils.h | 13 +++++++++++++ samples/CMakeLists.txt | 3 +-- samples/test_BIGNUMModExp.c | 34 ++++++++++++---------------------- samples/test_bnConversion.cpp | 18 ++++++++---------- 6 files changed, 41 insertions(+), 34 deletions(-) diff --git a/he_qat/he_qat_utils.c b/he_qat/he_qat_utils.c index d16475d..1d4e2d6 100644 --- a/he_qat/he_qat_utils.c +++ b/he_qat/he_qat_utils.c @@ -1,3 +1,4 @@ +#include "cpa_sample_utils.h" #include "he_qat_utils.h" #include diff --git a/he_qat/include/he_qat_utils.h b/he_qat/include/he_qat_utils.h index ce43fb0..f0dcd6b 100644 --- a/he_qat/include/he_qat_utils.h +++ b/he_qat/include/he_qat_utils.h @@ -1,3 +1,6 @@ +///< @file he_qat_utils.h + +#pragma once #ifndef HE_QAT_UTILS_H_ #define HE_QAT_UTILS_H_ @@ -9,8 +12,11 @@ extern "C" { #include BIGNUM* generateTestBNData(int nbits); + unsigned char* paddingZeros(BIGNUM* bn, int nbits); + void showHexBN(BIGNUM* bn, int nbits); + void showHexBin(unsigned char* bin, int len); #ifdef __cplusplus diff --git a/include/cpa_sample_utils.h b/include/cpa_sample_utils.h index 56a206f..a128640 100644 --- a/include/cpa_sample_utils.h +++ b/include/cpa_sample_utils.h @@ -121,6 +121,19 @@ typedef pthread_t sampleThread; (CPA_CY_API_VERSION_NUM_MAJOR == major && \ CPA_CY_API_VERSION_NUM_MINOR >= minor)) +#ifdef HE_QAT_DEBUG +#define HE_QAT_PRINT_DBG(args...) \ + do \ + { \ + { \ + printf("%s(): ", __func__); \ + printf(args); \ + fflush(stdout); \ + } \ + } while (0) +#else +#define HE_QAT_PRINT_DBG(args...) { } +#endif /* Printing */ /**< Prints the name of the function and the arguments only if gDebugParam is * CPA_TRUE. diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 2a62889..8d459eb 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -1,6 +1,6 @@ if(HE_QAT_DEBUG) - add_definitions(-D_DESTINY_DEBUG_VERBOSE) + add_definitions(-DHE_QAT_DEBUG) endif() # ------------------------------------------------------------------------------------------- @@ -25,7 +25,6 @@ target_include_directories(test_BIGNUMModExp PUBLIC ${ICP_INC_DIR}) target_link_libraries(test_BIGNUMModExp PUBLIC he_qat) target_link_libraries(test_BIGNUMModExp PUBLIC OpenSSL::SSL) # OpenSSL::Crypto) -#target_link_libraries(test_BIGNUMModExp PUBLIC IPPCP::ippcp) install(TARGETS test_BIGNUMModExp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/samples/test_BIGNUMModExp.c b/samples/test_BIGNUMModExp.c index 9a91a98..b74f36c 100644 --- a/samples/test_BIGNUMModExp.c +++ b/samples/test_BIGNUMModExp.c @@ -13,7 +13,7 @@ struct timeval start_time, end_time; double time_taken = 0.0; -int gDebugParam = 1; // Active in Debug mode +//int gDebugParam = 1; // Active in Debug mode const unsigned int BATCH_SIZE = 1; int main(int argc, const char** argv) { @@ -41,10 +41,9 @@ int main(int argc, const char** argv) { if (!bn_mod) continue; -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG char* bn_str = BN_bn2hex(bn_mod); - printf("Generated modulus: %s num_bytes: %d num_bits: %d\n", bn_str, - BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); + PRINT("Generated modulus: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); OPENSSL_free(bn_str); #endif // bn_exponent in [0..bn_mod] @@ -69,20 +68,16 @@ int main(int argc, const char** argv) { ssl_elapsed = time_taken; if (!ERR_get_error()) { -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG bn_str = BN_bn2hex(ssl_res); - printf("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", bn_str, - BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); + PRINT("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); showHexBN(ssl_res, bit_length); OPENSSL_free(bn_str); #endif } else { - printf("Modular exponentiation failed.\n"); + HE_QAT_PRINT_DBG("Modular exponentiation failed.\n"); } - -#ifdef _DESTINY_DEBUG_VERBOSE - PRINT_DBG("\nStarting QAT bnModExp...\n"); -#endif + HE_QAT_PRINT_DBG("\nStarting QAT bnModExp...\n"); // Perform QAT ModExp Op BIGNUM* qat_res = BN_new(); @@ -106,23 +101,18 @@ int main(int argc, const char** argv) { (mod * avg_speed_up + (ssl_elapsed) / (qat_elapsed/BATCH_SIZE)) / (mod + 1); - printf( - "Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", - (mod + 1), ssl_avg_time, qat_avg_time, avg_speed_up); + PRINT("Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", (mod + 1), ssl_avg_time, qat_avg_time, avg_speed_up); if (HE_QAT_STATUS_SUCCESS != status) { PRINT_ERR("\nQAT bnModExpOp failed\n"); + } else { + HE_QAT_PRINT_DBG("\nQAT bnModExpOp finished\n"); } -#ifdef _DESTINY_DEBUG_VERBOSE - else { - PRINT_DBG("\nQAT bnModExpOp finished\n"); - } -#endif if (BN_cmp(qat_res, ssl_res) != 0) - printf("\t** FAIL **\n"); + PRINT("\t** FAIL **\n"); else - printf("\t** PASS **\n"); + PRINT("\t** PASS **\n"); BN_free(ssl_res); BN_free(qat_res); diff --git a/samples/test_bnConversion.cpp b/samples/test_bnConversion.cpp index 2e51b30..ee5490d 100644 --- a/samples/test_bnConversion.cpp +++ b/samples/test_bnConversion.cpp @@ -34,8 +34,7 @@ int main(int argc, const char** argv) { if (!bn_mod) continue; char* bn_str = BN_bn2hex(bn_mod); - printf("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, - BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); + PRINT("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); OPENSSL_free(bn_str); int len_ = (bit_length + 7) >> 3; @@ -52,7 +51,7 @@ int main(int argc, const char** argv) { gettimeofday(&start_time, NULL); status = binToBigNumber(big_num, bn_mod_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { - printf("Failed at binToBigNumber()\n"); + PRINT("Failed at binToBigNumber()\n"); exit(1); } gettimeofday(&end_time, NULL); @@ -60,14 +59,14 @@ int main(int argc, const char** argv) { time_taken = (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; ssl_elapsed = time_taken; - printf("Conversion to BigNumber has completed in %.1lfus.\n", + PRINT("Conversion to BigNumber has completed in %.1lfus.\n", (ssl_elapsed)); int bit_len = 0; ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); std::string str; big_num.num2hex(str); - printf("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, + PRINT("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, bit_len); gettimeofday(&start_time, NULL); @@ -76,7 +75,7 @@ int main(int argc, const char** argv) { if (NULL == ref_bn_data_) exit(1); status = bigNumberToBin(ref_bn_data_, bit_length, big_num); if (HE_QAT_STATUS_SUCCESS != status) { - printf("Failed at bigNumberToBin()\n"); + PRINT("Failed at bigNumberToBin()\n"); exit(1); } gettimeofday(&end_time, NULL); @@ -84,15 +83,14 @@ int main(int argc, const char** argv) { time_taken = (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; qat_elapsed = time_taken; - printf("Conversion from BigNumber has completed %.1lfus.\n", + PRINT("Conversion from BigNumber has completed %.1lfus.\n", (qat_elapsed)); BIGNUM* ref_bin_ = BN_new(); BN_bin2bn(ref_bn_data_, len_, ref_bin_); bn_str = BN_bn2hex(ref_bin_); - printf("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, - BN_num_bytes(ref_bin_), BN_num_bits(ref_bin_)); - printf("-----------------------\n"); + PRINT("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, BN_num_bytes(ref_bin_), BN_num_bits(ref_bin_)); + PRINT("-----------------------\n"); OPENSSL_free(bn_str); free(bn_mod_data_); From b51163e17232c4fed3a6835f811ac3aaa815d227 Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Tue, 18 Oct 2022 11:06:00 +0800 Subject: [PATCH 283/364] Add a wrapper function: modExp (#133) --- ipcl/ciphertext.cpp | 4 ++-- ipcl/include/ipcl/mod_exp.hpp | 36 +++++++++++++++++++++++++++++++++-- ipcl/mod_exp.cpp | 28 +++++++++++++++++++++++++-- ipcl/pri_key.cpp | 11 +++++------ ipcl/pub_key.cpp | 6 +++--- 5 files changed, 70 insertions(+), 15 deletions(-) diff --git a/ipcl/ciphertext.cpp b/ipcl/ciphertext.cpp index 685b264..efcdc66 100644 --- a/ipcl/ciphertext.cpp +++ b/ipcl/ciphertext.cpp @@ -142,14 +142,14 @@ BigNumber CipherText::raw_add(const BigNumber& a, const BigNumber& b) const { BigNumber CipherText::raw_mul(const BigNumber& a, const BigNumber& b) const { const BigNumber& sq = m_pubkey->getNSQ(); - return ipcl::ippModExp(a, b, sq); + return modExp(a, b, sq); } std::vector CipherText::raw_mul( const std::vector& a, const std::vector& b) const { std::size_t v_size = a.size(); std::vector sq(v_size, m_pubkey->getNSQ()); - return ipcl::ippModExp(a, b, sq); + return modExp(a, b, sq); } } // namespace ipcl diff --git a/ipcl/include/ipcl/mod_exp.hpp b/ipcl/include/ipcl/mod_exp.hpp index 0419e60..cf081e7 100644 --- a/ipcl/include/ipcl/mod_exp.hpp +++ b/ipcl/include/ipcl/mod_exp.hpp @@ -9,8 +9,29 @@ #include "ipcl/bignum.h" namespace ipcl { + +/** + * Modular exponentiation for multi BigNumber + * @param[in] base base of the exponentiation + * @param[in] exp pow of the exponentiation + * @param[in] mod modular + * @return the modular exponentiation result of type BigNumber + */ +std::vector modExp(const std::vector& base, + const std::vector& exp, + const std::vector& mod); /** - * Modular exponentiation for multi buffer + * Modular exponentiation for single BigNumber + * @param[in] base base of the exponentiation + * @param[in] exp pow of the exponentiation + * @param[in] mod modular + * @return the modular exponentiation result of type BigNumber + */ +BigNumber modExp(const BigNumber& base, const BigNumber& exp, + const BigNumber& mod); + +/** + * IPP modular exponentiation for multi buffer * @param[in] base base of the exponentiation * @param[in] exp pow of the exponentiation * @param[in] mod modular @@ -21,7 +42,7 @@ std::vector ippModExp(const std::vector& base, const std::vector& mod); /** - * Modular exponentiation for single buffer + * IPP modular exponentiation for single buffer * @param[in] base base of the exponentiation * @param[in] exp pow of the exponentiation * @param[in] mod modular @@ -30,5 +51,16 @@ std::vector ippModExp(const std::vector& base, BigNumber ippModExp(const BigNumber& base, const BigNumber& exp, const BigNumber& mod); +/** + * QAT modular exponentiation for multi BigNumber + * @param[in] base base of the exponentiation + * @param[in] exp pow of the exponentiation + * @param[in] mod modular + * @return the modular exponentiation result of type BigNumber + */ +std::vector qatModExp(const std::vector& base, + const std::vector& exp, + const std::vector& mod); + } // namespace ipcl #endif // IPCL_INCLUDE_IPCL_MOD_EXP_HPP_ diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index b628ee4..e1f68db 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -595,17 +595,25 @@ static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& exp, return res; } -std::vector ippModExp(const std::vector& base, +std::vector qatModExp(const std::vector& base, const std::vector& exp, const std::vector& mod) { #ifdef IPCL_USE_QAT // TODO(fdiasmor): Slice with custom batches, test OMP std::size_t worksize = base.size(); std::vector remainder(worksize); - // remainder = heQatBnModExp(base, pow, m); + + // remainder = heQatBnModExp(base, exp, mod); remainder = heQatBnModExp(base, exp, mod, 1024); return remainder; #else + ERROR_CHECK(false, "qatModExp: Need to turn on IPCL_ENABLE_QAT"); +#endif // IPCL_USE_QAT +} + +std::vector ippModExp(const std::vector& base, + const std::vector& exp, + const std::vector& mod) { std::size_t v_size = base.size(); std::vector res(v_size); @@ -719,11 +727,27 @@ std::vector ippModExp(const std::vector& base, #endif // IPCL_CRYPTO_MB_MOD_EXP #endif // IPCL_RUNTIME_MOD_EXP +} + +std::vector modExp(const std::vector& base, + const std::vector& exp, + const std::vector& mod) { +#ifdef IPCL_USE_QAT + return qatModExp(base, exp, mod); +#else + return ippModExp(base, exp, mod); #endif // IPCL_USE_QAT } +BigNumber modExp(const BigNumber& base, const BigNumber& exp, + const BigNumber& mod) { + // QAT mod exp is NOT needed, when there is only 1 BigNumber. + return ippModExp(base, exp, mod); +} + BigNumber ippModExp(const BigNumber& base, const BigNumber& exp, const BigNumber& mod) { + // IPP multi buffer mod exp is NOT needed, when there is only 1 BigNumber. return ippSBModExp(base, exp, mod); } diff --git a/ipcl/pri_key.cpp b/ipcl/pri_key.cpp index 060e858..9a781fd 100644 --- a/ipcl/pri_key.cpp +++ b/ipcl/pri_key.cpp @@ -43,8 +43,7 @@ PrivateKey::PrivateKey(const PublicKey* public_key, const BigNumber& p, m_lambda(lcm(m_pminusone, m_qminusone)), // TODO(bwang30): check if ippsModInv_BN does the same thing with // mpz_invert - m_x(m_n.InverseMul((ipcl::ippModExp(m_g, m_lambda, m_nsquare) - 1) / - m_n)), + m_x(m_n.InverseMul((modExp(m_g, m_lambda, m_nsquare) - 1) / m_n)), m_bits(m_pubkey->getBits()), m_dwords(m_pubkey->getDwords()), m_enable_crt(true) { @@ -77,7 +76,7 @@ void PrivateKey::decryptRAW(std::vector& plaintext, std::vector pow_lambda(v_size, m_lambda); std::vector modulo(v_size, m_nsquare); - std::vector res = ipcl::ippModExp(ciphertext, pow_lambda, modulo); + std::vector res = modExp(ciphertext, pow_lambda, modulo); #ifdef IPCL_USE_OMP int omp_remaining_threads = OMPUtilities::MaxThreads; @@ -112,8 +111,8 @@ void PrivateKey::decryptCRT(std::vector& plaintext, } // Based on the fact a^b mod n = (a mod n)^b mod n - std::vector resp = ipcl::ippModExp(basep, pm1, psq); - std::vector resq = ipcl::ippModExp(baseq, qm1, qsq); + std::vector resp = modExp(basep, pm1, psq); + std::vector resq = modExp(baseq, qm1, qsq); #ifdef IPCL_USE_OMP omp_remaining_threads = OMPUtilities::MaxThreads; @@ -143,7 +142,7 @@ BigNumber PrivateKey::computeHfun(const BigNumber& a, // Based on the fact a^b mod n = (a mod n)^b mod n BigNumber xm = a - 1; BigNumber base = m_g % b; - BigNumber pm = ipcl::ippModExp(base, xm, b); + BigNumber pm = modExp(base, xm, b); BigNumber lcrt = computeLfun(pm, a); return a.InverseMul(lcrt); } diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index 01f8124..8e1a73c 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -48,7 +48,7 @@ void PublicKey::enableDJN() { BigNumber rmod_sq = rmod * rmod; BigNumber rmod_neg = rmod_sq * -1; BigNumber h = rmod_neg % m_n; - m_hs = ipcl::ippModExp(h, m_n, m_nsquare); + m_hs = modExp(h, m_n, m_nsquare); m_randbits = m_bits >> 1; // bits/2 m_enable_DJN = true; @@ -66,7 +66,7 @@ std::vector PublicKey::getDJNObfuscator(std::size_t sz) const { r_ = getRandomBN(m_randbits); } } - return ipcl::ippModExp(base, r, sq); + return modExp(base, r, sq); } std::vector PublicKey::getNormalObfuscator(std::size_t sz) const { @@ -82,7 +82,7 @@ std::vector PublicKey::getNormalObfuscator(std::size_t sz) const { r[i] = r[i] % (m_n - 1) + 1; } } - return ipcl::ippModExp(r, pown, sq); + return modExp(r, pown, sq); } void PublicKey::applyObfuscator(std::vector& ciphertext) const { From 5f1f4970ee69af6b3c42d214f4fee3aab6cae025 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 18 Oct 2022 12:31:49 -0700 Subject: [PATCH 284/364] Refactoring include directories. Signed-off-by: Souza, Fillipe --- CMakeLists.txt | 22 +- README.md | 22 +- common/CMakeLists.txt | 43 -- {he_qat => heqat}/CMakeLists.txt | 69 +- he_qat/he_qat_ops.c => heqat/bnops.c | 13 +- he_qat/he_qat_cb.c => heqat/cb.c | 6 +- heqat/common/CMakeLists.txt | 43 ++ {common => heqat/common}/cpa_sample_utils.c | 2 +- he_qat/he_qat_utils.c => heqat/common/utils.c | 4 +- he_qat/he_qat_context.c => heqat/context.c | 11 +- he_qat/he_qat_ctrl.c => heqat/ctrl.c | 10 +- .../include/heqat/bnops.h | 3 +- heqat/include/heqat/common.h | 13 + .../include/heqat/common/consts.h | 2 +- heqat/include/heqat/common/cpa_sample_utils.h | 651 ++++++++++++++++++ .../include/heqat/common/types.h | 7 +- .../include/heqat/common/utils.h | 2 +- .../include/heqat/context.h | 2 +- heqat/include/heqat/heqat.h | 7 + .../include/heqat/misc.h | 15 +- {misc => heqat/include/heqat/misc}/bignum.h | 0 {misc => heqat/include/heqat/misc}/utils.h | 0 heqat/misc/CMakeLists.txt | 59 ++ {misc => heqat/misc}/bignum.cpp | 6 +- misc/he_qat_misc.cpp => heqat/misc/misc.cpp | 11 +- {misc => heqat/misc}/utils.cpp | 2 +- icp/CMakeLists.txt | 4 +- misc/CMakeLists.txt | 51 -- samples/CMakeLists.txt | 116 ++-- samples/test_BIGNUMModExp.c | 6 +- samples/test_bnConversion.cpp | 5 +- samples/test_bnModExp.cpp | 18 +- samples/test_bnModExp_MT.cpp | 95 +-- samples/test_context.c | 4 +- scripts/run.sh | 2 +- 35 files changed, 983 insertions(+), 343 deletions(-) delete mode 100644 common/CMakeLists.txt rename {he_qat => heqat}/CMakeLists.txt (59%) rename he_qat/he_qat_ops.c => heqat/bnops.c (99%) rename he_qat/he_qat_cb.c => heqat/cb.c (98%) create mode 100644 heqat/common/CMakeLists.txt rename {common => heqat/common}/cpa_sample_utils.c (99%) rename he_qat/he_qat_utils.c => heqat/common/utils.c (95%) rename he_qat/he_qat_context.c => heqat/context.c (99%) rename he_qat/he_qat_ctrl.c => heqat/ctrl.c (99%) rename he_qat/include/he_qat_bn_ops.h => heqat/include/heqat/bnops.h (99%) create mode 100644 heqat/include/heqat/common.h rename he_qat/include/he_qat_gconst.h => heqat/include/heqat/common/consts.h (91%) create mode 100644 heqat/include/heqat/common/cpa_sample_utils.h rename he_qat/include/he_qat_types.h => heqat/include/heqat/common/types.h (98%) rename he_qat/include/he_qat_utils.h => heqat/include/heqat/common/utils.h (92%) rename he_qat/include/he_qat_context.h => heqat/include/heqat/context.h (94%) create mode 100644 heqat/include/heqat/heqat.h rename misc/he_qat_misc.h => heqat/include/heqat/misc.h (86%) rename {misc => heqat/include/heqat/misc}/bignum.h (100%) rename {misc => heqat/include/heqat/misc}/utils.h (100%) create mode 100644 heqat/misc/CMakeLists.txt rename {misc => heqat/misc}/bignum.cpp (99%) rename misc/he_qat_misc.cpp => heqat/misc/misc.cpp (89%) rename {misc => heqat/misc}/utils.cpp (97%) delete mode 100644 misc/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 9cb6694..92dc855 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.13) # The hekat or heqat (transcribed HqA.t) was an ancient Egyptian volume unit # used to measure grain, bread, and beer. -project(HE_QAT VERSION 0.1.0 LANGUAGES C CXX) +project(HE_QAT VERSION 1.2.1 LANGUAGES C CXX) include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) @@ -76,11 +76,15 @@ else() set(HE_QAT_DEBUG OFF) endif() +if(HE_QAT_MISC) + add_definitions(-DHE_QAT_MISC) +endif() + # Why? set(HE_QAT_CMAKE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/he_qat") set(HE_QAT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) -set(HE_QAT_SRC_DIR ${HE_QAT_ROOT_DIR}/he_qat) -set(HE_QAT_INC_DIR ${HE_QAT_ROOT_DIR}/he_qat/include) +set(HE_QAT_SRC_DIR ${HE_QAT_ROOT_DIR}/heqat) +set(HE_QAT_INC_DIR ${HE_QAT_ROOT_DIR}/heqat/include) if(HE_QAT_OMP) find_package(OpenMP REQUIRED) @@ -153,7 +157,7 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/he_qat) include(heqat-util) -set(COMMON_INC_DIR ${CMAKE_CURRENT_LIST_DIR}/include) +#set(COMMON_INC_DIR ${CMAKE_CURRENT_LIST_DIR}/include) if(NOT CMAKE_INSTALL_PREFIX) set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_LIST_DIR}/install) endif() @@ -162,15 +166,15 @@ endif() include(icp/CMakeLists.txt) #Common utility functions -add_subdirectory(common) +#add_subdirectory(common) # Helper functions for BigNumber -if(HE_QAT_MISC) - add_subdirectory(misc) -endif() +#if(HE_QAT_MISC) +# add_subdirectory(misc) +#endif() # HE_QAT Library -add_subdirectory(he_qat) +add_subdirectory(heqat) if(HE_QAT_TEST) include(cmake/gtest.cmake) diff --git a/README.md b/README.md index c8f7050..b50cfd5 100644 --- a/README.md +++ b/README.md @@ -225,13 +225,13 @@ In addition to the standard CMake configuration options, Intel HE Acceleration L Test showing creation and teardown of the QAT runtime environment: ``` -./build/samples/test_context +./build/samples/sample_context ``` -Test showing functional correctness and performance: +Test showing functional correctness and performance using BIGNUM data as input: ``` -./build/samples/test_bnModExpPerformOp +./build/samples/sample_BIGNUMModExp ``` If built with `HE_QAT_MISC=ON`, then the following samples below are also available to try. @@ -239,14 +239,26 @@ If built with `HE_QAT_MISC=ON`, then the following samples below are also availa Test showing data conversion between `BigNumber` and `CpaFlatBuffer` formats: ``` -./build/samples/test_bnConversion +./build/samples/sample_bnConversion ``` Test showing functional correctness and performance using `BigNumber` data types: ``` -./build/samples/test_bnModExp +./build/samples/sample_bnModExp ``` + +Test showing functional correctness and performance of multithreading support: + +``` +./build/samples/sample_bnModExp_MT +``` +#### Running All Samples + +``` +HEQATLIB_ROOT_DIR=$PWD ./scripts/run.sh +``` + ## Troubleshooting - **Issue #1** diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt deleted file mode 100644 index eb0ed9b..0000000 --- a/common/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -# Include directories -#list(APPEND COMMON_INC_DIR -# ${ICP_API_DIR}/include/dc -# ${ICP_API_DIR}/include/lac -#) -message(STATUS "COMMON_INC_DIR: ${COMMON_INC_DIR}") -message(STATUS "ICP_INC_DIR: ${ICP_INC_DIR}") - -# Source files -set(COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/cpa_sample_utils.c) - -if(HE_QAT_SHARED) - add_library(cpa_sample_utils SHARED ${COMMON_SRC}) -else() - add_library(cpa_sample_utils STATIC ${COMMON_SRC}) -endif() - -target_include_directories(cpa_sample_utils - PRIVATE $ # Public headers - PRIVATE $ # Public headers - PUBLIC $ # Public headers - PRIVATE ${COMMON_INC_DIR} # Private headers - PRIVATE ${ICP_INC_DIR} # Private headers -) - -target_link_libraries(cpa_sample_utils PRIVATE udev z) - -if(HE_QAT_SHARED) - target_link_libraries(cpa_sample_utils PRIVATE ${ICP_BUILDOUTPUT_PATH}/libqat_s.so) - target_link_libraries(cpa_sample_utils PRIVATE ${ICP_BUILDOUTPUT_PATH}/libusdm_drv_s.so) -else() - heqat_create_archive(cpa_sample_utils libadf_static) - heqat_create_archive(cpa_sample_utils libosal_static) - heqat_create_archive(cpa_sample_utils libqat_static) - heqat_create_archive(cpa_sample_utils libusdm_drv_static) -endif() - -#install(TARGETS cpa_sample_utils DESTINATION ${CMAKE_INSTALL_LIBDIR}) -install(TARGETS cpa_sample_utils EXPORT he_qatTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}) - -set(COMMON_INC_DIR ${COMMON_INC_DIR} PARENT_SCOPE) - - diff --git a/he_qat/CMakeLists.txt b/heqat/CMakeLists.txt similarity index 59% rename from he_qat/CMakeLists.txt rename to heqat/CMakeLists.txt index f6a8e76..3b6e8b8 100644 --- a/he_qat/CMakeLists.txt +++ b/heqat/CMakeLists.txt @@ -1,34 +1,30 @@ -set(HE_QAT_SRC ${HE_QAT_SRC_DIR}/he_qat_cb.c - ${HE_QAT_SRC_DIR}/he_qat_context.c - ${HE_QAT_SRC_DIR}/he_qat_utils.c +set(HE_QAT_SRC ${HE_QAT_SRC_DIR}/cb.c + ${HE_QAT_SRC_DIR}/context.c + ${HE_QAT_SRC_DIR}/ctrl.c + ${HE_QAT_SRC_DIR}/bnops.c ) -list(APPEND HE_QAT_SRC ${HE_QAT_SRC_DIR}/he_qat_ops.c - ${HE_QAT_SRC_DIR}/he_qat_ctrl.c) +add_subdirectory(common) + +if(HE_QAT_MISC) + add_subdirectory(misc) +endif() if(HE_QAT_SHARED) - add_library(he_qat SHARED ${HE_QAT_SRC}) + add_library(he_qat SHARED ${HE_QAT_SRC}) else() - add_library(he_qat STATIC ${HE_QAT_SRC}) + add_library(he_qat STATIC ${HE_QAT_SRC}) endif() add_library(HE_QAT::he_qat ALIAS he_qat) target_include_directories(he_qat - PUBLIC $ #Public headers PUBLIC $ #Public headers PUBLIC $ #Public headers - PRIVATE ${COMMON_INC_DIR} #Private headers PRIVATE ${ICP_INC_DIR} #Private headers ) -install(DIRECTORY ${COMMON_INC_DIR}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ - FILES_MATCHING - PATTERN "*.hpp" - PATTERN "*.h") - install(DIRECTORY ${HE_QAT_INC_DIR}/ DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ FILES_MATCHING @@ -36,30 +32,43 @@ install(DIRECTORY ${HE_QAT_INC_DIR}/ PATTERN "*.h") target_link_directories(he_qat PUBLIC ${ICP_BUILDOUTPUT_PATH}) -target_link_libraries(he_qat PRIVATE OpenSSL::SSL Threads::Threads) -target_link_libraries(he_qat PRIVATE udev z) - -if(HE_QAT_MISC) - target_link_libraries(he_qat PRIVATE he_qat_misc) -endif() +target_link_libraries(he_qat PRIVATE udev z) +target_link_libraries(he_qat PRIVATE OpenSSL::SSL) +target_link_libraries(he_qat PRIVATE Threads::Threads) if(HE_QAT_SHARED) - target_link_libraries(he_qat PRIVATE qat_s usdm_drv_s) - target_link_libraries(he_qat PRIVATE cpa_sample_utils) + target_link_libraries(he_qat PRIVATE qat_s) + target_link_libraries(he_qat PRIVATE usdm_drv_s) else() - heqat_create_archive(he_qat cpa_sample_utils) + heqat_create_archive(he_qat OpenSSL::SSL) + heqat_create_archive(he_qat Threads::Threads) + heqat_create_archive(he_qat libadf_static) + heqat_create_archive(he_qat libosal_static) + heqat_create_archive(he_qat libqat_static) + heqat_create_archive(he_qat libusdm_drv_static) +endif() + +if(HE_QAT_MISC) + target_include_directories(he_qat PRIVATE ${IPPCP_DIR}/../../../include) + target_link_directories(he_qat PUBLIC ${IPPCP_DIR}/lib/intel64) + if(HE_QAT_SHARED) + target_link_libraries(he_qat PRIVATE IPPCP::ippcp) + # target_link_libraries(he_qat PRIVATE IPPCP::crypto_mb) + else() + heqat_create_archive (he_qat IPPCP::ippcp) + # heqat_create_archive (he_qat IPPCP::crypto_mb) + endif() endif() set_target_properties(he_qat PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(he_qat PROPERTIES VERSION ${HE_QAT_VERSION}) if(HE_QAT_DEBUG) - set_target_properties(he_qat PROPERTIES OUTPUT_NAME "he_qat_debug") + set_target_properties(he_qat PROPERTIES OUTPUT_NAME "he_qat_debug") else() - set_target_properties(he_qat PROPERTIES OUTPUT_NAME "he_qat") + set_target_properties(he_qat PROPERTIES OUTPUT_NAME "he_qat") endif() - install(TARGETS he_qat DESTINATION ${CMAKE_INSTALL_LIBDIR}) include(CMakePackageConfigHelpers) @@ -78,9 +87,9 @@ install( ) write_basic_package_version_file( - ${HE_QAT_CONFIG_VERSION_FILENAME} - VERSION ${HE_QAT_VERSION} - COMPATIBILITY ExactVersion + ${HE_QAT_CONFIG_VERSION_FILENAME} + VERSION ${HE_QAT_VERSION} + COMPATIBILITY ExactVersion ) configure_package_config_file( diff --git a/he_qat/he_qat_ops.c b/heqat/bnops.c similarity index 99% rename from he_qat/he_qat_ops.c rename to heqat/bnops.c index ba8d942..f0abb67 100644 --- a/he_qat/he_qat_ops.c +++ b/heqat/bnops.c @@ -1,14 +1,14 @@ -/// @file he_qat_ops.c +/// @file heqat/bnops.c #include "cpa.h" #include "cpa_cy_im.h" #include "cpa_cy_ln.h" #include "icp_sal_poll.h" -#include "cpa_sample_utils.h" - -#include "he_qat_types.h" -#include "he_qat_bn_ops.h" +#include "heqat/common/cpa_sample_utils.h" +#include "heqat/common/consts.h" +#include "heqat/common/types.h" +#include "heqat/bnops.h" #ifdef HE_QAT_PERF #include @@ -25,8 +25,6 @@ #pragma message "Asynchronous execution mode." #endif -#include "he_qat_gconst.h" - // Global buffer for the runtime environment extern HE_QAT_RequestBuffer he_qat_buffer; extern HE_QAT_OutstandingBuffer outstanding; @@ -40,7 +38,6 @@ extern void HE_QAT_bnModExpCallback(void* pCallbackTag, CpaStatus status, void* /// This function is implemented in he_qat_ctrl.c. extern void submit_request(HE_QAT_RequestBuffer* _buffer, void* args); - /* * ************************************************************************** * Implementation of Functions for the Single Interface Support diff --git a/he_qat/he_qat_cb.c b/heqat/cb.c similarity index 98% rename from he_qat/he_qat_cb.c rename to heqat/cb.c index 80bae5e..5e2db31 100644 --- a/he_qat/he_qat_cb.c +++ b/heqat/cb.c @@ -1,15 +1,15 @@ -/// @file he_qat_cb.c +/// @file heqat/cb.c // QAT-API headers #include -#include // C support libraries #include #include // Local headers -#include "he_qat_types.h" +#include "heqat/common/cpa_sample_utils.h" +#include "heqat/common/types.h" // Global variables static pthread_mutex_t response_mutex; ///< It protects against race condition on response_count due to concurrent callback events. diff --git a/heqat/common/CMakeLists.txt b/heqat/common/CMakeLists.txt new file mode 100644 index 0000000..f1d5612 --- /dev/null +++ b/heqat/common/CMakeLists.txt @@ -0,0 +1,43 @@ +# Include directories +set(COMMON_INC_DIR ${HE_QAT_INC_DIR}) +message(STATUS "COMMON_INC_DIR: ${COMMON_INC_DIR}") +message(STATUS "ICP_INC_DIR: ${ICP_INC_DIR}") + +# Source files +set(COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/cpa_sample_utils.c + ${CMAKE_CURRENT_LIST_DIR}/utils.c) +list(APPEND HE_QAT_SRC ${COMMON_SRC}) + +set(HE_QAT_SRC ${HE_QAT_SRC} PARENT_SCOPE) + +#if(HE_QAT_SHARED) +# add_library(heqat_common SHARED ${COMMON_SRC}) +#else() +# add_library(heqat_common STATIC ${COMMON_SRC}) +#endif() +# +#target_include_directories(heqat_common +# PRIVATE $ # Public headers +# PRIVATE $ # Public headers +# PUBLIC $ # Public headers +# PRIVATE ${COMMON_INC_DIR} # Private headers +# PRIVATE ${ICP_INC_DIR} # Private headers +#) +# +#target_link_libraries(heqat_common PRIVATE udev z) +# +#if(HE_QAT_SHARED) +# target_link_libraries(heqat_common PRIVATE ${ICP_BUILDOUTPUT_PATH}/libqat_s.so) +# target_link_libraries(heqat_common PRIVATE ${ICP_BUILDOUTPUT_PATH}/libusdm_drv_s.so) +#else() +# heqat_create_archive(heqat_common libadf_static) +# heqat_create_archive(heqat_common libosal_static) +# heqat_create_archive(heqat_common libqat_static) +# heqat_create_archive(heqat_common libusdm_drv_static) +#endif() +# +#install(TARGETS heqat_common EXPORT he_qatTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}) +# +#set(COMMON_INC_DIR ${COMMON_INC_DIR} PARENT_SCOPE) + + diff --git a/common/cpa_sample_utils.c b/heqat/common/cpa_sample_utils.c similarity index 99% rename from common/cpa_sample_utils.c rename to heqat/common/cpa_sample_utils.c index 5949134..53551e3 100644 --- a/common/cpa_sample_utils.c +++ b/heqat/common/cpa_sample_utils.c @@ -72,7 +72,7 @@ * ***************************************************************************/ -#include "cpa_sample_utils.h" +#include "heqat/common/cpa_sample_utils.h" #include "cpa_dc.h" #include "icp_sal_poll.h" diff --git a/he_qat/he_qat_utils.c b/heqat/common/utils.c similarity index 95% rename from he_qat/he_qat_utils.c rename to heqat/common/utils.c index 1d4e2d6..8d1aa0d 100644 --- a/he_qat/he_qat_utils.c +++ b/heqat/common/utils.c @@ -1,5 +1,5 @@ -#include "cpa_sample_utils.h" -#include "he_qat_utils.h" +#include "heqat/common/cpa_sample_utils.h" +#include "heqat/common/utils.h" #include #include diff --git a/he_qat/he_qat_context.c b/heqat/context.c similarity index 99% rename from he_qat/he_qat_context.c rename to heqat/context.c index d740e30..6f0e9b8 100644 --- a/he_qat/he_qat_context.c +++ b/heqat/context.c @@ -2,16 +2,16 @@ #define _GNU_SOURCE -#include "he_qat_types.h" -#include "he_qat_context.h" +#include "icp_sal_user.h" +#include "icp_sal_poll.h" #include #include #include -#include "cpa_sample_utils.h" -#include "icp_sal_user.h" -#include "icp_sal_poll.h" +#include "heqat/common/cpa_sample_utils.h" +#include "heqat/common/types.h" +#include "heqat/context.h" #ifdef USER_SPACE #define MAX_INSTANCES 1024 @@ -57,7 +57,6 @@ static CpaInstanceHandle get_qat_instance() { CpaInstanceInfo2 info = {0}; if (0 == numInstances) { - //*pCyInstHandle = NULL; status = cpaCyGetNumInstances(&numInstances); if (numInstances >= MAX_INSTANCES) { numInstances = MAX_INSTANCES; diff --git a/he_qat/he_qat_ctrl.c b/heqat/ctrl.c similarity index 99% rename from he_qat/he_qat_ctrl.c rename to heqat/ctrl.c index 8a95aa6..3f0e45b 100644 --- a/he_qat/he_qat_ctrl.c +++ b/heqat/ctrl.c @@ -1,4 +1,4 @@ -/// @file he_qat_ctrl.c +/// @file heqat/ctrl.c // QAT-API headers #include "cpa.h" @@ -20,10 +20,10 @@ double time_taken = 0.0; #include #include -// Loca headers -#include "he_qat_types.h" -#include "he_qat_bn_ops.h" -#include "he_qat_gconst.h" +// Local headers +#include "heqat/common/consts.h" +#include "heqat/common/types.h" +#include "heqat/bnops.h" // Warn user on selected execution mode #ifdef HE_QAT_SYNC_MODE diff --git a/he_qat/include/he_qat_bn_ops.h b/heqat/include/heqat/bnops.h similarity index 99% rename from he_qat/include/he_qat_bn_ops.h rename to heqat/include/heqat/bnops.h index 11c2259..87c8991 100644 --- a/he_qat/include/he_qat_bn_ops.h +++ b/heqat/include/heqat/bnops.h @@ -39,8 +39,9 @@ extern "C" { #endif +#include "heqat/common/types.h" + #include -#include "he_qat_types.h" /// @brief Performs modular exponentiation using BIGNUM data structure. /// diff --git a/heqat/include/heqat/common.h b/heqat/include/heqat/common.h new file mode 100644 index 0000000..67f9ede --- /dev/null +++ b/heqat/include/heqat/common.h @@ -0,0 +1,13 @@ +/// @file heqat/common.h + +#include "heqat/common/cpa_sample_utils.h" +#include "heqat/common/consts.h" +#include "heqat/common/types.h" +#include "heqat/common/utils.h" + +#ifdef __cplusplus +#ifdef HE_QAT_MISC +#include "heqat/misc.h" +#endif +#endif + diff --git a/he_qat/include/he_qat_gconst.h b/heqat/include/heqat/common/consts.h similarity index 91% rename from he_qat/include/he_qat_gconst.h rename to heqat/include/heqat/common/consts.h index 1883577..2de1a33 100644 --- a/he_qat/include/he_qat_gconst.h +++ b/heqat/include/heqat/common/consts.h @@ -1,4 +1,4 @@ -/// @file he_qat_gconst.h +/// @file heqat/common/consts.h #pragma once diff --git a/heqat/include/heqat/common/cpa_sample_utils.h b/heqat/include/heqat/common/cpa_sample_utils.h new file mode 100644 index 0000000..a128640 --- /dev/null +++ b/heqat/include/heqat/common/cpa_sample_utils.h @@ -0,0 +1,651 @@ +/*************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Corporation + * + * BSD LICENSE + * + * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * version: QAT.L.4.15.0-00011 + * + ***************************************************************************/ + +/** + ***************************************************************************** + * @file cpa_sample_utils.h + * + * @defgroup sampleUtils Macro and inline function definitions + * + * @ingroup sampleCode + * + * @description + * Defines macros for printing and debugging, inline functions for memory + * allocating and freeing and thread creation + * + ***************************************************************************/ + +#ifndef CPA_SAMPLE_UTILS_H +#define CPA_SAMPLE_UTILS_H + +#ifdef __cplusplus +#define HE_QAT_RESTRICT __restrict__ +#else +#define HE_QAT_RESTRICT restrict +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "cpa.h" +#include "cpa_cy_im.h" +#include "cpa_dc.h" + + +#ifdef DO_CRYPTO +#include "cpa_cy_sym.h" +#endif + +#ifdef USER_SPACE +/* User space utils */ +#include +#include +#include +#include +#include +#include +/* Performance sample code mem utils */ + +#include "qae_mem.h" + +extern CpaDcHuffType huffmanType_g; +extern CpaStatus qaeMemInit(void); +extern void qaeMemDestroy(void); +/* Threads */ +typedef pthread_t sampleThread; + +/* Check for CY API version */ +#define CY_API_VERSION_AT_LEAST(major, minor) \ + (CPA_CY_API_VERSION_NUM_MAJOR > major || \ + (CPA_CY_API_VERSION_NUM_MAJOR == major && \ + CPA_CY_API_VERSION_NUM_MINOR >= minor)) + +#ifdef HE_QAT_DEBUG +#define HE_QAT_PRINT_DBG(args...) \ + do \ + { \ + { \ + printf("%s(): ", __func__); \ + printf(args); \ + fflush(stdout); \ + } \ + } while (0) +#else +#define HE_QAT_PRINT_DBG(args...) { } +#endif +/* Printing */ +/**< Prints the name of the function and the arguments only if gDebugParam is + * CPA_TRUE. + */ +#define PRINT_DBG(args...) \ + do \ + { \ + if (CPA_TRUE == gDebugParam) \ + { \ + printf("%s(): ", __func__); \ + printf(args); \ + fflush(stdout); \ + } \ + } while (0) + +/**< Prints the arguments */ +#ifndef PRINT +#define PRINT(args...) \ + do \ + { \ + printf(args); \ + } while (0) +#endif + +/**< Prints the name of the function and the arguments */ +#ifndef PRINT_ERR +#define PRINT_ERR(args...) \ + do \ + { \ + printf("%s(): ", __func__); \ + printf(args); \ + } while (0) +#endif +/** + ******************************************************************************* + * @ingroup sampleUtils + * Completion definitions + * + ******************************************************************************/ +struct completion_struct +{ + sem_t semaphore; +}; +/* Use semaphores to signal completion of events */ +#define COMPLETION_STRUCT completion_struct + +#define COMPLETION_INIT(s) sem_init(&((s)->semaphore), 0, 0); + +#define COMPLETION_WAIT(s, timeout) (sem_wait(&((s)->semaphore)) == 0) + +#define COMPLETE(s) sem_post(&((s)->semaphore)) + +#define COMPLETION_DESTROY(s) sem_destroy(&((s)->semaphore)) + +#else +/* Kernel space utils */ +#include +#include +#include +#include +#include +#include +#include + +#ifdef __x86_64__ +#define SAMPLE_ADDR_LEN uint64_t +#else +#define SAMPLE_ADDR_LEN uint32_t +#endif + +extern CpaDcHuffType huffmanType_g; + +/* Threads */ +typedef struct task_struct *sampleThread; + +/* Check for CY API version */ +#define CY_API_VERSION_AT_LEAST(major, minor) \ + (CPA_CY_API_VERSION_NUM_MAJOR > major || \ + (CPA_CY_API_VERSION_NUM_MAJOR == major && \ + CPA_CY_API_VERSION_NUM_MINOR >= minor)) + +/* Printing */ +/**< Prints the name of the function and the arguments only if gDebugParam is + * CPA_TRUE. + */ +#define PRINT_DBG(args...) \ + do \ + { \ + if (CPA_TRUE == gDebugParam) \ + { \ + printk("%s(): ", __func__); \ + printk(KERN_CONT args); \ + } \ + } while (0) + +/**< Regular prints */ +#ifndef PRINT +#define PRINT(args...) \ + do \ + { \ + printk(KERN_CONT args); \ + } while (0) +#endif + +/**< Prints the name of the function and the arguments */ +#ifndef PRINT_ERR +#define PRINT_ERR(args...) \ + do \ + { \ + printk("%s(): ", __func__); \ + printk(KERN_CONT args); \ + } while (0) +#endif +/** + ******************************************************************************* + * @ingroup sampleUtils + * Completion definitions + * + ******************************************************************************/ +#define COMPLETION_STRUCT completion + +#define COMPLETION_INIT(c) init_completion(c) + +#define COMPLETION_WAIT(c, timeout) \ + wait_for_completion_interruptible_timeout(c, timeout) + +#define COMPLETE(c) complete(c) + +#define COMPLETION_DESTROY(s) + +#endif + +#ifndef BYTE_ALIGNMENT_8 +#define BYTE_ALIGNMENT_8 (8) +#endif +#ifndef BYTE_ALIGNMENT_64 +#define BYTE_ALIGNMENT_64 (64) +#endif + +/** + ***************************************************************************** + * @ingroup fipsSampleCodeUtils + * displayHexArray + * + * @description + * Display the contents of a buffer + * + * @param[in] pLabel String to giving a short description of the printed + * value + * @param[in] pBuff pointer to the data to be printed + * @param[in] len len of the data to be printed + * + * @retval none + * + * @pre + * none + * @post + * none + *****************************************************************************/ +static inline void displayHexArray(const char *HE_QAT_RESTRICT pLabel, + const Cpa8U *HE_QAT_RESTRICT pBuff, + Cpa32U len) +{ + + int i = 0; + PRINT("%s(%d)", pLabel, len); + if (NULL == pBuff) + { + PRINT("%s(%d) Buff is NULL!!\n", __FUNCTION__, __LINE__); + return; + } + for (i = 0; i < len; i++) + { + PRINT("%02x", pBuff[i]); + } + PRINT("\n"); +} +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function and associated macro sleeps for ms milliseconds + * + * @param[in] ms sleep time in ms + * + * @retval none + * + ******************************************************************************/ +static __inline CpaStatus sampleSleep(Cpa32U ms) +{ +#ifdef USER_SPACE + int ret = 0; + struct timespec resTime, remTime; + //resTime.tv_sec = ms / 1000; + //resTime.tv_nsec = (ms % 1000) * 1000000; + // microseconds + resTime.tv_sec = ms / 1000000; + resTime.tv_nsec = (ms % 1000000) * 1000; + do + { + ret = nanosleep(&resTime, &remTime); + resTime = remTime; + } while ((ret != 0) && (errno == EINTR)); + + if (ret != 0) + { + PRINT_ERR("nanoSleep failed with code %d\n", ret); + return CPA_STATUS_FAIL; + } + else + { + return CPA_STATUS_SUCCESS; + } +#else + if (ms != 0) + { + set_current_state((long)TASK_INTERRUPTIBLE); + schedule_timeout((ms * HZ) / 1000); + } + else + { + schedule(); + } + + return CPA_STATUS_SUCCESS; +#endif +} +/** + ******************************************************************************* + * @ingroup sampleUtils + * Macro from the sampleSleep function + * + ******************************************************************************/ +#define OS_SLEEP(ms) sampleSleep((ms)) + +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function and associated macro allocates the memory for the given + * size and stores the address of the memory allocated in the pointer. + * Memory allocated by this function is NOT guaranteed to be physically + * contiguous. + * + * @param[out] ppMemAddr address of pointer where address will be stored + * @param[in] sizeBytes the size of the memory to be allocated + * + * @retval CPA_STATUS_RESOURCE Macro failed to allocate Memory + * @retval CPA_STATUS_SUCCESS Macro executed successfully + * + ******************************************************************************/ +static __inline CpaStatus Mem_OsMemAlloc(void **ppMemAddr, Cpa32U sizeBytes) +{ +#ifdef USER_SPACE + *ppMemAddr = malloc(sizeBytes); + if (NULL == *ppMemAddr) + { + return CPA_STATUS_RESOURCE; + } + return CPA_STATUS_SUCCESS; +#else + *ppMemAddr = kmalloc(sizeBytes, GFP_KERNEL); + if (NULL == *ppMemAddr) + { + return CPA_STATUS_RESOURCE; + } + return CPA_STATUS_SUCCESS; +#endif +} + +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function and associated macro allocates the memory for the given + * size for the given alignment and stores the address of the memory + * allocated in the pointer. Memory allocated by this function is + * guaranteed to be physically contiguous. + * + * @param[out] ppMemAddr address of pointer where address will be stored + * @param[in] sizeBytes the size of the memory to be allocated + * @param[in] alignement the alignment of the memory to be allocated + *(non-zero) + * + * @retval CPA_STATUS_RESOURCE Macro failed to allocate Memory + * @retval CPA_STATUS_SUCCESS Macro executed successfully + * + ******************************************************************************/ +static __inline CpaStatus Mem_Alloc_Contig(void **ppMemAddr, + Cpa32U sizeBytes, + Cpa32U alignment) +{ +#ifdef USER_SPACE + /* Use perf sample code memory allocator */ + + /* In this sample all allocations are done from node=0 + * This might not be optimal in a dual processor system. + */ + *ppMemAddr = qaeMemAllocNUMA(sizeBytes, 0, alignment); + if (NULL == *ppMemAddr) + { + return CPA_STATUS_RESOURCE; + } + return CPA_STATUS_SUCCESS; +#else + void *pAlloc = NULL; + uint32_t align = 0; + + pAlloc = + kmalloc_node((sizeBytes + alignment + sizeof(void *)), GFP_KERNEL, 0); + if (NULL == pAlloc) + { + return CPA_STATUS_RESOURCE; + } + + *ppMemAddr = pAlloc + sizeof(void *); + + align = ((SAMPLE_ADDR_LEN)(*ppMemAddr)) % alignment; + + *ppMemAddr += (alignment - align); + *(SAMPLE_ADDR_LEN *)(*ppMemAddr - sizeof(void *)) = (SAMPLE_ADDR_LEN)pAlloc; + + return CPA_STATUS_SUCCESS; +#endif +} + +/** + ******************************************************************************* + * @ingroup sampleUtils + * Macro from the Mem_OsMemAlloc function + * + ******************************************************************************/ +#define OS_MALLOC(ppMemAddr, sizeBytes) \ + Mem_OsMemAlloc((void *)(ppMemAddr), (sizeBytes)) + +/** + ******************************************************************************* + * @ingroup sampleUtils + * Macro from the Mem_Alloc_Contig function + * + ******************************************************************************/ +#define PHYS_CONTIG_ALLOC(ppMemAddr, sizeBytes) \ + Mem_Alloc_Contig((void *)(ppMemAddr), (sizeBytes), 1) + +/** + ******************************************************************************* + * @ingroup sampleUtils + * Algined version of PHYS_CONTIG_ALLOC() macro + * + ******************************************************************************/ +#define PHYS_CONTIG_ALLOC_ALIGNED(ppMemAddr, sizeBytes, alignment) \ + Mem_Alloc_Contig((void *)(ppMemAddr), (sizeBytes), (alignment)) + +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function and associated macro frees the memory at the given address + * and resets the pointer to NULL. The memory must have been allocated by + * the function Mem_OsMemAlloc() + * + * @param[out] ppMemAddr address of pointer where mem address is stored. + * If pointer is NULL, the function will exit silently + * + * @retval void + * + ******************************************************************************/ +static __inline void Mem_OsMemFree(void **ppMemAddr) +{ +#ifdef USER_SPACE + if (NULL != *ppMemAddr) + { + free(*ppMemAddr); + *ppMemAddr = NULL; + } +#else + if (NULL != *ppMemAddr) + { + kfree(*ppMemAddr); + *ppMemAddr = NULL; + } +#endif +} + +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function and associated macro frees the memory at the given address + * and resets the pointer to NULL. The memory must have been allocated by + * the function Mem_Alloc_Contig(). + * + * @param[out] ppMemAddr address of pointer where mem address is stored. + * If pointer is NULL, the function will exit silently + * + * @retval void + * + ******************************************************************************/ +static __inline void Mem_Free_Contig(void **ppMemAddr) +{ +#ifdef USER_SPACE + if (NULL != *ppMemAddr) + { + qaeMemFreeNUMA(ppMemAddr); + *ppMemAddr = NULL; + } +#else + void *pAlloc = NULL; + + if (NULL != *ppMemAddr) + { + pAlloc = (void *)(*((SAMPLE_ADDR_LEN *)(*ppMemAddr - sizeof(void *)))); + kfree(pAlloc); + *ppMemAddr = NULL; + } +#endif +} + +/** + ******************************************************************************* + * @ingroup sampleUtils + * Macro from the Mem_OsMemFree function + * + ******************************************************************************/ +#define OS_FREE(pMemAddr) Mem_OsMemFree((void *)&pMemAddr) + +/** + ******************************************************************************* + * @ingroup sampleUtils + * Macro from the Mem_Free_Contig function + * + ******************************************************************************/ +#define PHYS_CONTIG_FREE(pMemAddr) Mem_Free_Contig((void *)&pMemAddr) + +#define _4K_PAGE_SIZE (4 * 1024) + +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function returns the physical address for a given virtual address. + * In case of error 0 is returned. + * + * @param[in] virtAddr Virtual address + * + * @retval CpaPhysicalAddr Physical address or 0 in case of error + * + ******************************************************************************/ + +static __inline CpaPhysicalAddr sampleVirtToPhys(void *virtAddr) +{ +#ifdef USER_SPACE + return (CpaPhysicalAddr)qaeVirtToPhysNUMA(virtAddr); +#else + return (CpaPhysicalAddr)virt_to_phys(virtAddr); +#endif +} + +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function creates a thread + * + ******************************************************************************/ + +static __inline CpaStatus sampleThreadCreate(sampleThread *thread, + void *funct, + void *args) +{ +#ifdef USER_SPACE +#ifdef __cplusplus + if (pthread_create(thread, NULL, (void* (*)(void*)) funct, args) != 0) +#else + if (pthread_create(thread, NULL, funct, args) != 0) +#endif + { + PRINT_ERR("Failed create thread\n"); + return CPA_STATUS_FAIL; + } + else + { + pthread_detach(*thread); + return CPA_STATUS_SUCCESS; + } +#else + *thread = kthread_create(funct, args, "SAMPLE_THREAD"); + wake_up_process(*thread); + return CPA_STATUS_SUCCESS; +#endif +} + +static __inline void sampleThreadExit(void) +{ +#ifdef USER_SPACE + pthread_exit(NULL); +#endif +} + +#ifdef DO_CRYPTO +void sampleCyGetInstance(CpaInstanceHandle *pCyInstHandle); + +void sampleCyStartPolling(CpaInstanceHandle cyInstHandle); + +void sampleCyStopPolling(void); + +void symSessionWaitForInflightReq(CpaCySymSessionCtx pSessionCtx); +#endif // DO_CRYPTO + +void sampleDcGetInstance(CpaInstanceHandle *pDcInstHandle); + +void sampleDcStartPolling(CpaInstanceHandle dcInstHandle); + +void sampleDcStopPolling(void); + +#ifdef __cplusplus +} //extern "C" { +#endif + + +#endif + diff --git a/he_qat/include/he_qat_types.h b/heqat/include/heqat/common/types.h similarity index 98% rename from he_qat/include/he_qat_types.h rename to heqat/include/heqat/common/types.h index 71c4671..6df1c0c 100644 --- a/he_qat/include/he_qat_types.h +++ b/heqat/include/heqat/common/types.h @@ -1,4 +1,4 @@ -/// @file he_qat_types.h +/// @file heqat/common/types.h #pragma once @@ -13,7 +13,7 @@ extern "C" { #include "cpa.h" #include "cpa_cy_im.h" #include "cpa_cy_ln.h" -#include "cpa_sample_utils.h" + // C Libraries #include @@ -21,7 +21,8 @@ extern "C" { #include #endif -#include "he_qat_gconst.h" +#include "heqat/common/cpa_sample_utils.h" +#include "heqat/common/consts.h" // Type definitions typedef enum { diff --git a/he_qat/include/he_qat_utils.h b/heqat/include/heqat/common/utils.h similarity index 92% rename from he_qat/include/he_qat_utils.h rename to heqat/include/heqat/common/utils.h index f0dcd6b..44d10d1 100644 --- a/he_qat/include/he_qat_utils.h +++ b/heqat/include/heqat/common/utils.h @@ -1,4 +1,4 @@ -///< @file he_qat_utils.h +/// @file heqat/common/utils.h #pragma once diff --git a/he_qat/include/he_qat_context.h b/heqat/include/heqat/context.h similarity index 94% rename from he_qat/include/he_qat_context.h rename to heqat/include/heqat/context.h index 86fbc8b..ea9af91 100644 --- a/he_qat/include/he_qat_context.h +++ b/heqat/include/heqat/context.h @@ -9,7 +9,7 @@ extern "C" { #endif -#include "he_qat_types.h" +#include "heqat/common/types.h" /// @brief /// Configure and initialize QAT runtime environment. diff --git a/heqat/include/heqat/heqat.h b/heqat/include/heqat/heqat.h new file mode 100644 index 0000000..5921924 --- /dev/null +++ b/heqat/include/heqat/heqat.h @@ -0,0 +1,7 @@ +/// @file heqat/heqat.h +//#pragma once + +#include "heqat/common.h" +#include "heqat/context.h" +#include "heqat/bnops.h" + diff --git a/misc/he_qat_misc.h b/heqat/include/heqat/misc.h similarity index 86% rename from misc/he_qat_misc.h rename to heqat/include/heqat/misc.h index 459d5e0..b366742 100644 --- a/misc/he_qat_misc.h +++ b/heqat/include/heqat/misc.h @@ -1,14 +1,16 @@ -/// @file he_qat_misc.h +/// @file heqat/misc.h + +#pragma once #ifndef HE_QAT_MISC_H_ #define HE_QAT_MISC_H_ -#pragma once +#include "heqat/common/consts.h" +#include "heqat/common/types.h" + +#ifdef __cplusplus -#include "he_qat_gconst.h" -#include "he_qat_types.h" -#include "bignum.h" -#include +#include "heqat/misc/bignum.h" /// @brief /// Convert QAT large number into little endian format and encapsulate it into a @@ -29,5 +31,6 @@ HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, /// represented in nbits. HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, const BigNumber& bn); +#endif // __cpluscplus #endif // HE_QAT_MISC_H_ diff --git a/misc/bignum.h b/heqat/include/heqat/misc/bignum.h similarity index 100% rename from misc/bignum.h rename to heqat/include/heqat/misc/bignum.h diff --git a/misc/utils.h b/heqat/include/heqat/misc/utils.h similarity index 100% rename from misc/utils.h rename to heqat/include/heqat/misc/utils.h diff --git a/heqat/misc/CMakeLists.txt b/heqat/misc/CMakeLists.txt new file mode 100644 index 0000000..b6719a9 --- /dev/null +++ b/heqat/misc/CMakeLists.txt @@ -0,0 +1,59 @@ + +set(HE_QAT_MISC_SRC ${CMAKE_CURRENT_LIST_DIR}/misc.cpp + ${CMAKE_CURRENT_LIST_DIR}/utils.cpp + ${CMAKE_CURRENT_LIST_DIR}/bignum.cpp) + +list(APPEND HE_QAT_SRC ${HE_QAT_MISC_SRC}) + +set(HE_QAT_SRC ${HE_QAT_SRC} PARENT_SCOPE) + +##Include directories +##list(APPEND HE_QAT_MISC_INC_DIR +#set(HE_QAT_MISC_INC_DIR ${COMMON_INC_DIR} +# ${HE_QAT_INC_DIR} +# ${CMAKE_CURRENT_LIST_DIR} +# # ${IPPCP_DIR}/include +#) +# +#message(STATUS "HE_QAT_MISC_INC_DIR: ${HE_QAT_MISC_INC_DIR}") +# +##Source files +##list(APPEND HE_QAT_MISC_SRC ${CMAKE_CURRENT_LIST_DIR} / utils.cpp +#set(HE_QAT_MISC_SRC +# ${CMAKE_CURRENT_LIST_DIR}/heqat_misc.cpp +# ${CMAKE_CURRENT_LIST_DIR}/utils.cpp +# ${CMAKE_CURRENT_LIST_DIR}/bignum.cpp) +# +#if(HE_QAT_SHARED) +# add_library(heqat_misc SHARED ${HE_QAT_MISC_SRC}) +#else() +# add_library(heqat_misc STATIC ${HE_QAT_MISC_SRC}) +#endif() +# +#message(STATUS "IPPCP Headers Directory ${IPPCP_DIR}/include") +#target_include_directories(heqat_misc #PUBLIC $ #Public headers +# #PUBLIC $ #Public headers +# PRIVATE ${IPPCP_DIR}/../../../include +# PRIVATE ${HE_QAT_MISC_INC_DIR} #Private headers +# PRIVATE ${ICP_INC_DIR} #Private headers +# +#) +##target_link_directories(he_qat_misc PUBLIC ${IPPCP_DIR}/lib/intel64) +##target_link_libraries(he_qat_misc PRIVATE ippcpmx crypto_mb) +# +#if(HE_QAT_SHARED) +# target_link_libraries(heqat_misc PRIVATE IPPCP::ippcp IPPCP::crypto_mb) +#else() +# heqat_create_archive(heqat_misc IPPCP::ippcp) +# heqat_create_archive(heqat_misc IPPCP::crypto_mb) +#endif() +# +#install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/ +# DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ +# FILES_MATCHING +# PATTERN "*.hpp" +# PATTERN "*.h") +##install(TARGETS he_qat_misc DESTINATION ${CMAKE_INSTALL_LIBDIR}) +#install(TARGETS heqat_misc EXPORT he_qatTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}) +# +#set(HE_QAT_MISC_INC_DIR ${HE_QAT_MISC_INC_DIR} PARENT_SCOPE) diff --git a/misc/bignum.cpp b/heqat/misc/bignum.cpp similarity index 99% rename from misc/bignum.cpp rename to heqat/misc/bignum.cpp index 1e88859..8a5a869 100644 --- a/misc/bignum.cpp +++ b/heqat/misc/bignum.cpp @@ -14,10 +14,12 @@ * limitations under the License. *******************************************************************************/ -#include "bignum.h" +#include "heqat/misc/bignum.h" +#include "heqat/misc/utils.h" + #include #include -#include "utils.h" + ////////////////////////////////////////////////////////////////////// // diff --git a/misc/he_qat_misc.cpp b/heqat/misc/misc.cpp similarity index 89% rename from misc/he_qat_misc.cpp rename to heqat/misc/misc.cpp index efee2e2..2fd8157 100644 --- a/misc/he_qat_misc.cpp +++ b/heqat/misc/misc.cpp @@ -1,15 +1,10 @@ -/// @file he_qat_misc.cpp +/// @file heqat/misc/misc.cpp -#include "he_qat_misc.h" - -//#ifdef __cplusplus -//#include "bignum.h" -//#endif +#include "heqat/misc.h" #include #include -//#ifdef __cplusplus HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, int nbits) { if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; @@ -43,5 +38,3 @@ HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, return HE_QAT_STATUS_SUCCESS; } -//} // extern "C" { -//#endif diff --git a/misc/utils.cpp b/heqat/misc/utils.cpp similarity index 97% rename from misc/utils.cpp rename to heqat/misc/utils.cpp index 1bf189b..e0ffc4f 100644 --- a/misc/utils.cpp +++ b/heqat/misc/utils.cpp @@ -14,7 +14,7 @@ * limitations under the License. *******************************************************************************/ -#include "utils.h" +#include "heqat/misc/utils.h" size_t strlen_safe(const char* dest, size_t dmax) { size_t count; diff --git a/icp/CMakeLists.txt b/icp/CMakeLists.txt index 8bae5b4..e440b79 100644 --- a/icp/CMakeLists.txt +++ b/icp/CMakeLists.txt @@ -18,10 +18,10 @@ set(ICP_INC_DIR ${ICP_API_DIR}/include ${ICP_LAC_DIR}/include ${ICP_ADF_DIR}/include ${CMN_ROOT} - ${ICP_API_DIR}/include/dc + ${ICP_API_DIR}/include/dc ${ICP_API_DIR}/include/lac) -# Macros for the test case +# Active macros for cpa_sample_utils add_definitions(-DDO_CRYPTO) add_definitions(-DUSER_SPACE) add_compile_options(-fPIC) diff --git a/misc/CMakeLists.txt b/misc/CMakeLists.txt deleted file mode 100644 index f37b8db..0000000 --- a/misc/CMakeLists.txt +++ /dev/null @@ -1,51 +0,0 @@ - -#Include directories -#list(APPEND HE_QAT_MISC_INC_DIR -set(HE_QAT_MISC_INC_DIR ${COMMON_INC_DIR} - ${HE_QAT_INC_DIR} - ${CMAKE_CURRENT_LIST_DIR} - # ${IPPCP_DIR}/include -) - -message(STATUS "HE_QAT_MISC_INC_DIR: ${HE_QAT_MISC_INC_DIR}") - -#Source files -#list(APPEND HE_QAT_MISC_SRC ${CMAKE_CURRENT_LIST_DIR} / utils.cpp -set(HE_QAT_MISC_SRC - ${CMAKE_CURRENT_LIST_DIR}/he_qat_misc.cpp - ${CMAKE_CURRENT_LIST_DIR}/utils.cpp - ${CMAKE_CURRENT_LIST_DIR}/bignum.cpp) - -if(HE_QAT_SHARED) - add_library(he_qat_misc SHARED ${HE_QAT_MISC_SRC}) -else() - add_library(he_qat_misc STATIC ${HE_QAT_MISC_SRC}) -endif() - -message(STATUS "IPPCP Headers Directory ${IPPCP_DIR}/include") -target_include_directories(he_qat_misc #PUBLIC $ #Public headers - #PUBLIC $ #Public headers - PRIVATE ${IPPCP_DIR}/../../../include - PRIVATE ${HE_QAT_MISC_INC_DIR} #Private headers - PRIVATE ${ICP_INC_DIR} #Private headers - -) -#target_link_directories(he_qat_misc PUBLIC ${IPPCP_DIR}/lib/intel64) -#target_link_libraries(he_qat_misc PRIVATE ippcpmx crypto_mb) - -if(HE_QAT_SHARED) - target_link_libraries(he_qat_misc PRIVATE IPPCP::ippcp IPPCP::crypto_mb) -else() - heqat_create_archive(he_qat_misc IPPCP::ippcp) - heqat_create_archive(he_qat_misc IPPCP::crypto_mb) -endif() - -install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ - FILES_MATCHING - PATTERN "*.hpp" - PATTERN "*.h") -#install(TARGETS he_qat_misc DESTINATION ${CMAKE_INSTALL_LIBDIR}) -install(TARGETS he_qat_misc EXPORT he_qatTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}) - -set(HE_QAT_MISC_INC_DIR ${HE_QAT_MISC_INC_DIR} PARENT_SCOPE) diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 8d459eb..6d0fd3a 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -1,80 +1,66 @@ -if(HE_QAT_DEBUG) - add_definitions(-DHE_QAT_DEBUG) -endif() - -# ------------------------------------------------------------------------------------------- - -add_executable(test_context test_context.c) +############################################################################### -target_include_directories(test_context PUBLIC ${COMMON_INC_DIR}) -#target_include_directories(test_context PUBLIC ${HE_QAT_INC_DIR}) -target_include_directories(test_context PUBLIC ${ICP_INC_DIR}) - -target_link_libraries(test_context PUBLIC he_qat) - -install(TARGETS test_context RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +macro(heqat_create_executable sample_case language dependencies) + if(${language} STREQUAL "C" OR ${language} STREQUAL "c") + set(extension "c") + elseif(${language} STREQUAL "CXX" OR ${language} STREQUAL "cxx") + set(extension "cpp") + else() + message(FATAL_ERROR "Error language not supported. Options: C or CXX.") + endif() -# ------------------------------------------------------------------------------------------- + set(target sample_${sample_case}) + add_executable(${target} test_${sample_case}.${extension}) + + target_include_directories(${target} PUBLIC ${HE_QAT_INC_DIR}) + target_include_directories(${target} PUBLIC ${ICP_INC_DIR}) + + target_link_libraries(${target} PUBLIC he_qat) + + if(NOT ${dependencies} STREQUAL "") + message(STATUS "Target: ${target} Additional Dependencies: ${${dependencies}}") + target_link_libraries(${target} PUBLIC ${${dependencies}}) + endif() -add_executable(test_BIGNUMModExp test_BIGNUMModExp.c) + install(TARGETS ${target} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +endmacro() -target_include_directories(test_BIGNUMModExp PUBLIC ${COMMON_INC_DIR}) # ${HE_QAT_UTILS_INC_DIR}) -#target_include_directories(test_BIGNUMModExp PUBLIC ${HE_QAT_INC_DIR}) -target_include_directories(test_BIGNUMModExp PUBLIC ${ICP_INC_DIR}) +############################################################################## -target_link_libraries(test_BIGNUMModExp PUBLIC he_qat) -target_link_libraries(test_BIGNUMModExp PUBLIC OpenSSL::SSL) # OpenSSL::Crypto) +set(EXECUTABLE_DEPENDENCIES + OpenSSL::SSL + IPPCP::ippcp +) -install(TARGETS test_BIGNUMModExp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +# Sample testing the robustness of the heqatlib context functions +heqat_create_executable(context c "") -# ------------------------------------------------------------------------------------------- +# Sample demonstrating how to use API for BIGNUM inputs +heqat_create_executable(BIGNUMModExp C EXECUTABLE_DEPENDENCIES) if(HE_QAT_MISC) add_compile_options(-fpermissive) - + # Sample showing how to convert from/to BigNumber to/from CpaFlatBuffer - add_executable(test_bnConversion test_bnConversion.cpp) - - target_include_directories(test_bnConversion PUBLIC ${COMMON_INC_DIR}) - target_include_directories(test_bnConversion PUBLIC ${ICP_INC_DIR}) - target_include_directories(test_bnConversion PUBLIC ${HE_QAT_MISC_INC_DIR}) - - target_link_libraries(test_bnConversion PUBLIC he_qat) - target_link_libraries(test_bnConversion PUBLIC he_qat_misc) - target_link_libraries(test_bnConversion PUBLIC IPPCP::ippcp) # IPPCP::crypto_mb) - target_link_libraries(test_bnConversion PUBLIC OpenSSL::SSL) # OpenSSL::Crypto) - - install(TARGETS test_bnConversion RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) - - # Sample demonstrating how to use bnModExp - add_executable(test_bnModExp test_bnModExp.cpp) - - target_include_directories(test_bnModExp PUBLIC ${COMMON_INC_DIR}) - target_include_directories(test_bnModExp PUBLIC ${ICP_INC_DIR}) - target_include_directories(test_bnModExp PUBLIC ${HE_QAT_MISC_INC_DIR}) - - target_link_libraries(test_bnModExp PUBLIC he_qat) - target_link_libraries(test_bnModExp PUBLIC he_qat_misc) - target_link_libraries(test_bnModExp PUBLIC IPPCP::ippcp) # IPPCP::crypto_mb) - target_link_libraries(test_bnModExp PUBLIC OpenSSL::SSL) # OpenSSL::Crypto) - - install(TARGETS test_bnModExp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) - + heqat_create_executable(bnConversion cxx EXECUTABLE_DEPENDENCIES) + + # Sample showing how to use bnModExp API + heqat_create_executable(bnModExp CXX EXECUTABLE_DEPENDENCIES) + # add_executable(sample_bnModExp test_bnModExp.cpp) + # + # target_include_directories(sample_bnModExp PUBLIC ${HE_QAT_INC_DIR}) + # target_include_directories(sample_bnModExp PUBLIC ${ICP_INC_DIR}) + # + # target_link_libraries(sample_bnModExp PUBLIC he_qat) + # target_link_libraries(sample_bnModExp PUBLIC OpenSSL::SSL) + # target_link_libraries(sample_bnModExp PUBLIC IPPCP::ippcp) + if(OpenMP_CXX_FOUND) - # Sample demonstrating how to use multithread-supported interface bnModExp_MT - add_executable(test_bnModExp_MT test_bnModExp_MT.cpp) - - target_include_directories(test_bnModExp_MT PUBLIC ${COMMON_INC_DIR}) - target_include_directories(test_bnModExp_MT PUBLIC ${ICP_INC_DIR}) - target_include_directories(test_bnModExp_MT PUBLIC ${HE_QAT_MISC_INC_DIR}) - - target_link_libraries(test_bnModExp_MT PUBLIC he_qat) - target_link_libraries(test_bnModExp_MT PUBLIC he_qat_misc) - target_link_libraries(test_bnModExp_MT PUBLIC OpenMP::OpenMP_CXX) - target_link_libraries(test_bnModExp_MT PUBLIC IPPCP::ippcp) # IPPCP::crypto_mb) - target_link_libraries(test_bnModExp_MT PUBLIC OpenSSL::SSL) # OpenSSL::Crypto) - - install(TARGETS test_bnModExp_MT RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + list(APPEND EXECUTABLE_DEPENDENCIES OpenMP::OpenMP_CXX) + # Sample showing how to use bnModExp_MT API for multithreaded applications + heqat_create_executable(bnModExp_MT CXX EXECUTABLE_DEPENDENCIES) endif() endif() + +############################################################################### diff --git a/samples/test_BIGNUMModExp.c b/samples/test_BIGNUMModExp.c index b74f36c..71ab5a9 100644 --- a/samples/test_BIGNUMModExp.c +++ b/samples/test_BIGNUMModExp.c @@ -1,8 +1,5 @@ -#include "cpa_sample_utils.h" -#include "he_qat_utils.h" -#include "he_qat_bn_ops.h" -#include "he_qat_context.h" +#include "heqat/heqat.h" #include #include @@ -13,7 +10,6 @@ struct timeval start_time, end_time; double time_taken = 0.0; -//int gDebugParam = 1; // Active in Debug mode const unsigned int BATCH_SIZE = 1; int main(int argc, const char** argv) { diff --git a/samples/test_bnConversion.cpp b/samples/test_bnConversion.cpp index ee5490d..617d063 100644 --- a/samples/test_bnConversion.cpp +++ b/samples/test_bnConversion.cpp @@ -1,6 +1,7 @@ -#include "he_qat_misc.h" -#include "he_qat_utils.h" +//#include "he_qat_misc.h" +//#include "he_qat_utils.h" +#include "heqat/heqat.h" #include #include diff --git a/samples/test_bnModExp.cpp b/samples/test_bnModExp.cpp index 7499445..1a5d5aa 100644 --- a/samples/test_bnModExp.cpp +++ b/samples/test_bnModExp.cpp @@ -1,9 +1,5 @@ -#include "he_qat_misc.h" -#include "he_qat_utils.h" -#include "he_qat_bn_ops.h" -#include "he_qat_context.h" -#include "cpa_sample_utils.h" +#include "heqat/heqat.h" #include #include @@ -14,10 +10,6 @@ #include #include -#ifdef _DESTINY_DEBUG_VERBOSE -int gDebugParam = 1; -#endif - const unsigned int BATCH_SIZE = 48; using namespace std::chrono; @@ -46,7 +38,7 @@ int main(int argc, const char** argv) { if (!bn_mod) continue; char* bn_str = BN_bn2hex(bn_mod); -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG printf("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); #endif @@ -174,7 +166,7 @@ int main(int argc, const char** argv) { if (HE_QAT_STATUS_SUCCESS != status) { PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); } -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG else { PRINT_DBG("\nQAT bnModExpOp finished\n"); } @@ -187,13 +179,13 @@ int main(int argc, const char** argv) { exit(1); } -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG bn_str = BN_bn2hex(qat_res); printf("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, BN_num_bytes(qat_res), BN_num_bits(qat_res)); #endif -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG int bit_len = 0; ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); std::string str; diff --git a/samples/test_bnModExp_MT.cpp b/samples/test_bnModExp_MT.cpp index e3ef33c..18d22d4 100644 --- a/samples/test_bnModExp_MT.cpp +++ b/samples/test_bnModExp_MT.cpp @@ -1,9 +1,5 @@ -#include "he_qat_misc.h" -#include "he_qat_utils.h" -#include "he_qat_bn_ops.h" -#include "he_qat_context.h" -#include "cpa_sample_utils.h" +#include "heqat/heqat.h" #include #include @@ -15,26 +11,18 @@ #include #include -#ifdef _DESTINY_DEBUG_VERBOSE -int gDebugParam = 1; -#endif - const unsigned int BATCH_SIZE = 4096; using namespace std::chrono; int main(int argc, const char** argv) { const int bit_length = 4096; - const size_t num_trials = 10000; + const size_t num_trials = 20; double avg_speed_up = 0.0; double ssl_avg_time = 0.0; double qat_avg_time = 0.0; - // clock_t start = CLOCKS_PER_SEC; - // clock_t ssl_elapsed = CLOCKS_PER_SEC; - // clock_t qat_elapsed = CLOCKS_PER_SEC; - HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; // Set up QAT runtime context @@ -52,10 +40,10 @@ int main(int argc, const char** argv) { if (!bn_mod) continue; char* bn_str = BN_bn2hex(bn_mod); -#ifdef _DESTINY_DEBUG_VERBOSE - printf("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, + + HE_QAT_PRINT_DBG("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); -#endif + OPENSSL_free(bn_str); // Generate exponent in [0..bn_mod] @@ -71,16 +59,13 @@ int main(int argc, const char** argv) { // Perform OpenSSL ModExp Op BIGNUM* ssl_res = BN_new(); auto start = high_resolution_clock::now(); - // start = clock(); BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); auto stop = high_resolution_clock::now(); auto ssl_duration = duration_cast(stop - start); - // ssl_elapsed = clock() - start; int len_ = (bit_length + 7) >> 3; // Start QAT timer (including data conversion overhead) - // start = clock(); start = high_resolution_clock::now(); unsigned char* bn_base_data_ = (unsigned char*)calloc(len_, sizeof(unsigned char)); @@ -99,7 +84,6 @@ int main(int argc, const char** argv) { if (NULL == bn_remainder_data_) exit(1); stop = high_resolution_clock::now(); auto cvt_duration = duration_cast(stop - start); - // clock_t cvt_elapsed = clock() - start; // Simulate input number in BigNumber representation BigNumber big_num_base((Ipp32u)0); @@ -137,18 +121,18 @@ int main(int argc, const char** argv) { start = high_resolution_clock::now(); status = bigNumberToBin(bn_base_data_, bit_length, big_num_base); if (HE_QAT_STATUS_SUCCESS != status) { - printf("bn_base_data_: failed at bignumbertobin()\n"); + PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); exit(1); } status = bigNumberToBin(bn_mod_data_, bit_length, big_num_mod); if (HE_QAT_STATUS_SUCCESS != status) { - printf("bn_base_data_: failed at bignumbertobin()\n"); + PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); exit(1); } status = bigNumberToBin(bn_exponent_data_, bit_length, big_num_exponent); if (HE_QAT_STATUS_SUCCESS != status) { - printf("bn_base_data_: failed at bignumbertobin()\n"); + PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); exit(1); } // cvt_elapsed += (clock() - start); @@ -168,36 +152,31 @@ int main(int argc, const char** argv) { // Secure one of the distributed outstanding buffers status = acquire_bnModExp_buffer(&buffer_id); if (HE_QAT_STATUS_SUCCESS != status) { - printf("Error: acquire_bnModExp_buffer()\n"); + PRINT_ERR("Failed to acquire_bnModExp_buffer()\n"); exit(1); } -#ifdef HE_QAT_DEBUG - printf("Thread #%d HE QAT ACQUIRED BUFFER ID: %u\n",thread_id,buffer_id); -#endif + + HE_QAT_PRINT_DBG("Thread #%d HE QAT ACQUIRED BUFFER ID: %u\n",thread_id,buffer_id); + // Divide work among threads unsigned int worksize = BATCH_SIZE/nthreads; unsigned int begin = thread_id*worksize; unsigned int end = begin + worksize; -#ifdef HE_QAT_DEBUG - printf("Thread #%d Begin: %u End: %u\n",thread_id,begin,end); -#endif + HE_QAT_PRINT_DBG("Thread #%d Begin: %u End: %u\n",thread_id,begin,end); // For local thread, schedule work execution for (unsigned int b = begin; b < end; b++) status = HE_QAT_bnModExp_MT(buffer_id, bn_remainder_data_ + thread_id*len_, bn_base_data_, bn_exponent_data_, bn_mod_data_, bit_length); -#ifdef HE_QAT_DEBUG - printf("Thread #%d Waiting\n",thread_id); -#endif + HE_QAT_PRINT_DBG("Thread #%d Waiting\n",thread_id); // Wait for the request to complete release_bnModExp_buffer(buffer_id, BATCH_SIZE/nthreads); -#ifdef HE_QAT_DEBUG - printf("Thread #%d Completed\n",thread_id); -#endif + HE_QAT_PRINT_DBG("Thread #%d Completed\n",thread_id); + } // pragma omp parallel stop = high_resolution_clock::now(); @@ -212,57 +191,45 @@ int main(int argc, const char** argv) { (ssl_duration.count() / (double)(qat_duration.count() / BATCH_SIZE))) / (mod + 1); - // qat_elapsed = clock() - start; - - // printf("BigNumber data conversion overhead: %.1lfus.\n", - // (cvt_elapsed / (CLOCKS_PER_SEC / 1000000.0))); - // printf("BigNumber modular exponentiation on QAT: %.1lfus.\n", - // (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); - // qat_elapsed += cvt_elapsed; - printf("Request #%u\t", mod + 1); - printf("Overhead: %.1luus", cvt_duration.count()); - printf("\tOpenSSL: %.1lfus", ssl_avg_time); - printf("\tQAT: %.1lfus", qat_avg_time); - printf("\tSpeed-up: %.1lfx", avg_speed_up); - // qat_elapsed += cvt_elapsed; + + PRINT("Request #%u\t", mod + 1); + PRINT("Overhead: %.1luus", cvt_duration.count()); + PRINT("\tOpenSSL: %.1lfus", ssl_avg_time); + PRINT("\tQAT: %.1lfus", qat_avg_time); + PRINT("\tSpeed-up: %.1lfx", avg_speed_up); BIGNUM* qat_res = BN_new(); BN_bin2bn(bn_remainder_data_, len_, qat_res); if (HE_QAT_STATUS_SUCCESS != status) { PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); + exit(1); } -#ifdef _DESTINY_DEBUG_VERBOSE - else { - PRINT_DBG("\nQAT bnModExpOp finished\n"); - } -#endif + + HE_QAT_PRINT_DBG("\nQAT bnModExpOp finished\n"); // start = clock(); BigNumber big_num((Ipp32u)0); status = binToBigNumber(big_num, bn_remainder_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { - printf("bn_remainder_data_: Failed at bigNumberToBin()\n"); + PRINT_ERR("bn_remainder_data_: Failed at bigNumberToBin()\n"); exit(1); } - // qat_elapsed += (clock() - start); - // printf("BigNumber ModExp total time: %.1lfus.\n", - // (qat_elapsed / (CLOCKS_PER_SEC / 1000000.0))); -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG bn_str = BN_bn2hex(qat_res); - printf("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, + HE_QAT_PRINT_DBG("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, BN_num_bytes(qat_res), BN_num_bits(qat_res)); #endif -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG int bit_len = 0; ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); std::string str; big_num.num2hex(str); - printf("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, + HE_QAT_PRINT_DBG("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, bit_len); - printf( + HE_QAT_PRINT_DBG( "---------------------################-----------------------\n"); #endif diff --git a/samples/test_context.c b/samples/test_context.c index 8cbc1f0..69fda71 100644 --- a/samples/test_context.c +++ b/samples/test_context.c @@ -1,7 +1,5 @@ -#include -#include "cpa_sample_utils.h" -#include "he_qat_context.h" +#include "heqat/heqat.h" int main() { HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; diff --git a/scripts/run.sh b/scripts/run.sh index aa451dd..dee46a0 100755 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -6,7 +6,7 @@ export LD_LIBRARY_PATH=$HEQATLIB_INSTALL_DIR/lib:$ICP_ROOT/build:$LD_LIBRARY_PAT pushd $HEQATLIB_INSTALL_DIR/bin -for app in $(ls test_*) +for app in $(ls sample_*) do echo "*****************************************************************" echo "* [START] RUNNING TEST SAMPLE $app *" From 710f400eabb9fb8e244f36152945d657f31c890d Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 18 Oct 2022 14:17:04 -0700 Subject: [PATCH 285/364] Update example. Signed-off-by: Souza, Fillipe --- example/CMakeLists.txt | 15 ++++++++++----- example/example.cpp | 41 +++++++++++++++++------------------------ 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 388f815..ae65df5 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -5,12 +5,17 @@ cmake_minimum_required(VERSION 3.13) set(CMAKE_CXX_STANDARD 11) set(HE_QAT_HINT_DIR ${CMAKE_PREFIX_PATH}) message(STATUS "CMAKE_PREFIX_PATH ${HE_QAT_HINT_DIR}") + # Example using source -find_package(HE_QAT 0.1.0 - HINTS ${HE_QAT_HINT_DIR} - REQUIRED) -if (NOT TARGET HE_QAT::he_qat) - message(FATAL_ERROR "TARGET HE_QAT::he_qat not found") +find_package(HE_QAT 1.3.0 + HINTS ${HE_QAT_HINT_DIR} + REQUIRED) +if(NOT TARGET HE_QAT::he_qat) + message(FATAL_ERROR "TARGET HE_QAT::he_qat not found") +endif() + +if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") + add_definitions(-DHE_QAT_DEBUG) endif() find_package(OpenSSL REQUIRED) diff --git a/example/example.cpp b/example/example.cpp index da19a99..559baca 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -1,8 +1,5 @@ -#include "he_qat_bn_ops.h" -#include "he_qat_context.h" -#include "he_qat_utils.h" -#include "cpa_sample_utils.h" +#include "heqat/heqat.h" #include #include @@ -46,9 +43,9 @@ int main(int argc, const char** argv) { if (!bn_mod) continue; -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG char* bn_str = BN_bn2hex(bn_mod); - printf("Generated modulus: %s num_bytes: %d num_bits: %d\n", bn_str, + PRINT("Generated modulus: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); OPENSSL_free(bn_str); #endif @@ -72,26 +69,25 @@ int main(int argc, const char** argv) { ssl_elapsed = time_taken; if (!ERR_get_error()) { -#ifdef _DESTINY_DEBUG_VERBOSE +#ifdef HE_QAT_DEBUG bn_str = BN_bn2hex(ssl_res); - printf("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", bn_str, + PRINT("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); showHexBN(ssl_res, bit_length); OPENSSL_free(bn_str); #endif } else { - printf("Modular exponentiation failed.\n"); + PRINT_ERR("Modular exponentiation failed.\n"); + exit(1); } -#ifdef _DESTINY_DEBUG_VERBOSE - PRINT_DBG("\nStarting QAT bnModExp...\n"); -#endif + HE_QAT_PRINT_DBG("\nStarting QAT bnModExp...\n"); // Perform QAT ModExp Op BIGNUM* qat_res = BN_new(); gettimeofday(&start_time, NULL); for (unsigned int j = 0; j < BATCH_SIZE; j++) - status = bnModExpPerformOp(qat_res, bn_base, bn_exponent, bn_mod, + status = HE_QAT_BIGNUMModExp(qat_res, bn_base, bn_exponent, bn_mod, bit_length); getBnModExpRequest(BATCH_SIZE); gettimeofday(&end_time, NULL); @@ -107,23 +103,20 @@ int main(int argc, const char** argv) { (mod * avg_speed_up + (ssl_elapsed) / (qat_elapsed/BATCH_SIZE)) / (mod + 1); - printf( - "Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", + PRINT("Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", (mod + 1), ssl_avg_time, qat_avg_time, avg_speed_up); if (HE_QAT_STATUS_SUCCESS != status) { PRINT_ERR("\nQAT bnModExpOp failed\n"); + exit(1); } -#ifdef _DESTINY_DEBUG_VERBOSE - else { - PRINT_DBG("\nQAT bnModExpOp finished\n"); - } -#endif - - if (BN_cmp(qat_res, ssl_res) != 0) - printf("\t** FAIL **\n"); + + if (BN_cmp(qat_res, ssl_res) != 0) + PRINT("\t** FAIL **\n"); else - printf("\t** PASS **\n"); + PRINT("\t** PASS **\n"); + + HE_QAT_PRINT_DBG("\nQAT bnModExpOp finished\n"); BN_free(ssl_res); BN_free(qat_res); From 3867d2a11b34446397923727b1c39eaa6c8a1e90 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 18 Oct 2022 14:19:54 -0700 Subject: [PATCH 286/364] Update CMakeLists.txt. Signed-off-by: Souza, Fillipe --- CMakeLists.txt | 14 ++-------- heqat/CMakeLists.txt | 5 ++-- heqat/common/CMakeLists.txt | 39 +------------------------- heqat/misc/CMakeLists.txt | 55 +------------------------------------ 4 files changed, 7 insertions(+), 106 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 92dc855..10f02f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.13) # The hekat or heqat (transcribed HqA.t) was an ancient Egyptian volume unit # used to measure grain, bread, and beer. -project(HE_QAT VERSION 1.2.1 LANGUAGES C CXX) +project(HE_QAT VERSION 1.3.0 LANGUAGES C CXX) include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) @@ -139,13 +139,12 @@ set(HE_QAT_FORWARD_CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ) - #OpenSSL installation if(NOT HE_QAT_SHARED) set(OPENSSL_USE_STATIC_LIBS TRUE) message(STATUS "OPENSSL_USE_STATIC_LIBS TRUE") else() - message(STATUS "OPENSSL_USE_STATIC_LIBS FALSE") + message(STATUS "OPENSSL_USE_STATIC_LIBS FALSE") endif() find_package(OpenSSL REQUIRED) @@ -157,7 +156,6 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/he_qat) include(heqat-util) -#set(COMMON_INC_DIR ${CMAKE_CURRENT_LIST_DIR}/include) if(NOT CMAKE_INSTALL_PREFIX) set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_LIST_DIR}/install) endif() @@ -165,14 +163,6 @@ endif() # Include QAT lib API support include(icp/CMakeLists.txt) -#Common utility functions -#add_subdirectory(common) - -# Helper functions for BigNumber -#if(HE_QAT_MISC) -# add_subdirectory(misc) -#endif() - # HE_QAT Library add_subdirectory(heqat) diff --git a/heqat/CMakeLists.txt b/heqat/CMakeLists.txt index 3b6e8b8..0b00a3a 100644 --- a/heqat/CMakeLists.txt +++ b/heqat/CMakeLists.txt @@ -1,12 +1,15 @@ +# HEQAT Lib source code set(HE_QAT_SRC ${HE_QAT_SRC_DIR}/cb.c ${HE_QAT_SRC_DIR}/context.c ${HE_QAT_SRC_DIR}/ctrl.c ${HE_QAT_SRC_DIR}/bnops.c ) +# Common utility functions, types and constants add_subdirectory(common) +# Helper functions for ippcrypto's BigNumber class if(HE_QAT_MISC) add_subdirectory(misc) endif() @@ -53,10 +56,8 @@ if(HE_QAT_MISC) target_link_directories(he_qat PUBLIC ${IPPCP_DIR}/lib/intel64) if(HE_QAT_SHARED) target_link_libraries(he_qat PRIVATE IPPCP::ippcp) - # target_link_libraries(he_qat PRIVATE IPPCP::crypto_mb) else() heqat_create_archive (he_qat IPPCP::ippcp) - # heqat_create_archive (he_qat IPPCP::crypto_mb) endif() endif() diff --git a/heqat/common/CMakeLists.txt b/heqat/common/CMakeLists.txt index f1d5612..478f463 100644 --- a/heqat/common/CMakeLists.txt +++ b/heqat/common/CMakeLists.txt @@ -1,43 +1,6 @@ -# Include directories -set(COMMON_INC_DIR ${HE_QAT_INC_DIR}) -message(STATUS "COMMON_INC_DIR: ${COMMON_INC_DIR}") -message(STATUS "ICP_INC_DIR: ${ICP_INC_DIR}") - # Source files set(COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/cpa_sample_utils.c ${CMAKE_CURRENT_LIST_DIR}/utils.c) -list(APPEND HE_QAT_SRC ${COMMON_SRC}) - +list(APPEND HE_QAT_SRC ${COMMON_SRC}) set(HE_QAT_SRC ${HE_QAT_SRC} PARENT_SCOPE) -#if(HE_QAT_SHARED) -# add_library(heqat_common SHARED ${COMMON_SRC}) -#else() -# add_library(heqat_common STATIC ${COMMON_SRC}) -#endif() -# -#target_include_directories(heqat_common -# PRIVATE $ # Public headers -# PRIVATE $ # Public headers -# PUBLIC $ # Public headers -# PRIVATE ${COMMON_INC_DIR} # Private headers -# PRIVATE ${ICP_INC_DIR} # Private headers -#) -# -#target_link_libraries(heqat_common PRIVATE udev z) -# -#if(HE_QAT_SHARED) -# target_link_libraries(heqat_common PRIVATE ${ICP_BUILDOUTPUT_PATH}/libqat_s.so) -# target_link_libraries(heqat_common PRIVATE ${ICP_BUILDOUTPUT_PATH}/libusdm_drv_s.so) -#else() -# heqat_create_archive(heqat_common libadf_static) -# heqat_create_archive(heqat_common libosal_static) -# heqat_create_archive(heqat_common libqat_static) -# heqat_create_archive(heqat_common libusdm_drv_static) -#endif() -# -#install(TARGETS heqat_common EXPORT he_qatTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}) -# -#set(COMMON_INC_DIR ${COMMON_INC_DIR} PARENT_SCOPE) - - diff --git a/heqat/misc/CMakeLists.txt b/heqat/misc/CMakeLists.txt index b6719a9..99325e5 100644 --- a/heqat/misc/CMakeLists.txt +++ b/heqat/misc/CMakeLists.txt @@ -1,59 +1,6 @@ - +# Add MISC source code set(HE_QAT_MISC_SRC ${CMAKE_CURRENT_LIST_DIR}/misc.cpp ${CMAKE_CURRENT_LIST_DIR}/utils.cpp ${CMAKE_CURRENT_LIST_DIR}/bignum.cpp) - list(APPEND HE_QAT_SRC ${HE_QAT_MISC_SRC}) - set(HE_QAT_SRC ${HE_QAT_SRC} PARENT_SCOPE) - -##Include directories -##list(APPEND HE_QAT_MISC_INC_DIR -#set(HE_QAT_MISC_INC_DIR ${COMMON_INC_DIR} -# ${HE_QAT_INC_DIR} -# ${CMAKE_CURRENT_LIST_DIR} -# # ${IPPCP_DIR}/include -#) -# -#message(STATUS "HE_QAT_MISC_INC_DIR: ${HE_QAT_MISC_INC_DIR}") -# -##Source files -##list(APPEND HE_QAT_MISC_SRC ${CMAKE_CURRENT_LIST_DIR} / utils.cpp -#set(HE_QAT_MISC_SRC -# ${CMAKE_CURRENT_LIST_DIR}/heqat_misc.cpp -# ${CMAKE_CURRENT_LIST_DIR}/utils.cpp -# ${CMAKE_CURRENT_LIST_DIR}/bignum.cpp) -# -#if(HE_QAT_SHARED) -# add_library(heqat_misc SHARED ${HE_QAT_MISC_SRC}) -#else() -# add_library(heqat_misc STATIC ${HE_QAT_MISC_SRC}) -#endif() -# -#message(STATUS "IPPCP Headers Directory ${IPPCP_DIR}/include") -#target_include_directories(heqat_misc #PUBLIC $ #Public headers -# #PUBLIC $ #Public headers -# PRIVATE ${IPPCP_DIR}/../../../include -# PRIVATE ${HE_QAT_MISC_INC_DIR} #Private headers -# PRIVATE ${ICP_INC_DIR} #Private headers -# -#) -##target_link_directories(he_qat_misc PUBLIC ${IPPCP_DIR}/lib/intel64) -##target_link_libraries(he_qat_misc PRIVATE ippcpmx crypto_mb) -# -#if(HE_QAT_SHARED) -# target_link_libraries(heqat_misc PRIVATE IPPCP::ippcp IPPCP::crypto_mb) -#else() -# heqat_create_archive(heqat_misc IPPCP::ippcp) -# heqat_create_archive(heqat_misc IPPCP::crypto_mb) -#endif() -# -#install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/ -# DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ -# FILES_MATCHING -# PATTERN "*.hpp" -# PATTERN "*.h") -##install(TARGETS he_qat_misc DESTINATION ${CMAKE_INSTALL_LIBDIR}) -#install(TARGETS heqat_misc EXPORT he_qatTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}) -# -#set(HE_QAT_MISC_INC_DIR ${HE_QAT_MISC_INC_DIR} PARENT_SCOPE) From 10ac85231721f36e1b056f4fac99fc9de902ae95 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 18 Oct 2022 14:32:49 -0700 Subject: [PATCH 287/364] Update heqat module. Signed-off-by: Souza, Fillipe --- module/heqat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/heqat b/module/heqat index 801e491..bd0f7a9 160000 --- a/module/heqat +++ b/module/heqat @@ -1 +1 @@ -Subproject commit 801e491dbdb60261bd830fac307d5d5c7c9b61c5 +Subproject commit bd0f7a98d7949dc57e635dff0fdc390b2469e1c8 From 47a21a2726733f592d940fa9d6cdc0d30f8db3d4 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 18 Oct 2022 15:11:29 -0700 Subject: [PATCH 288/364] Fix compilation for static lib. Signed-off-by: Souza, Fillipe --- CMakeLists.txt | 2 +- example/CMakeLists.txt | 5 ++++- heqat/CMakeLists.txt | 2 -- heqat/include/heqat/heqat.h | 1 - samples/CMakeLists.txt | 15 +++------------ 5 files changed, 8 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 10f02f5..45ee6fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.13) # The hekat or heqat (transcribed HqA.t) was an ancient Egyptian volume unit # used to measure grain, bread, and beer. -project(HE_QAT VERSION 1.3.0 LANGUAGES C CXX) +project(HE_QAT VERSION 1.3.1 LANGUAGES C CXX) include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index ae65df5..2aea6a1 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -14,11 +14,14 @@ if(NOT TARGET HE_QAT::he_qat) message(FATAL_ERROR "TARGET HE_QAT::he_qat not found") endif() -if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") +if(CMAKE_BUILD_TYPE STREQUAL "Debug") add_definitions(-DHE_QAT_DEBUG) endif() find_package(OpenSSL REQUIRED) +find_package(Threads REQUIRED) +set(CMAKE_THREAD_PREFER_PTHREAD ON) +set(THREADS_PREFER_PTHREAD_FLAG ON) include(../icp/CMakeLists.txt) diff --git a/heqat/CMakeLists.txt b/heqat/CMakeLists.txt index 0b00a3a..7dfe4c7 100644 --- a/heqat/CMakeLists.txt +++ b/heqat/CMakeLists.txt @@ -43,8 +43,6 @@ if(HE_QAT_SHARED) target_link_libraries(he_qat PRIVATE qat_s) target_link_libraries(he_qat PRIVATE usdm_drv_s) else() - heqat_create_archive(he_qat OpenSSL::SSL) - heqat_create_archive(he_qat Threads::Threads) heqat_create_archive(he_qat libadf_static) heqat_create_archive(he_qat libosal_static) heqat_create_archive(he_qat libqat_static) diff --git a/heqat/include/heqat/heqat.h b/heqat/include/heqat/heqat.h index 5921924..9b5c7a7 100644 --- a/heqat/include/heqat/heqat.h +++ b/heqat/include/heqat/heqat.h @@ -1,5 +1,4 @@ /// @file heqat/heqat.h -//#pragma once #include "heqat/common.h" #include "heqat/context.h" diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 6d0fd3a..64791f4 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -28,10 +28,7 @@ endmacro() ############################################################################## -set(EXECUTABLE_DEPENDENCIES - OpenSSL::SSL - IPPCP::ippcp -) +set(EXECUTABLE_DEPENDENCIES OpenSSL::SSL) # Sample testing the robustness of the heqatlib context functions heqat_create_executable(context c "") @@ -42,19 +39,13 @@ heqat_create_executable(BIGNUMModExp C EXECUTABLE_DEPENDENCIES) if(HE_QAT_MISC) add_compile_options(-fpermissive) + list(APPEND EXECUTABLE_DEPENDENCIES IPPCP::ippcp) + # Sample showing how to convert from/to BigNumber to/from CpaFlatBuffer heqat_create_executable(bnConversion cxx EXECUTABLE_DEPENDENCIES) # Sample showing how to use bnModExp API heqat_create_executable(bnModExp CXX EXECUTABLE_DEPENDENCIES) - # add_executable(sample_bnModExp test_bnModExp.cpp) - # - # target_include_directories(sample_bnModExp PUBLIC ${HE_QAT_INC_DIR}) - # target_include_directories(sample_bnModExp PUBLIC ${ICP_INC_DIR}) - # - # target_link_libraries(sample_bnModExp PUBLIC he_qat) - # target_link_libraries(sample_bnModExp PUBLIC OpenSSL::SSL) - # target_link_libraries(sample_bnModExp PUBLIC IPPCP::ippcp) if(OpenMP_CXX_FOUND) list(APPEND EXECUTABLE_DEPENDENCIES OpenMP::OpenMP_CXX) From 11e68624c072aa117d0641b83bb53b7701e37e2a Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 18 Oct 2022 15:14:47 -0700 Subject: [PATCH 289/364] Update heqat module. Signed-off-by: Souza, Fillipe --- module/heqat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/heqat b/module/heqat index bd0f7a9..47a21a2 160000 --- a/module/heqat +++ b/module/heqat @@ -1 +1 @@ -Subproject commit bd0f7a98d7949dc57e635dff0fdc390b2469e1c8 +Subproject commit 47a21a2726733f592d940fa9d6cdc0d30f8db3d4 From dabc87a5d05b964710647753ec53d65a3fab8cc7 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 18 Oct 2022 16:00:29 -0700 Subject: [PATCH 290/364] Add heqat to IPCL install dir. Signed-off-by: Souza, Fillipe --- ipcl/CMakeLists.txt | 11 +++++++++-- ipcl/context.cpp | 2 +- ipcl/mod_exp.cpp | 4 ++-- module/heqat.cmake | 11 ++++++++--- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 38eeaf8..77e47af 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -61,6 +61,14 @@ install(DIRECTORY ${IPPCRYPTO_INC_DIR}/ PATTERN "*.hpp" PATTERN "*.h") +if(IPCL_ENABLE_QAT) + install(DIRECTORY ${HEQAT_INC_DIR}/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING + PATTERN "*.hpp" + PATTERN "*.h") +endif() + find_package(OpenSSL REQUIRED) find_package(Threads REQUIRED) target_link_libraries(ipcl PUBLIC OpenSSL::SSL OpenSSL::Crypto Threads::Threads -lnuma) @@ -88,11 +96,10 @@ else() if(IPCL_ENABLE_QAT) ipcl_create_archive(ipcl libhe_qat) - message(STATUS "HEQAT_PREFIX_INCLUDE : ${HEQAT_PREFIX}/include") message(STATUS "HEQAT_INC_DIR : ${HEQAT_INC_DIR}") target_include_directories(ipcl PRIVATE "$") target_link_libraries(ipcl PRIVATE udev z) - endif() + endif() if(IPCL_DETECT_IFMA_RUNTIME) ipcl_create_archive(ipcl libcpu_features) diff --git a/ipcl/context.cpp b/ipcl/context.cpp index 14262a5..7a920f7 100644 --- a/ipcl/context.cpp +++ b/ipcl/context.cpp @@ -7,7 +7,7 @@ #include #ifdef IPCL_USE_QAT -#include +#include #endif namespace ipcl { diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index e1f68db..979cf8f 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -10,8 +10,8 @@ #include #ifdef IPCL_USE_QAT -#include -#include +#include +#include #endif #include "ipcl/util.hpp" diff --git a/module/heqat.cmake b/module/heqat.cmake index fbb5625..9adb27c 100644 --- a/module/heqat.cmake +++ b/module/heqat.cmake @@ -9,7 +9,7 @@ set(HEQAT_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/module/heqat) set(HEQAT_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS}") set(HEQAT_BUILD_TYPE Release) -if (CMAKE_BUILD_TYPE STREQUAL "Debug") +if (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") set(HEQAT_BUILD_TYPE Debug) endif() @@ -17,7 +17,7 @@ ExternalProject_Add( ext_he_qat SOURCE_DIR ${HEQAT_SRC_DIR} PREFIX ${HEQAT_PREFIX} - INSTALL_DIR ${HEQAT_DESTDIR} + # INSTALL_DIR ${HEQAT_DESTDIR} CMAKE_ARGS ${HEQAT_CXX_FLAGS} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DHE_QAT_MISC=OFF @@ -45,13 +45,18 @@ if(IPCL_SHARED) ExternalProject_Get_Property(ext_he_qat SOURCE_DIR BINARY_DIR) - target_link_libraries(libhe_qat INTERFACE ${HEQAT_LIB_DIR}/libcpa_sample_utils.so) if(CMAKE_BUILD_TYPE STREQUAL "Debug") target_link_libraries(libhe_qat INTERFACE ${HEQAT_LIB_DIR}/libhe_qat_debug.so) else() target_link_libraries(libhe_qat INTERFACE ${HEQAT_LIB_DIR}/libhe_qat.so) endif() target_include_directories(libhe_qat SYSTEM INTERFACE ${HEQAT_INC_DIR}) + + install( + DIRECTORY ${HEQAT_LIB_DIR}/ + DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/heqat" + USE_SOURCE_PERMISSIONS + ) else() add_library(libhe_qat STATIC IMPORTED GLOBAL) add_dependencies(libhe_qat ext_he_qat) From 81c9a37cf69979b2e8a993204f9c1c5d7076b5ac Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Wed, 19 Oct 2022 09:10:16 -0700 Subject: [PATCH 291/364] Fix header in ctrl.c (#31) --- heqat/ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/heqat/ctrl.c b/heqat/ctrl.c index 3f0e45b..bc1a55c 100644 --- a/heqat/ctrl.c +++ b/heqat/ctrl.c @@ -5,7 +5,7 @@ #include "cpa_cy_im.h" #include "cpa_cy_ln.h" #include "icp_sal_poll.h" -#include "cpa_sample_utils.h" +#include "heqat/common/cpa_sample_utils.h" // Global variables used to hold measured performance numbers. #ifdef HE_QAT_PERF From eba4a7bde9910842c3d2b96688c18a685c2a5741 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Wed, 19 Oct 2022 09:53:00 -0700 Subject: [PATCH 292/364] Fix fedora build --- cmake/cpufeatures.cmake | 4 ++-- cmake/gbenchmark.cmake | 4 ++-- cmake/gtest.cmake | 2 +- cmake/ippcrypto.cmake | 3 ++- module/heqat | 2 +- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/cmake/cpufeatures.cmake b/cmake/cpufeatures.cmake index 6df3c12..478fa10 100644 --- a/cmake/cpufeatures.cmake +++ b/cmake/cpufeatures.cmake @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 include(ExternalProject) -include(GNUInstallDirs) message(STATUS "configuring cpu_features") set(CPUFEATURES_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_cpufeatures) @@ -20,6 +19,7 @@ ExternalProject_Add( -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + -DCMAKE_INSTALL_LIBDIR=lib UPDATE_COMMAND "" EXCLUDE_FROM_ALL TRUE INSTALL_COMMAND make DESTDIR=${CPUFEATURES_DESTDIR} install @@ -27,7 +27,7 @@ ExternalProject_Add( set(CPUFEATURES_INC_DIR ${CPUFEATURES_DESTDIR}/${CMAKE_INSTALL_PREFIX}/include) -set(CPUFEATURES_LIB_DIR ${CPUFEATURES_DESTDIR}/${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) +set(CPUFEATURES_LIB_DIR ${CPUFEATURES_DESTDIR}/${CMAKE_INSTALL_PREFIX}/lib) if(IPCL_SHARED) add_library(libcpu_features INTERFACE) diff --git a/cmake/gbenchmark.cmake b/cmake/gbenchmark.cmake index 8c3e8c6..50118ef 100644 --- a/cmake/gbenchmark.cmake +++ b/cmake/gbenchmark.cmake @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 include(ExternalProject) -include(GNUInstallDirs) set(GBENCHMARK_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_gbenchmark) @@ -24,6 +23,7 @@ ExternalProject_Add( -DBENCHMARK_ENABLE_GTEST_TESTS=OFF -DBENCHMARK_ENABLE_TESTING=OFF -DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_LIBDIR=lib BUILD_BYPRODUCTS ${GBENCHMARK_PATHS} # Skip updates UPDATE_COMMAND "" @@ -33,7 +33,7 @@ ExternalProject_Add( add_library(libgbenchmark INTERFACE) add_dependencies(libgbenchmark ext_gbenchmark) -target_link_libraries(libgbenchmark INTERFACE ${GBENCHMARK_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libbenchmark.a) +target_link_libraries(libgbenchmark INTERFACE ${GBENCHMARK_PREFIX}/lib/libbenchmark.a) target_include_directories(libgbenchmark SYSTEM INTERFACE ${GBENCHMARK_PREFIX}/include) diff --git a/cmake/gtest.cmake b/cmake/gtest.cmake index 24b80a7..b5d9dc5 100644 --- a/cmake/gtest.cmake +++ b/cmake/gtest.cmake @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 include(ExternalProject) -include(GNUInstallDirs) set(GTEST_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_gtest) set(GTEST_GIT_REPO_URL https://github.com/google/googletest.git) @@ -16,6 +15,7 @@ ExternalProject_Add( GIT_TAG ${GTEST_GIT_LABEL} CMAKE_ARGS ${GTEST_CXX_FLAGS} -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + -DCMAKE_INSTALL_LIBDIR=lib UPDATE_COMMAND "" EXCLUDE_FROM_ALL TRUE INSTALL_COMMAND "" diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake index 497bad7..0e2135c 100644 --- a/cmake/ippcrypto.cmake +++ b/cmake/ippcrypto.cmake @@ -32,12 +32,13 @@ ExternalProject_Add( -DCMAKE_ASM_NASM_COMPILER=nasm -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + -DCMAKE_INSTALL_LIBDIR=lib UPDATE_COMMAND "" INSTALL_COMMAND make DESTDIR=${IPPCRYPTO_DESTDIR} install ) set(IPPCRYPTO_INC_DIR ${IPPCRYPTO_DESTDIR}/${CMAKE_INSTALL_PREFIX}/include) -set(IPPCRYPTO_LIB_DIR ${IPPCRYPTO_DESTDIR}/${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${IPPCRYPTO_ARCH}) +set(IPPCRYPTO_LIB_DIR ${IPPCRYPTO_DESTDIR}/${CMAKE_INSTALL_PREFIX}/lib/${IPPCRYPTO_ARCH}) if(IPCL_SHARED) add_library(libippcrypto INTERFACE) add_dependencies(libippcrypto ext_ipp-crypto) diff --git a/module/heqat b/module/heqat index 47a21a2..81c9a37 160000 --- a/module/heqat +++ b/module/heqat @@ -1 +1 @@ -Subproject commit 47a21a2726733f592d940fa9d6cdc0d30f8db3d4 +Subproject commit 81c9a37cf69979b2e8a993204f9c1c5d7076b5ac From a72bd3c5ced7bb2ffb323874ca0e2324b13743b9 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 19 Oct 2022 10:00:43 -0700 Subject: [PATCH 293/364] Fix header placement. Signed-off-by: Souza, Fillipe --- heqat/ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/heqat/ctrl.c b/heqat/ctrl.c index bc1a55c..f6ce48f 100644 --- a/heqat/ctrl.c +++ b/heqat/ctrl.c @@ -5,7 +5,6 @@ #include "cpa_cy_im.h" #include "cpa_cy_ln.h" #include "icp_sal_poll.h" -#include "heqat/common/cpa_sample_utils.h" // Global variables used to hold measured performance numbers. #ifdef HE_QAT_PERF @@ -21,6 +20,7 @@ double time_taken = 0.0; #include // Local headers +#include "heqat/common/cpa_sample_utils.h" #include "heqat/common/consts.h" #include "heqat/common/types.h" #include "heqat/bnops.h" From efb9be1e8670f8fcd9a444bc148da6a794a2063d Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 19 Oct 2022 10:03:52 -0700 Subject: [PATCH 294/364] Remove dangling header. Signed-off-by: Souza, Fillipe --- include/cpa_sample_utils.h | 651 ------------------------------------- 1 file changed, 651 deletions(-) delete mode 100644 include/cpa_sample_utils.h diff --git a/include/cpa_sample_utils.h b/include/cpa_sample_utils.h deleted file mode 100644 index a128640..0000000 --- a/include/cpa_sample_utils.h +++ /dev/null @@ -1,651 +0,0 @@ -/*************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Corporation - * - * BSD LICENSE - * - * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * version: QAT.L.4.15.0-00011 - * - ***************************************************************************/ - -/** - ***************************************************************************** - * @file cpa_sample_utils.h - * - * @defgroup sampleUtils Macro and inline function definitions - * - * @ingroup sampleCode - * - * @description - * Defines macros for printing and debugging, inline functions for memory - * allocating and freeing and thread creation - * - ***************************************************************************/ - -#ifndef CPA_SAMPLE_UTILS_H -#define CPA_SAMPLE_UTILS_H - -#ifdef __cplusplus -#define HE_QAT_RESTRICT __restrict__ -#else -#define HE_QAT_RESTRICT restrict -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#include "cpa.h" -#include "cpa_cy_im.h" -#include "cpa_dc.h" - - -#ifdef DO_CRYPTO -#include "cpa_cy_sym.h" -#endif - -#ifdef USER_SPACE -/* User space utils */ -#include -#include -#include -#include -#include -#include -/* Performance sample code mem utils */ - -#include "qae_mem.h" - -extern CpaDcHuffType huffmanType_g; -extern CpaStatus qaeMemInit(void); -extern void qaeMemDestroy(void); -/* Threads */ -typedef pthread_t sampleThread; - -/* Check for CY API version */ -#define CY_API_VERSION_AT_LEAST(major, minor) \ - (CPA_CY_API_VERSION_NUM_MAJOR > major || \ - (CPA_CY_API_VERSION_NUM_MAJOR == major && \ - CPA_CY_API_VERSION_NUM_MINOR >= minor)) - -#ifdef HE_QAT_DEBUG -#define HE_QAT_PRINT_DBG(args...) \ - do \ - { \ - { \ - printf("%s(): ", __func__); \ - printf(args); \ - fflush(stdout); \ - } \ - } while (0) -#else -#define HE_QAT_PRINT_DBG(args...) { } -#endif -/* Printing */ -/**< Prints the name of the function and the arguments only if gDebugParam is - * CPA_TRUE. - */ -#define PRINT_DBG(args...) \ - do \ - { \ - if (CPA_TRUE == gDebugParam) \ - { \ - printf("%s(): ", __func__); \ - printf(args); \ - fflush(stdout); \ - } \ - } while (0) - -/**< Prints the arguments */ -#ifndef PRINT -#define PRINT(args...) \ - do \ - { \ - printf(args); \ - } while (0) -#endif - -/**< Prints the name of the function and the arguments */ -#ifndef PRINT_ERR -#define PRINT_ERR(args...) \ - do \ - { \ - printf("%s(): ", __func__); \ - printf(args); \ - } while (0) -#endif -/** - ******************************************************************************* - * @ingroup sampleUtils - * Completion definitions - * - ******************************************************************************/ -struct completion_struct -{ - sem_t semaphore; -}; -/* Use semaphores to signal completion of events */ -#define COMPLETION_STRUCT completion_struct - -#define COMPLETION_INIT(s) sem_init(&((s)->semaphore), 0, 0); - -#define COMPLETION_WAIT(s, timeout) (sem_wait(&((s)->semaphore)) == 0) - -#define COMPLETE(s) sem_post(&((s)->semaphore)) - -#define COMPLETION_DESTROY(s) sem_destroy(&((s)->semaphore)) - -#else -/* Kernel space utils */ -#include -#include -#include -#include -#include -#include -#include - -#ifdef __x86_64__ -#define SAMPLE_ADDR_LEN uint64_t -#else -#define SAMPLE_ADDR_LEN uint32_t -#endif - -extern CpaDcHuffType huffmanType_g; - -/* Threads */ -typedef struct task_struct *sampleThread; - -/* Check for CY API version */ -#define CY_API_VERSION_AT_LEAST(major, minor) \ - (CPA_CY_API_VERSION_NUM_MAJOR > major || \ - (CPA_CY_API_VERSION_NUM_MAJOR == major && \ - CPA_CY_API_VERSION_NUM_MINOR >= minor)) - -/* Printing */ -/**< Prints the name of the function and the arguments only if gDebugParam is - * CPA_TRUE. - */ -#define PRINT_DBG(args...) \ - do \ - { \ - if (CPA_TRUE == gDebugParam) \ - { \ - printk("%s(): ", __func__); \ - printk(KERN_CONT args); \ - } \ - } while (0) - -/**< Regular prints */ -#ifndef PRINT -#define PRINT(args...) \ - do \ - { \ - printk(KERN_CONT args); \ - } while (0) -#endif - -/**< Prints the name of the function and the arguments */ -#ifndef PRINT_ERR -#define PRINT_ERR(args...) \ - do \ - { \ - printk("%s(): ", __func__); \ - printk(KERN_CONT args); \ - } while (0) -#endif -/** - ******************************************************************************* - * @ingroup sampleUtils - * Completion definitions - * - ******************************************************************************/ -#define COMPLETION_STRUCT completion - -#define COMPLETION_INIT(c) init_completion(c) - -#define COMPLETION_WAIT(c, timeout) \ - wait_for_completion_interruptible_timeout(c, timeout) - -#define COMPLETE(c) complete(c) - -#define COMPLETION_DESTROY(s) - -#endif - -#ifndef BYTE_ALIGNMENT_8 -#define BYTE_ALIGNMENT_8 (8) -#endif -#ifndef BYTE_ALIGNMENT_64 -#define BYTE_ALIGNMENT_64 (64) -#endif - -/** - ***************************************************************************** - * @ingroup fipsSampleCodeUtils - * displayHexArray - * - * @description - * Display the contents of a buffer - * - * @param[in] pLabel String to giving a short description of the printed - * value - * @param[in] pBuff pointer to the data to be printed - * @param[in] len len of the data to be printed - * - * @retval none - * - * @pre - * none - * @post - * none - *****************************************************************************/ -static inline void displayHexArray(const char *HE_QAT_RESTRICT pLabel, - const Cpa8U *HE_QAT_RESTRICT pBuff, - Cpa32U len) -{ - - int i = 0; - PRINT("%s(%d)", pLabel, len); - if (NULL == pBuff) - { - PRINT("%s(%d) Buff is NULL!!\n", __FUNCTION__, __LINE__); - return; - } - for (i = 0; i < len; i++) - { - PRINT("%02x", pBuff[i]); - } - PRINT("\n"); -} -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function and associated macro sleeps for ms milliseconds - * - * @param[in] ms sleep time in ms - * - * @retval none - * - ******************************************************************************/ -static __inline CpaStatus sampleSleep(Cpa32U ms) -{ -#ifdef USER_SPACE - int ret = 0; - struct timespec resTime, remTime; - //resTime.tv_sec = ms / 1000; - //resTime.tv_nsec = (ms % 1000) * 1000000; - // microseconds - resTime.tv_sec = ms / 1000000; - resTime.tv_nsec = (ms % 1000000) * 1000; - do - { - ret = nanosleep(&resTime, &remTime); - resTime = remTime; - } while ((ret != 0) && (errno == EINTR)); - - if (ret != 0) - { - PRINT_ERR("nanoSleep failed with code %d\n", ret); - return CPA_STATUS_FAIL; - } - else - { - return CPA_STATUS_SUCCESS; - } -#else - if (ms != 0) - { - set_current_state((long)TASK_INTERRUPTIBLE); - schedule_timeout((ms * HZ) / 1000); - } - else - { - schedule(); - } - - return CPA_STATUS_SUCCESS; -#endif -} -/** - ******************************************************************************* - * @ingroup sampleUtils - * Macro from the sampleSleep function - * - ******************************************************************************/ -#define OS_SLEEP(ms) sampleSleep((ms)) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function and associated macro allocates the memory for the given - * size and stores the address of the memory allocated in the pointer. - * Memory allocated by this function is NOT guaranteed to be physically - * contiguous. - * - * @param[out] ppMemAddr address of pointer where address will be stored - * @param[in] sizeBytes the size of the memory to be allocated - * - * @retval CPA_STATUS_RESOURCE Macro failed to allocate Memory - * @retval CPA_STATUS_SUCCESS Macro executed successfully - * - ******************************************************************************/ -static __inline CpaStatus Mem_OsMemAlloc(void **ppMemAddr, Cpa32U sizeBytes) -{ -#ifdef USER_SPACE - *ppMemAddr = malloc(sizeBytes); - if (NULL == *ppMemAddr) - { - return CPA_STATUS_RESOURCE; - } - return CPA_STATUS_SUCCESS; -#else - *ppMemAddr = kmalloc(sizeBytes, GFP_KERNEL); - if (NULL == *ppMemAddr) - { - return CPA_STATUS_RESOURCE; - } - return CPA_STATUS_SUCCESS; -#endif -} - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function and associated macro allocates the memory for the given - * size for the given alignment and stores the address of the memory - * allocated in the pointer. Memory allocated by this function is - * guaranteed to be physically contiguous. - * - * @param[out] ppMemAddr address of pointer where address will be stored - * @param[in] sizeBytes the size of the memory to be allocated - * @param[in] alignement the alignment of the memory to be allocated - *(non-zero) - * - * @retval CPA_STATUS_RESOURCE Macro failed to allocate Memory - * @retval CPA_STATUS_SUCCESS Macro executed successfully - * - ******************************************************************************/ -static __inline CpaStatus Mem_Alloc_Contig(void **ppMemAddr, - Cpa32U sizeBytes, - Cpa32U alignment) -{ -#ifdef USER_SPACE - /* Use perf sample code memory allocator */ - - /* In this sample all allocations are done from node=0 - * This might not be optimal in a dual processor system. - */ - *ppMemAddr = qaeMemAllocNUMA(sizeBytes, 0, alignment); - if (NULL == *ppMemAddr) - { - return CPA_STATUS_RESOURCE; - } - return CPA_STATUS_SUCCESS; -#else - void *pAlloc = NULL; - uint32_t align = 0; - - pAlloc = - kmalloc_node((sizeBytes + alignment + sizeof(void *)), GFP_KERNEL, 0); - if (NULL == pAlloc) - { - return CPA_STATUS_RESOURCE; - } - - *ppMemAddr = pAlloc + sizeof(void *); - - align = ((SAMPLE_ADDR_LEN)(*ppMemAddr)) % alignment; - - *ppMemAddr += (alignment - align); - *(SAMPLE_ADDR_LEN *)(*ppMemAddr - sizeof(void *)) = (SAMPLE_ADDR_LEN)pAlloc; - - return CPA_STATUS_SUCCESS; -#endif -} - -/** - ******************************************************************************* - * @ingroup sampleUtils - * Macro from the Mem_OsMemAlloc function - * - ******************************************************************************/ -#define OS_MALLOC(ppMemAddr, sizeBytes) \ - Mem_OsMemAlloc((void *)(ppMemAddr), (sizeBytes)) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * Macro from the Mem_Alloc_Contig function - * - ******************************************************************************/ -#define PHYS_CONTIG_ALLOC(ppMemAddr, sizeBytes) \ - Mem_Alloc_Contig((void *)(ppMemAddr), (sizeBytes), 1) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * Algined version of PHYS_CONTIG_ALLOC() macro - * - ******************************************************************************/ -#define PHYS_CONTIG_ALLOC_ALIGNED(ppMemAddr, sizeBytes, alignment) \ - Mem_Alloc_Contig((void *)(ppMemAddr), (sizeBytes), (alignment)) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function and associated macro frees the memory at the given address - * and resets the pointer to NULL. The memory must have been allocated by - * the function Mem_OsMemAlloc() - * - * @param[out] ppMemAddr address of pointer where mem address is stored. - * If pointer is NULL, the function will exit silently - * - * @retval void - * - ******************************************************************************/ -static __inline void Mem_OsMemFree(void **ppMemAddr) -{ -#ifdef USER_SPACE - if (NULL != *ppMemAddr) - { - free(*ppMemAddr); - *ppMemAddr = NULL; - } -#else - if (NULL != *ppMemAddr) - { - kfree(*ppMemAddr); - *ppMemAddr = NULL; - } -#endif -} - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function and associated macro frees the memory at the given address - * and resets the pointer to NULL. The memory must have been allocated by - * the function Mem_Alloc_Contig(). - * - * @param[out] ppMemAddr address of pointer where mem address is stored. - * If pointer is NULL, the function will exit silently - * - * @retval void - * - ******************************************************************************/ -static __inline void Mem_Free_Contig(void **ppMemAddr) -{ -#ifdef USER_SPACE - if (NULL != *ppMemAddr) - { - qaeMemFreeNUMA(ppMemAddr); - *ppMemAddr = NULL; - } -#else - void *pAlloc = NULL; - - if (NULL != *ppMemAddr) - { - pAlloc = (void *)(*((SAMPLE_ADDR_LEN *)(*ppMemAddr - sizeof(void *)))); - kfree(pAlloc); - *ppMemAddr = NULL; - } -#endif -} - -/** - ******************************************************************************* - * @ingroup sampleUtils - * Macro from the Mem_OsMemFree function - * - ******************************************************************************/ -#define OS_FREE(pMemAddr) Mem_OsMemFree((void *)&pMemAddr) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * Macro from the Mem_Free_Contig function - * - ******************************************************************************/ -#define PHYS_CONTIG_FREE(pMemAddr) Mem_Free_Contig((void *)&pMemAddr) - -#define _4K_PAGE_SIZE (4 * 1024) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function returns the physical address for a given virtual address. - * In case of error 0 is returned. - * - * @param[in] virtAddr Virtual address - * - * @retval CpaPhysicalAddr Physical address or 0 in case of error - * - ******************************************************************************/ - -static __inline CpaPhysicalAddr sampleVirtToPhys(void *virtAddr) -{ -#ifdef USER_SPACE - return (CpaPhysicalAddr)qaeVirtToPhysNUMA(virtAddr); -#else - return (CpaPhysicalAddr)virt_to_phys(virtAddr); -#endif -} - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function creates a thread - * - ******************************************************************************/ - -static __inline CpaStatus sampleThreadCreate(sampleThread *thread, - void *funct, - void *args) -{ -#ifdef USER_SPACE -#ifdef __cplusplus - if (pthread_create(thread, NULL, (void* (*)(void*)) funct, args) != 0) -#else - if (pthread_create(thread, NULL, funct, args) != 0) -#endif - { - PRINT_ERR("Failed create thread\n"); - return CPA_STATUS_FAIL; - } - else - { - pthread_detach(*thread); - return CPA_STATUS_SUCCESS; - } -#else - *thread = kthread_create(funct, args, "SAMPLE_THREAD"); - wake_up_process(*thread); - return CPA_STATUS_SUCCESS; -#endif -} - -static __inline void sampleThreadExit(void) -{ -#ifdef USER_SPACE - pthread_exit(NULL); -#endif -} - -#ifdef DO_CRYPTO -void sampleCyGetInstance(CpaInstanceHandle *pCyInstHandle); - -void sampleCyStartPolling(CpaInstanceHandle cyInstHandle); - -void sampleCyStopPolling(void); - -void symSessionWaitForInflightReq(CpaCySymSessionCtx pSessionCtx); -#endif // DO_CRYPTO - -void sampleDcGetInstance(CpaInstanceHandle *pDcInstHandle); - -void sampleDcStartPolling(CpaInstanceHandle dcInstHandle); - -void sampleDcStopPolling(void); - -#ifdef __cplusplus -} //extern "C" { -#endif - - -#endif - From 004a3f88f77c882efe1969201a41a17332402c77 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Wed, 19 Oct 2022 11:03:49 -0700 Subject: [PATCH 295/364] Applied fedora build fix --- module/heqat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/heqat b/module/heqat index 81c9a37..efb9be1 160000 --- a/module/heqat +++ b/module/heqat @@ -1 +1 @@ -Subproject commit 81c9a37cf69979b2e8a993204f9c1c5d7076b5ac +Subproject commit efb9be1e8670f8fcd9a444bc148da6a794a2063d From 251a54832aff7cc54cc759e68030ff47c1b85ae8 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 19 Oct 2022 15:15:27 -0700 Subject: [PATCH 296/364] Update heqat module. Signed-off-by: Souza, Fillipe --- module/heqat.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/heqat.cmake b/module/heqat.cmake index 9adb27c..1a0a0f3 100644 --- a/module/heqat.cmake +++ b/module/heqat.cmake @@ -37,8 +37,8 @@ set(HEQAT_LIB_DIR ${HEQAT_DESTDIR}/${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDI # Bring up CPA variables include(${HEQAT_SRC_DIR}/icp/CMakeLists.txt) -list(APPEND HEQAT_INC_DIR ${ICP_INC_DIR}) +# Create heqat library interface if(IPCL_SHARED) add_library(libhe_qat INTERFACE) add_dependencies(libhe_qat ext_he_qat) From 7483345edc8c63880e93a44db4a958719107c677 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Wed, 19 Oct 2022 15:16:39 -0700 Subject: [PATCH 297/364] Install ICP headers. Signed-off-by: Souza, Fillipe --- ipcl/CMakeLists.txt | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 77e47af..87643d6 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -62,6 +62,16 @@ install(DIRECTORY ${IPPCRYPTO_INC_DIR}/ PATTERN "*.h") if(IPCL_ENABLE_QAT) + target_include_directories(ipcl PUBLIC "$") + target_include_directories(ipcl PUBLIC "$") + target_include_directories(ipcl PUBLIC "$") + + install(DIRECTORY ${ICP_INC_DIR}/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING + PATTERN "*.hpp" + PATTERN "*.h") + install(DIRECTORY ${HEQAT_INC_DIR}/ DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING @@ -81,11 +91,12 @@ endif() if(IPCL_SHARED) target_link_libraries(ipcl PRIVATE libippcrypto) if(IPCL_DETECT_IFMA_RUNTIME) - target_link_libraries(ipcl PRIVATE libcpu_features) - target_include_directories(ipcl PRIVATE ${CPUFEATURES_INC_DIR}) + target_link_libraries(ipcl PRIVATE libcpu_features) + target_include_directories(ipcl PRIVATE ${CPUFEATURES_INC_DIR}) endif() target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) if(IPCL_ENABLE_QAT) + target_include_directories(ipcl PRIVATE ${HEQAT_INC_DIR}) target_link_libraries(ipcl PRIVATE libhe_qat udev z) endif() @@ -95,15 +106,14 @@ else() ipcl_create_archive(ipcl libippcrypto::crypto_mb) if(IPCL_ENABLE_QAT) - ipcl_create_archive(ipcl libhe_qat) - message(STATUS "HEQAT_INC_DIR : ${HEQAT_INC_DIR}") - target_include_directories(ipcl PRIVATE "$") - target_link_libraries(ipcl PRIVATE udev z) + ipcl_create_archive(ipcl libhe_qat) + target_include_directories(ipcl PRIVATE ${HEQAT_INC_DIR}) + target_link_libraries(ipcl PRIVATE udev z) endif() if(IPCL_DETECT_IFMA_RUNTIME) - ipcl_create_archive(ipcl libcpu_features) - target_include_directories(ipcl PRIVATE ${CPUFEATURES_INC_DIR}) + ipcl_create_archive(ipcl libcpu_features) + target_include_directories(ipcl PRIVATE ${CPUFEATURES_INC_DIR}) endif() target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) From b371755d552fdff03c7e180d5ec6a6b6463bc334 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 25 Oct 2022 16:42:01 -0700 Subject: [PATCH 298/364] Update CMakeLists.txt Signed-off-by: Souza, Fillipe --- CMakeLists.txt | 2 +- example/CMakeLists.txt | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 45ee6fb..ada67a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.13) # The hekat or heqat (transcribed HqA.t) was an ancient Egyptian volume unit # used to measure grain, bread, and beer. -project(HE_QAT VERSION 1.3.1 LANGUAGES C CXX) +project(HE_QAT VERSION 1.3.2 LANGUAGES C CXX) include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 2aea6a1..88753b9 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -7,7 +7,7 @@ set(HE_QAT_HINT_DIR ${CMAKE_PREFIX_PATH}) message(STATUS "CMAKE_PREFIX_PATH ${HE_QAT_HINT_DIR}") # Example using source -find_package(HE_QAT 1.3.0 +find_package(HE_QAT 1.3.2 HINTS ${HE_QAT_HINT_DIR} REQUIRED) if(NOT TARGET HE_QAT::he_qat) @@ -29,5 +29,4 @@ add_definitions(-fpermissive) add_executable(example example.cpp) target_include_directories(example PRIVATE ${ICP_INC_DIR}) target_link_libraries(example PRIVATE HE_QAT::he_qat) -target_link_libraries(example PRIVATE qat_s) target_link_libraries(example PRIVATE OpenSSL::SSL) From 7a3a66aaaad0a1b37a271969cb2a9bd233eda65a Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 25 Oct 2022 16:46:07 -0700 Subject: [PATCH 299/364] Update README.md. Signed-off-by: Souza, Fillipe --- README.md | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index b50cfd5..1b6359e 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ The hardware requirement to use the library is the following: - Intel 4xxx co-processor -As for the operating systems, the library has been tested and confirmed to work on Ubuntu 20.04. +As for the operating systems, the library has been tested and confirmed to work on Ubuntu 20.04 and CentOS 7.9. ### Dependencies @@ -132,9 +132,13 @@ $ sudo usermod -aG qat $USER Verify the QAT installation by checking the QAT service status: - + - Ubuntu ``` sudo service qat_service status +``` + - CentOS +``` +sudo systemctl status qat_service.service ``` If all checks out, following the instructions below to build the HE QAT library. @@ -144,18 +148,23 @@ If all checks out, following the instructions below to build the HE QAT library. This step is required. Note that if the step [Installing QAT Software Stack](#installing-qat-software-stack) has just been performed, then the exact path of the installation is known, i.e. ``` -$ export ICP_ROOT=$HOME/QAT +export ICP_ROOT=$HOME/QAT ``` -Alternatively, if the system has a ore-built QAT software stack, the script `auto_find_qat_install.sh` can used to help automatically find the path where it was installed (see command below). +Alternatively, if the system has a pre-built QAT software stack installed, the script `auto_find_qat_install.sh` can used to help automatically find the path where it was installed (see command below). The script `auto_find_qat_install.sh` assumes that the QAT package is installed in a single location, such that if multiple installations are available at different locations, the script may produce undetermined behavior. + - Explicity way: ``` -$ export ICP_ROOT=$(./auto_find_qat_install.sh) +export ICP_ROOT=$(./auto_find_qat_install.sh) +``` + - Implicity way: +``` +source setup_env.sh ``` #### Building the Library -Execute step []() before building the library. +Follow the steps in the sections [Installing QAT Software Stack](#installing-qat-software-stack) and [Setup Environment](#setup-environment) before attempting to build the library. - How to build without `BigNumber` support @@ -193,16 +202,18 @@ $ cmake --build _build -j $ sudo cmake --install _build ``` -#### Configure QAT endpoints +#### Configuring QAT endpoints Before trying to run any application or example that uses the HE QAT Lib, the QAT endpoints must be configured. -The default configuration provided in this release is the optimal configuration to provide computing acceleration support for IPCL. -The boilerplate configurations can be found in the directory `config`. +The default configuration provided in this release is the optimal configuration to provide computing acceleration support for [IPCL](https://github.com/intel/pailliercryptolib). +The boilerplate configurations can be found in the `config` directory. ``` -$ ./setup_devices.sh +./scripts/setup_devices.sh ``` +The script above will configure the QAT devices to perform asymmetric functions only. + #### Configuration Options In addition to the standard CMake configuration options, Intel HE Acceleration Library for QAT supports several cmake options to configure the build. For convenience, they are listed below: From 77d128ba0023e7ce7b9ac3f021787c3584059c4e Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Tue, 25 Oct 2022 16:49:20 -0700 Subject: [PATCH 300/364] Update setup_devices.sh script. Signed-off-by: Souza, Fillipe --- scripts/setup_devices.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/setup_devices.sh b/scripts/setup_devices.sh index 2cc3bb6..c0f7475 100755 --- a/scripts/setup_devices.sh +++ b/scripts/setup_devices.sh @@ -5,7 +5,8 @@ # Refresh echo "sudo service restart qat_service" -sudo service qat_service restart +#sudo service qat_service restart +sudo systemctl restart qat_service.service num_phys_dev=$(lspci -d 8086:4940 | wc -l) if [ $num_phys_dev -eq 0 ]; then @@ -72,7 +73,8 @@ done # Refresh echo "sudo service restart qat_service" -sudo service qat_service restart +#sudo service qat_service restart +sudo systemctl restart qat_service.service # If Virtualization Mode Enabled start=0 From a2be0a019654e06ce8391d3e62a5bf1a7dfc865b Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Tue, 25 Oct 2022 22:47:48 -0700 Subject: [PATCH 301/364] Updated install paths (#137) * Major updates - Refactor installation - Updated install rpath - Added ```heqat``` and install libraries under ```${CMAKE_INSTALL_LIBDIR}/ipcl/``` - Rearrange headers installation: public header and everything in ```${CMAKE_INSTALL_INCLUDEDIR}/ipcl``` - Added ippcrypto patch file to modify absoluate paths - works only with ippcp_2021.6 tag - to support custom include location - Added CMake functions for lscpu and qat detection - Added qat environment variable check, qat processors devices detection and service status check - Set OPENSSL_USE_STATIC_LIBS to FLASE when building IPCL static library * Minor updates - Removed unused ```${IPCL_INCLUDE_DIR}``` flag in examples cmake file - Removed unneeded and obsolete installation commands in ```ipcl/CMakeLists.txt``` - Refactoring and cleanup overall cmake files --- CMakeLists.txt | 134 +++++++++++++++++++----------------- cmake/cpufeatures.cmake | 2 +- cmake/ipcl/ipcl-util.cmake | 69 +++++++++++++++++++ cmake/ippcrypto.cmake | 6 +- cmake/ippcrypto_patch.patch | 87 +++++++++++++++++++++++ example/CMakeLists.txt | 2 +- example/test.cpp | 3 + ipcl/CMakeLists.txt | 82 +++++++++++----------- module/heqat.cmake | 9 ++- 9 files changed, 278 insertions(+), 116 deletions(-) create mode 100644 cmake/ippcrypto_patch.patch diff --git a/CMakeLists.txt b/CMakeLists.txt index a91d374..e1ead8b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,10 +5,13 @@ cmake_minimum_required(VERSION 3.15.1) project(IPCL VERSION 2.0.0 LANGUAGES C CXX) +# includes include(CMakePackageConfigHelpers) include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) include(GNUInstallDirs) +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ipcl) +include(ipcl-util) if(CMAKE_BUILD_TYPE) set(RELEASE_TYPES @@ -42,10 +45,11 @@ endif() set(CMAKE_C_FLAGS "-O2 -Wno-error=deprecated-declarations") set(CMAKE_CXX_FLAGS "-O2 -fpermissive -Wno-error=deprecated-declarations") -set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR};${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ippcrypto") +set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ipcl;${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ipcl/ippcrypto") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) + #--------------------------------------------------- option(IPCL_TEST "Enable testing" ON) option(IPCL_BENCHMARK "Enable benchmark" ON) @@ -55,22 +59,23 @@ option(IPCL_ENABLE_OMP "Enable OpenMP testing/benchmarking" ON) option(IPCL_THREAD_COUNT "The max number of threads used by OpenMP(If the value is OFF/0, it is determined at runtime)" OFF) option(IPCL_DOCS "Enable document building" OFF) option(IPCL_SHARED "Build shared library" ON) +option(IPCL_DETECT_IFMA_RUNTIME "Detect AVX512/IFMA instructions during runtime" OFF) +option(IPCL_DEBUG_DISABLE_AVX512IFMA "(Debugging) Disable usage of AVX512IFMA instructions" OFF) if(IPCL_ENABLE_QAT) - add_compile_definitions(IPCL_USE_QAT) - message(STATUS "QAT enabled - IPCL_ENABLE_OMP set to OFF") - set(IPCL_ENABLE_OMP OFF) - if(IPCL_USE_QAT_LITE) - add_compile_definitions(IPCL_USE_QAT_LITE) - message(STATUS "QAT Lite enabled - IPCL_USE_QAT_LITE set to ON") - else() - message(STATUS "QAT Lite disabled - IPCL_USE_QAT_LITE set to OFF") + ipcl_detect_qat() + if(IPCL_FOUND_QAT) + add_compile_definitions(IPCL_USE_QAT) + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ipcl/heqat") + if(IPCL_USE_QAT_LITE) + add_compile_definitions(IPCL_USE_QAT_LITE) + message(STATUS "QAT Lite enabled - IPCL_USE_QAT_LITE set to ON") + else() + message(STATUS "QAT Lite disabled - IPCL_USE_QAT_LITE set to OFF") + endif() endif() endif() -option(IPCL_DETECT_IFMA_RUNTIME "Detect AVX512/IFMA instructions during runtime" OFF) -option(IPCL_DEBUG_DISABLE_AVX512IFMA "(Debugging) Disable usage of AVX512IFMA instructions" OFF) - if(IPCL_ENABLE_OMP) add_compile_definitions(IPCL_USE_OMP) if(IPCL_THREAD_COUNT) @@ -78,15 +83,22 @@ if(IPCL_ENABLE_OMP) endif() endif() - -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(IPCL_DEBUG ON) +if(IPCL_DETECT_IFMA_RUNTIME) + add_compile_definitions(IPCL_RUNTIME_MOD_EXP) + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ipcl/cpufeatures") else() - set(IPCL_DEBUG OFF) + # check whether cpu support avx512 flag + if(IPCL_DEBUG_DISABLE_AVX512IFMA) + message(STATUS "Support AVX512IFMA: False") + else() + ipcl_detect_lscpu_flag("avx512ifma" FALSE) + if(IPCL_FOUND_avx512ifma) + add_compile_definitions(IPCL_CRYPTO_MB_MOD_EXP) + message(STATUS "Support AVX512IFMA instruction: True") + endif() + endif() endif() -set(IPCL_CMAKE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/ipcl") - message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}") message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}") @@ -104,10 +116,24 @@ message(STATUS "IPCL_DOCS: ${IPCL_DOCS}") message(STATUS "IPCL_SHARED: ${IPCL_SHARED}") message(STATUS "IPCL_DETECT_IFMA_RUNTIME: ${IPCL_DETECT_IFMA_RUNTIME}") -set(IPCL_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) -set(IPCL_SRC_DIR ${IPCL_ROOT_DIR}/ipcl) -set(IPCL_INC_DIR ${IPCL_SRC_DIR}/include) - +# check whether cpu support rdseed or rdrand instruction +ipcl_detect_lscpu_flag("rdseed" FALSE) +if(IPCL_FOUND_rdseed) + message(STATUS "Support RDSEED instruction: True") + add_compile_definitions(IPCL_RNG_INSTR_RDSEED) +else() + ipcl_detect_lscpu_flag("rdrand" FALSE) + if(IPCL_FOUND_rdrand) + message(STATUS "Support RDRAND instruction: True") + add_compile_definitions(IPCL_RNG_INSTR_RDRAND) + else() + message(WARNING + "CPU doesn't support RDSEED and RDRAND instruction, using IPP-Crypto" + " S/W psuedo random number generator" + ) + endif() +endif() + set(IPCL_FORWARD_CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} @@ -120,55 +146,33 @@ set(IPCL_FORWARD_CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ) -if(IPCL_DETECT_IFMA_RUNTIME) - add_compile_definitions(IPCL_RUNTIME_MOD_EXP) - set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cpufeatures") -else() - # check whether cpu support avx512 flag - if(IPCL_DEBUG_DISABLE_AVX512IFMA) - message(STATUS "Support AVX512IFMA: False") - else() - set(CPU_AVX512_FLAG "avx512ifma") - execute_process(COMMAND lscpu COMMAND grep ${CPU_AVX512_FLAG} OUTPUT_VARIABLE CPU_ENABLE_AVX512) - if("${CPU_ENABLE_AVX512}" STREQUAL "") - message(STATUS "Support AVX512IFMA: False") - else() - message(STATUS "Support AVX512IFMA: True") - add_compile_definitions(IPCL_CRYPTO_MB_MOD_EXP) - endif() - endif() -endif() - -# check whether cpu support rdseed or rdrand instruction -set(CPU_RDSEED_FLAG "rdseed") -execute_process(COMMAND lscpu COMMAND grep ${CPU_RDSEED_FLAG} OUTPUT_VARIABLE CPU_ENABLE_RDSEED) -if("${CPU_ENABLE_RDSEED}" STREQUAL "") - set(CPU_RDRAND_FLAG "rdrand") - execute_process(COMMAND lscpu COMMAND grep ${CPU_RDRAND_FLAG} OUTPUT_VARIABLE CPU_ENABLE_RDRAND) - if("${CPU_ENABLE_RDRAND}" STREQUAL "") - message(WARNING "CPU doesn't support RDSEED and RDRAND instruction, using random generator will cause errors.") - else () - message(STATUS "Support RDRAND instruction: True") - add_compile_definitions(IPCL_RNG_INSTR_RDRAND) - endif() +# global IPCL folders +set(IPCL_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(IPCL_SRC_DIR ${IPCL_ROOT_DIR}/ipcl) +set(IPCL_INC_DIR ${IPCL_SRC_DIR}/include) +set(IPCL_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ipcl) +set(IPCL_INSTALL_LIBDIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ipcl) +set(IPCL_CMAKE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/ipcl") +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(IPCL_DEBUG ON) else() - message(STATUS "Support RDSEED instruction: True") - add_compile_definitions(IPCL_RNG_INSTR_RDSEED) + set(IPCL_DEBUG OFF) endif() -# find package for OpenSSL and Threads +# find package: Threads config set(CMAKE_THREAD_PREFER_PTHREAD ON) -# set(THREADS_PREFER_PTHREAD_FLAG ON) -# set(OPENSSL_USE_STATIC_LIBS TRUE) - find_package(Threads REQUIRED) -set(OPENSSL_USE_STATIC_LIBS TRUE) + +# find package: OpenSSL config +if(IPCL_SHARED) + set(OPENSSL_USE_STATIC_LIBS TRUE) + message(STATUS "OPENSSL_USE_STATIC_LIBS: TRUE" ) +else() + message(STATUS "OPENSSL_USE_STATIC_LIBS: FALSE" ) +endif() find_package(OpenSSL REQUIRED) # External dependencies -set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ipcl) -include(ipcl-util) - include(cmake/ippcrypto.cmake) if(IPCL_DETECT_IFMA_RUNTIME) include(cmake/cpufeatures.cmake) @@ -185,8 +189,7 @@ if(IPCL_BENCHMARK) include(cmake/gbenchmark.cmake) endif() - - +# IPCL main directory add_subdirectory(ipcl) # unit-test and benchmarks @@ -201,6 +204,7 @@ if(IPCL_BENCHMARK) add_custom_target(benchmark COMMAND $ DEPENDS bench_ipcl) endif() +# doxygen generation if(IPCL_DOCS) add_subdirectory(docs) endif() diff --git a/cmake/cpufeatures.cmake b/cmake/cpufeatures.cmake index 478fa10..1526750 100644 --- a/cmake/cpufeatures.cmake +++ b/cmake/cpufeatures.cmake @@ -40,7 +40,7 @@ if(IPCL_SHARED) install( DIRECTORY ${CPUFEATURES_LIB_DIR}/ - DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cpufeatures" + DESTINATION "${IPCL_INSTALL_LIBDIR}/cpufeatures" USE_SOURCE_PERMISSIONS ) else() diff --git a/cmake/ipcl/ipcl-util.cmake b/cmake/ipcl/ipcl-util.cmake index e9d2cfe..ea47ee1 100644 --- a/cmake/ipcl/ipcl-util.cmake +++ b/cmake/ipcl/ipcl-util.cmake @@ -29,3 +29,72 @@ function(ipcl_create_archive target dependency) message(WARNING "Unsupported compiler ${CMAKE_CXX_COMPILER_ID}") endif() endfunction() + + +function(ipcl_detect_lscpu_flag flag verbose) + # Detect IFMA by parsing lscpu + set(LSCPU_FLAG ${flag}) + execute_process(COMMAND lscpu COMMAND grep ${LSCPU_FLAG} OUTPUT_VARIABLE LSCPU_FLAG) + if("${LSCPU_FLAG}" STREQUAL "") + if(verbose) + message(STATUS "Support ${flag}: False") + endif() + set(IPCL_FOUND_${flag} FALSE PARENT_SCOPE) + else() + if(verbose) + message(STATUS "Support ${flag}: True") + endif() + set(IPCL_FOUND_${flag} TRUE PARENT_SCOPE) + endif() +endfunction() + +function(ipcl_detect_qat) + # Detect SPR based QAT + message(STATUS "Detecting QAT...... ") + if(DEFINED ENV{ICP_ROOT}) + set(tmp_ICP_ROOT $ENV{ICP_ROOT}) + get_filename_component(tmp_ICP_ROOT_fullpath "${tmp_ICP_ROOT}" REALPATH) + if(EXISTS "${tmp_ICP_ROOT_fullpath}" AND + EXISTS "${tmp_ICP_ROOT_fullpath}/build" AND + EXISTS "${tmp_ICP_ROOT_fullpath}/quickassist") + message(STATUS "Environment variable ICP_ROOT is defined as ${tmp_ICP_ROOT_fullpath}.") + else() + message(FATAL_ERROR "Environment variable ICP_ROOT is incorrect. Try \$ export ICP_ROOT=") + endif() + else() + message(FATAL_ERROR "Environment variable ICP_ROOT must be defined. Try \$ export ICP_ROOT=") + endif() + execute_process(COMMAND lspci -d 8086:4940 COMMAND wc -l OUTPUT_VARIABLE QAT_PHYSICAL OUTPUT_STRIP_TRAILING_WHITESPACE) + set(IPCL_FOUND_QAT FALSE PARENT_SCOPE) + if(${QAT_PHYSICAL} GREATER_EQUAL "1") + message(STATUS "Detected ${QAT_PHYSICAL} physical QAT processes") + execute_process(COMMAND lspci -d 8086:4941 COMMAND wc -l OUTPUT_VARIABLE QAT_VIRTUAL OUTPUT_STRIP_TRAILING_WHITESPACE) + if(${QAT_VIRTUAL} GREATER_EQUAL "1") + message(STATUS "Detected ${QAT_VIRTUAL} virtual QAT processes") + ipcl_check_qat_service_status() + set(IPCL_FOUND_QAT TRUE PARENT_SCOPE) + else() + message(STATUS "NO virtual QAT processors - IPCL_ENABLE_QAT set to OFF") + endif() + else() + message(STATUS "NO physical QAT processors - IPCL_ENABLE_QAT set to OFF") + endif() +endfunction() + + +function(ipcl_check_qat_service_status) + # Detect qat_service service status + execute_process(COMMAND systemctl status qat_service.service COMMAND grep "Active: active" COMMAND wc -l OUTPUT_VARIABLE QAT_SERVICE_STATUS OUTPUT_STRIP_TRAILING_WHITESPACE) + if(${QAT_SERVICE_STATUS} EQUAL "1") + message(STATUS "qat_service is ACTIVE") + else() + message(WARNING + " qat_service is NOT ACTIVE!\n" + " Since QAT is detected, compilation will continue however the" + " qat_service need to be active to use the library.\n" + " To start the service, issue the following command --" + " \$ sudo systemctl start qat_service.service" + ) + endif() +endfunction() + diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake index 0e2135c..28ed163 100644 --- a/cmake/ippcrypto.cmake +++ b/cmake/ippcrypto.cmake @@ -6,6 +6,7 @@ message(STATUS "Configuring ipp-crypto") set(IPPCRYPTO_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_ipp-crypto) set(IPPCRYPTO_DESTDIR ${IPPCRYPTO_PREFIX}/ippcrypto_install) +set(IPPCRYPTO_DEST_INCLUDE_DIR include/ippcrypto) set(IPPCRYPTO_GIT_REPO_URL https://github.com/intel/ipp-crypto.git) set(IPPCRYPTO_GIT_LABEL ippcp_2021.6) set(IPPCRYPTO_SRC_DIR ${IPPCRYPTO_PREFIX}/src/ext_ipp-crypto/) @@ -32,8 +33,9 @@ ExternalProject_Add( -DCMAKE_ASM_NASM_COMPILER=nasm -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} - -DCMAKE_INSTALL_LIBDIR=lib + -DCMAKE_INSTALL_INCLUDEDIR=${IPPCRYPTO_DEST_INCLUDE_DIR} UPDATE_COMMAND "" + PATCH_COMMAND git apply ${CMAKE_CURRENT_LIST_DIR}/ippcrypto_patch.patch INSTALL_COMMAND make DESTDIR=${IPPCRYPTO_DESTDIR} install ) @@ -50,7 +52,7 @@ if(IPCL_SHARED) install( DIRECTORY ${IPPCRYPTO_LIB_DIR}/ - DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ippcrypto" + DESTINATION "${IPCL_INSTALL_LIBDIR}/ippcrypto" USE_SOURCE_PERMISSIONS ) else() diff --git a/cmake/ippcrypto_patch.patch b/cmake/ippcrypto_patch.patch new file mode 100644 index 0000000..9b607fe --- /dev/null +++ b/cmake/ippcrypto_patch.patch @@ -0,0 +1,87 @@ +# Copyright (C) 2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# applicable to https://github.com/intel/ipp-crypto/releases/tag/ippcp_2021.6 +diff --git a/CMakeLists.txt b/CMakeLists.txt +index ddb61db..302ca95 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -54,6 +54,7 @@ endif() + project(${PROJECT_NAME} + VERSION ${PROJECT_VERSION} + LANGUAGES C CXX) ++include(GNUInstallDirs) + + if("${CMAKE_BUILD_TYPE}" STREQUAL "") + message(STATUS "CMAKE_BUILD_TYPE is unset, defaulting to Release") +diff --git a/sources/ippcp/CMakeLists.txt b/sources/ippcp/CMakeLists.txt +index dd5ef41..b60357e 100644 +--- a/sources/ippcp/CMakeLists.txt ++++ b/sources/ippcp/CMakeLists.txt +@@ -378,7 +378,7 @@ foreach(opt ${PLATFORM_LIST}) + install(TARGETS ${IPPCP_DYN_ITER} + LIBRARY DESTINATION "lib/${ARCH}/$<$:nonpic>" + RUNTIME DESTINATION "lib/${ARCH}/$<$:nonpic>" +- PUBLIC_HEADER DESTINATION "include") ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + list(APPEND IPPCP_LIB_DYNAMIC ${IPPCP_DYN_ITER}) + endif(DYNAMIC_LIB AND NOT MERGED_BLD) + +@@ -407,7 +407,7 @@ foreach(opt ${PLATFORM_LIST}) + set_target_properties(${IPPCP_ST_ITER} PROPERTIES PUBLIC_HEADER "${IPPCP_PUBLIC_HEADERS}") + install(TARGETS ${IPPCP_ST_ITER} + ARCHIVE DESTINATION "lib/${ARCH}/$<$:nonpic>" +- PUBLIC_HEADER DESTINATION "include") ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + endif() + + list(APPEND IPPCP_LIB_STATIC ${IPPCP_ST_ITER}) +@@ -482,7 +482,7 @@ if(MERGED_BLD) + + install(TARGETS ${IPPCP_LIB_MERGED} + ARCHIVE DESTINATION "lib/${ARCH}/$<$:nonpic>" +- PUBLIC_HEADER DESTINATION "include" ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + PRIVATE_HEADER DESTINATION "tools/${ARCH}/staticlib") + + set_source_files_properties(${DISPATCHER_C_SOURCES} pcpver.rc PROPERTIES INCLUDE_DIRECTORIES "${C_INCLUDE_DIRECTORIES}") +@@ -521,7 +521,7 @@ if(MERGED_BLD) + install(TARGETS ${IPPCP_LIB_PCS} + LIBRARY DESTINATION "lib/${ARCH}/$<$:nonpic>" + RUNTIME DESTINATION "lib/${ARCH}/$<$:nonpic>" +- PUBLIC_HEADER DESTINATION "include" ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + PRIVATE_HEADER DESTINATION "tools/${ARCH}/staticlib") + + if(WIN32) +diff --git a/sources/ippcp/crypto_mb/src/CMakeLists.txt b/sources/ippcp/crypto_mb/src/CMakeLists.txt +index f75f448..2f43255 100644 +--- a/sources/ippcp/crypto_mb/src/CMakeLists.txt ++++ b/sources/ippcp/crypto_mb/src/CMakeLists.txt +@@ -117,12 +117,12 @@ if (MB_STANDALONE) # standalone crypto_mb's cmake run + install(TARGETS ${MB_DYN_LIB_TARGET} + LIBRARY DESTINATION "lib" + RUNTIME DESTINATION "lib" +- PUBLIC_HEADER DESTINATION "include/crypto_mb") ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/crypto_mb) + elseif (DYNAMIC_LIB) # build from ippcp's cmake + install(TARGETS ${MB_DYN_LIB_TARGET} + LIBRARY DESTINATION "lib/intel64" + RUNTIME DESTINATION "lib/intel64" +- PUBLIC_HEADER DESTINATION "include/crypto_mb") ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/crypto_mb) + endif() + + # Static library +@@ -147,9 +147,9 @@ endif() + if(MB_STANDALONE) + install(TARGETS ${MB_STATIC_LIB_TARGET} + ARCHIVE DESTINATION "lib" +- PUBLIC_HEADER DESTINATION "include/crypto_mb") ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/crypto_mb) + else() + install(TARGETS ${MB_STATIC_LIB_TARGET} + ARCHIVE DESTINATION "lib/intel64" +- PUBLIC_HEADER DESTINATION "include/crypto_mb") ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/crypto_mb) + endif() diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index cb66be8..83314d7 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -9,7 +9,7 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) -find_package(IPCL 1.1.4 REQUIRED HINTS ${IPCL_HINT_DIR}) +find_package(IPCL 2.0.0 REQUIRED HINTS ${IPCL_HINT_DIR}) add_executable(test test.cpp) target_link_libraries(test PRIVATE IPCL::ipcl) diff --git a/example/test.cpp b/example/test.cpp index 5ac7a31..b3e052f 100644 --- a/example/test.cpp +++ b/example/test.cpp @@ -8,6 +8,8 @@ #include int main() { + ipcl::initializeContext("QAT"); + const uint32_t num_values = 9; ipcl::keyPair key = ipcl::generateKeypair(2048, true); @@ -37,4 +39,5 @@ int main() { delete key.pub_key; delete key.priv_key; + ipcl::terminateContext(); } diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 87643d6..e7fcf02 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -14,6 +14,7 @@ set(IPCL_SRCS pri_key.cpp common.cpp ) +set(IPCL_PUBLIC_HEADER ${IPCL_INC_DIR}/ipcl/ipcl.hpp) if(IPCL_SHARED) add_library(ipcl SHARED ${IPCL_SRCS}) @@ -23,57 +24,66 @@ endif() add_library(IPCL::ipcl ALIAS ipcl) +set_target_properties(ipcl PROPERTIES PUBLIC_HEADER ${IPCL_PUBLIC_HEADER}) + +target_include_directories(ipcl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + +# include and install definition of IPCL target_include_directories(ipcl - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PUBLIC $ - PUBLIC $ + PUBLIC $ ) +install(DIRECTORY ${IPCL_INC_DIR}/ + DESTINATION ${IPCL_INSTALL_INCLUDEDIR} + FILES_MATCHING + PATTERN "*.hpp" + PATTERN "*.h") + +# include and install definition of IPP-Crypto target_include_directories(ipcl - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PUBLIC $ - PUBLIC $ + PUBLIC $ + PUBLIC $ ) +install(DIRECTORY ${IPPCRYPTO_INC_DIR}/ + DESTINATION ${IPCL_INSTALL_INCLUDEDIR} + FILES_MATCHING + PATTERN "*.hpp" + PATTERN "*.h") + +# include and install definition of cpu_features if(IPCL_DETECT_IFMA_RUNTIME) target_include_directories(ipcl - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PUBLIC $ - PUBLIC $ + PUBLIC $ + PRIVATE $ ) install(DIRECTORY ${CPUFEATURES_INC_DIR}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} + DESTINATION ${IPCL_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h") endif() -install(DIRECTORY ${IPCL_INC_DIR}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} - FILES_MATCHING - PATTERN "*.hpp" - PATTERN "*.h") - -install(DIRECTORY ${IPPCRYPTO_INC_DIR}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} - FILES_MATCHING - PATTERN "*.hpp" - PATTERN "*.h") - if(IPCL_ENABLE_QAT) - target_include_directories(ipcl PUBLIC "$") - target_include_directories(ipcl PUBLIC "$") - target_include_directories(ipcl PUBLIC "$") + target_include_directories(ipcl + PRIVATE "$" + PRIVATE $ + ) + target_include_directories(ipcl + PRIVATE "$" + PRIVATE $ + ) install(DIRECTORY ${ICP_INC_DIR}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} + DESTINATION ${IPCL_INSTALL_INCLUDEDIR}/icp FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h") install(DIRECTORY ${HEQAT_INC_DIR}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} + DESTINATION ${IPCL_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h") @@ -92,31 +102,20 @@ if(IPCL_SHARED) target_link_libraries(ipcl PRIVATE libippcrypto) if(IPCL_DETECT_IFMA_RUNTIME) target_link_libraries(ipcl PRIVATE libcpu_features) - target_include_directories(ipcl PRIVATE ${CPUFEATURES_INC_DIR}) endif() - target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) if(IPCL_ENABLE_QAT) - target_include_directories(ipcl PRIVATE ${HEQAT_INC_DIR}) target_link_libraries(ipcl PRIVATE libhe_qat udev z) endif() - else() - ipcl_create_archive(ipcl libippcrypto::ippcp) ipcl_create_archive(ipcl libippcrypto::crypto_mb) - if(IPCL_ENABLE_QAT) ipcl_create_archive(ipcl libhe_qat) - target_include_directories(ipcl PRIVATE ${HEQAT_INC_DIR}) target_link_libraries(ipcl PRIVATE udev z) endif() - if(IPCL_DETECT_IFMA_RUNTIME) ipcl_create_archive(ipcl libcpu_features) - target_include_directories(ipcl PRIVATE ${CPUFEATURES_INC_DIR}) endif() - - target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) endif() set_target_properties(ipcl PROPERTIES POSITION_INDEPENDENT_CODE ON) @@ -127,8 +126,6 @@ else() set_target_properties(ipcl PROPERTIES OUTPUT_NAME "ipcl") endif() -install(TARGETS ipcl DESTINATION ${CMAKE_INSTALL_LIBDIR}) - # config cmake config and target file set(IPCL_TARGET_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/cmake/ipcl-${IPCL_VERSION}/IPCLTargets.cmake) set(IPCL_CONFIG_IN_FILENAME ${IPCL_CMAKE_PATH}/IPCLConfig.cmake.in) @@ -156,9 +153,10 @@ configure_package_config_file( install( TARGETS ipcl EXPORT IPCLTargets - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + PUBLIC_HEADER DESTINATION ${IPCL_INSTALL_INCLUDEDIR} + ARCHIVE DESTINATION ${IPCL_INSTALL_LIBDIR} + LIBRARY DESTINATION ${IPCL_INSTALL_LIBDIR} + RUNTIME DESTINATION ${IPCL_INSTALL_LIBDIR} ) install(FILES ${IPCL_CONFIG_FILENAME} diff --git a/module/heqat.cmake b/module/heqat.cmake index 1a0a0f3..7988d8c 100644 --- a/module/heqat.cmake +++ b/module/heqat.cmake @@ -22,9 +22,8 @@ ExternalProject_Add( -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DHE_QAT_MISC=OFF -DHE_QAT_DOCS=${IPCL_DOCS} - # REVIEW IPPCP_PREFIX_PATH (DEPS ON LOCAL INSTALL) - -DIPPCP_PREFIX_PATH=${IPPCRYPTO_DESTDIR}/lib/cmake - -DHE_QAT_SHARED=${IPCL_SHARED} + -DHE_QAT_SHARED=${IPCL_SHARED} + -DHE_QAT_SAMPLES=OFF -DCMAKE_BUILD_TYPE=${HEQAT_BUILD_TYPE} UPDATE_COMMAND "" EXCLUDE_FROM_ALL TRUE @@ -51,10 +50,10 @@ if(IPCL_SHARED) target_link_libraries(libhe_qat INTERFACE ${HEQAT_LIB_DIR}/libhe_qat.so) endif() target_include_directories(libhe_qat SYSTEM INTERFACE ${HEQAT_INC_DIR}) - + install( DIRECTORY ${HEQAT_LIB_DIR}/ - DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/heqat" + DESTINATION "${IPCL_INSTALL_LIBDIR}/heqat" USE_SOURCE_PERMISSIONS ) else() From b69f837c1c020d918a24e67804bb16d51c1977be Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Thu, 27 Oct 2022 00:19:12 -0700 Subject: [PATCH 302/364] Remove unused variables and functions. Signed-off-by: Souza, Fillipe --- heqat/context.c | 27 --------------------------- heqat/ctrl.c | 41 ----------------------------------------- 2 files changed, 68 deletions(-) diff --git a/heqat/context.c b/heqat/context.c index 6f0e9b8..985d253 100644 --- a/heqat/context.c +++ b/heqat/context.c @@ -25,7 +25,6 @@ static pthread_mutex_t context_lock; // Global variable declarations static pthread_t buffer_manager; static pthread_t he_qat_runner; -static HE_QAT_Inst he_qat_instances[HE_QAT_NUM_ACTIVE_INSTANCES]; static pthread_attr_t he_qat_inst_attr[HE_QAT_NUM_ACTIVE_INSTANCES]; static HE_QAT_InstConfig he_qat_inst_config[HE_QAT_NUM_ACTIVE_INSTANCES]; static HE_QAT_Config* he_qat_config = NULL; @@ -47,7 +46,6 @@ extern void stop_perform_op(void* _inst_config, unsigned num_inst); // WARNING: Deprecated when "start_instances" becomes default. extern void* start_perform_op(void* _inst_config); -static CpaInstanceHandle handle = NULL; static Cpa16U numInstances = 0; static Cpa16U nextInstance = 0; @@ -100,7 +98,6 @@ static CpaInstanceHandle get_qat_instance() { #endif if (status == CPA_STATUS_SUCCESS) return cyInstHandles[nextInstance]; - //*pCyInstHandle = cyInstHandles[0]; } if (0 == numInstances) { @@ -160,7 +157,6 @@ HE_QAT_STATUS acquire_qat_devices() { // Potential out-of-scope hazard for segmentation fault CpaInstanceHandle _inst_handle[HE_QAT_NUM_ACTIVE_INSTANCES]; // = NULL; // TODO: @fdiasmor Create a CyGetInstance that retrieves more than one. - // sampleCyGetInstance(&_inst_handle); for (unsigned int i = 0; i < HE_QAT_NUM_ACTIVE_INSTANCES; i++) { _inst_handle[i] = get_qat_instance(); if (_inst_handle[i] == NULL) { @@ -170,11 +166,6 @@ HE_QAT_STATUS acquire_qat_devices() { } } - // sampleCyGetInstance(&handle); - // if (handle == NULL) { - // printf("Failed to find QAT endpoints.\n"); - // return HE_QAT_STATUS_FAIL; - //} #ifdef HE_QAT_DEBUG printf("Found QAT endpoints.\n"); #endif @@ -212,9 +203,7 @@ HE_QAT_STATUS acquire_qat_devices() { pthread_cond_init(&outstanding.any_ready_buffer, NULL); // Creating QAT instances (consumer threads) to process op requests - pthread_attr_t attr; cpu_set_t cpus; - // for (int i = 0; i < HE_QAT_SYNC; i++) { for (int i = 0; i < HE_QAT_NUM_ACTIVE_INSTANCES; i++) { CPU_ZERO(&cpus); CPU_SET(i, &cpus); @@ -223,22 +212,15 @@ HE_QAT_STATUS acquire_qat_devices() { &cpus); // configure thread - // HE_QAT_InstConfig *config = (HE_QAT_InstConfig *) - // malloc(sizeof(QATInstConfig)); - // if (config == NULL) return HE_QAT_FAIL; he_qat_inst_config[i].active = 0; // HE_QAT_STATUS_INACTIVE he_qat_inst_config[i].polling = 0; // HE_QAT_STATUS_INACTIVE he_qat_inst_config[i].running = 0; he_qat_inst_config[i].status = CPA_STATUS_FAIL; - // he_qat_inst_config[i].mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_init(&he_qat_inst_config[i].mutex, NULL); - // he_qat_inst_config[i].ready = PTHREAD_COND_INITIALIZER; pthread_cond_init(&he_qat_inst_config[i].ready, NULL); he_qat_inst_config[i].inst_handle = _inst_handle[i]; he_qat_inst_config[i].inst_id = i; he_qat_inst_config[i].attr = &he_qat_inst_attr[i]; -// pthread_create(&he_qat_instances[i], he_qat_inst_config[i].attr, -// start_perform_op, (void*)&he_qat_inst_config[i]); } he_qat_config = (HE_QAT_Config *) malloc(sizeof(HE_QAT_Config)); @@ -248,18 +230,12 @@ HE_QAT_STATUS acquire_qat_devices() { he_qat_config->active = 0; // Work on this - // pthread_create(&he_qat_instances[0], NULL, start_instances, (void*)he_qat_config); pthread_create(&he_qat_runner, NULL, start_instances, (void*)he_qat_config); #ifdef HE_QAT_DEBUG printf("Created processing threads.\n"); #endif // Dispatch the qat instances to run independently in the background -// for (int i = 0; i < HE_QAT_NUM_ACTIVE_INSTANCES; i++) { -// pthread_detach(he_qat_instances[i]); -// } - // Dispatch all QAT instances in a single thread -// pthread_detach(he_qat_instances[0]); pthread_detach(he_qat_runner); #ifdef HE_QAT_DEBUG printf("Detached processing threads.\n"); @@ -296,8 +272,6 @@ HE_QAT_STATUS acquire_qat_devices() { /// @brief /// Release QAT instances and tear down QAT execution environment. HE_QAT_STATUS release_qat_devices() { - CpaStatus status = CPA_STATUS_FAIL; - pthread_mutex_lock(&context_lock); if (HE_QAT_STATUS_INACTIVE == context_state) { @@ -306,7 +280,6 @@ HE_QAT_STATUS release_qat_devices() { } stop_instances(he_qat_config); - //stop_perform_op(he_qat_inst_config, HE_QAT_NUM_ACTIVE_INSTANCES); #ifdef HE_QAT_DEBUG printf("Stopped polling and processing threads.\n"); #endif diff --git a/heqat/ctrl.c b/heqat/ctrl.c index f6ce48f..88fd913 100644 --- a/heqat/ctrl.c +++ b/heqat/ctrl.c @@ -37,7 +37,6 @@ HE_QAT_RequestBuffer he_qat_buffer; ///< This the internal buffer that holds HE_QAT_OutstandingBuffer outstanding; ///< This is the data structure that holds outstanding requests from separate active threads calling the API. volatile unsigned long response_count = 0; ///< Counter of processed requests and it is used to help control throttling. static volatile unsigned long request_count = 0; ///< Counter of received requests and it is used to help control throttling. -static unsigned long request_latency = 0; ///< Variable used to hold measured averaged latency of requests (currently unused). static unsigned long restart_threshold = NUM_PKE_SLICES * HE_QAT_NUM_ACTIVE_INSTANCES; ///< Number of concurrent requests allowed to be sent to accelerator at once. static unsigned long max_pending = (2 * NUM_PKE_SLICES * HE_QAT_NUM_ACTIVE_INSTANCES); ///< Number of requests sent to the accelerator that are pending completion. @@ -120,46 +119,6 @@ static void submit_request_list(HE_QAT_RequestBuffer* _buffer, #endif } - -/// @brief Retrive single request from internal buffer. -/// @details Thread-safe consumer implementation for the shared request buffer. -/// Read request from internal buffer `he_qat_buffer` to finally offload the request to be processed by QAT devices. -/// Supported in single-threaded or multi-threaded mode. -/// @param[in] _buffer buffer of type HE_QAT_RequestBuffer, typically the internal buffer in current implementation. -/// @retval single work request in HE_QAT_TaskRequest data structure. -static HE_QAT_TaskRequest* read_request(HE_QAT_RequestBuffer* _buffer) -{ - void* item = NULL; - static unsigned int counter = 0; - - pthread_mutex_lock(&_buffer->mutex); - -#ifdef HE_QAT_DEBUG - printf("Wait lock read request. [internal buffer size: %d] Request #%u\n", - _buffer->count, counter++); -#endif - // Wait while buffer is empty - while (_buffer->count <= 0) - pthread_cond_wait(&_buffer->any_more_data, &_buffer->mutex); - - assert(_buffer->count > 0); - - item = _buffer->data[_buffer->next_data_slot++]; - - _buffer->next_data_slot %= HE_QAT_BUFFER_SIZE; - _buffer->count--; - - pthread_cond_signal(&_buffer->any_free_slot); - pthread_mutex_unlock(&_buffer->mutex); - -#ifdef HE_QAT_DEBUG - printf("Unlocked read request. [internal buffer count: %d]\n", - _buffer->count); -#endif - - return (HE_QAT_TaskRequest*)(item); -} - /// @brief Retrieve multiple requests from the outstanding buffer. /// @details Thread-safe consumer implementation for the outstanding request buffer. /// Read requests from outstanding buffer (requests ready to be scheduled) to later pass From f2c63fd1b289d2cc25a863c30c4d5cc5eb47b484 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Thu, 27 Oct 2022 16:11:28 -0700 Subject: [PATCH 303/364] Remove cpa_sample_utils from repository and enable build without external codes(#32) * Remove cpa_sample_utils src code - qat_config.cmake added to handle previous icp/CMakeLists.txt and cpa_sample_utils.so build - Removed ICP_ROOT related settings in HE_QATConfig.cmake.in --- CMakeLists.txt | 6 +- cmake/he_qat/HE_QATConfig.cmake.in | 1 + icp/CMakeLists.txt => cmake/qat_config.cmake | 25 +- example/CMakeLists.txt | 4 +- heqat/CMakeLists.txt | 21 +- heqat/bnops.c | 2 +- heqat/cb.c | 2 +- heqat/common/CMakeLists.txt | 3 +- heqat/common/cpa_sample_utils.c | 285 -------- heqat/common/utils.c | 2 +- heqat/context.c | 2 +- heqat/ctrl.c | 2 +- heqat/include/heqat/common.h | 15 +- heqat/include/heqat/common/cpa_sample_utils.h | 651 ------------------ heqat/include/heqat/common/types.h | 2 +- samples/CMakeLists.txt | 1 - 16 files changed, 66 insertions(+), 958 deletions(-) rename icp/CMakeLists.txt => cmake/qat_config.cmake (67%) delete mode 100644 heqat/common/cpa_sample_utils.c delete mode 100644 heqat/include/heqat/common/cpa_sample_utils.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ada67a7..5eb776b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,10 +140,11 @@ set(HE_QAT_FORWARD_CMAKE_ARGS ) #OpenSSL installation -if(NOT HE_QAT_SHARED) +if(HE_QAT_SHARED) set(OPENSSL_USE_STATIC_LIBS TRUE) message(STATUS "OPENSSL_USE_STATIC_LIBS TRUE") else() + set(OPENSSL_USE_STATIC_LIBS FALSE) message(STATUS "OPENSSL_USE_STATIC_LIBS FALSE") endif() find_package(OpenSSL REQUIRED) @@ -161,7 +162,8 @@ if(NOT CMAKE_INSTALL_PREFIX) endif() # Include QAT lib API support -include(icp/CMakeLists.txt) +# include(icp/CMakeLists.txt) +include(cmake/qat_config.cmake) # HE_QAT Library add_subdirectory(heqat) diff --git a/cmake/he_qat/HE_QATConfig.cmake.in b/cmake/he_qat/HE_QATConfig.cmake.in index 81dc91c..1868908 100644 --- a/cmake/he_qat/HE_QATConfig.cmake.in +++ b/cmake/he_qat/HE_QATConfig.cmake.in @@ -9,6 +9,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/he_qatTargets.cmake) if(TARGET HE_QAT::he_qat) set(HE_QAT_FOUND TRUE) message(STATUS "Intel Homomorphic Encryption Acceleration Library for QAT found") + add_definitions(-DUSER_SPACE) else() message(STATUS "Intel Homomorphic Encryption Acceleraiton Library for QAT not found") endif() diff --git a/icp/CMakeLists.txt b/cmake/qat_config.cmake similarity index 67% rename from icp/CMakeLists.txt rename to cmake/qat_config.cmake index e440b79..59bfc54 100644 --- a/icp/CMakeLists.txt +++ b/cmake/qat_config.cmake @@ -1,4 +1,7 @@ +# Copyright (C) 2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 +# Setup ICP variables if(DEFINED ENV{ICP_ROOT}) message(STATUS "Environment variable ICP_ROOT is defined as $ENV{ICP_ROOT}.") else() @@ -13,19 +16,21 @@ set(ICP_LAC_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer) set(ICP_OSAL_DIR ${ICP_ROOT}/quickassist/utilities/oasl) set(ICP_ADF_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/qat_direct) set(CMN_ROOT ${ICP_ROOT}/quickassist/utilities/libusdm_drv) +set(CPA_SAMPLES_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/sample_code/functional) set(ICP_INC_DIR ${ICP_API_DIR}/include ${ICP_LAC_DIR}/include ${ICP_ADF_DIR}/include ${CMN_ROOT} ${ICP_API_DIR}/include/dc - ${ICP_API_DIR}/include/lac) + ${ICP_API_DIR}/include/lac + ${CPA_SAMPLES_DIR}/include) -# Active macros for cpa_sample_utils add_definitions(-DDO_CRYPTO) add_definitions(-DUSER_SPACE) add_compile_options(-fPIC) +# Active macros for cpa_sample_utils add_library(libadf_static STATIC IMPORTED GLOBAL) add_library(libosal_static STATIC IMPORTED GLOBAL) add_library(libqat_static STATIC IMPORTED GLOBAL) @@ -46,3 +51,19 @@ set_target_properties(libqat_static PROPERTIES set_target_properties(libusdm_drv_static PROPERTIES IMPORTED_LOCATION ${ICP_BUILDOUTPUT_PATH}/libusdm_drv.a ) + +# Build cpa_sample_utils +set(CPA_SAMPLE_UTILS_SRC ${CPA_SAMPLES_DIR}/common/cpa_sample_utils.c) +set(CPA_SAMPLE_UTILS_HDR ${CPA_SAMPLES_DIR}/include/cpa_sample_utils.h) +if(HE_QAT_SHARED) + add_library(cpa_sample_utils SHARED ${CPA_SAMPLE_UTILS_SRC}) +else() + add_library(cpa_sample_utils STATIC ${CPA_SAMPLE_UTILS_SRC}) +endif() + +set_target_properties(cpa_sample_utils PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/heqat) + +target_include_directories(cpa_sample_utils + PRIVATE ${ICP_INC_DIR} +) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 88753b9..6fb0f59 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -23,10 +23,8 @@ find_package(Threads REQUIRED) set(CMAKE_THREAD_PREFER_PTHREAD ON) set(THREADS_PREFER_PTHREAD_FLAG ON) -include(../icp/CMakeLists.txt) - add_definitions(-fpermissive) add_executable(example example.cpp) -target_include_directories(example PRIVATE ${ICP_INC_DIR}) + target_link_libraries(example PRIVATE HE_QAT::he_qat) target_link_libraries(example PRIVATE OpenSSL::SSL) diff --git a/heqat/CMakeLists.txt b/heqat/CMakeLists.txt index 7dfe4c7..4d44718 100644 --- a/heqat/CMakeLists.txt +++ b/heqat/CMakeLists.txt @@ -25,24 +25,27 @@ add_library(HE_QAT::he_qat ALIAS he_qat) target_include_directories(he_qat PUBLIC $ #Public headers PUBLIC $ #Public headers - PRIVATE ${ICP_INC_DIR} #Private headers + PUBLIC ${ICP_INC_DIR} ) install(DIRECTORY ${HE_QAT_INC_DIR}/ DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ FILES_MATCHING PATTERN "*.hpp" - PATTERN "*.h") + PATTERN "*.h") target_link_directories(he_qat PUBLIC ${ICP_BUILDOUTPUT_PATH}) target_link_libraries(he_qat PRIVATE udev z) target_link_libraries(he_qat PRIVATE OpenSSL::SSL) target_link_libraries(he_qat PRIVATE Threads::Threads) + if(HE_QAT_SHARED) + target_link_libraries(he_qat PUBLIC cpa_sample_utils) target_link_libraries(he_qat PRIVATE qat_s) target_link_libraries(he_qat PRIVATE usdm_drv_s) else() + heqat_create_archive(he_qat cpa_sample_utils) heqat_create_archive(he_qat libadf_static) heqat_create_archive(he_qat libosal_static) heqat_create_archive(he_qat libqat_static) @@ -68,8 +71,6 @@ else() set_target_properties(he_qat PROPERTIES OUTPUT_NAME "he_qat") endif() -install(TARGETS he_qat DESTINATION ${CMAKE_INSTALL_LIBDIR}) - include(CMakePackageConfigHelpers) # config cmake config and target file @@ -96,13 +97,23 @@ configure_package_config_file( INSTALL_DESTINATION ${HE_QAT_CONFIG_INSTALL_DIR} ) -install( +if(HE_QAT_SHARED) + install( + TARGETS he_qat cpa_sample_utils + EXPORT he_qatTargets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) +else() + install( TARGETS he_qat EXPORT he_qatTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) +endif() install(FILES ${HE_QAT_CONFIG_FILENAME} ${HE_QAT_CONFIG_VERSION_FILENAME} diff --git a/heqat/bnops.c b/heqat/bnops.c index f0abb67..fc47426 100644 --- a/heqat/bnops.c +++ b/heqat/bnops.c @@ -5,7 +5,7 @@ #include "cpa_cy_ln.h" #include "icp_sal_poll.h" -#include "heqat/common/cpa_sample_utils.h" +#include "cpa_sample_utils.h" #include "heqat/common/consts.h" #include "heqat/common/types.h" #include "heqat/bnops.h" diff --git a/heqat/cb.c b/heqat/cb.c index 5e2db31..e8f5906 100644 --- a/heqat/cb.c +++ b/heqat/cb.c @@ -8,7 +8,7 @@ #include // Local headers -#include "heqat/common/cpa_sample_utils.h" +#include "cpa_sample_utils.h" #include "heqat/common/types.h" // Global variables diff --git a/heqat/common/CMakeLists.txt b/heqat/common/CMakeLists.txt index 478f463..2e16c41 100644 --- a/heqat/common/CMakeLists.txt +++ b/heqat/common/CMakeLists.txt @@ -1,6 +1,5 @@ # Source files -set(COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/cpa_sample_utils.c - ${CMAKE_CURRENT_LIST_DIR}/utils.c) +set(COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/utils.c) list(APPEND HE_QAT_SRC ${COMMON_SRC}) set(HE_QAT_SRC ${HE_QAT_SRC} PARENT_SCOPE) diff --git a/heqat/common/cpa_sample_utils.c b/heqat/common/cpa_sample_utils.c deleted file mode 100644 index 53551e3..0000000 --- a/heqat/common/cpa_sample_utils.c +++ /dev/null @@ -1,285 +0,0 @@ -/*************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Corporation - * - * BSD LICENSE - * - * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * version: QAT.L.4.15.0-00011 - * - ***************************************************************************/ - -/** - ***************************************************************************** - * @file cpa_sample_utils.c - * - * @ingroup sampleCode - * - * @description - * Defines functions to get an instance and poll an instance - * - ***************************************************************************/ - -#include "heqat/common/cpa_sample_utils.h" -#include "cpa_dc.h" -#include "icp_sal_poll.h" - -/* - * Maximum number of instances to query from the API - */ -#ifdef USER_SPACE -#define MAX_INSTANCES 1024 -#else -#define MAX_INSTANCES 1 -#endif - -#ifdef DO_CRYPTO -static sampleThread gPollingThread; -static volatile int gPollingCy = 0; -#endif - -static sampleThread gPollingThreadDc; -static volatile int gPollingDc = 0; - -#ifdef SC_ENABLE_DYNAMIC_COMPRESSION -CpaDcHuffType huffmanType_g = CPA_DC_HT_FULL_DYNAMIC; -#else -CpaDcHuffType huffmanType_g = CPA_DC_HT_STATIC; -#endif -/* ************************************************************* - * - * Common instance functions - * - * ************************************************************* - */ - -/* - * This function returns a handle to an instance of the cryptographic - * API. It does this by querying the API for all instances and - * returning the first such instance. - */ -// -#ifdef DO_CRYPTO -void sampleCyGetInstance(CpaInstanceHandle *pCyInstHandle) -{ - CpaInstanceHandle cyInstHandles[MAX_INSTANCES]; - Cpa16U numInstances = 0; - CpaStatus status = CPA_STATUS_SUCCESS; - - *pCyInstHandle = NULL; - status = cpaCyGetNumInstances(&numInstances); - if (numInstances >= MAX_INSTANCES) - { - numInstances = MAX_INSTANCES; - } - if ((status == CPA_STATUS_SUCCESS) && (numInstances > 0)) - { - status = cpaCyGetInstances(numInstances, cyInstHandles); - if (status == CPA_STATUS_SUCCESS) - *pCyInstHandle = cyInstHandles[0]; - } - - if (0 == numInstances) - { - PRINT_ERR("No instances found for 'SSL'\n"); - PRINT_ERR("Please check your section names"); - PRINT_ERR(" in the config file.\n"); - PRINT_ERR("Also make sure to use config file version 2.\n"); - } -} - -void symSessionWaitForInflightReq(CpaCySymSessionCtx pSessionCtx) -{ - -/* Session reuse is available since Cryptographic API version 2.2 */ -#if CY_API_VERSION_AT_LEAST(2, 2) - CpaBoolean sessionInUse = CPA_FALSE; - - do - { - cpaCySymSessionInUse(pSessionCtx, &sessionInUse); - } while (sessionInUse); -#endif - - return; -} -#endif -// - -/* - * This function polls a crypto instance. - * - */ -#ifdef DO_CRYPTO -static void sal_polling(CpaInstanceHandle cyInstHandle) -{ - gPollingCy = 1; - while (gPollingCy) - { - icp_sal_CyPollInstance(cyInstHandle, 0); - OS_SLEEP(10); - } - - sampleThreadExit(); -} -#endif -/* - * This function checks the instance info. If the instance is - * required to be polled then it starts a polling thread. - */ - -#ifdef DO_CRYPTO -void sampleCyStartPolling(CpaInstanceHandle cyInstHandle) -{ - CpaInstanceInfo2 info2 = {0}; - CpaStatus status = CPA_STATUS_SUCCESS; - - status = cpaCyInstanceGetInfo2(cyInstHandle, &info2); - if ((status == CPA_STATUS_SUCCESS) && (info2.isPolled == CPA_TRUE)) - { - /* Start thread to poll instance */ - sampleThreadCreate(&gPollingThread, sal_polling, cyInstHandle); - } -} -#endif -/* - * This function stops the polling of a crypto instance. - */ -#ifdef DO_CRYPTO -void sampleCyStopPolling(void) -{ - gPollingCy = 0; - OS_SLEEP(10); -} -#endif - -/* - * This function returns a handle to an instance of the data - * compression API. It does this by querying the API for all - * instances and returning the first such instance. - */ -// -void sampleDcGetInstance(CpaInstanceHandle *pDcInstHandle) -{ - CpaInstanceHandle dcInstHandles[MAX_INSTANCES]; - Cpa16U numInstances = 0; - CpaStatus status = CPA_STATUS_SUCCESS; - - *pDcInstHandle = NULL; - status = cpaDcGetNumInstances(&numInstances); - if (numInstances >= MAX_INSTANCES) - { - numInstances = MAX_INSTANCES; - } - if ((status == CPA_STATUS_SUCCESS) && (numInstances > 0)) - { - status = cpaDcGetInstances(numInstances, dcInstHandles); - if (status == CPA_STATUS_SUCCESS) - *pDcInstHandle = dcInstHandles[0]; - } - - if (0 == numInstances) - { - PRINT_ERR("No instances found for 'SSL'\n"); - PRINT_ERR("Please check your section names"); - PRINT_ERR(" in the config file.\n"); - PRINT_ERR("Also make sure to use config file version 2.\n"); - } -} -// - -/* - * This function polls a compression instance. - * - */ -static void sal_dc_polling(CpaInstanceHandle dcInstHandle) -{ - - gPollingDc = 1; - while (gPollingDc) - { - icp_sal_DcPollInstance(dcInstHandle, 0); - OS_SLEEP(10); - } - - sampleThreadExit(); -} - -/* - * This function checks the instance info. If the instance is - * required to be polled then it starts a polling thread. - */ -void sampleDcStartPolling(CpaInstanceHandle dcInstHandle) -{ - CpaInstanceInfo2 info2 = {0}; - CpaStatus status = CPA_STATUS_SUCCESS; - - status = cpaDcInstanceGetInfo2(dcInstHandle, &info2); - if ((status == CPA_STATUS_SUCCESS) && (info2.isPolled == CPA_TRUE)) - { - /* Start thread to poll instance */ - sampleThreadCreate(&gPollingThreadDc, sal_dc_polling, dcInstHandle); - } -} - -/* - * This function stops the thread polling the compression instance. - */ -void sampleDcStopPolling(void) -{ - gPollingDc = 0; - OS_SLEEP(10); -} - diff --git a/heqat/common/utils.c b/heqat/common/utils.c index 8d1aa0d..7500b3a 100644 --- a/heqat/common/utils.c +++ b/heqat/common/utils.c @@ -1,4 +1,4 @@ -#include "heqat/common/cpa_sample_utils.h" +#include "cpa_sample_utils.h" #include "heqat/common/utils.h" #include diff --git a/heqat/context.c b/heqat/context.c index 985d253..c15172a 100644 --- a/heqat/context.c +++ b/heqat/context.c @@ -9,7 +9,7 @@ #include #include -#include "heqat/common/cpa_sample_utils.h" +#include "cpa_sample_utils.h" #include "heqat/common/types.h" #include "heqat/context.h" diff --git a/heqat/ctrl.c b/heqat/ctrl.c index 88fd913..cc1c271 100644 --- a/heqat/ctrl.c +++ b/heqat/ctrl.c @@ -20,7 +20,7 @@ double time_taken = 0.0; #include // Local headers -#include "heqat/common/cpa_sample_utils.h" +#include "cpa_sample_utils.h" #include "heqat/common/consts.h" #include "heqat/common/types.h" #include "heqat/bnops.h" diff --git a/heqat/include/heqat/common.h b/heqat/include/heqat/common.h index 67f9ede..70c322f 100644 --- a/heqat/include/heqat/common.h +++ b/heqat/include/heqat/common.h @@ -1,6 +1,6 @@ /// @file heqat/common.h -#include "heqat/common/cpa_sample_utils.h" +#include "cpa_sample_utils.h" #include "heqat/common/consts.h" #include "heqat/common/types.h" #include "heqat/common/utils.h" @@ -11,3 +11,16 @@ #endif #endif +#ifdef HE_QAT_DEBUG +#define HE_QAT_PRINT_DBG(args...) \ + do \ + { \ + { \ + printf("%s(): ", __func__); \ + printf(args); \ + fflush(stdout); \ + } \ + } while (0) +#else +#define HE_QAT_PRINT_DBG(args...) { } +#endif \ No newline at end of file diff --git a/heqat/include/heqat/common/cpa_sample_utils.h b/heqat/include/heqat/common/cpa_sample_utils.h deleted file mode 100644 index a128640..0000000 --- a/heqat/include/heqat/common/cpa_sample_utils.h +++ /dev/null @@ -1,651 +0,0 @@ -/*************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Corporation - * - * BSD LICENSE - * - * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * version: QAT.L.4.15.0-00011 - * - ***************************************************************************/ - -/** - ***************************************************************************** - * @file cpa_sample_utils.h - * - * @defgroup sampleUtils Macro and inline function definitions - * - * @ingroup sampleCode - * - * @description - * Defines macros for printing and debugging, inline functions for memory - * allocating and freeing and thread creation - * - ***************************************************************************/ - -#ifndef CPA_SAMPLE_UTILS_H -#define CPA_SAMPLE_UTILS_H - -#ifdef __cplusplus -#define HE_QAT_RESTRICT __restrict__ -#else -#define HE_QAT_RESTRICT restrict -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#include "cpa.h" -#include "cpa_cy_im.h" -#include "cpa_dc.h" - - -#ifdef DO_CRYPTO -#include "cpa_cy_sym.h" -#endif - -#ifdef USER_SPACE -/* User space utils */ -#include -#include -#include -#include -#include -#include -/* Performance sample code mem utils */ - -#include "qae_mem.h" - -extern CpaDcHuffType huffmanType_g; -extern CpaStatus qaeMemInit(void); -extern void qaeMemDestroy(void); -/* Threads */ -typedef pthread_t sampleThread; - -/* Check for CY API version */ -#define CY_API_VERSION_AT_LEAST(major, minor) \ - (CPA_CY_API_VERSION_NUM_MAJOR > major || \ - (CPA_CY_API_VERSION_NUM_MAJOR == major && \ - CPA_CY_API_VERSION_NUM_MINOR >= minor)) - -#ifdef HE_QAT_DEBUG -#define HE_QAT_PRINT_DBG(args...) \ - do \ - { \ - { \ - printf("%s(): ", __func__); \ - printf(args); \ - fflush(stdout); \ - } \ - } while (0) -#else -#define HE_QAT_PRINT_DBG(args...) { } -#endif -/* Printing */ -/**< Prints the name of the function and the arguments only if gDebugParam is - * CPA_TRUE. - */ -#define PRINT_DBG(args...) \ - do \ - { \ - if (CPA_TRUE == gDebugParam) \ - { \ - printf("%s(): ", __func__); \ - printf(args); \ - fflush(stdout); \ - } \ - } while (0) - -/**< Prints the arguments */ -#ifndef PRINT -#define PRINT(args...) \ - do \ - { \ - printf(args); \ - } while (0) -#endif - -/**< Prints the name of the function and the arguments */ -#ifndef PRINT_ERR -#define PRINT_ERR(args...) \ - do \ - { \ - printf("%s(): ", __func__); \ - printf(args); \ - } while (0) -#endif -/** - ******************************************************************************* - * @ingroup sampleUtils - * Completion definitions - * - ******************************************************************************/ -struct completion_struct -{ - sem_t semaphore; -}; -/* Use semaphores to signal completion of events */ -#define COMPLETION_STRUCT completion_struct - -#define COMPLETION_INIT(s) sem_init(&((s)->semaphore), 0, 0); - -#define COMPLETION_WAIT(s, timeout) (sem_wait(&((s)->semaphore)) == 0) - -#define COMPLETE(s) sem_post(&((s)->semaphore)) - -#define COMPLETION_DESTROY(s) sem_destroy(&((s)->semaphore)) - -#else -/* Kernel space utils */ -#include -#include -#include -#include -#include -#include -#include - -#ifdef __x86_64__ -#define SAMPLE_ADDR_LEN uint64_t -#else -#define SAMPLE_ADDR_LEN uint32_t -#endif - -extern CpaDcHuffType huffmanType_g; - -/* Threads */ -typedef struct task_struct *sampleThread; - -/* Check for CY API version */ -#define CY_API_VERSION_AT_LEAST(major, minor) \ - (CPA_CY_API_VERSION_NUM_MAJOR > major || \ - (CPA_CY_API_VERSION_NUM_MAJOR == major && \ - CPA_CY_API_VERSION_NUM_MINOR >= minor)) - -/* Printing */ -/**< Prints the name of the function and the arguments only if gDebugParam is - * CPA_TRUE. - */ -#define PRINT_DBG(args...) \ - do \ - { \ - if (CPA_TRUE == gDebugParam) \ - { \ - printk("%s(): ", __func__); \ - printk(KERN_CONT args); \ - } \ - } while (0) - -/**< Regular prints */ -#ifndef PRINT -#define PRINT(args...) \ - do \ - { \ - printk(KERN_CONT args); \ - } while (0) -#endif - -/**< Prints the name of the function and the arguments */ -#ifndef PRINT_ERR -#define PRINT_ERR(args...) \ - do \ - { \ - printk("%s(): ", __func__); \ - printk(KERN_CONT args); \ - } while (0) -#endif -/** - ******************************************************************************* - * @ingroup sampleUtils - * Completion definitions - * - ******************************************************************************/ -#define COMPLETION_STRUCT completion - -#define COMPLETION_INIT(c) init_completion(c) - -#define COMPLETION_WAIT(c, timeout) \ - wait_for_completion_interruptible_timeout(c, timeout) - -#define COMPLETE(c) complete(c) - -#define COMPLETION_DESTROY(s) - -#endif - -#ifndef BYTE_ALIGNMENT_8 -#define BYTE_ALIGNMENT_8 (8) -#endif -#ifndef BYTE_ALIGNMENT_64 -#define BYTE_ALIGNMENT_64 (64) -#endif - -/** - ***************************************************************************** - * @ingroup fipsSampleCodeUtils - * displayHexArray - * - * @description - * Display the contents of a buffer - * - * @param[in] pLabel String to giving a short description of the printed - * value - * @param[in] pBuff pointer to the data to be printed - * @param[in] len len of the data to be printed - * - * @retval none - * - * @pre - * none - * @post - * none - *****************************************************************************/ -static inline void displayHexArray(const char *HE_QAT_RESTRICT pLabel, - const Cpa8U *HE_QAT_RESTRICT pBuff, - Cpa32U len) -{ - - int i = 0; - PRINT("%s(%d)", pLabel, len); - if (NULL == pBuff) - { - PRINT("%s(%d) Buff is NULL!!\n", __FUNCTION__, __LINE__); - return; - } - for (i = 0; i < len; i++) - { - PRINT("%02x", pBuff[i]); - } - PRINT("\n"); -} -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function and associated macro sleeps for ms milliseconds - * - * @param[in] ms sleep time in ms - * - * @retval none - * - ******************************************************************************/ -static __inline CpaStatus sampleSleep(Cpa32U ms) -{ -#ifdef USER_SPACE - int ret = 0; - struct timespec resTime, remTime; - //resTime.tv_sec = ms / 1000; - //resTime.tv_nsec = (ms % 1000) * 1000000; - // microseconds - resTime.tv_sec = ms / 1000000; - resTime.tv_nsec = (ms % 1000000) * 1000; - do - { - ret = nanosleep(&resTime, &remTime); - resTime = remTime; - } while ((ret != 0) && (errno == EINTR)); - - if (ret != 0) - { - PRINT_ERR("nanoSleep failed with code %d\n", ret); - return CPA_STATUS_FAIL; - } - else - { - return CPA_STATUS_SUCCESS; - } -#else - if (ms != 0) - { - set_current_state((long)TASK_INTERRUPTIBLE); - schedule_timeout((ms * HZ) / 1000); - } - else - { - schedule(); - } - - return CPA_STATUS_SUCCESS; -#endif -} -/** - ******************************************************************************* - * @ingroup sampleUtils - * Macro from the sampleSleep function - * - ******************************************************************************/ -#define OS_SLEEP(ms) sampleSleep((ms)) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function and associated macro allocates the memory for the given - * size and stores the address of the memory allocated in the pointer. - * Memory allocated by this function is NOT guaranteed to be physically - * contiguous. - * - * @param[out] ppMemAddr address of pointer where address will be stored - * @param[in] sizeBytes the size of the memory to be allocated - * - * @retval CPA_STATUS_RESOURCE Macro failed to allocate Memory - * @retval CPA_STATUS_SUCCESS Macro executed successfully - * - ******************************************************************************/ -static __inline CpaStatus Mem_OsMemAlloc(void **ppMemAddr, Cpa32U sizeBytes) -{ -#ifdef USER_SPACE - *ppMemAddr = malloc(sizeBytes); - if (NULL == *ppMemAddr) - { - return CPA_STATUS_RESOURCE; - } - return CPA_STATUS_SUCCESS; -#else - *ppMemAddr = kmalloc(sizeBytes, GFP_KERNEL); - if (NULL == *ppMemAddr) - { - return CPA_STATUS_RESOURCE; - } - return CPA_STATUS_SUCCESS; -#endif -} - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function and associated macro allocates the memory for the given - * size for the given alignment and stores the address of the memory - * allocated in the pointer. Memory allocated by this function is - * guaranteed to be physically contiguous. - * - * @param[out] ppMemAddr address of pointer where address will be stored - * @param[in] sizeBytes the size of the memory to be allocated - * @param[in] alignement the alignment of the memory to be allocated - *(non-zero) - * - * @retval CPA_STATUS_RESOURCE Macro failed to allocate Memory - * @retval CPA_STATUS_SUCCESS Macro executed successfully - * - ******************************************************************************/ -static __inline CpaStatus Mem_Alloc_Contig(void **ppMemAddr, - Cpa32U sizeBytes, - Cpa32U alignment) -{ -#ifdef USER_SPACE - /* Use perf sample code memory allocator */ - - /* In this sample all allocations are done from node=0 - * This might not be optimal in a dual processor system. - */ - *ppMemAddr = qaeMemAllocNUMA(sizeBytes, 0, alignment); - if (NULL == *ppMemAddr) - { - return CPA_STATUS_RESOURCE; - } - return CPA_STATUS_SUCCESS; -#else - void *pAlloc = NULL; - uint32_t align = 0; - - pAlloc = - kmalloc_node((sizeBytes + alignment + sizeof(void *)), GFP_KERNEL, 0); - if (NULL == pAlloc) - { - return CPA_STATUS_RESOURCE; - } - - *ppMemAddr = pAlloc + sizeof(void *); - - align = ((SAMPLE_ADDR_LEN)(*ppMemAddr)) % alignment; - - *ppMemAddr += (alignment - align); - *(SAMPLE_ADDR_LEN *)(*ppMemAddr - sizeof(void *)) = (SAMPLE_ADDR_LEN)pAlloc; - - return CPA_STATUS_SUCCESS; -#endif -} - -/** - ******************************************************************************* - * @ingroup sampleUtils - * Macro from the Mem_OsMemAlloc function - * - ******************************************************************************/ -#define OS_MALLOC(ppMemAddr, sizeBytes) \ - Mem_OsMemAlloc((void *)(ppMemAddr), (sizeBytes)) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * Macro from the Mem_Alloc_Contig function - * - ******************************************************************************/ -#define PHYS_CONTIG_ALLOC(ppMemAddr, sizeBytes) \ - Mem_Alloc_Contig((void *)(ppMemAddr), (sizeBytes), 1) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * Algined version of PHYS_CONTIG_ALLOC() macro - * - ******************************************************************************/ -#define PHYS_CONTIG_ALLOC_ALIGNED(ppMemAddr, sizeBytes, alignment) \ - Mem_Alloc_Contig((void *)(ppMemAddr), (sizeBytes), (alignment)) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function and associated macro frees the memory at the given address - * and resets the pointer to NULL. The memory must have been allocated by - * the function Mem_OsMemAlloc() - * - * @param[out] ppMemAddr address of pointer where mem address is stored. - * If pointer is NULL, the function will exit silently - * - * @retval void - * - ******************************************************************************/ -static __inline void Mem_OsMemFree(void **ppMemAddr) -{ -#ifdef USER_SPACE - if (NULL != *ppMemAddr) - { - free(*ppMemAddr); - *ppMemAddr = NULL; - } -#else - if (NULL != *ppMemAddr) - { - kfree(*ppMemAddr); - *ppMemAddr = NULL; - } -#endif -} - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function and associated macro frees the memory at the given address - * and resets the pointer to NULL. The memory must have been allocated by - * the function Mem_Alloc_Contig(). - * - * @param[out] ppMemAddr address of pointer where mem address is stored. - * If pointer is NULL, the function will exit silently - * - * @retval void - * - ******************************************************************************/ -static __inline void Mem_Free_Contig(void **ppMemAddr) -{ -#ifdef USER_SPACE - if (NULL != *ppMemAddr) - { - qaeMemFreeNUMA(ppMemAddr); - *ppMemAddr = NULL; - } -#else - void *pAlloc = NULL; - - if (NULL != *ppMemAddr) - { - pAlloc = (void *)(*((SAMPLE_ADDR_LEN *)(*ppMemAddr - sizeof(void *)))); - kfree(pAlloc); - *ppMemAddr = NULL; - } -#endif -} - -/** - ******************************************************************************* - * @ingroup sampleUtils - * Macro from the Mem_OsMemFree function - * - ******************************************************************************/ -#define OS_FREE(pMemAddr) Mem_OsMemFree((void *)&pMemAddr) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * Macro from the Mem_Free_Contig function - * - ******************************************************************************/ -#define PHYS_CONTIG_FREE(pMemAddr) Mem_Free_Contig((void *)&pMemAddr) - -#define _4K_PAGE_SIZE (4 * 1024) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function returns the physical address for a given virtual address. - * In case of error 0 is returned. - * - * @param[in] virtAddr Virtual address - * - * @retval CpaPhysicalAddr Physical address or 0 in case of error - * - ******************************************************************************/ - -static __inline CpaPhysicalAddr sampleVirtToPhys(void *virtAddr) -{ -#ifdef USER_SPACE - return (CpaPhysicalAddr)qaeVirtToPhysNUMA(virtAddr); -#else - return (CpaPhysicalAddr)virt_to_phys(virtAddr); -#endif -} - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function creates a thread - * - ******************************************************************************/ - -static __inline CpaStatus sampleThreadCreate(sampleThread *thread, - void *funct, - void *args) -{ -#ifdef USER_SPACE -#ifdef __cplusplus - if (pthread_create(thread, NULL, (void* (*)(void*)) funct, args) != 0) -#else - if (pthread_create(thread, NULL, funct, args) != 0) -#endif - { - PRINT_ERR("Failed create thread\n"); - return CPA_STATUS_FAIL; - } - else - { - pthread_detach(*thread); - return CPA_STATUS_SUCCESS; - } -#else - *thread = kthread_create(funct, args, "SAMPLE_THREAD"); - wake_up_process(*thread); - return CPA_STATUS_SUCCESS; -#endif -} - -static __inline void sampleThreadExit(void) -{ -#ifdef USER_SPACE - pthread_exit(NULL); -#endif -} - -#ifdef DO_CRYPTO -void sampleCyGetInstance(CpaInstanceHandle *pCyInstHandle); - -void sampleCyStartPolling(CpaInstanceHandle cyInstHandle); - -void sampleCyStopPolling(void); - -void symSessionWaitForInflightReq(CpaCySymSessionCtx pSessionCtx); -#endif // DO_CRYPTO - -void sampleDcGetInstance(CpaInstanceHandle *pDcInstHandle); - -void sampleDcStartPolling(CpaInstanceHandle dcInstHandle); - -void sampleDcStopPolling(void); - -#ifdef __cplusplus -} //extern "C" { -#endif - - -#endif - diff --git a/heqat/include/heqat/common/types.h b/heqat/include/heqat/common/types.h index 6df1c0c..cbb9313 100644 --- a/heqat/include/heqat/common/types.h +++ b/heqat/include/heqat/common/types.h @@ -21,7 +21,7 @@ extern "C" { #include #endif -#include "heqat/common/cpa_sample_utils.h" +#include "cpa_sample_utils.h" #include "heqat/common/consts.h" // Type definitions diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 64791f4..b74b8a7 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -14,7 +14,6 @@ macro(heqat_create_executable sample_case language dependencies) add_executable(${target} test_${sample_case}.${extension}) target_include_directories(${target} PUBLIC ${HE_QAT_INC_DIR}) - target_include_directories(${target} PUBLIC ${ICP_INC_DIR}) target_link_libraries(${target} PUBLIC he_qat) From f85cb41275849292d854f212b6b48188e16e08cb Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Thu, 27 Oct 2022 16:12:07 -0700 Subject: [PATCH 304/364] Revert "Remove cpa_sample_utils from repository and enable build without external codes(#32)" (#34) This reverts commit f2c63fd1b289d2cc25a863c30c4d5cc5eb47b484. --- CMakeLists.txt | 6 +- cmake/he_qat/HE_QATConfig.cmake.in | 1 - example/CMakeLists.txt | 4 +- heqat/CMakeLists.txt | 21 +- heqat/bnops.c | 2 +- heqat/cb.c | 2 +- heqat/common/CMakeLists.txt | 3 +- heqat/common/cpa_sample_utils.c | 285 ++++++++ heqat/common/utils.c | 2 +- heqat/context.c | 2 +- heqat/ctrl.c | 2 +- heqat/include/heqat/common.h | 15 +- heqat/include/heqat/common/cpa_sample_utils.h | 651 ++++++++++++++++++ heqat/include/heqat/common/types.h | 2 +- cmake/qat_config.cmake => icp/CMakeLists.txt | 25 +- samples/CMakeLists.txt | 1 + 16 files changed, 958 insertions(+), 66 deletions(-) create mode 100644 heqat/common/cpa_sample_utils.c create mode 100644 heqat/include/heqat/common/cpa_sample_utils.h rename cmake/qat_config.cmake => icp/CMakeLists.txt (67%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5eb776b..ada67a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,11 +140,10 @@ set(HE_QAT_FORWARD_CMAKE_ARGS ) #OpenSSL installation -if(HE_QAT_SHARED) +if(NOT HE_QAT_SHARED) set(OPENSSL_USE_STATIC_LIBS TRUE) message(STATUS "OPENSSL_USE_STATIC_LIBS TRUE") else() - set(OPENSSL_USE_STATIC_LIBS FALSE) message(STATUS "OPENSSL_USE_STATIC_LIBS FALSE") endif() find_package(OpenSSL REQUIRED) @@ -162,8 +161,7 @@ if(NOT CMAKE_INSTALL_PREFIX) endif() # Include QAT lib API support -# include(icp/CMakeLists.txt) -include(cmake/qat_config.cmake) +include(icp/CMakeLists.txt) # HE_QAT Library add_subdirectory(heqat) diff --git a/cmake/he_qat/HE_QATConfig.cmake.in b/cmake/he_qat/HE_QATConfig.cmake.in index 1868908..81dc91c 100644 --- a/cmake/he_qat/HE_QATConfig.cmake.in +++ b/cmake/he_qat/HE_QATConfig.cmake.in @@ -9,7 +9,6 @@ include(${CMAKE_CURRENT_LIST_DIR}/he_qatTargets.cmake) if(TARGET HE_QAT::he_qat) set(HE_QAT_FOUND TRUE) message(STATUS "Intel Homomorphic Encryption Acceleration Library for QAT found") - add_definitions(-DUSER_SPACE) else() message(STATUS "Intel Homomorphic Encryption Acceleraiton Library for QAT not found") endif() diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 6fb0f59..88753b9 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -23,8 +23,10 @@ find_package(Threads REQUIRED) set(CMAKE_THREAD_PREFER_PTHREAD ON) set(THREADS_PREFER_PTHREAD_FLAG ON) +include(../icp/CMakeLists.txt) + add_definitions(-fpermissive) add_executable(example example.cpp) - +target_include_directories(example PRIVATE ${ICP_INC_DIR}) target_link_libraries(example PRIVATE HE_QAT::he_qat) target_link_libraries(example PRIVATE OpenSSL::SSL) diff --git a/heqat/CMakeLists.txt b/heqat/CMakeLists.txt index 4d44718..7dfe4c7 100644 --- a/heqat/CMakeLists.txt +++ b/heqat/CMakeLists.txt @@ -25,27 +25,24 @@ add_library(HE_QAT::he_qat ALIAS he_qat) target_include_directories(he_qat PUBLIC $ #Public headers PUBLIC $ #Public headers - PUBLIC ${ICP_INC_DIR} + PRIVATE ${ICP_INC_DIR} #Private headers ) install(DIRECTORY ${HE_QAT_INC_DIR}/ DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ FILES_MATCHING PATTERN "*.hpp" - PATTERN "*.h") + PATTERN "*.h") target_link_directories(he_qat PUBLIC ${ICP_BUILDOUTPUT_PATH}) target_link_libraries(he_qat PRIVATE udev z) target_link_libraries(he_qat PRIVATE OpenSSL::SSL) target_link_libraries(he_qat PRIVATE Threads::Threads) - if(HE_QAT_SHARED) - target_link_libraries(he_qat PUBLIC cpa_sample_utils) target_link_libraries(he_qat PRIVATE qat_s) target_link_libraries(he_qat PRIVATE usdm_drv_s) else() - heqat_create_archive(he_qat cpa_sample_utils) heqat_create_archive(he_qat libadf_static) heqat_create_archive(he_qat libosal_static) heqat_create_archive(he_qat libqat_static) @@ -71,6 +68,8 @@ else() set_target_properties(he_qat PROPERTIES OUTPUT_NAME "he_qat") endif() +install(TARGETS he_qat DESTINATION ${CMAKE_INSTALL_LIBDIR}) + include(CMakePackageConfigHelpers) # config cmake config and target file @@ -97,23 +96,13 @@ configure_package_config_file( INSTALL_DESTINATION ${HE_QAT_CONFIG_INSTALL_DIR} ) -if(HE_QAT_SHARED) - install( - TARGETS he_qat cpa_sample_utils - EXPORT he_qatTargets - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - ) -else() - install( +install( TARGETS he_qat EXPORT he_qatTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) -endif() install(FILES ${HE_QAT_CONFIG_FILENAME} ${HE_QAT_CONFIG_VERSION_FILENAME} diff --git a/heqat/bnops.c b/heqat/bnops.c index fc47426..f0abb67 100644 --- a/heqat/bnops.c +++ b/heqat/bnops.c @@ -5,7 +5,7 @@ #include "cpa_cy_ln.h" #include "icp_sal_poll.h" -#include "cpa_sample_utils.h" +#include "heqat/common/cpa_sample_utils.h" #include "heqat/common/consts.h" #include "heqat/common/types.h" #include "heqat/bnops.h" diff --git a/heqat/cb.c b/heqat/cb.c index e8f5906..5e2db31 100644 --- a/heqat/cb.c +++ b/heqat/cb.c @@ -8,7 +8,7 @@ #include // Local headers -#include "cpa_sample_utils.h" +#include "heqat/common/cpa_sample_utils.h" #include "heqat/common/types.h" // Global variables diff --git a/heqat/common/CMakeLists.txt b/heqat/common/CMakeLists.txt index 2e16c41..478f463 100644 --- a/heqat/common/CMakeLists.txt +++ b/heqat/common/CMakeLists.txt @@ -1,5 +1,6 @@ # Source files -set(COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/utils.c) +set(COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/cpa_sample_utils.c + ${CMAKE_CURRENT_LIST_DIR}/utils.c) list(APPEND HE_QAT_SRC ${COMMON_SRC}) set(HE_QAT_SRC ${HE_QAT_SRC} PARENT_SCOPE) diff --git a/heqat/common/cpa_sample_utils.c b/heqat/common/cpa_sample_utils.c new file mode 100644 index 0000000..53551e3 --- /dev/null +++ b/heqat/common/cpa_sample_utils.c @@ -0,0 +1,285 @@ +/*************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Corporation + * + * BSD LICENSE + * + * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * version: QAT.L.4.15.0-00011 + * + ***************************************************************************/ + +/** + ***************************************************************************** + * @file cpa_sample_utils.c + * + * @ingroup sampleCode + * + * @description + * Defines functions to get an instance and poll an instance + * + ***************************************************************************/ + +#include "heqat/common/cpa_sample_utils.h" +#include "cpa_dc.h" +#include "icp_sal_poll.h" + +/* + * Maximum number of instances to query from the API + */ +#ifdef USER_SPACE +#define MAX_INSTANCES 1024 +#else +#define MAX_INSTANCES 1 +#endif + +#ifdef DO_CRYPTO +static sampleThread gPollingThread; +static volatile int gPollingCy = 0; +#endif + +static sampleThread gPollingThreadDc; +static volatile int gPollingDc = 0; + +#ifdef SC_ENABLE_DYNAMIC_COMPRESSION +CpaDcHuffType huffmanType_g = CPA_DC_HT_FULL_DYNAMIC; +#else +CpaDcHuffType huffmanType_g = CPA_DC_HT_STATIC; +#endif +/* ************************************************************* + * + * Common instance functions + * + * ************************************************************* + */ + +/* + * This function returns a handle to an instance of the cryptographic + * API. It does this by querying the API for all instances and + * returning the first such instance. + */ +// +#ifdef DO_CRYPTO +void sampleCyGetInstance(CpaInstanceHandle *pCyInstHandle) +{ + CpaInstanceHandle cyInstHandles[MAX_INSTANCES]; + Cpa16U numInstances = 0; + CpaStatus status = CPA_STATUS_SUCCESS; + + *pCyInstHandle = NULL; + status = cpaCyGetNumInstances(&numInstances); + if (numInstances >= MAX_INSTANCES) + { + numInstances = MAX_INSTANCES; + } + if ((status == CPA_STATUS_SUCCESS) && (numInstances > 0)) + { + status = cpaCyGetInstances(numInstances, cyInstHandles); + if (status == CPA_STATUS_SUCCESS) + *pCyInstHandle = cyInstHandles[0]; + } + + if (0 == numInstances) + { + PRINT_ERR("No instances found for 'SSL'\n"); + PRINT_ERR("Please check your section names"); + PRINT_ERR(" in the config file.\n"); + PRINT_ERR("Also make sure to use config file version 2.\n"); + } +} + +void symSessionWaitForInflightReq(CpaCySymSessionCtx pSessionCtx) +{ + +/* Session reuse is available since Cryptographic API version 2.2 */ +#if CY_API_VERSION_AT_LEAST(2, 2) + CpaBoolean sessionInUse = CPA_FALSE; + + do + { + cpaCySymSessionInUse(pSessionCtx, &sessionInUse); + } while (sessionInUse); +#endif + + return; +} +#endif +// + +/* + * This function polls a crypto instance. + * + */ +#ifdef DO_CRYPTO +static void sal_polling(CpaInstanceHandle cyInstHandle) +{ + gPollingCy = 1; + while (gPollingCy) + { + icp_sal_CyPollInstance(cyInstHandle, 0); + OS_SLEEP(10); + } + + sampleThreadExit(); +} +#endif +/* + * This function checks the instance info. If the instance is + * required to be polled then it starts a polling thread. + */ + +#ifdef DO_CRYPTO +void sampleCyStartPolling(CpaInstanceHandle cyInstHandle) +{ + CpaInstanceInfo2 info2 = {0}; + CpaStatus status = CPA_STATUS_SUCCESS; + + status = cpaCyInstanceGetInfo2(cyInstHandle, &info2); + if ((status == CPA_STATUS_SUCCESS) && (info2.isPolled == CPA_TRUE)) + { + /* Start thread to poll instance */ + sampleThreadCreate(&gPollingThread, sal_polling, cyInstHandle); + } +} +#endif +/* + * This function stops the polling of a crypto instance. + */ +#ifdef DO_CRYPTO +void sampleCyStopPolling(void) +{ + gPollingCy = 0; + OS_SLEEP(10); +} +#endif + +/* + * This function returns a handle to an instance of the data + * compression API. It does this by querying the API for all + * instances and returning the first such instance. + */ +// +void sampleDcGetInstance(CpaInstanceHandle *pDcInstHandle) +{ + CpaInstanceHandle dcInstHandles[MAX_INSTANCES]; + Cpa16U numInstances = 0; + CpaStatus status = CPA_STATUS_SUCCESS; + + *pDcInstHandle = NULL; + status = cpaDcGetNumInstances(&numInstances); + if (numInstances >= MAX_INSTANCES) + { + numInstances = MAX_INSTANCES; + } + if ((status == CPA_STATUS_SUCCESS) && (numInstances > 0)) + { + status = cpaDcGetInstances(numInstances, dcInstHandles); + if (status == CPA_STATUS_SUCCESS) + *pDcInstHandle = dcInstHandles[0]; + } + + if (0 == numInstances) + { + PRINT_ERR("No instances found for 'SSL'\n"); + PRINT_ERR("Please check your section names"); + PRINT_ERR(" in the config file.\n"); + PRINT_ERR("Also make sure to use config file version 2.\n"); + } +} +// + +/* + * This function polls a compression instance. + * + */ +static void sal_dc_polling(CpaInstanceHandle dcInstHandle) +{ + + gPollingDc = 1; + while (gPollingDc) + { + icp_sal_DcPollInstance(dcInstHandle, 0); + OS_SLEEP(10); + } + + sampleThreadExit(); +} + +/* + * This function checks the instance info. If the instance is + * required to be polled then it starts a polling thread. + */ +void sampleDcStartPolling(CpaInstanceHandle dcInstHandle) +{ + CpaInstanceInfo2 info2 = {0}; + CpaStatus status = CPA_STATUS_SUCCESS; + + status = cpaDcInstanceGetInfo2(dcInstHandle, &info2); + if ((status == CPA_STATUS_SUCCESS) && (info2.isPolled == CPA_TRUE)) + { + /* Start thread to poll instance */ + sampleThreadCreate(&gPollingThreadDc, sal_dc_polling, dcInstHandle); + } +} + +/* + * This function stops the thread polling the compression instance. + */ +void sampleDcStopPolling(void) +{ + gPollingDc = 0; + OS_SLEEP(10); +} + diff --git a/heqat/common/utils.c b/heqat/common/utils.c index 7500b3a..8d1aa0d 100644 --- a/heqat/common/utils.c +++ b/heqat/common/utils.c @@ -1,4 +1,4 @@ -#include "cpa_sample_utils.h" +#include "heqat/common/cpa_sample_utils.h" #include "heqat/common/utils.h" #include diff --git a/heqat/context.c b/heqat/context.c index c15172a..985d253 100644 --- a/heqat/context.c +++ b/heqat/context.c @@ -9,7 +9,7 @@ #include #include -#include "cpa_sample_utils.h" +#include "heqat/common/cpa_sample_utils.h" #include "heqat/common/types.h" #include "heqat/context.h" diff --git a/heqat/ctrl.c b/heqat/ctrl.c index cc1c271..88fd913 100644 --- a/heqat/ctrl.c +++ b/heqat/ctrl.c @@ -20,7 +20,7 @@ double time_taken = 0.0; #include // Local headers -#include "cpa_sample_utils.h" +#include "heqat/common/cpa_sample_utils.h" #include "heqat/common/consts.h" #include "heqat/common/types.h" #include "heqat/bnops.h" diff --git a/heqat/include/heqat/common.h b/heqat/include/heqat/common.h index 70c322f..67f9ede 100644 --- a/heqat/include/heqat/common.h +++ b/heqat/include/heqat/common.h @@ -1,6 +1,6 @@ /// @file heqat/common.h -#include "cpa_sample_utils.h" +#include "heqat/common/cpa_sample_utils.h" #include "heqat/common/consts.h" #include "heqat/common/types.h" #include "heqat/common/utils.h" @@ -11,16 +11,3 @@ #endif #endif -#ifdef HE_QAT_DEBUG -#define HE_QAT_PRINT_DBG(args...) \ - do \ - { \ - { \ - printf("%s(): ", __func__); \ - printf(args); \ - fflush(stdout); \ - } \ - } while (0) -#else -#define HE_QAT_PRINT_DBG(args...) { } -#endif \ No newline at end of file diff --git a/heqat/include/heqat/common/cpa_sample_utils.h b/heqat/include/heqat/common/cpa_sample_utils.h new file mode 100644 index 0000000..a128640 --- /dev/null +++ b/heqat/include/heqat/common/cpa_sample_utils.h @@ -0,0 +1,651 @@ +/*************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Corporation + * + * BSD LICENSE + * + * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * version: QAT.L.4.15.0-00011 + * + ***************************************************************************/ + +/** + ***************************************************************************** + * @file cpa_sample_utils.h + * + * @defgroup sampleUtils Macro and inline function definitions + * + * @ingroup sampleCode + * + * @description + * Defines macros for printing and debugging, inline functions for memory + * allocating and freeing and thread creation + * + ***************************************************************************/ + +#ifndef CPA_SAMPLE_UTILS_H +#define CPA_SAMPLE_UTILS_H + +#ifdef __cplusplus +#define HE_QAT_RESTRICT __restrict__ +#else +#define HE_QAT_RESTRICT restrict +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "cpa.h" +#include "cpa_cy_im.h" +#include "cpa_dc.h" + + +#ifdef DO_CRYPTO +#include "cpa_cy_sym.h" +#endif + +#ifdef USER_SPACE +/* User space utils */ +#include +#include +#include +#include +#include +#include +/* Performance sample code mem utils */ + +#include "qae_mem.h" + +extern CpaDcHuffType huffmanType_g; +extern CpaStatus qaeMemInit(void); +extern void qaeMemDestroy(void); +/* Threads */ +typedef pthread_t sampleThread; + +/* Check for CY API version */ +#define CY_API_VERSION_AT_LEAST(major, minor) \ + (CPA_CY_API_VERSION_NUM_MAJOR > major || \ + (CPA_CY_API_VERSION_NUM_MAJOR == major && \ + CPA_CY_API_VERSION_NUM_MINOR >= minor)) + +#ifdef HE_QAT_DEBUG +#define HE_QAT_PRINT_DBG(args...) \ + do \ + { \ + { \ + printf("%s(): ", __func__); \ + printf(args); \ + fflush(stdout); \ + } \ + } while (0) +#else +#define HE_QAT_PRINT_DBG(args...) { } +#endif +/* Printing */ +/**< Prints the name of the function and the arguments only if gDebugParam is + * CPA_TRUE. + */ +#define PRINT_DBG(args...) \ + do \ + { \ + if (CPA_TRUE == gDebugParam) \ + { \ + printf("%s(): ", __func__); \ + printf(args); \ + fflush(stdout); \ + } \ + } while (0) + +/**< Prints the arguments */ +#ifndef PRINT +#define PRINT(args...) \ + do \ + { \ + printf(args); \ + } while (0) +#endif + +/**< Prints the name of the function and the arguments */ +#ifndef PRINT_ERR +#define PRINT_ERR(args...) \ + do \ + { \ + printf("%s(): ", __func__); \ + printf(args); \ + } while (0) +#endif +/** + ******************************************************************************* + * @ingroup sampleUtils + * Completion definitions + * + ******************************************************************************/ +struct completion_struct +{ + sem_t semaphore; +}; +/* Use semaphores to signal completion of events */ +#define COMPLETION_STRUCT completion_struct + +#define COMPLETION_INIT(s) sem_init(&((s)->semaphore), 0, 0); + +#define COMPLETION_WAIT(s, timeout) (sem_wait(&((s)->semaphore)) == 0) + +#define COMPLETE(s) sem_post(&((s)->semaphore)) + +#define COMPLETION_DESTROY(s) sem_destroy(&((s)->semaphore)) + +#else +/* Kernel space utils */ +#include +#include +#include +#include +#include +#include +#include + +#ifdef __x86_64__ +#define SAMPLE_ADDR_LEN uint64_t +#else +#define SAMPLE_ADDR_LEN uint32_t +#endif + +extern CpaDcHuffType huffmanType_g; + +/* Threads */ +typedef struct task_struct *sampleThread; + +/* Check for CY API version */ +#define CY_API_VERSION_AT_LEAST(major, minor) \ + (CPA_CY_API_VERSION_NUM_MAJOR > major || \ + (CPA_CY_API_VERSION_NUM_MAJOR == major && \ + CPA_CY_API_VERSION_NUM_MINOR >= minor)) + +/* Printing */ +/**< Prints the name of the function and the arguments only if gDebugParam is + * CPA_TRUE. + */ +#define PRINT_DBG(args...) \ + do \ + { \ + if (CPA_TRUE == gDebugParam) \ + { \ + printk("%s(): ", __func__); \ + printk(KERN_CONT args); \ + } \ + } while (0) + +/**< Regular prints */ +#ifndef PRINT +#define PRINT(args...) \ + do \ + { \ + printk(KERN_CONT args); \ + } while (0) +#endif + +/**< Prints the name of the function and the arguments */ +#ifndef PRINT_ERR +#define PRINT_ERR(args...) \ + do \ + { \ + printk("%s(): ", __func__); \ + printk(KERN_CONT args); \ + } while (0) +#endif +/** + ******************************************************************************* + * @ingroup sampleUtils + * Completion definitions + * + ******************************************************************************/ +#define COMPLETION_STRUCT completion + +#define COMPLETION_INIT(c) init_completion(c) + +#define COMPLETION_WAIT(c, timeout) \ + wait_for_completion_interruptible_timeout(c, timeout) + +#define COMPLETE(c) complete(c) + +#define COMPLETION_DESTROY(s) + +#endif + +#ifndef BYTE_ALIGNMENT_8 +#define BYTE_ALIGNMENT_8 (8) +#endif +#ifndef BYTE_ALIGNMENT_64 +#define BYTE_ALIGNMENT_64 (64) +#endif + +/** + ***************************************************************************** + * @ingroup fipsSampleCodeUtils + * displayHexArray + * + * @description + * Display the contents of a buffer + * + * @param[in] pLabel String to giving a short description of the printed + * value + * @param[in] pBuff pointer to the data to be printed + * @param[in] len len of the data to be printed + * + * @retval none + * + * @pre + * none + * @post + * none + *****************************************************************************/ +static inline void displayHexArray(const char *HE_QAT_RESTRICT pLabel, + const Cpa8U *HE_QAT_RESTRICT pBuff, + Cpa32U len) +{ + + int i = 0; + PRINT("%s(%d)", pLabel, len); + if (NULL == pBuff) + { + PRINT("%s(%d) Buff is NULL!!\n", __FUNCTION__, __LINE__); + return; + } + for (i = 0; i < len; i++) + { + PRINT("%02x", pBuff[i]); + } + PRINT("\n"); +} +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function and associated macro sleeps for ms milliseconds + * + * @param[in] ms sleep time in ms + * + * @retval none + * + ******************************************************************************/ +static __inline CpaStatus sampleSleep(Cpa32U ms) +{ +#ifdef USER_SPACE + int ret = 0; + struct timespec resTime, remTime; + //resTime.tv_sec = ms / 1000; + //resTime.tv_nsec = (ms % 1000) * 1000000; + // microseconds + resTime.tv_sec = ms / 1000000; + resTime.tv_nsec = (ms % 1000000) * 1000; + do + { + ret = nanosleep(&resTime, &remTime); + resTime = remTime; + } while ((ret != 0) && (errno == EINTR)); + + if (ret != 0) + { + PRINT_ERR("nanoSleep failed with code %d\n", ret); + return CPA_STATUS_FAIL; + } + else + { + return CPA_STATUS_SUCCESS; + } +#else + if (ms != 0) + { + set_current_state((long)TASK_INTERRUPTIBLE); + schedule_timeout((ms * HZ) / 1000); + } + else + { + schedule(); + } + + return CPA_STATUS_SUCCESS; +#endif +} +/** + ******************************************************************************* + * @ingroup sampleUtils + * Macro from the sampleSleep function + * + ******************************************************************************/ +#define OS_SLEEP(ms) sampleSleep((ms)) + +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function and associated macro allocates the memory for the given + * size and stores the address of the memory allocated in the pointer. + * Memory allocated by this function is NOT guaranteed to be physically + * contiguous. + * + * @param[out] ppMemAddr address of pointer where address will be stored + * @param[in] sizeBytes the size of the memory to be allocated + * + * @retval CPA_STATUS_RESOURCE Macro failed to allocate Memory + * @retval CPA_STATUS_SUCCESS Macro executed successfully + * + ******************************************************************************/ +static __inline CpaStatus Mem_OsMemAlloc(void **ppMemAddr, Cpa32U sizeBytes) +{ +#ifdef USER_SPACE + *ppMemAddr = malloc(sizeBytes); + if (NULL == *ppMemAddr) + { + return CPA_STATUS_RESOURCE; + } + return CPA_STATUS_SUCCESS; +#else + *ppMemAddr = kmalloc(sizeBytes, GFP_KERNEL); + if (NULL == *ppMemAddr) + { + return CPA_STATUS_RESOURCE; + } + return CPA_STATUS_SUCCESS; +#endif +} + +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function and associated macro allocates the memory for the given + * size for the given alignment and stores the address of the memory + * allocated in the pointer. Memory allocated by this function is + * guaranteed to be physically contiguous. + * + * @param[out] ppMemAddr address of pointer where address will be stored + * @param[in] sizeBytes the size of the memory to be allocated + * @param[in] alignement the alignment of the memory to be allocated + *(non-zero) + * + * @retval CPA_STATUS_RESOURCE Macro failed to allocate Memory + * @retval CPA_STATUS_SUCCESS Macro executed successfully + * + ******************************************************************************/ +static __inline CpaStatus Mem_Alloc_Contig(void **ppMemAddr, + Cpa32U sizeBytes, + Cpa32U alignment) +{ +#ifdef USER_SPACE + /* Use perf sample code memory allocator */ + + /* In this sample all allocations are done from node=0 + * This might not be optimal in a dual processor system. + */ + *ppMemAddr = qaeMemAllocNUMA(sizeBytes, 0, alignment); + if (NULL == *ppMemAddr) + { + return CPA_STATUS_RESOURCE; + } + return CPA_STATUS_SUCCESS; +#else + void *pAlloc = NULL; + uint32_t align = 0; + + pAlloc = + kmalloc_node((sizeBytes + alignment + sizeof(void *)), GFP_KERNEL, 0); + if (NULL == pAlloc) + { + return CPA_STATUS_RESOURCE; + } + + *ppMemAddr = pAlloc + sizeof(void *); + + align = ((SAMPLE_ADDR_LEN)(*ppMemAddr)) % alignment; + + *ppMemAddr += (alignment - align); + *(SAMPLE_ADDR_LEN *)(*ppMemAddr - sizeof(void *)) = (SAMPLE_ADDR_LEN)pAlloc; + + return CPA_STATUS_SUCCESS; +#endif +} + +/** + ******************************************************************************* + * @ingroup sampleUtils + * Macro from the Mem_OsMemAlloc function + * + ******************************************************************************/ +#define OS_MALLOC(ppMemAddr, sizeBytes) \ + Mem_OsMemAlloc((void *)(ppMemAddr), (sizeBytes)) + +/** + ******************************************************************************* + * @ingroup sampleUtils + * Macro from the Mem_Alloc_Contig function + * + ******************************************************************************/ +#define PHYS_CONTIG_ALLOC(ppMemAddr, sizeBytes) \ + Mem_Alloc_Contig((void *)(ppMemAddr), (sizeBytes), 1) + +/** + ******************************************************************************* + * @ingroup sampleUtils + * Algined version of PHYS_CONTIG_ALLOC() macro + * + ******************************************************************************/ +#define PHYS_CONTIG_ALLOC_ALIGNED(ppMemAddr, sizeBytes, alignment) \ + Mem_Alloc_Contig((void *)(ppMemAddr), (sizeBytes), (alignment)) + +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function and associated macro frees the memory at the given address + * and resets the pointer to NULL. The memory must have been allocated by + * the function Mem_OsMemAlloc() + * + * @param[out] ppMemAddr address of pointer where mem address is stored. + * If pointer is NULL, the function will exit silently + * + * @retval void + * + ******************************************************************************/ +static __inline void Mem_OsMemFree(void **ppMemAddr) +{ +#ifdef USER_SPACE + if (NULL != *ppMemAddr) + { + free(*ppMemAddr); + *ppMemAddr = NULL; + } +#else + if (NULL != *ppMemAddr) + { + kfree(*ppMemAddr); + *ppMemAddr = NULL; + } +#endif +} + +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function and associated macro frees the memory at the given address + * and resets the pointer to NULL. The memory must have been allocated by + * the function Mem_Alloc_Contig(). + * + * @param[out] ppMemAddr address of pointer where mem address is stored. + * If pointer is NULL, the function will exit silently + * + * @retval void + * + ******************************************************************************/ +static __inline void Mem_Free_Contig(void **ppMemAddr) +{ +#ifdef USER_SPACE + if (NULL != *ppMemAddr) + { + qaeMemFreeNUMA(ppMemAddr); + *ppMemAddr = NULL; + } +#else + void *pAlloc = NULL; + + if (NULL != *ppMemAddr) + { + pAlloc = (void *)(*((SAMPLE_ADDR_LEN *)(*ppMemAddr - sizeof(void *)))); + kfree(pAlloc); + *ppMemAddr = NULL; + } +#endif +} + +/** + ******************************************************************************* + * @ingroup sampleUtils + * Macro from the Mem_OsMemFree function + * + ******************************************************************************/ +#define OS_FREE(pMemAddr) Mem_OsMemFree((void *)&pMemAddr) + +/** + ******************************************************************************* + * @ingroup sampleUtils + * Macro from the Mem_Free_Contig function + * + ******************************************************************************/ +#define PHYS_CONTIG_FREE(pMemAddr) Mem_Free_Contig((void *)&pMemAddr) + +#define _4K_PAGE_SIZE (4 * 1024) + +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function returns the physical address for a given virtual address. + * In case of error 0 is returned. + * + * @param[in] virtAddr Virtual address + * + * @retval CpaPhysicalAddr Physical address or 0 in case of error + * + ******************************************************************************/ + +static __inline CpaPhysicalAddr sampleVirtToPhys(void *virtAddr) +{ +#ifdef USER_SPACE + return (CpaPhysicalAddr)qaeVirtToPhysNUMA(virtAddr); +#else + return (CpaPhysicalAddr)virt_to_phys(virtAddr); +#endif +} + +/** + ******************************************************************************* + * @ingroup sampleUtils + * This function creates a thread + * + ******************************************************************************/ + +static __inline CpaStatus sampleThreadCreate(sampleThread *thread, + void *funct, + void *args) +{ +#ifdef USER_SPACE +#ifdef __cplusplus + if (pthread_create(thread, NULL, (void* (*)(void*)) funct, args) != 0) +#else + if (pthread_create(thread, NULL, funct, args) != 0) +#endif + { + PRINT_ERR("Failed create thread\n"); + return CPA_STATUS_FAIL; + } + else + { + pthread_detach(*thread); + return CPA_STATUS_SUCCESS; + } +#else + *thread = kthread_create(funct, args, "SAMPLE_THREAD"); + wake_up_process(*thread); + return CPA_STATUS_SUCCESS; +#endif +} + +static __inline void sampleThreadExit(void) +{ +#ifdef USER_SPACE + pthread_exit(NULL); +#endif +} + +#ifdef DO_CRYPTO +void sampleCyGetInstance(CpaInstanceHandle *pCyInstHandle); + +void sampleCyStartPolling(CpaInstanceHandle cyInstHandle); + +void sampleCyStopPolling(void); + +void symSessionWaitForInflightReq(CpaCySymSessionCtx pSessionCtx); +#endif // DO_CRYPTO + +void sampleDcGetInstance(CpaInstanceHandle *pDcInstHandle); + +void sampleDcStartPolling(CpaInstanceHandle dcInstHandle); + +void sampleDcStopPolling(void); + +#ifdef __cplusplus +} //extern "C" { +#endif + + +#endif + diff --git a/heqat/include/heqat/common/types.h b/heqat/include/heqat/common/types.h index cbb9313..6df1c0c 100644 --- a/heqat/include/heqat/common/types.h +++ b/heqat/include/heqat/common/types.h @@ -21,7 +21,7 @@ extern "C" { #include #endif -#include "cpa_sample_utils.h" +#include "heqat/common/cpa_sample_utils.h" #include "heqat/common/consts.h" // Type definitions diff --git a/cmake/qat_config.cmake b/icp/CMakeLists.txt similarity index 67% rename from cmake/qat_config.cmake rename to icp/CMakeLists.txt index 59bfc54..e440b79 100644 --- a/cmake/qat_config.cmake +++ b/icp/CMakeLists.txt @@ -1,7 +1,4 @@ -# Copyright (C) 2021 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 -# Setup ICP variables if(DEFINED ENV{ICP_ROOT}) message(STATUS "Environment variable ICP_ROOT is defined as $ENV{ICP_ROOT}.") else() @@ -16,21 +13,19 @@ set(ICP_LAC_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer) set(ICP_OSAL_DIR ${ICP_ROOT}/quickassist/utilities/oasl) set(ICP_ADF_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/qat_direct) set(CMN_ROOT ${ICP_ROOT}/quickassist/utilities/libusdm_drv) -set(CPA_SAMPLES_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/sample_code/functional) set(ICP_INC_DIR ${ICP_API_DIR}/include ${ICP_LAC_DIR}/include ${ICP_ADF_DIR}/include ${CMN_ROOT} ${ICP_API_DIR}/include/dc - ${ICP_API_DIR}/include/lac - ${CPA_SAMPLES_DIR}/include) + ${ICP_API_DIR}/include/lac) +# Active macros for cpa_sample_utils add_definitions(-DDO_CRYPTO) add_definitions(-DUSER_SPACE) add_compile_options(-fPIC) -# Active macros for cpa_sample_utils add_library(libadf_static STATIC IMPORTED GLOBAL) add_library(libosal_static STATIC IMPORTED GLOBAL) add_library(libqat_static STATIC IMPORTED GLOBAL) @@ -51,19 +46,3 @@ set_target_properties(libqat_static PROPERTIES set_target_properties(libusdm_drv_static PROPERTIES IMPORTED_LOCATION ${ICP_BUILDOUTPUT_PATH}/libusdm_drv.a ) - -# Build cpa_sample_utils -set(CPA_SAMPLE_UTILS_SRC ${CPA_SAMPLES_DIR}/common/cpa_sample_utils.c) -set(CPA_SAMPLE_UTILS_HDR ${CPA_SAMPLES_DIR}/include/cpa_sample_utils.h) -if(HE_QAT_SHARED) - add_library(cpa_sample_utils SHARED ${CPA_SAMPLE_UTILS_SRC}) -else() - add_library(cpa_sample_utils STATIC ${CPA_SAMPLE_UTILS_SRC}) -endif() - -set_target_properties(cpa_sample_utils PROPERTIES - LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/heqat) - -target_include_directories(cpa_sample_utils - PRIVATE ${ICP_INC_DIR} -) diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index b74b8a7..64791f4 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -14,6 +14,7 @@ macro(heqat_create_executable sample_case language dependencies) add_executable(${target} test_${sample_case}.${extension}) target_include_directories(${target} PUBLIC ${HE_QAT_INC_DIR}) + target_include_directories(${target} PUBLIC ${ICP_INC_DIR}) target_link_libraries(${target} PUBLIC he_qat) From 14c54132d051ac76d31ab580b52b44c80d4d18e4 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 28 Oct 2022 00:44:10 -0700 Subject: [PATCH 305/364] Remove cpa_sample_utils dependency. Signed-off-by: Souza, Fillipe --- doc/Doxyfile.in | 8 +- example/example.cpp | 14 +- heqat/CMakeLists.txt | 2 +- heqat/bnops.c | 181 +++-- heqat/cb.c | 7 +- heqat/common/CMakeLists.txt | 3 +- heqat/common/cpa_sample_utils.c | 285 -------- heqat/common/utils.c | 24 +- heqat/context.c | 124 ++-- heqat/ctrl.c | 40 +- heqat/include/heqat/bnops.h | 4 +- heqat/include/heqat/common.h | 1 - heqat/include/heqat/common/cpa_sample_utils.h | 651 ------------------ heqat/include/heqat/common/types.h | 17 +- heqat/include/heqat/common/utils.h | 142 ++++ heqat/include/heqat/context.h | 2 +- samples/test_BIGNUMModExp.c | 12 +- samples/test_bnConversion.cpp | 18 +- samples/test_bnModExp.cpp | 44 +- samples/test_bnModExp_MT.cpp | 46 +- samples/test_context.c | 2 +- 21 files changed, 417 insertions(+), 1210 deletions(-) delete mode 100644 heqat/common/cpa_sample_utils.c delete mode 100644 heqat/include/heqat/common/cpa_sample_utils.h diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index 6bf8078..3c33f32 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -5,8 +5,12 @@ PROJECT_NAME = "Intel HE Acceleration Library for QAT" PROJECT_BRIEF = "Intel Homomorphic Encryption Acceleration Library for QAT, accelerating the modular arithmetic operations used in partial homomorphic encryption on Intel QAT." OUTPUT_DIRECTORY = @CMAKE_BINARY_DIR@/doc/doxygen -INPUT = @CMAKE_SOURCE_DIR@/he_qat/include \ - @CMAKE_SOURCE_DIR@/misc \ +INPUT = @CMAKE_SOURCE_DIR@/heqat/include/heqat \ + @CMAKE_SOURCE_DIR@/heqat/include/heqat/common \ + @CMAKE_SOURCE_DIR@/heqat/include/heqat/misc \ + @CMAKE_SOURCE_DIR@/heqat \ + @CMAKE_SOURCE_DIR@/heqat/misc \ + @CMAKE_SOURCE_DIR@/heqat/common \ @CMAKE_SOURCE_DIR@/icp \ @CMAKE_SOURCE_DIR@/samples \ @CMAKE_SOURCE_DIR@/README.md diff --git a/example/example.cpp b/example/example.cpp index 559baca..b8e8bb7 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -45,7 +45,7 @@ int main(int argc, const char** argv) { #ifdef HE_QAT_DEBUG char* bn_str = BN_bn2hex(bn_mod); - PRINT("Generated modulus: %s num_bytes: %d num_bits: %d\n", bn_str, + HE_QAT_PRINT("Generated modulus: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); OPENSSL_free(bn_str); #endif @@ -71,13 +71,13 @@ int main(int argc, const char** argv) { if (!ERR_get_error()) { #ifdef HE_QAT_DEBUG bn_str = BN_bn2hex(ssl_res); - PRINT("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", bn_str, + HE_QAT_PRINT("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); showHexBN(ssl_res, bit_length); OPENSSL_free(bn_str); #endif } else { - PRINT_ERR("Modular exponentiation failed.\n"); + HE_QAT_PRINT_ERR("Modular exponentiation failed.\n"); exit(1); } @@ -103,18 +103,18 @@ int main(int argc, const char** argv) { (mod * avg_speed_up + (ssl_elapsed) / (qat_elapsed/BATCH_SIZE)) / (mod + 1); - PRINT("Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", + HE_QAT_PRINT("Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", (mod + 1), ssl_avg_time, qat_avg_time, avg_speed_up); if (HE_QAT_STATUS_SUCCESS != status) { - PRINT_ERR("\nQAT bnModExpOp failed\n"); + HE_QAT_PRINT_ERR("\nQAT bnModExpOp failed\n"); exit(1); } if (BN_cmp(qat_res, ssl_res) != 0) - PRINT("\t** FAIL **\n"); + HE_QAT_PRINT("\t** FAIL **\n"); else - PRINT("\t** PASS **\n"); + HE_QAT_PRINT("\t** PASS **\n"); HE_QAT_PRINT_DBG("\nQAT bnModExpOp finished\n"); diff --git a/heqat/CMakeLists.txt b/heqat/CMakeLists.txt index 7dfe4c7..ba0b7aa 100644 --- a/heqat/CMakeLists.txt +++ b/heqat/CMakeLists.txt @@ -1,5 +1,5 @@ -# HEQAT Lib source code +# HE QAT Lib source code set(HE_QAT_SRC ${HE_QAT_SRC_DIR}/cb.c ${HE_QAT_SRC_DIR}/context.c ${HE_QAT_SRC_DIR}/ctrl.c diff --git a/heqat/bnops.c b/heqat/bnops.c index f0abb67..29b4d6a 100644 --- a/heqat/bnops.c +++ b/heqat/bnops.c @@ -5,10 +5,10 @@ #include "cpa_cy_ln.h" #include "icp_sal_poll.h" -#include "heqat/common/cpa_sample_utils.h" +#include "heqat/bnops.h" #include "heqat/common/consts.h" #include "heqat/common/types.h" -#include "heqat/bnops.h" +#include "heqat/common/utils.h" #ifdef HE_QAT_PERF #include @@ -17,6 +17,7 @@ #include #include #include +#include #include #ifdef HE_QAT_SYNC_MODE @@ -61,19 +62,22 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, Cpa8U* pExponent = NULL; // TODO(fdiasmor): Try it with 8-byte alignment. - CpaStatus status = CPA_STATUS_FAIL; + //CpaStatus status = CPA_STATUS_FAIL; // status = PHYS_CONTIG_ALLOC(&pBase, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pBase, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pBase) { + //status = PHYS_CONTIG_ALLOC_ALIGNED(&pBase, len, 8); + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + status = HE_QAT_MEM_ALLOC_CONTIG(&pBase, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != pBase) { memcpy(pBase, b, len); } else { - printf("Contiguous memory allocation failed for pBase.\n"); + HE_QAT_PRINT_ERR("Contiguous memory allocation failed for pBase.\n"); return HE_QAT_STATUS_FAIL; } // status = PHYS_CONTIG_ALLOC(&pExponent, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pExponent, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { + //status = PHYS_CONTIG_ALLOC_ALIGNED(&pExponent, len, 8); + status = HE_QAT_MEM_ALLOC_CONTIG(&pExponent, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != pExponent) { memcpy(pExponent, e, len); } else { printf("Contiguous memory allocation failed for pBase.\n"); @@ -81,21 +85,20 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, } // status = PHYS_CONTIG_ALLOC(&pModulus, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pModulus, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { + //status = PHYS_CONTIG_ALLOC_ALIGNED(&pModulus, len, 8); + status = HE_QAT_MEM_ALLOC_CONTIG(&pModulus, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != pModulus) { memcpy(pModulus, m, len); } else { - printf("Contiguous memory allocation failed for pBase.\n"); + HE_QAT_PRINT_ERR("Contiguous memory allocation failed for pBase.\n"); return HE_QAT_STATUS_FAIL; } - // HE_QAT_TaskRequest request = - // HE_QAT_PACK_MODEXP_REQUEST(pBase, pExponent, pModulus, r) // Pack it as a QAT Task Request HE_QAT_TaskRequest* request = (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); if (NULL == request) { - printf( + HE_QAT_PRINT_ERR( "HE_QAT_TaskRequest memory allocation failed in " "bnModExpPerformOp.\n"); return HE_QAT_STATUS_FAIL; @@ -104,7 +107,7 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)calloc(1, sizeof(CpaCyLnModExpOpData)); if (NULL == op_data) { - printf("Cpa memory allocation failed in bnModExpPerformOp.\n"); + HE_QAT_PRINT_ERR("Cpa memory allocation failed in bnModExpPerformOp.\n"); return HE_QAT_STATUS_FAIL; } op_data->base.pData = pBase; @@ -116,11 +119,12 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, request->op_data = (void*)op_data; // status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&request->op_result.pData, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != request->op_result.pData) { + //status = PHYS_CONTIG_ALLOC_ALIGNED(&request->op_result.pData, len, 8); + status = HE_QAT_MEM_ALLOC_CONTIG(&request->op_result.pData, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != request->op_result.pData) { request->op_result.dataLenInBytes = len; } else { - printf( + HE_QAT_PRINT_ERR( "CpaFlatBuffer.pData memory allocation failed in " "bnModExpPerformOp.\n"); return HE_QAT_STATUS_FAIL; @@ -137,9 +141,7 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, pthread_mutex_init(&request->mutex, NULL); pthread_cond_init(&request->ready, NULL); -#ifdef HE_QAT_DEBUG - printf("BN ModExp interface call for request #%llu\n", req_count); -#endif + HE_QAT_PRINT_DBG("BN ModExp interface call for request #%llu\n", req_count); // Submit request using producer function submit_request(&he_qat_buffer, (void*)request); @@ -160,47 +162,55 @@ HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, in HE_QAT_TaskRequest* request = (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); if (NULL == request) { - printf( + HE_QAT_PRINT_ERR( "HE_QAT_TaskRequest memory allocation failed in " "bnModExpPerformOp.\n"); return HE_QAT_STATUS_FAIL; } // TODO: @fdiasmor Try it with 8-byte alignment. - CpaStatus status = CPA_STATUS_FAIL; - status = PHYS_CONTIG_ALLOC(&pBase, len); - if (CPA_STATUS_SUCCESS == status && NULL != pBase) { + //CpaStatus status = CPA_STATUS_FAIL; + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + //status = PHYS_CONTIG_ALLOC(&pBase, len); + //status = PHYS_CONTIG_ALLOC(&pBase, len); + status = HE_QAT_MEM_ALLOC_CONTIG(&pBase, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != pBase) { if (!BN_bn2binpad(b, pBase, len)) { - printf("BN_bn2binpad (base) failed in bnModExpPerformOp.\n"); - PHYS_CONTIG_FREE(pBase); + HE_QAT_PRINT_ERR("BN_bn2binpad (base) failed in bnModExpPerformOp.\n"); + //PHYS_CONTIG_FREE(pBase); + HE_QAT_MEM_FREE_CONTIG(pBase); return HE_QAT_STATUS_FAIL; } } else { - printf("Contiguous memory allocation failed for pBase.\n"); + HE_QAT_PRINT_ERR("Contiguous memory allocation failed for pBase.\n"); return HE_QAT_STATUS_FAIL; } - status = PHYS_CONTIG_ALLOC(&pExponent, len); - if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { + //status = PHYS_CONTIG_ALLOC(&pExponent, len); + status = HE_QAT_MEM_ALLOC_CONTIG(&pExponent, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != pExponent) { if (!BN_bn2binpad(e, pExponent, len)) { - printf("BN_bn2binpad (exponent) failed in bnModExpPerformOp.\n"); - PHYS_CONTIG_FREE(pExponent); + HE_QAT_PRINT_ERR("BN_bn2binpad (exponent) failed in bnModExpPerformOp.\n"); + //PHYS_CONTIG_FREE(pExponent); + HE_QAT_MEM_FREE_CONTIG(pExponent); return HE_QAT_STATUS_FAIL; } } else { - printf("Contiguous memory allocation failed for pBase.\n"); + HE_QAT_PRINT_ERR("Contiguous memory allocation failed for pBase.\n"); return HE_QAT_STATUS_FAIL; } - status = PHYS_CONTIG_ALLOC(&pModulus, len); - if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { + //status = PHYS_CONTIG_ALLOC(&pModulus, len); + status = HE_QAT_MEM_ALLOC_CONTIG(&pModulus, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != pModulus) { if (!BN_bn2binpad(m, pModulus, len)) { - printf("BN_bn2binpad failed in bnModExpPerformOp.\n"); - PHYS_CONTIG_FREE(pModulus); + HE_QAT_PRINT_ERR("BN_bn2binpad failed in bnModExpPerformOp.\n"); + //PHYS_CONTIG_FREE(pModulus); + HE_QAT_MEM_FREE_CONTIG(pModulus); return HE_QAT_STATUS_FAIL; } } else { - printf("Contiguous memory allocation failed for pBase.\n"); + HE_QAT_PRINT_ERR("Contiguous memory allocation failed for pBase.\n"); return HE_QAT_STATUS_FAIL; } @@ -219,11 +229,12 @@ HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, in op_data->modulus.dataLenInBytes = len; request->op_data = (void*)op_data; - status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); - if (CPA_STATUS_SUCCESS == status && NULL != request->op_result.pData) { + //status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); + status = HE_QAT_MEM_ALLOC_CONTIG(&request->op_result.pData, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != request->op_result.pData) { request->op_result.dataLenInBytes = len; } else { - printf( + HE_QAT_PRINT_ERR( "CpaFlatBuffer.pData memory allocation failed in " "bnModExpPerformOp.\n"); return HE_QAT_STATUS_FAIL; @@ -275,20 +286,20 @@ void getBnModExpRequest(unsigned int batch_size) { time_taken = (task->end.tv_sec - task->start.tv_sec) * 1e6; time_taken = (time_taken + (task->end.tv_usec - task->start.tv_usec)); //*1e-6; - printf("%u time: %.1lfus\n", j, time_taken); + HE_QAT_PRINT("%u time: %.1lfus\n", j, time_taken); #endif // Free up QAT temporary memory CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; if (op_data) { - PHYS_CONTIG_FREE(op_data->base.pData); - PHYS_CONTIG_FREE(op_data->exponent.pData); - PHYS_CONTIG_FREE(op_data->modulus.pData); + HE_QAT_MEM_FREE_CONTIG(op_data->base.pData); + HE_QAT_MEM_FREE_CONTIG(op_data->exponent.pData); + HE_QAT_MEM_FREE_CONTIG(op_data->modulus.pData); } free(task->op_data); task->op_data = NULL; if (task->op_result.pData) { - PHYS_CONTIG_FREE(task->op_result.pData); + HE_QAT_MEM_FREE_CONTIG(task->op_result.pData); } // Move forward to wait for the next request that will be offloaded @@ -308,7 +319,7 @@ void getBnModExpRequest(unsigned int batch_size) { time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; time_taken = (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; - printf("Batch Wall Time: %.1lfus\n", time_taken); + HE_QAT_PRINT("Batch Wall Time: %.1lfus\n", time_taken); #endif return; @@ -338,31 +349,35 @@ HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, Cpa8U* pExponent = NULL; // TODO(fdiasmor): Try it with 8-byte alignment. - CpaStatus status = CPA_STATUS_FAIL; + //CpaStatus status = CPA_STATUS_FAIL; // status = PHYS_CONTIG_ALLOC(&pBase, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pBase, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pBase) { + //status = PHYS_CONTIG_ALLOC_ALIGNED(&pBase, len, 8); + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + status = HE_QAT_MEM_ALLOC_CONTIG(&pBase, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != pBase) { memcpy(pBase, b, len); } else { - printf("Contiguous memory allocation failed for pBase.\n"); + HE_QAT_PRINT("Contiguous memory allocation failed for pBase.\n"); return HE_QAT_STATUS_FAIL; } // status = PHYS_CONTIG_ALLOC(&pExponent, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pExponent, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pExponent) { + // status = PHYS_CONTIG_ALLOC_ALIGNED(&pExponent, len, 8); + status = HE_QAT_MEM_ALLOC_CONTIG(&pExponent, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != pExponent) { memcpy(pExponent, e, len); } else { - printf("Contiguous memory allocation failed for pBase.\n"); + HE_QAT_PRINT_ERR("Contiguous memory allocation failed for pBase.\n"); return HE_QAT_STATUS_FAIL; } // status = PHYS_CONTIG_ALLOC(&pModulus, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&pModulus, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != pModulus) { + //status = PHYS_CONTIG_ALLOC_ALIGNED(&pModulus, len, 8); + status = HE_QAT_MEM_ALLOC_CONTIG(&pModulus, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != pModulus) { memcpy(pModulus, m, len); } else { - printf("Contiguous memory allocation failed for pBase.\n"); + HE_QAT_PRINT_ERR("Contiguous memory allocation failed for pBase.\n"); return HE_QAT_STATUS_FAIL; } @@ -372,7 +387,7 @@ HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, HE_QAT_TaskRequest* request = (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); if (NULL == request) { - printf( + HE_QAT_PRINT_ERR( "HE_QAT_TaskRequest memory allocation failed in " "bnModExpPerformOp.\n"); return HE_QAT_STATUS_FAIL; @@ -393,11 +408,12 @@ HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, request->op_data = (void*)op_data; // status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); - status = PHYS_CONTIG_ALLOC_ALIGNED(&request->op_result.pData, len, 8); - if (CPA_STATUS_SUCCESS == status && NULL != request->op_result.pData) { + //status = PHYS_CONTIG_ALLOC_ALIGNED(&request->op_result.pData, len, 8); + status = HE_QAT_MEM_ALLOC_CONTIG(&request->op_result.pData, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != request->op_result.pData) { request->op_result.dataLenInBytes = len; } else { - printf( + HE_QAT_PRINT_ERR( "CpaFlatBuffer.pData memory allocation failed in " "bnModExpPerformOp.\n"); return HE_QAT_STATUS_FAIL; @@ -414,9 +430,7 @@ HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, pthread_mutex_init(&request->mutex, NULL); pthread_cond_init(&request->ready, NULL); -#ifdef HE_QAT_DEBUG - printf("BN ModExp interface call for request #%llu\n", req_count); -#endif + HE_QAT_PRINT_DBG("BN ModExp interface call for request #%llu\n", req_count); // Submit request using producer function submit_request(&outstanding.buffer[_buffer_id], (void*)request); @@ -424,14 +438,10 @@ HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, return HE_QAT_STATUS_SUCCESS; } -/// @brief Frontend for multithreading support. -/// @details Try to acquire an available buffer to store outstanding work requests sent by caller. -/// If none is available, it blocks further processing and waits until another caller's concurrent -/// thread releases one. This function must be called before -/// calling HE_QAT_bnModExp_MT(.). -/// @param[out] Pointer to memory space allocated by caller to hold the buffer ID of the buffer used to store caller's outstanding requests. HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id) { if (NULL == _buffer_id) return HE_QAT_STATUS_INVALID_PARAM; + + HE_QAT_PRINT_DBG("acquire_bnModExp_buffer #%u\n", _buffer_id); pthread_mutex_lock(&outstanding.mutex); @@ -465,19 +475,11 @@ HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id) { return HE_QAT_STATUS_SUCCESS; } -/// @brief Wait for request processing to complete and release previously acquired buffer. -/// @details Caution: It assumes acquire_bnModExp_buffer(&_buffer_id) to be called first -/// to secure and be assigned an outstanding buffer for the target thread. -/// Equivalent to getBnModExpRequests() for the multithreading support interfaces. -/// param[in] _buffer_id Buffer ID of the buffer to be released/unlock for reuse by the next concurrent thread. -/// param[in] _batch_size Total number of requests to wait for completion before releasing the buffer. void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size) { unsigned int next_data_out = outstanding.buffer[_buffer_id].next_data_out; unsigned int j = 0; -#ifdef HE_QAT_DEBUG - printf("release_bnModExp_buffer #%u\n", _buffer_id); -#endif + HE_QAT_PRINT_DBG("release_bnModExp_buffer #%u\n", _buffer_id); #ifdef HE_QAT_PERF struct timeval start_time, end_time; @@ -492,10 +494,8 @@ void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size) if (NULL == task) continue; -#ifdef HE_QAT_DEBUG - printf("BatchSize %u Buffer #%u Request #%u Waiting\n", _batch_size, + HE_QAT_PRINT_DBG("BatchSize %u Buffer #%u Request #%u Waiting\n", _batch_size, _buffer_id, j); -#endif // Block and synchronize: Wait for the most recently offloaded request // to complete processing. Mutex only needed for the conditional variable. @@ -507,28 +507,27 @@ void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size) time_taken = (task->end.tv_sec - task->start.tv_sec) * 1e6; time_taken = (time_taken + (task->end.tv_usec - task->start.tv_usec)); //*1e-6; - printf("%u time: %.1lfus\n", j, time_taken); + HE_QAT_PRINT("%u time: %.1lfus\n", j, time_taken); #endif // Free up QAT temporary memory CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; if (op_data) { - PHYS_CONTIG_FREE(op_data->base.pData); - PHYS_CONTIG_FREE(op_data->exponent.pData); - PHYS_CONTIG_FREE(op_data->modulus.pData); + HE_QAT_MEM_FREE_CONTIG(op_data->base.pData); + HE_QAT_MEM_FREE_CONTIG(op_data->exponent.pData); + HE_QAT_MEM_FREE_CONTIG(op_data->modulus.pData); } free(task->op_data); task->op_data = NULL; if (task->op_result.pData) { - PHYS_CONTIG_FREE(task->op_result.pData); + HE_QAT_MEM_FREE_CONTIG(task->op_result.pData); } // Move forward to wait for the next request that will be offloaded pthread_mutex_unlock(&task->mutex); -#ifdef HE_QAT_DEBUG - printf("Buffer #%u Request #%u Completed\n", _buffer_id, j); -#endif + HE_QAT_PRINT_DBG("Buffer #%u Request #%u Completed\n", _buffer_id, j); + // outstanding.buffer[_buffer_id].count--; free(outstanding.buffer[_buffer_id].data[next_data_out]); @@ -545,7 +544,7 @@ void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size) time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; time_taken = (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; - printf("Batch Wall Time: %.1lfus\n", time_taken); + HE_QAT_PRINT("Batch Wall Time: %.1lfus\n", time_taken); #endif outstanding.buffer[_buffer_id].next_data_out = next_data_out; diff --git a/heqat/cb.c b/heqat/cb.c index 5e2db31..ba39aa0 100644 --- a/heqat/cb.c +++ b/heqat/cb.c @@ -5,11 +5,12 @@ // C support libraries #include +#include #include // Local headers -#include "heqat/common/cpa_sample_utils.h" #include "heqat/common/types.h" +#include "heqat/common/utils.h" // Global variables static pthread_mutex_t response_mutex; ///< It protects against race condition on response_count due to concurrent callback events. @@ -31,7 +32,7 @@ void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, void* pOp // Read request data request = (HE_QAT_TaskRequest*)pCallbackTag; - pthread_mutex_lock(&response_mutex); + pthread_mutex_lock(&response_mutex); // Global track of reponses by accelerator response_count += 1; pthread_mutex_unlock(&response_mutex); @@ -47,7 +48,7 @@ void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, void* pOp BIGNUM* r = BN_bin2bn(request->op_result.pData, request->op_result.dataLenInBytes, (BIGNUM*)request->op_output); - if (NULL == r) + if (NULL == r) request->request_status = HE_QAT_STATUS_FAIL; #ifdef HE_QAT_PERF gettimeofday(&request->end, NULL); diff --git a/heqat/common/CMakeLists.txt b/heqat/common/CMakeLists.txt index 478f463..2e16c41 100644 --- a/heqat/common/CMakeLists.txt +++ b/heqat/common/CMakeLists.txt @@ -1,6 +1,5 @@ # Source files -set(COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/cpa_sample_utils.c - ${CMAKE_CURRENT_LIST_DIR}/utils.c) +set(COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/utils.c) list(APPEND HE_QAT_SRC ${COMMON_SRC}) set(HE_QAT_SRC ${HE_QAT_SRC} PARENT_SCOPE) diff --git a/heqat/common/cpa_sample_utils.c b/heqat/common/cpa_sample_utils.c deleted file mode 100644 index 53551e3..0000000 --- a/heqat/common/cpa_sample_utils.c +++ /dev/null @@ -1,285 +0,0 @@ -/*************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Corporation - * - * BSD LICENSE - * - * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * version: QAT.L.4.15.0-00011 - * - ***************************************************************************/ - -/** - ***************************************************************************** - * @file cpa_sample_utils.c - * - * @ingroup sampleCode - * - * @description - * Defines functions to get an instance and poll an instance - * - ***************************************************************************/ - -#include "heqat/common/cpa_sample_utils.h" -#include "cpa_dc.h" -#include "icp_sal_poll.h" - -/* - * Maximum number of instances to query from the API - */ -#ifdef USER_SPACE -#define MAX_INSTANCES 1024 -#else -#define MAX_INSTANCES 1 -#endif - -#ifdef DO_CRYPTO -static sampleThread gPollingThread; -static volatile int gPollingCy = 0; -#endif - -static sampleThread gPollingThreadDc; -static volatile int gPollingDc = 0; - -#ifdef SC_ENABLE_DYNAMIC_COMPRESSION -CpaDcHuffType huffmanType_g = CPA_DC_HT_FULL_DYNAMIC; -#else -CpaDcHuffType huffmanType_g = CPA_DC_HT_STATIC; -#endif -/* ************************************************************* - * - * Common instance functions - * - * ************************************************************* - */ - -/* - * This function returns a handle to an instance of the cryptographic - * API. It does this by querying the API for all instances and - * returning the first such instance. - */ -// -#ifdef DO_CRYPTO -void sampleCyGetInstance(CpaInstanceHandle *pCyInstHandle) -{ - CpaInstanceHandle cyInstHandles[MAX_INSTANCES]; - Cpa16U numInstances = 0; - CpaStatus status = CPA_STATUS_SUCCESS; - - *pCyInstHandle = NULL; - status = cpaCyGetNumInstances(&numInstances); - if (numInstances >= MAX_INSTANCES) - { - numInstances = MAX_INSTANCES; - } - if ((status == CPA_STATUS_SUCCESS) && (numInstances > 0)) - { - status = cpaCyGetInstances(numInstances, cyInstHandles); - if (status == CPA_STATUS_SUCCESS) - *pCyInstHandle = cyInstHandles[0]; - } - - if (0 == numInstances) - { - PRINT_ERR("No instances found for 'SSL'\n"); - PRINT_ERR("Please check your section names"); - PRINT_ERR(" in the config file.\n"); - PRINT_ERR("Also make sure to use config file version 2.\n"); - } -} - -void symSessionWaitForInflightReq(CpaCySymSessionCtx pSessionCtx) -{ - -/* Session reuse is available since Cryptographic API version 2.2 */ -#if CY_API_VERSION_AT_LEAST(2, 2) - CpaBoolean sessionInUse = CPA_FALSE; - - do - { - cpaCySymSessionInUse(pSessionCtx, &sessionInUse); - } while (sessionInUse); -#endif - - return; -} -#endif -// - -/* - * This function polls a crypto instance. - * - */ -#ifdef DO_CRYPTO -static void sal_polling(CpaInstanceHandle cyInstHandle) -{ - gPollingCy = 1; - while (gPollingCy) - { - icp_sal_CyPollInstance(cyInstHandle, 0); - OS_SLEEP(10); - } - - sampleThreadExit(); -} -#endif -/* - * This function checks the instance info. If the instance is - * required to be polled then it starts a polling thread. - */ - -#ifdef DO_CRYPTO -void sampleCyStartPolling(CpaInstanceHandle cyInstHandle) -{ - CpaInstanceInfo2 info2 = {0}; - CpaStatus status = CPA_STATUS_SUCCESS; - - status = cpaCyInstanceGetInfo2(cyInstHandle, &info2); - if ((status == CPA_STATUS_SUCCESS) && (info2.isPolled == CPA_TRUE)) - { - /* Start thread to poll instance */ - sampleThreadCreate(&gPollingThread, sal_polling, cyInstHandle); - } -} -#endif -/* - * This function stops the polling of a crypto instance. - */ -#ifdef DO_CRYPTO -void sampleCyStopPolling(void) -{ - gPollingCy = 0; - OS_SLEEP(10); -} -#endif - -/* - * This function returns a handle to an instance of the data - * compression API. It does this by querying the API for all - * instances and returning the first such instance. - */ -// -void sampleDcGetInstance(CpaInstanceHandle *pDcInstHandle) -{ - CpaInstanceHandle dcInstHandles[MAX_INSTANCES]; - Cpa16U numInstances = 0; - CpaStatus status = CPA_STATUS_SUCCESS; - - *pDcInstHandle = NULL; - status = cpaDcGetNumInstances(&numInstances); - if (numInstances >= MAX_INSTANCES) - { - numInstances = MAX_INSTANCES; - } - if ((status == CPA_STATUS_SUCCESS) && (numInstances > 0)) - { - status = cpaDcGetInstances(numInstances, dcInstHandles); - if (status == CPA_STATUS_SUCCESS) - *pDcInstHandle = dcInstHandles[0]; - } - - if (0 == numInstances) - { - PRINT_ERR("No instances found for 'SSL'\n"); - PRINT_ERR("Please check your section names"); - PRINT_ERR(" in the config file.\n"); - PRINT_ERR("Also make sure to use config file version 2.\n"); - } -} -// - -/* - * This function polls a compression instance. - * - */ -static void sal_dc_polling(CpaInstanceHandle dcInstHandle) -{ - - gPollingDc = 1; - while (gPollingDc) - { - icp_sal_DcPollInstance(dcInstHandle, 0); - OS_SLEEP(10); - } - - sampleThreadExit(); -} - -/* - * This function checks the instance info. If the instance is - * required to be polled then it starts a polling thread. - */ -void sampleDcStartPolling(CpaInstanceHandle dcInstHandle) -{ - CpaInstanceInfo2 info2 = {0}; - CpaStatus status = CPA_STATUS_SUCCESS; - - status = cpaDcInstanceGetInfo2(dcInstHandle, &info2); - if ((status == CPA_STATUS_SUCCESS) && (info2.isPolled == CPA_TRUE)) - { - /* Start thread to poll instance */ - sampleThreadCreate(&gPollingThreadDc, sal_dc_polling, dcInstHandle); - } -} - -/* - * This function stops the thread polling the compression instance. - */ -void sampleDcStopPolling(void) -{ - gPollingDc = 0; - OS_SLEEP(10); -} - diff --git a/heqat/common/utils.c b/heqat/common/utils.c index 8d1aa0d..fd7dec7 100644 --- a/heqat/common/utils.c +++ b/heqat/common/utils.c @@ -1,5 +1,6 @@ -#include "heqat/common/cpa_sample_utils.h" + #include "heqat/common/utils.h" +#include "heqat/common/types.h" #include #include @@ -7,15 +8,13 @@ BIGNUM* generateTestBNData(int nbits) { if (!RAND_status()) return NULL; -#ifdef HE_QAT_DEBUG - printf("PRNG properly seeded.\n"); -#endif + HE_QAT_PRINT_DBG("PRNG properly seeded.\n"); BIGNUM* bn = BN_new(); if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { BN_free(bn); - printf("Error while generating BN random number: %lu\n", + HE_QAT_PRINT_ERR("Error while generating BN random number: %lu\n", ERR_get_error()); return NULL; } @@ -36,9 +35,8 @@ unsigned char* paddingZeros(BIGNUM* bn, int nbits) { int len = bytes_left + num_bytes; if (!(bin = (unsigned char*)OPENSSL_zalloc(len))) return NULL; -#ifdef HE_QAT_DEBUG - PRINT("Padding bn with %d bytes to total %d bytes\n", bytes_left, len); -#endif + HE_QAT_PRINT_DBG("Padding bn with %d bytes to total %d bytes\n", + bytes_left, len); BN_bn2binpad(bn, bin, len); if (ERR_get_error()) { @@ -54,8 +52,9 @@ void showHexBN(BIGNUM* bn, int nbits) { unsigned char* bin = (unsigned char*)OPENSSL_zalloc(len); if (!bin) return; if (BN_bn2binpad(bn, bin, len)) { - for (size_t i = 0; i < len; i++) printf("%2.2x", bin[i]); - printf("\n"); + for (size_t i = 0; i < len; i++) + HE_QAT_PRINT("%2.2x", bin[i]); + HE_QAT_PRINT("\n"); } OPENSSL_free(bin); return; @@ -63,7 +62,8 @@ void showHexBN(BIGNUM* bn, int nbits) { void showHexBin(unsigned char* bin, int len) { if (!bin) return; - for (size_t i = 0; i < len; i++) printf("%2.2x", bin[i]); - printf("\n"); + for (size_t i = 0; i < len; i++) + HE_QAT_PRINT("%2.2x", bin[i]); + HE_QAT_PRINT("\n"); return; } diff --git a/heqat/context.c b/heqat/context.c index 985d253..cf6180c 100644 --- a/heqat/context.c +++ b/heqat/context.c @@ -1,16 +1,17 @@ -/// @file he_qat_context.c +/// @file heqat/context.c #define _GNU_SOURCE -#include "icp_sal_user.h" -#include "icp_sal_poll.h" +#include +#include +#include #include #include #include -#include "heqat/common/cpa_sample_utils.h" #include "heqat/common/types.h" +#include "heqat/common/utils.h" #include "heqat/context.h" #ifdef USER_SPACE @@ -19,6 +20,10 @@ #define MAX_INSTANCES 1 #endif +// Utilities functions from qae_mem.h header +extern CpaStatus qaeMemInit(void); +extern void qaeMemDestroy(void); + static volatile HE_QAT_STATUS context_state = HE_QAT_STATUS_INACTIVE; static pthread_mutex_t context_lock; @@ -63,48 +68,46 @@ static CpaInstanceHandle get_qat_instance() { numInstances = HE_QAT_NUM_ACTIVE_INSTANCES; } - if (CPA_STATUS_SUCCESS != status) { -#ifdef HE_QAT_DEBUG - printf("No CyInstances Found.\n", numInstances); -#endif - return NULL; - } -#ifdef HE_QAT_DEBUG - printf("Found %d CyInstances.\n", numInstances); -#endif + if (CPA_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("No CyInstances Found (%d).\n", numInstances); + return NULL; + } + + HE_QAT_PRINT_DBG("Found %d CyInstances.\n", numInstances); + if ((status == CPA_STATUS_SUCCESS) && (numInstances > 0)) { status = cpaCyGetInstances(numInstances, cyInstHandles); - // List instances and their characteristics - for (unsigned int i = 0; i < numInstances; i++) { - status = cpaCyInstanceGetInfo2(cyInstHandles[i],&info); - if (CPA_STATUS_SUCCESS != status) - return NULL; + + // List instances and their characteristics + for (unsigned int i = 0; i < numInstances; i++) { + status = cpaCyInstanceGetInfo2(cyInstHandles[i],&info); + if (CPA_STATUS_SUCCESS != status) + return NULL; #ifdef HE_QAT_DEBUG - printf("Vendor Name: %s\n",info.vendorName); - printf("Part Name: %s\n",info.partName); - printf("Inst Name: %s\n",info.instName); - printf("Inst ID: %s\n",info.instID); - printf("Node Affinity: %u\n",info.nodeAffinity); - printf("Physical Instance:\n"); - printf("\tpackageId: %d\n",info.physInstId.packageId); - printf("\tacceleratorId: %d\n",info.physInstId.acceleratorId); - printf("\texecutionEngineId: %d\n",info.physInstId.executionEngineId); - printf("\tbusAddress: %d\n",info.physInstId.busAddress); - printf("\tkptAcHandle: %d\n",info.physInstId.kptAcHandle); -#endif - } -#ifdef HE_QAT_DEBUG - printf("Next Instance: %d.\n", nextInstance); + HE_QAT_PRINT("Vendor Name: %s\n",info.vendorName); + HE_QAT_PRINT("Part Name: %s\n",info.partName); + HE_QAT_PRINT("Inst Name: %s\n",info.instName); + HE_QAT_PRINT("Inst ID: %s\n",info.instID); + HE_QAT_PRINT("Node Affinity: %u\n",info.nodeAffinity); + HE_QAT_PRINT("Physical Instance:\n"); + HE_QAT_PRINT("\tpackageId: %d\n",info.physInstId.packageId); + HE_QAT_PRINT("\tacceleratorId: %d\n",info.physInstId.acceleratorId); + HE_QAT_PRINT("\texecutionEngineId: %d\n",info.physInstId.executionEngineId); + HE_QAT_PRINT("\tbusAddress: %d\n",info.physInstId.busAddress); + HE_QAT_PRINT("\tkptAcHandle: %d\n",info.physInstId.kptAcHandle); #endif + } + HE_QAT_PRINT_DBG("Next Instance: %d.\n", nextInstance); + if (status == CPA_STATUS_SUCCESS) return cyInstHandles[nextInstance]; } if (0 == numInstances) { - PRINT_ERR("No instances found for 'SSL'\n"); - PRINT_ERR("Please check your section names"); - PRINT_ERR(" in the config file.\n"); - PRINT_ERR("Also make sure to use config file version 2.\n"); + HE_QAT_PRINT_ERR("No instances found for 'SSL'\n"); + HE_QAT_PRINT_ERR("Please check your section names"); + HE_QAT_PRINT_ERR(" in the config file.\n"); + HE_QAT_PRINT_ERR("Also make sure to use config file version 2.\n"); } return NULL; @@ -134,25 +137,21 @@ HE_QAT_STATUS acquire_qat_devices() { status = qaeMemInit(); if (CPA_STATUS_SUCCESS != status) { pthread_mutex_unlock(&context_lock); - printf("Failed to initialized memory driver.\n"); + HE_QAT_PRINT_ERR("Failed to initialized memory driver.\n"); return HE_QAT_STATUS_FAIL; // HEQAT_STATUS_ERROR } -#ifdef HE_QAT_DEBUG - printf("QAT memory successfully initialized.\n"); -#endif + HE_QAT_PRINT_DBG("QAT memory successfully initialized.\n"); // Not sure if for multiple instances the id will need to be specified, e.g. // "SSL1" status = icp_sal_userStartMultiProcess("SSL", CPA_FALSE); if (CPA_STATUS_SUCCESS != status) { pthread_mutex_unlock(&context_lock); - printf("Failed to start SAL user process SSL\n"); + HE_QAT_PRINT_ERR("Failed to start SAL user process SSL\n"); qaeMemDestroy(); - return HE_QAT_STATUS_FAIL; // HEQAT_STATUS_ERROR + return HE_QAT_STATUS_FAIL; // HE_QAT_STATUS_FAIL } -#ifdef HE_QAT_DEBUG - printf("SAL user process successfully started.\n"); -#endif + HE_QAT_PRINT_DBG("SAL user process successfully started.\n"); // Potential out-of-scope hazard for segmentation fault CpaInstanceHandle _inst_handle[HE_QAT_NUM_ACTIVE_INSTANCES]; // = NULL; @@ -161,14 +160,12 @@ HE_QAT_STATUS acquire_qat_devices() { _inst_handle[i] = get_qat_instance(); if (_inst_handle[i] == NULL) { pthread_mutex_unlock(&context_lock); - printf("Failed to find QAT endpoints.\n"); + HE_QAT_PRINT_ERR("Failed to find QAT endpoints.\n"); return HE_QAT_STATUS_FAIL; } } -#ifdef HE_QAT_DEBUG - printf("Found QAT endpoints.\n"); -#endif + HE_QAT_PRINT_DBG("Found QAT endpoints.\n"); // Initialize QAT buffer synchronization attributes he_qat_buffer.count = 0; @@ -231,15 +228,11 @@ HE_QAT_STATUS acquire_qat_devices() { // Work on this pthread_create(&he_qat_runner, NULL, start_instances, (void*)he_qat_config); -#ifdef HE_QAT_DEBUG - printf("Created processing threads.\n"); -#endif + HE_QAT_PRINT_DBG("Created processing threads.\n"); // Dispatch the qat instances to run independently in the background pthread_detach(he_qat_runner); -#ifdef HE_QAT_DEBUG - printf("Detached processing threads.\n"); -#endif + HE_QAT_PRINT_DBG("Detached processing threads.\n"); // Set context state to active context_state = HE_QAT_STATUS_ACTIVE; @@ -249,7 +242,7 @@ HE_QAT_STATUS acquire_qat_devices() { (void*)&context_state)) { pthread_mutex_unlock(&context_lock); release_qat_devices(); - printf( + HE_QAT_PRINT_ERR( "Failed to complete QAT initialization while creating buffer " "manager thread.\n"); return HE_QAT_STATUS_FAIL; @@ -258,7 +251,7 @@ HE_QAT_STATUS acquire_qat_devices() { if (0 != pthread_detach(buffer_manager)) { pthread_mutex_unlock(&context_lock); release_qat_devices(); - printf( + HE_QAT_PRINT_ERR( "Failed to complete QAT initialization while launching buffer " "manager thread.\n"); return HE_QAT_STATUS_FAIL; @@ -280,9 +273,7 @@ HE_QAT_STATUS release_qat_devices() { } stop_instances(he_qat_config); -#ifdef HE_QAT_DEBUG - printf("Stopped polling and processing threads.\n"); -#endif + HE_QAT_PRINT_DBG("Stopped polling and processing threads.\n"); // Deactivate context (this will cause the buffer manager thread to be // terminated) @@ -290,15 +281,11 @@ HE_QAT_STATUS release_qat_devices() { // Stop QAT SSL service icp_sal_userStop(); -#ifdef HE_QAT_DEBUG - printf("Stopped SAL user process.\n"); -#endif + HE_QAT_PRINT_DBG("Stopped SAL user process.\n"); // Release QAT allocated memory qaeMemDestroy(); -#ifdef HE_QAT_DEBUG - printf("Release QAT memory.\n"); -#endif + HE_QAT_PRINT_DBG("Release QAT memory.\n"); numInstances = 0; nextInstance = 0; @@ -308,6 +295,9 @@ HE_QAT_STATUS release_qat_devices() { return HE_QAT_STATUS_SUCCESS; } +/// @brief Retrieve and read context state. +/// @return Possible return values are HE_QAT_STATUS_ACTIVE, +/// HE_QAT_STATUS_RUNNING, and HE_QAT_STATUS_INACTIVE. HE_QAT_STATUS get_qat_context_state() { return context_state; } diff --git a/heqat/ctrl.c b/heqat/ctrl.c index 88fd913..5334313 100644 --- a/heqat/ctrl.c +++ b/heqat/ctrl.c @@ -20,10 +20,10 @@ double time_taken = 0.0; #include // Local headers -#include "heqat/common/cpa_sample_utils.h" +#include "heqat/common/utils.h" #include "heqat/common/consts.h" #include "heqat/common/types.h" -#include "heqat/bnops.h" +//#include "heqat/bnops.h" // Warn user on selected execution mode #ifdef HE_QAT_SYNC_MODE @@ -165,7 +165,7 @@ static void read_request_list(HE_QAT_TaskRequestList* _requests, /// This function is supported in single-threaded or multi-threaded mode. /// @param[out] _requests list of work requests retrieved from outstanding buffer. /// @param[in] _outstanding_buffer outstanding buffer holding requests in ready-to-be-scheduled state. -/// @param[in] max_requests maximum number of requests to retrieve from outstanding buffer if available. +/// @param[in] max_num_requests maximum number of requests to retrieve from outstanding buffer if available. static void pull_outstanding_requests(HE_QAT_TaskRequestList* _requests, HE_QAT_OutstandingBuffer* _outstanding_buffer, unsigned int max_num_requests) { if (NULL == _requests) return; @@ -248,7 +248,7 @@ static void pull_outstanding_requests(HE_QAT_TaskRequestList* _requests, HE_QAT_ /// @brief Schedule outstanding requests to the internal buffer and be ready for processing. /// @details Schedule outstanding requests from outstanding buffers to the internal buffer, /// from which requests are ready to be submitted to the device for processing. -/// @param[in] state A volatile integer variable used to activate (val>0) or +/// @param[in] context_state A volatile integer variable used to activate (val>0) or /// disactive (val=0) the scheduler. void* schedule_requests(void* context_state) { if (NULL == context_state) { @@ -299,7 +299,8 @@ static void* start_inst_polling(void* _inst_config) { config->polling = 1; while (config->polling) { icp_sal_CyPollInstance(config->inst_handle, 0); - OS_SLEEP(50); + //OS_SLEEP(50); + HE_QAT_SLEEP(50, HE_QAT_MICROSEC); } pthread_exit(NULL); @@ -370,7 +371,7 @@ void* start_instances(void* _config) { printf("Cpa CyInstance has successfully started.\n"); status = cpaCySetAddressTranslation(config->inst_config[j].inst_handle, - sampleVirtToPhys); + HE_QAT_virtToPhys); } pthread_cond_signal(&config->inst_config[j].ready); @@ -417,13 +418,13 @@ void* start_instances(void* _config) { request_count,response_count,pending,available); #endif while (available < restart_threshold) { -#ifdef HE_QAT_DEBUG - printf("[WAIT]\n"); -#endif - // argument passed in microseconds - OS_SLEEP(RESTART_LATENCY_MICROSEC); - pending = request_count - response_count; - available = max_pending - ((pending < max_pending)?pending:max_pending); + HE_QAT_PRINT_DBG("[WAIT]\n"); + + // argument passed in microseconds + //OS_SLEEP(RESTART_LATENCY_MICROSEC); + HE_QAT_SLEEP(RESTART_LATENCY_MICROSEC, HE_QAT_MICROSEC); + pending = request_count - response_count; + available = max_pending - ((pending < max_pending)?pending:max_pending); #ifdef HE_QAT_DEBUG printf("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", request_count,response_count,pending,available); @@ -562,7 +563,7 @@ void* start_perform_op(void* _inst_config) { if (CPA_STATUS_SUCCESS == status) { printf("Cpa CyInstance has successfully started.\n"); status = - cpaCySetAddressTranslation(config->inst_handle, sampleVirtToPhys); + cpaCySetAddressTranslation(config->inst_handle, HE_QAT_virtToPhys); } pthread_cond_signal(&config->ready); @@ -606,8 +607,9 @@ void* start_perform_op(void* _inst_config) { printf("[WAIT]\n"); #endif // argument passed in microseconds - OS_SLEEP(650); - pending = request_count - response_count; + //OS_SLEEP(650); + HE_QAT_SLEEP(650,HE_QAT_MICROSEC); + pending = request_count - response_count; available = max_pending - ((pending < max_pending)?pending:max_pending); } #ifdef HE_QAT_DEBUG @@ -667,7 +669,8 @@ void* start_perform_op(void* _inst_config) { if (CPA_STATUS_RETRY == status) { printf("CPA requested RETRY\n"); printf("RETRY count: %u\n",retry); - OS_SLEEP(600); + //OS_SLEEP(600); + HE_QAT_SLEEP(600, HE_QAT_MICROSEC); } } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); @@ -741,7 +744,8 @@ void stop_perform_op(HE_QAT_InstConfig* config, unsigned num_inst) { #endif config[i].polling = 0; config[i].running = 0; - OS_SLEEP(10); + //OS_SLEEP(10); + HE_QAT_SLEEP(10, HE_QAT_MICROSEC); #ifdef HE_QAT_DEBUG printf("Stop cpaCyInstance #%d\n", i); #endif diff --git a/heqat/include/heqat/bnops.h b/heqat/include/heqat/bnops.h index 87c8991..bcaf393 100644 --- a/heqat/include/heqat/bnops.h +++ b/heqat/include/heqat/bnops.h @@ -1,5 +1,5 @@ /** - * @file he_qat_bn_ops.h + * @file heqat/bnops.h * * @details * In this file, functions for Big Number operations accelerated by the @@ -121,7 +121,7 @@ HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, /// thread releases one. This function must be called before /// calling HE_QAT_bnModExp_MT(.). /// -/// @param[out] _buffer_id Pointer to memory space allocated by caller to hold the buffer ID of the buffer used to store caller's outstanding requests. +/// @param[out] _buffer_id Memory space address allocated by caller to hold the buffer ID of the buffer used to store caller's outstanding requests. HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id); /// @brief Wait for request processing to complete and release previously acquired buffer. diff --git a/heqat/include/heqat/common.h b/heqat/include/heqat/common.h index 67f9ede..f382925 100644 --- a/heqat/include/heqat/common.h +++ b/heqat/include/heqat/common.h @@ -1,6 +1,5 @@ /// @file heqat/common.h -#include "heqat/common/cpa_sample_utils.h" #include "heqat/common/consts.h" #include "heqat/common/types.h" #include "heqat/common/utils.h" diff --git a/heqat/include/heqat/common/cpa_sample_utils.h b/heqat/include/heqat/common/cpa_sample_utils.h deleted file mode 100644 index a128640..0000000 --- a/heqat/include/heqat/common/cpa_sample_utils.h +++ /dev/null @@ -1,651 +0,0 @@ -/*************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Corporation - * - * BSD LICENSE - * - * Copyright(c) 2007-2021 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * version: QAT.L.4.15.0-00011 - * - ***************************************************************************/ - -/** - ***************************************************************************** - * @file cpa_sample_utils.h - * - * @defgroup sampleUtils Macro and inline function definitions - * - * @ingroup sampleCode - * - * @description - * Defines macros for printing and debugging, inline functions for memory - * allocating and freeing and thread creation - * - ***************************************************************************/ - -#ifndef CPA_SAMPLE_UTILS_H -#define CPA_SAMPLE_UTILS_H - -#ifdef __cplusplus -#define HE_QAT_RESTRICT __restrict__ -#else -#define HE_QAT_RESTRICT restrict -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#include "cpa.h" -#include "cpa_cy_im.h" -#include "cpa_dc.h" - - -#ifdef DO_CRYPTO -#include "cpa_cy_sym.h" -#endif - -#ifdef USER_SPACE -/* User space utils */ -#include -#include -#include -#include -#include -#include -/* Performance sample code mem utils */ - -#include "qae_mem.h" - -extern CpaDcHuffType huffmanType_g; -extern CpaStatus qaeMemInit(void); -extern void qaeMemDestroy(void); -/* Threads */ -typedef pthread_t sampleThread; - -/* Check for CY API version */ -#define CY_API_VERSION_AT_LEAST(major, minor) \ - (CPA_CY_API_VERSION_NUM_MAJOR > major || \ - (CPA_CY_API_VERSION_NUM_MAJOR == major && \ - CPA_CY_API_VERSION_NUM_MINOR >= minor)) - -#ifdef HE_QAT_DEBUG -#define HE_QAT_PRINT_DBG(args...) \ - do \ - { \ - { \ - printf("%s(): ", __func__); \ - printf(args); \ - fflush(stdout); \ - } \ - } while (0) -#else -#define HE_QAT_PRINT_DBG(args...) { } -#endif -/* Printing */ -/**< Prints the name of the function and the arguments only if gDebugParam is - * CPA_TRUE. - */ -#define PRINT_DBG(args...) \ - do \ - { \ - if (CPA_TRUE == gDebugParam) \ - { \ - printf("%s(): ", __func__); \ - printf(args); \ - fflush(stdout); \ - } \ - } while (0) - -/**< Prints the arguments */ -#ifndef PRINT -#define PRINT(args...) \ - do \ - { \ - printf(args); \ - } while (0) -#endif - -/**< Prints the name of the function and the arguments */ -#ifndef PRINT_ERR -#define PRINT_ERR(args...) \ - do \ - { \ - printf("%s(): ", __func__); \ - printf(args); \ - } while (0) -#endif -/** - ******************************************************************************* - * @ingroup sampleUtils - * Completion definitions - * - ******************************************************************************/ -struct completion_struct -{ - sem_t semaphore; -}; -/* Use semaphores to signal completion of events */ -#define COMPLETION_STRUCT completion_struct - -#define COMPLETION_INIT(s) sem_init(&((s)->semaphore), 0, 0); - -#define COMPLETION_WAIT(s, timeout) (sem_wait(&((s)->semaphore)) == 0) - -#define COMPLETE(s) sem_post(&((s)->semaphore)) - -#define COMPLETION_DESTROY(s) sem_destroy(&((s)->semaphore)) - -#else -/* Kernel space utils */ -#include -#include -#include -#include -#include -#include -#include - -#ifdef __x86_64__ -#define SAMPLE_ADDR_LEN uint64_t -#else -#define SAMPLE_ADDR_LEN uint32_t -#endif - -extern CpaDcHuffType huffmanType_g; - -/* Threads */ -typedef struct task_struct *sampleThread; - -/* Check for CY API version */ -#define CY_API_VERSION_AT_LEAST(major, minor) \ - (CPA_CY_API_VERSION_NUM_MAJOR > major || \ - (CPA_CY_API_VERSION_NUM_MAJOR == major && \ - CPA_CY_API_VERSION_NUM_MINOR >= minor)) - -/* Printing */ -/**< Prints the name of the function and the arguments only if gDebugParam is - * CPA_TRUE. - */ -#define PRINT_DBG(args...) \ - do \ - { \ - if (CPA_TRUE == gDebugParam) \ - { \ - printk("%s(): ", __func__); \ - printk(KERN_CONT args); \ - } \ - } while (0) - -/**< Regular prints */ -#ifndef PRINT -#define PRINT(args...) \ - do \ - { \ - printk(KERN_CONT args); \ - } while (0) -#endif - -/**< Prints the name of the function and the arguments */ -#ifndef PRINT_ERR -#define PRINT_ERR(args...) \ - do \ - { \ - printk("%s(): ", __func__); \ - printk(KERN_CONT args); \ - } while (0) -#endif -/** - ******************************************************************************* - * @ingroup sampleUtils - * Completion definitions - * - ******************************************************************************/ -#define COMPLETION_STRUCT completion - -#define COMPLETION_INIT(c) init_completion(c) - -#define COMPLETION_WAIT(c, timeout) \ - wait_for_completion_interruptible_timeout(c, timeout) - -#define COMPLETE(c) complete(c) - -#define COMPLETION_DESTROY(s) - -#endif - -#ifndef BYTE_ALIGNMENT_8 -#define BYTE_ALIGNMENT_8 (8) -#endif -#ifndef BYTE_ALIGNMENT_64 -#define BYTE_ALIGNMENT_64 (64) -#endif - -/** - ***************************************************************************** - * @ingroup fipsSampleCodeUtils - * displayHexArray - * - * @description - * Display the contents of a buffer - * - * @param[in] pLabel String to giving a short description of the printed - * value - * @param[in] pBuff pointer to the data to be printed - * @param[in] len len of the data to be printed - * - * @retval none - * - * @pre - * none - * @post - * none - *****************************************************************************/ -static inline void displayHexArray(const char *HE_QAT_RESTRICT pLabel, - const Cpa8U *HE_QAT_RESTRICT pBuff, - Cpa32U len) -{ - - int i = 0; - PRINT("%s(%d)", pLabel, len); - if (NULL == pBuff) - { - PRINT("%s(%d) Buff is NULL!!\n", __FUNCTION__, __LINE__); - return; - } - for (i = 0; i < len; i++) - { - PRINT("%02x", pBuff[i]); - } - PRINT("\n"); -} -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function and associated macro sleeps for ms milliseconds - * - * @param[in] ms sleep time in ms - * - * @retval none - * - ******************************************************************************/ -static __inline CpaStatus sampleSleep(Cpa32U ms) -{ -#ifdef USER_SPACE - int ret = 0; - struct timespec resTime, remTime; - //resTime.tv_sec = ms / 1000; - //resTime.tv_nsec = (ms % 1000) * 1000000; - // microseconds - resTime.tv_sec = ms / 1000000; - resTime.tv_nsec = (ms % 1000000) * 1000; - do - { - ret = nanosleep(&resTime, &remTime); - resTime = remTime; - } while ((ret != 0) && (errno == EINTR)); - - if (ret != 0) - { - PRINT_ERR("nanoSleep failed with code %d\n", ret); - return CPA_STATUS_FAIL; - } - else - { - return CPA_STATUS_SUCCESS; - } -#else - if (ms != 0) - { - set_current_state((long)TASK_INTERRUPTIBLE); - schedule_timeout((ms * HZ) / 1000); - } - else - { - schedule(); - } - - return CPA_STATUS_SUCCESS; -#endif -} -/** - ******************************************************************************* - * @ingroup sampleUtils - * Macro from the sampleSleep function - * - ******************************************************************************/ -#define OS_SLEEP(ms) sampleSleep((ms)) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function and associated macro allocates the memory for the given - * size and stores the address of the memory allocated in the pointer. - * Memory allocated by this function is NOT guaranteed to be physically - * contiguous. - * - * @param[out] ppMemAddr address of pointer where address will be stored - * @param[in] sizeBytes the size of the memory to be allocated - * - * @retval CPA_STATUS_RESOURCE Macro failed to allocate Memory - * @retval CPA_STATUS_SUCCESS Macro executed successfully - * - ******************************************************************************/ -static __inline CpaStatus Mem_OsMemAlloc(void **ppMemAddr, Cpa32U sizeBytes) -{ -#ifdef USER_SPACE - *ppMemAddr = malloc(sizeBytes); - if (NULL == *ppMemAddr) - { - return CPA_STATUS_RESOURCE; - } - return CPA_STATUS_SUCCESS; -#else - *ppMemAddr = kmalloc(sizeBytes, GFP_KERNEL); - if (NULL == *ppMemAddr) - { - return CPA_STATUS_RESOURCE; - } - return CPA_STATUS_SUCCESS; -#endif -} - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function and associated macro allocates the memory for the given - * size for the given alignment and stores the address of the memory - * allocated in the pointer. Memory allocated by this function is - * guaranteed to be physically contiguous. - * - * @param[out] ppMemAddr address of pointer where address will be stored - * @param[in] sizeBytes the size of the memory to be allocated - * @param[in] alignement the alignment of the memory to be allocated - *(non-zero) - * - * @retval CPA_STATUS_RESOURCE Macro failed to allocate Memory - * @retval CPA_STATUS_SUCCESS Macro executed successfully - * - ******************************************************************************/ -static __inline CpaStatus Mem_Alloc_Contig(void **ppMemAddr, - Cpa32U sizeBytes, - Cpa32U alignment) -{ -#ifdef USER_SPACE - /* Use perf sample code memory allocator */ - - /* In this sample all allocations are done from node=0 - * This might not be optimal in a dual processor system. - */ - *ppMemAddr = qaeMemAllocNUMA(sizeBytes, 0, alignment); - if (NULL == *ppMemAddr) - { - return CPA_STATUS_RESOURCE; - } - return CPA_STATUS_SUCCESS; -#else - void *pAlloc = NULL; - uint32_t align = 0; - - pAlloc = - kmalloc_node((sizeBytes + alignment + sizeof(void *)), GFP_KERNEL, 0); - if (NULL == pAlloc) - { - return CPA_STATUS_RESOURCE; - } - - *ppMemAddr = pAlloc + sizeof(void *); - - align = ((SAMPLE_ADDR_LEN)(*ppMemAddr)) % alignment; - - *ppMemAddr += (alignment - align); - *(SAMPLE_ADDR_LEN *)(*ppMemAddr - sizeof(void *)) = (SAMPLE_ADDR_LEN)pAlloc; - - return CPA_STATUS_SUCCESS; -#endif -} - -/** - ******************************************************************************* - * @ingroup sampleUtils - * Macro from the Mem_OsMemAlloc function - * - ******************************************************************************/ -#define OS_MALLOC(ppMemAddr, sizeBytes) \ - Mem_OsMemAlloc((void *)(ppMemAddr), (sizeBytes)) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * Macro from the Mem_Alloc_Contig function - * - ******************************************************************************/ -#define PHYS_CONTIG_ALLOC(ppMemAddr, sizeBytes) \ - Mem_Alloc_Contig((void *)(ppMemAddr), (sizeBytes), 1) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * Algined version of PHYS_CONTIG_ALLOC() macro - * - ******************************************************************************/ -#define PHYS_CONTIG_ALLOC_ALIGNED(ppMemAddr, sizeBytes, alignment) \ - Mem_Alloc_Contig((void *)(ppMemAddr), (sizeBytes), (alignment)) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function and associated macro frees the memory at the given address - * and resets the pointer to NULL. The memory must have been allocated by - * the function Mem_OsMemAlloc() - * - * @param[out] ppMemAddr address of pointer where mem address is stored. - * If pointer is NULL, the function will exit silently - * - * @retval void - * - ******************************************************************************/ -static __inline void Mem_OsMemFree(void **ppMemAddr) -{ -#ifdef USER_SPACE - if (NULL != *ppMemAddr) - { - free(*ppMemAddr); - *ppMemAddr = NULL; - } -#else - if (NULL != *ppMemAddr) - { - kfree(*ppMemAddr); - *ppMemAddr = NULL; - } -#endif -} - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function and associated macro frees the memory at the given address - * and resets the pointer to NULL. The memory must have been allocated by - * the function Mem_Alloc_Contig(). - * - * @param[out] ppMemAddr address of pointer where mem address is stored. - * If pointer is NULL, the function will exit silently - * - * @retval void - * - ******************************************************************************/ -static __inline void Mem_Free_Contig(void **ppMemAddr) -{ -#ifdef USER_SPACE - if (NULL != *ppMemAddr) - { - qaeMemFreeNUMA(ppMemAddr); - *ppMemAddr = NULL; - } -#else - void *pAlloc = NULL; - - if (NULL != *ppMemAddr) - { - pAlloc = (void *)(*((SAMPLE_ADDR_LEN *)(*ppMemAddr - sizeof(void *)))); - kfree(pAlloc); - *ppMemAddr = NULL; - } -#endif -} - -/** - ******************************************************************************* - * @ingroup sampleUtils - * Macro from the Mem_OsMemFree function - * - ******************************************************************************/ -#define OS_FREE(pMemAddr) Mem_OsMemFree((void *)&pMemAddr) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * Macro from the Mem_Free_Contig function - * - ******************************************************************************/ -#define PHYS_CONTIG_FREE(pMemAddr) Mem_Free_Contig((void *)&pMemAddr) - -#define _4K_PAGE_SIZE (4 * 1024) - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function returns the physical address for a given virtual address. - * In case of error 0 is returned. - * - * @param[in] virtAddr Virtual address - * - * @retval CpaPhysicalAddr Physical address or 0 in case of error - * - ******************************************************************************/ - -static __inline CpaPhysicalAddr sampleVirtToPhys(void *virtAddr) -{ -#ifdef USER_SPACE - return (CpaPhysicalAddr)qaeVirtToPhysNUMA(virtAddr); -#else - return (CpaPhysicalAddr)virt_to_phys(virtAddr); -#endif -} - -/** - ******************************************************************************* - * @ingroup sampleUtils - * This function creates a thread - * - ******************************************************************************/ - -static __inline CpaStatus sampleThreadCreate(sampleThread *thread, - void *funct, - void *args) -{ -#ifdef USER_SPACE -#ifdef __cplusplus - if (pthread_create(thread, NULL, (void* (*)(void*)) funct, args) != 0) -#else - if (pthread_create(thread, NULL, funct, args) != 0) -#endif - { - PRINT_ERR("Failed create thread\n"); - return CPA_STATUS_FAIL; - } - else - { - pthread_detach(*thread); - return CPA_STATUS_SUCCESS; - } -#else - *thread = kthread_create(funct, args, "SAMPLE_THREAD"); - wake_up_process(*thread); - return CPA_STATUS_SUCCESS; -#endif -} - -static __inline void sampleThreadExit(void) -{ -#ifdef USER_SPACE - pthread_exit(NULL); -#endif -} - -#ifdef DO_CRYPTO -void sampleCyGetInstance(CpaInstanceHandle *pCyInstHandle); - -void sampleCyStartPolling(CpaInstanceHandle cyInstHandle); - -void sampleCyStopPolling(void); - -void symSessionWaitForInflightReq(CpaCySymSessionCtx pSessionCtx); -#endif // DO_CRYPTO - -void sampleDcGetInstance(CpaInstanceHandle *pDcInstHandle); - -void sampleDcStartPolling(CpaInstanceHandle dcInstHandle); - -void sampleDcStopPolling(void); - -#ifdef __cplusplus -} //extern "C" { -#endif - - -#endif - diff --git a/heqat/include/heqat/common/types.h b/heqat/include/heqat/common/types.h index 6df1c0c..cd7acec 100644 --- a/heqat/include/heqat/common/types.h +++ b/heqat/include/heqat/common/types.h @@ -14,16 +14,20 @@ extern "C" { #include "cpa_cy_im.h" #include "cpa_cy_ln.h" - // C Libraries #include +#include #ifdef HE_QAT_PERF #include #endif -#include "heqat/common/cpa_sample_utils.h" #include "heqat/common/consts.h" +struct completion_struct +{ + sem_t semaphore; +}; + // Type definitions typedef enum { HE_QAT_SYNC = 1, @@ -45,6 +49,13 @@ typedef enum { HE_QAT_OP_MODEXP = 1 ///< QAT Modular Exponentiation } HE_QAT_OP; +typedef enum { + HE_QAT_NANOSEC = 1000000000, + HE_QAT_MICROSEC = 1000000, + HE_QAT_MILLISEC = 1000, + HE_QAT_SEC = 1 +} HE_QAT_TIME_UNIT; + typedef pthread_t HE_QAT_Inst; typedef struct { @@ -98,7 +109,7 @@ typedef struct { typedef struct { unsigned long long id; ///< Work request ID. // sem_t callback; - struct COMPLETION_STRUCT callback; ///< Synchronization object. + struct completion_struct callback; ///< Synchronization object. HE_QAT_OP op_type; ///< Work type: type of operation to be offloaded to QAT. CpaStatus op_status; ///< Status of the operation after completion. CpaFlatBuffer op_result; ///< Output of the operation in contiguous memory. diff --git a/heqat/include/heqat/common/utils.h b/heqat/include/heqat/common/utils.h index 44d10d1..30cb2ed 100644 --- a/heqat/include/heqat/common/utils.h +++ b/heqat/include/heqat/common/utils.h @@ -5,11 +5,153 @@ #ifndef HE_QAT_UTILS_H_ #define HE_QAT_UTILS_H_ +#ifdef __cplusplus +#define HE_QAT_RESTRICT __restrict__ +#else +#define HE_QAT_RESTRICT restrict +#endif + #ifdef __cplusplus extern "C" { #endif +#include "heqat/common/types.h" + #include +#include + +#include + +#ifndef BYTE_ALIGNMENT_8 +#define BYTE_ALIGNMENT_8 (8) +#endif +#ifndef BYTE_ALIGNMENT_64 +#define BYTE_ALIGNMENT_64 (64) +#endif + +// 5 seconds +#ifndef TIMEOUT_MS +#define TIMEOUT_MS 5000 +#endif + +// Printing Functions +#ifdef HE_QAT_DEBUG +#define HE_QAT_PRINT_DBG(args...) \ + do \ + { \ + printf("%s(): ", __func__); \ + printf(args); \ + fflush(stdout); \ + } while (0) +#else +#define HE_QAT_PRINT_DBG(args...) { } +#endif + +#ifndef HE_QAT_PRINT +#define HE_QAT_PRINT(args...) \ + do \ + { \ + printf(args); \ + } while (0) +#endif + +#ifndef HE_QAT_PRINT_ERR +#define HE_QAT_PRINT_ERR(args...) \ + do \ + { \ + printf("%s(): ", __func__); \ + printf(args); \ + } while (0) +#endif + +// Use semaphores to signal completion of events +#define COMPLETION_STRUCT completion_struct +#define COMPLETION_INIT(s) sem_init(&((s)->semaphore), 0, 0); +#define COMPLETION_WAIT(s, timeout) (sem_wait(&((s)->semaphore)) == 0) +#define COMPLETE(s) sem_post(&((s)->semaphore)) +#define COMPLETION_DESTROY(s) sem_destroy(&((s)->semaphore)) + +/// @brief +/// This function and associated macro allocates the memory for the given +/// size for the given alignment and stores the address of the memory +/// allocated in the pointer. Memory allocated by this function is +/// guaranteed to be physically contiguous. +/// +/// @param[out] ppMemAddr address of pointer where address will be stored +/// @param[in] sizeBytes the size of the memory to be allocated +/// @param[in] alignment the alignment of the memory to be allocated (non-zero) +/// @param[in] node the allocate memory that is local to cpu(node) +/// +/// @retval HE_QAT_STATUS_FAIL Failed to allocate memory. +/// @retval HE_QAT_STATUS_SUCCESS Memory successfully allocated. +static __inline HE_QAT_STATUS HE_QAT_memAllocContig(void **ppMemAddr, + Cpa32U sizeBytes, + Cpa32U alignment, + Cpa32U node) +{ + *ppMemAddr = qaeMemAllocNUMA(sizeBytes, node, alignment); + if (NULL == *ppMemAddr) { + return HE_QAT_STATUS_FAIL; + } + return HE_QAT_STATUS_SUCCESS; +} +#define HE_QAT_MEM_ALLOC_CONTIG(ppMemAddr, sizeBytes, alignment) \ + HE_QAT_memAllocContig((void *)(ppMemAddr), (sizeBytes), (alignment), 0) + + +/// @brief +/// This function and associated macro frees the memory at the given address +/// and resets the pointer to NULL. The memory must have been allocated by +/// the function Mem_Alloc_Contig(). +/// +/// @param[out] ppMemAddr address of pointer where mem address is stored. +/// If pointer is NULL, the function will exit silently +static __inline void HE_QAT_memFreeContig(void **ppMemAddr) +{ + if (NULL != *ppMemAddr) { + qaeMemFreeNUMA(ppMemAddr); + *ppMemAddr = NULL; + } +} +#define HE_QAT_MEM_FREE_CONTIG(pMemAddr) \ + HE_QAT_memFreeContig((void *)&pMemAddr) + + +/// @brief Sleep for time unit. +/// @param[in] time Unsigned integer representing amount of time. +/// @param[in] unit Time unit of the amount of time passed in the first parameter. Unit values can be HE_QAT_NANOSEC (nano seconds), HE_QAT_MICROSEC (micro seconds), HE_QAT_MILLISEC (milli seconds), or HE_QAT_SEC (seconds). +static __inline HE_QAT_STATUS HE_QAT_sleep(unsigned int time, HE_QAT_TIME_UNIT unit) +{ + int ret = 0; + struct timespec resTime, remTime; + + resTime.tv_sec = time / unit; + resTime.tv_nsec = (time % unit) * (HE_QAT_NANOSEC/unit); + + do { + ret = nanosleep(&resTime, &remTime); + resTime = remTime; + } while ((0 != ret) && (EINTR == errno)); + + if (0 != ret) { + HE_QAT_PRINT_ERR("nano sleep failed with code %d\n", ret); + return HE_QAT_STATUS_FAIL; + } else { + return HE_QAT_STATUS_SUCCESS; + } +} +#define HE_QAT_SLEEP(time, timeUnit) \ + HE_QAT_sleep((time), (timeUnit)) + +/// @brief +/// This function returns the physical address for a given virtual address. +/// In case of error 0 is returned. +/// @param[in] virtAddr Virtual address +/// @retval CpaPhysicalAddr Physical address or 0 in case of error +static __inline CpaPhysicalAddr HE_QAT_virtToPhys(void *virtAddr) +{ + return (CpaPhysicalAddr)qaeVirtToPhysNUMA(virtAddr); +} BIGNUM* generateTestBNData(int nbits); diff --git a/heqat/include/heqat/context.h b/heqat/include/heqat/context.h index ea9af91..ba9391e 100644 --- a/heqat/include/heqat/context.h +++ b/heqat/include/heqat/context.h @@ -1,4 +1,4 @@ -/// @file he_qat_context.h +/// @file heqat/context.h #pragma once diff --git a/samples/test_BIGNUMModExp.c b/samples/test_BIGNUMModExp.c index 71ab5a9..e5a0f3a 100644 --- a/samples/test_BIGNUMModExp.c +++ b/samples/test_BIGNUMModExp.c @@ -39,7 +39,7 @@ int main(int argc, const char** argv) { #ifdef HE_QAT_DEBUG char* bn_str = BN_bn2hex(bn_mod); - PRINT("Generated modulus: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); + HE_QAT_PRINT("Generated modulus: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); OPENSSL_free(bn_str); #endif // bn_exponent in [0..bn_mod] @@ -66,7 +66,7 @@ int main(int argc, const char** argv) { if (!ERR_get_error()) { #ifdef HE_QAT_DEBUG bn_str = BN_bn2hex(ssl_res); - PRINT("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); + HE_QAT_PRINT("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); showHexBN(ssl_res, bit_length); OPENSSL_free(bn_str); #endif @@ -97,18 +97,18 @@ int main(int argc, const char** argv) { (mod * avg_speed_up + (ssl_elapsed) / (qat_elapsed/BATCH_SIZE)) / (mod + 1); - PRINT("Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", (mod + 1), ssl_avg_time, qat_avg_time, avg_speed_up); + HE_QAT_PRINT("Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", (mod + 1), ssl_avg_time, qat_avg_time, avg_speed_up); if (HE_QAT_STATUS_SUCCESS != status) { - PRINT_ERR("\nQAT bnModExpOp failed\n"); + HE_QAT_PRINT_ERR("\nQAT bnModExpOp failed\n"); } else { HE_QAT_PRINT_DBG("\nQAT bnModExpOp finished\n"); } if (BN_cmp(qat_res, ssl_res) != 0) - PRINT("\t** FAIL **\n"); + HE_QAT_PRINT("\t** FAIL **\n"); else - PRINT("\t** PASS **\n"); + HE_QAT_PRINT("\t** PASS **\n"); BN_free(ssl_res); BN_free(qat_res); diff --git a/samples/test_bnConversion.cpp b/samples/test_bnConversion.cpp index 617d063..b884ac5 100644 --- a/samples/test_bnConversion.cpp +++ b/samples/test_bnConversion.cpp @@ -1,6 +1,4 @@ -//#include "he_qat_misc.h" -//#include "he_qat_utils.h" #include "heqat/heqat.h" #include @@ -35,7 +33,7 @@ int main(int argc, const char** argv) { if (!bn_mod) continue; char* bn_str = BN_bn2hex(bn_mod); - PRINT("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); + HE_QAT_PRINT("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); OPENSSL_free(bn_str); int len_ = (bit_length + 7) >> 3; @@ -52,7 +50,7 @@ int main(int argc, const char** argv) { gettimeofday(&start_time, NULL); status = binToBigNumber(big_num, bn_mod_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { - PRINT("Failed at binToBigNumber()\n"); + HE_QAT_PRINT("Failed at binToBigNumber()\n"); exit(1); } gettimeofday(&end_time, NULL); @@ -60,14 +58,14 @@ int main(int argc, const char** argv) { time_taken = (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; ssl_elapsed = time_taken; - PRINT("Conversion to BigNumber has completed in %.1lfus.\n", + HE_QAT_PRINT("Conversion to BigNumber has completed in %.1lfus.\n", (ssl_elapsed)); int bit_len = 0; ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); std::string str; big_num.num2hex(str); - PRINT("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, + HE_QAT_PRINT("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, bit_len); gettimeofday(&start_time, NULL); @@ -76,7 +74,7 @@ int main(int argc, const char** argv) { if (NULL == ref_bn_data_) exit(1); status = bigNumberToBin(ref_bn_data_, bit_length, big_num); if (HE_QAT_STATUS_SUCCESS != status) { - PRINT("Failed at bigNumberToBin()\n"); + HE_QAT_PRINT("Failed at bigNumberToBin()\n"); exit(1); } gettimeofday(&end_time, NULL); @@ -84,14 +82,14 @@ int main(int argc, const char** argv) { time_taken = (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; qat_elapsed = time_taken; - PRINT("Conversion from BigNumber has completed %.1lfus.\n", + HE_QAT_PRINT("Conversion from BigNumber has completed %.1lfus.\n", (qat_elapsed)); BIGNUM* ref_bin_ = BN_new(); BN_bin2bn(ref_bn_data_, len_, ref_bin_); bn_str = BN_bn2hex(ref_bin_); - PRINT("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, BN_num_bytes(ref_bin_), BN_num_bits(ref_bin_)); - PRINT("-----------------------\n"); + HE_QAT_PRINT("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, BN_num_bytes(ref_bin_), BN_num_bits(ref_bin_)); + HE_QAT_PRINT("-----------------------\n"); OPENSSL_free(bn_str); free(bn_mod_data_); diff --git a/samples/test_bnModExp.cpp b/samples/test_bnModExp.cpp index 1a5d5aa..26ad389 100644 --- a/samples/test_bnModExp.cpp +++ b/samples/test_bnModExp.cpp @@ -7,8 +7,8 @@ #include #include -#include #include +#include const unsigned int BATCH_SIZE = 48; @@ -39,7 +39,7 @@ int main(int argc, const char** argv) { char* bn_str = BN_bn2hex(bn_mod); #ifdef HE_QAT_DEBUG - printf("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, + HE_QAT_PRINT("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); #endif OPENSSL_free(bn_str); @@ -89,18 +89,18 @@ int main(int argc, const char** argv) { BigNumber big_num_exponent((Ipp32u)0); status = binToBigNumber(big_num_base, bn_base_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { - printf("Failed at binToBigNumber()\n"); + HE_QAT_PRINT_ERR("Failed at binToBigNumber()\n"); exit(1); } status = binToBigNumber(big_num_mod, bn_mod_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { - printf("Failed at binToBigNumber()\n"); + HE_QAT_PRINT_ERR("Failed at binToBigNumber()\n"); exit(1); } status = binToBigNumber(big_num_exponent, bn_exponent_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { - printf("Failed at binToBigNumber()\n"); + HE_QAT_PRINT_ERR("Failed at binToBigNumber()\n"); exit(1); } @@ -111,25 +111,25 @@ int main(int argc, const char** argv) { // Make sure variables are reset if (memcmp(bn_base_data_, bn_mod_data_, len_) || memcmp(bn_base_data_, bn_exponent_data_, len_)) { - PRINT_ERR("Pointers are not reset to zero!"); + HE_QAT_PRINT_ERR("Pointers are not reset to zero!"); exit(1); } start = high_resolution_clock::now(); status = bigNumberToBin(bn_base_data_, bit_length, big_num_base); if (HE_QAT_STATUS_SUCCESS != status) { - printf("bn_base_data_: failed at bignumbertobin()\n"); + HE_QAT_PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); exit(1); } status = bigNumberToBin(bn_mod_data_, bit_length, big_num_mod); if (HE_QAT_STATUS_SUCCESS != status) { - printf("bn_base_data_: failed at bignumbertobin()\n"); + HE_QAT_PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); exit(1); } status = bigNumberToBin(bn_exponent_data_, bit_length, big_num_exponent); if (HE_QAT_STATUS_SUCCESS != status) { - printf("bn_base_data_: failed at bignumbertobin()\n"); + HE_QAT_PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); exit(1); } cvt_duration += @@ -154,34 +154,34 @@ int main(int argc, const char** argv) { (ssl_duration.count() / (double)(qat_duration.count() / BATCH_SIZE))) / (mod + 1); - printf("Request #%u\t", mod + 1); - printf("Overhead: %.1luus", cvt_duration.count()); - printf("\tOpenSSL: %.1lfus", ssl_avg_time); - printf("\tQAT: %.1lfus", qat_avg_time); - printf("\tSpeed-up: %.1lfx", avg_speed_up); + HE_QAT_PRINT("Request #%u\t", mod + 1); + HE_QAT_PRINT("Overhead: %.1luus", cvt_duration.count()); + HE_QAT_PRINT("\tOpenSSL: %.1lfus", ssl_avg_time); + HE_QAT_PRINT("\tQAT: %.1lfus", qat_avg_time); + HE_QAT_PRINT("\tSpeed-up: %.1lfx", avg_speed_up); BIGNUM* qat_res = BN_new(); BN_bin2bn(bn_remainder_data_, len_, qat_res); if (HE_QAT_STATUS_SUCCESS != status) { - PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); + HE_QAT_PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); } #ifdef HE_QAT_DEBUG else { - PRINT_DBG("\nQAT bnModExpOp finished\n"); + HE_QAT_PRINT("\nQAT bnModExpOp finished\n"); } #endif BigNumber big_num((Ipp32u)0); status = binToBigNumber(big_num, bn_remainder_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { - printf("bn_remainder_data_: Failed at bigNumberToBin()\n"); + HE_QAT_PRINT_ERR("bn_remainder_data_: Failed at bigNumberToBin()\n"); exit(1); } #ifdef HE_QAT_DEBUG bn_str = BN_bn2hex(qat_res); - printf("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, + HE_QAT_PRINT("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, BN_num_bytes(qat_res), BN_num_bits(qat_res)); #endif @@ -190,16 +190,16 @@ int main(int argc, const char** argv) { ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); std::string str; big_num.num2hex(str); - printf("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, + HE_QAT_PRINT("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, bit_len); - printf( + HE_QAT_PRINT( "---------------------################-----------------------\n"); #endif if (BN_cmp(qat_res, ssl_res) != 0) - printf("\t** FAIL **\n"); + HE_QAT_PRINT("\t** FAIL **\n"); else - printf("\t** PASS **\n"); + HE_QAT_PRINT("\t** PASS **\n"); BN_free(bn_mod); BN_free(bn_base); diff --git a/samples/test_bnModExp_MT.cpp b/samples/test_bnModExp_MT.cpp index 18d22d4..66a6be1 100644 --- a/samples/test_bnModExp_MT.cpp +++ b/samples/test_bnModExp_MT.cpp @@ -3,14 +3,14 @@ #include #include +#include +#include +#include + #include #include #include -#include -#include -#include - const unsigned int BATCH_SIZE = 4096; using namespace std::chrono; @@ -91,18 +91,18 @@ int main(int argc, const char** argv) { BigNumber big_num_exponent((Ipp32u)0); status = binToBigNumber(big_num_base, bn_base_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { - printf("Failed at binToBigNumber()\n"); + HE_QAT_PRINT_ERR("Failed at binToBigNumber()\n"); exit(1); } status = binToBigNumber(big_num_mod, bn_mod_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { - printf("Failed at binToBigNumber()\n"); + HE_QAT_PRINT_ERR("Failed at binToBigNumber()\n"); exit(1); } status = binToBigNumber(big_num_exponent, bn_exponent_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { - printf("Failed at binToBigNumber()\n"); + HE_QAT_PRINT_ERR("Failed at binToBigNumber()\n"); exit(1); } @@ -113,7 +113,7 @@ int main(int argc, const char** argv) { // Make sure variables are reset if (memcmp(bn_base_data_, bn_mod_data_, len_) || memcmp(bn_base_data_, bn_exponent_data_, len_)) { - PRINT_ERR("Pointers are not reset to zero!"); + HE_QAT_PRINT_ERR("Pointers are not reset to zero!"); exit(1); } @@ -121,18 +121,18 @@ int main(int argc, const char** argv) { start = high_resolution_clock::now(); status = bigNumberToBin(bn_base_data_, bit_length, big_num_base); if (HE_QAT_STATUS_SUCCESS != status) { - PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); + HE_QAT_PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); exit(1); } status = bigNumberToBin(bn_mod_data_, bit_length, big_num_mod); if (HE_QAT_STATUS_SUCCESS != status) { - PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); + HE_QAT_PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); exit(1); } status = bigNumberToBin(bn_exponent_data_, bit_length, big_num_exponent); if (HE_QAT_STATUS_SUCCESS != status) { - PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); + HE_QAT_PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); exit(1); } // cvt_elapsed += (clock() - start); @@ -152,7 +152,7 @@ int main(int argc, const char** argv) { // Secure one of the distributed outstanding buffers status = acquire_bnModExp_buffer(&buffer_id); if (HE_QAT_STATUS_SUCCESS != status) { - PRINT_ERR("Failed to acquire_bnModExp_buffer()\n"); + HE_QAT_PRINT_ERR("Failed to acquire_bnModExp_buffer()\n"); exit(1); } @@ -192,17 +192,17 @@ int main(int argc, const char** argv) { (double)(qat_duration.count() / BATCH_SIZE))) / (mod + 1); - PRINT("Request #%u\t", mod + 1); - PRINT("Overhead: %.1luus", cvt_duration.count()); - PRINT("\tOpenSSL: %.1lfus", ssl_avg_time); - PRINT("\tQAT: %.1lfus", qat_avg_time); - PRINT("\tSpeed-up: %.1lfx", avg_speed_up); + HE_QAT_PRINT("Request #%u\t", mod + 1); + HE_QAT_PRINT("Overhead: %.1luus", cvt_duration.count()); + HE_QAT_PRINT("\tOpenSSL: %.1lfus", ssl_avg_time); + HE_QAT_PRINT("\tQAT: %.1lfus", qat_avg_time); + HE_QAT_PRINT("\tSpeed-up: %.1lfx", avg_speed_up); BIGNUM* qat_res = BN_new(); BN_bin2bn(bn_remainder_data_, len_, qat_res); if (HE_QAT_STATUS_SUCCESS != status) { - PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); + HE_QAT_PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); exit(1); } @@ -212,7 +212,7 @@ int main(int argc, const char** argv) { BigNumber big_num((Ipp32u)0); status = binToBigNumber(big_num, bn_remainder_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { - PRINT_ERR("bn_remainder_data_: Failed at bigNumberToBin()\n"); + HE_QAT_PRINT_ERR("bn_remainder_data_: Failed at bigNumberToBin()\n"); exit(1); } @@ -234,9 +234,9 @@ int main(int argc, const char** argv) { #endif if (BN_cmp(qat_res, ssl_res) != 0) - printf("\t** FAIL **\n"); + HE_QAT_PRINT("\t** FAIL **\n"); else - printf("\t** PASS **\n"); + HE_QAT_PRINT("\t** PASS **\n"); BN_free(bn_mod); BN_free(bn_base); @@ -244,14 +244,10 @@ int main(int argc, const char** argv) { BN_free(qat_res); BN_free(ssl_res); - // OPENSSL_free(bn_str); - free(bn_mod_data_); free(bn_base_data_); free(bn_exponent_data_); free(bn_remainder_data_); - -// break; } // Tear down OpenSSL context diff --git a/samples/test_context.c b/samples/test_context.c index 69fda71..3e7449d 100644 --- a/samples/test_context.c +++ b/samples/test_context.c @@ -28,7 +28,7 @@ int main() { exit(1); } - OS_SLEEP(5000); + HE_QAT_SLEEP(5000, HE_QAT_MILLISEC); status = release_qat_devices(); if (HE_QAT_STATUS_SUCCESS == status) { From 384fd92eded0b94e99733813acf87d05cad95fa3 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 28 Oct 2022 01:15:55 -0700 Subject: [PATCH 306/364] Make ICP headers public. Signed-off-by: Souza, Fillipe --- example/CMakeLists.txt | 3 --- heqat/CMakeLists.txt | 2 +- samples/CMakeLists.txt | 1 - 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 88753b9..15f6d70 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -23,10 +23,7 @@ find_package(Threads REQUIRED) set(CMAKE_THREAD_PREFER_PTHREAD ON) set(THREADS_PREFER_PTHREAD_FLAG ON) -include(../icp/CMakeLists.txt) - add_definitions(-fpermissive) add_executable(example example.cpp) -target_include_directories(example PRIVATE ${ICP_INC_DIR}) target_link_libraries(example PRIVATE HE_QAT::he_qat) target_link_libraries(example PRIVATE OpenSSL::SSL) diff --git a/heqat/CMakeLists.txt b/heqat/CMakeLists.txt index ba0b7aa..5a5097b 100644 --- a/heqat/CMakeLists.txt +++ b/heqat/CMakeLists.txt @@ -25,7 +25,7 @@ add_library(HE_QAT::he_qat ALIAS he_qat) target_include_directories(he_qat PUBLIC $ #Public headers PUBLIC $ #Public headers - PRIVATE ${ICP_INC_DIR} #Private headers + PUBLIC ${ICP_INC_DIR} ) install(DIRECTORY ${HE_QAT_INC_DIR}/ diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 64791f4..b74b8a7 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -14,7 +14,6 @@ macro(heqat_create_executable sample_case language dependencies) add_executable(${target} test_${sample_case}.${extension}) target_include_directories(${target} PUBLIC ${HE_QAT_INC_DIR}) - target_include_directories(${target} PUBLIC ${ICP_INC_DIR}) target_link_libraries(${target} PUBLIC he_qat) From 94dd8045fb3b46f80371306a609d1d13c1468638 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 28 Oct 2022 09:13:54 -0700 Subject: [PATCH 307/364] Move icp/CMakeLists.txt to cmake/qatconfig.cmake Signed-off-by: Souza, Fillipe --- CMakeLists.txt | 2 +- icp/CMakeLists.txt => cmake/qatconfig.cmake | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) rename icp/CMakeLists.txt => cmake/qatconfig.cmake (98%) diff --git a/CMakeLists.txt b/CMakeLists.txt index ada67a7..d908e8d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -161,7 +161,7 @@ if(NOT CMAKE_INSTALL_PREFIX) endif() # Include QAT lib API support -include(icp/CMakeLists.txt) +include(cmake/qatconfig.cmake) # HE_QAT Library add_subdirectory(heqat) diff --git a/icp/CMakeLists.txt b/cmake/qatconfig.cmake similarity index 98% rename from icp/CMakeLists.txt rename to cmake/qatconfig.cmake index e440b79..5bcaf0a 100644 --- a/icp/CMakeLists.txt +++ b/cmake/qatconfig.cmake @@ -1,4 +1,5 @@ +# Setup ICP variables if(DEFINED ENV{ICP_ROOT}) message(STATUS "Environment variable ICP_ROOT is defined as $ENV{ICP_ROOT}.") else() From ccfd48e394c22238fdedb396893bed61b8d8d04e Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 28 Oct 2022 09:33:06 -0700 Subject: [PATCH 308/364] Minor addition. Signed-off-by: Souza, Fillipe --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index d908e8d..11a1827 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -144,6 +144,7 @@ if(NOT HE_QAT_SHARED) set(OPENSSL_USE_STATIC_LIBS TRUE) message(STATUS "OPENSSL_USE_STATIC_LIBS TRUE") else() + set(OPENSSL_USE_STATIC_LIBS FALSE) message(STATUS "OPENSSL_USE_STATIC_LIBS FALSE") endif() find_package(OpenSSL REQUIRED) From 899806beff83701f635451f1fcd2d3b08f36e2b8 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 28 Oct 2022 09:36:08 -0700 Subject: [PATCH 309/364] Update Contributors. Signed-off-by: Souza, Fillipe --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1b6359e..fda4847 100644 --- a/README.md +++ b/README.md @@ -314,5 +314,7 @@ TODO # Contributors -Fillipe D. M. de Souza (Lead) +Fillipe Dias M. de Souza (Lead) +Sejun Kim +Pengfei Zhao From e8cb5bcf1f1d6baf266cf812c83baa4520ff3626 Mon Sep 17 00:00:00 2001 From: Fillipe Souza Date: Fri, 28 Oct 2022 10:09:25 -0700 Subject: [PATCH 310/364] Add license headers. (#38) Signed-off-by: Souza, Fillipe --- CMakeLists.txt | 3 ++ cmake/he_qat/HE_QATConfig.cmake.in | 3 +- cmake/he_qat/heqat-util.cmake | 2 +- cmake/qatconfig.cmake | 2 + doc/CMakeLists.txt | 2 +- doc/Doxyfile.in | 3 +- example/CMakeLists.txt | 3 ++ example/example.cpp | 2 + heqat/CMakeLists.txt | 2 + heqat/bnops.c | 2 + heqat/cb.c | 2 + heqat/common/CMakeLists.txt | 3 ++ heqat/common/utils.c | 2 + heqat/context.c | 2 + heqat/ctrl.c | 2 + heqat/include/heqat/bnops.h | 58 ++++++++++++++--------------- heqat/include/heqat/common.h | 2 + heqat/include/heqat/common/consts.h | 2 + heqat/include/heqat/common/types.h | 2 + heqat/include/heqat/common/utils.h | 2 + heqat/include/heqat/context.h | 2 + heqat/include/heqat/heqat.h | 2 + heqat/include/heqat/misc.h | 2 + heqat/misc/CMakeLists.txt | 3 ++ heqat/misc/misc.cpp | 2 + samples/CMakeLists.txt | 3 +- samples/test_BIGNUMModExp.c | 2 + samples/test_bnConversion.cpp | 2 + samples/test_bnModExp.cpp | 2 + samples/test_bnModExp_MT.cpp | 2 + samples/test_context.c | 2 + scripts/auto_find_qat_install.sh | 3 ++ scripts/reset_asym_buffer_size.sh | 2 + scripts/restart_devices.sh | 2 + scripts/run.sh | 2 + scripts/setup_devices.sh | 3 +- 36 files changed, 100 insertions(+), 37 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 11a1827..6ef5073 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,6 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + cmake_minimum_required(VERSION 3.13) # The hekat or heqat (transcribed HqA.t) was an ancient Egyptian volume unit diff --git a/cmake/he_qat/HE_QATConfig.cmake.in b/cmake/he_qat/HE_QATConfig.cmake.in index 81dc91c..5267fd1 100644 --- a/cmake/he_qat/HE_QATConfig.cmake.in +++ b/cmake/he_qat/HE_QATConfig.cmake.in @@ -1,4 +1,5 @@ -# Copyright (C) 2021 Intel Corporation +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 @PACKAGE_INIT@ diff --git a/cmake/he_qat/heqat-util.cmake b/cmake/he_qat/heqat-util.cmake index 0b5ca8a..8034239 100644 --- a/cmake/he_qat/heqat-util.cmake +++ b/cmake/he_qat/heqat-util.cmake @@ -1,4 +1,4 @@ -# Copyright (C) 2021 Intel Corporation +# Copyright (C) 2022 Intel Corporation # SPDX-License-Identifier: Apache-2.0 # Add dependency to the target archive diff --git a/cmake/qatconfig.cmake b/cmake/qatconfig.cmake index 5bcaf0a..007ef08 100644 --- a/cmake/qatconfig.cmake +++ b/cmake/qatconfig.cmake @@ -1,3 +1,5 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 # Setup ICP variables if(DEFINED ENV{ICP_ROOT}) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index c3dfd67..8639c0d 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2022-2023 Intel Corporation +# Copyright (C) 2022 Intel Corporation # SPDX-License-Identifier: Apache-2.0 # Build Doxygen documentation diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index 3c33f32..5c8e2b7 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2022-2023 Intel Corporation +# Copyright (C) 2022 Intel Corporation # SPDX-License-Identifier: Apache-2.0 PROJECT_NAME = "Intel HE Acceleration Library for QAT" @@ -11,7 +11,6 @@ INPUT = @CMAKE_SOURCE_DIR@/heqat/include/heqat \ @CMAKE_SOURCE_DIR@/heqat \ @CMAKE_SOURCE_DIR@/heqat/misc \ @CMAKE_SOURCE_DIR@/heqat/common \ - @CMAKE_SOURCE_DIR@/icp \ @CMAKE_SOURCE_DIR@/samples \ @CMAKE_SOURCE_DIR@/README.md RECURSIVE = YES diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 15f6d70..ec84eac 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -1,3 +1,6 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + project(he_qat_example LANGUAGES C CXX) cmake_minimum_required(VERSION 3.13) diff --git a/example/example.cpp b/example/example.cpp index b8e8bb7..1a8f9f9 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #include "heqat/heqat.h" diff --git a/heqat/CMakeLists.txt b/heqat/CMakeLists.txt index 5a5097b..481dc95 100644 --- a/heqat/CMakeLists.txt +++ b/heqat/CMakeLists.txt @@ -1,3 +1,5 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 # HE QAT Lib source code set(HE_QAT_SRC ${HE_QAT_SRC_DIR}/cb.c diff --git a/heqat/bnops.c b/heqat/bnops.c index 29b4d6a..c0a45b8 100644 --- a/heqat/bnops.c +++ b/heqat/bnops.c @@ -1,3 +1,5 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 /// @file heqat/bnops.c #include "cpa.h" diff --git a/heqat/cb.c b/heqat/cb.c index ba39aa0..9dfab79 100644 --- a/heqat/cb.c +++ b/heqat/cb.c @@ -1,4 +1,6 @@ /// @file heqat/cb.c +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 // QAT-API headers #include diff --git a/heqat/common/CMakeLists.txt b/heqat/common/CMakeLists.txt index 2e16c41..cd35730 100644 --- a/heqat/common/CMakeLists.txt +++ b/heqat/common/CMakeLists.txt @@ -1,3 +1,6 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + # Source files set(COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/utils.c) list(APPEND HE_QAT_SRC ${COMMON_SRC}) diff --git a/heqat/common/utils.c b/heqat/common/utils.c index fd7dec7..d7df63f 100644 --- a/heqat/common/utils.c +++ b/heqat/common/utils.c @@ -1,3 +1,5 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #include "heqat/common/utils.h" #include "heqat/common/types.h" diff --git a/heqat/context.c b/heqat/context.c index cf6180c..d6d354b 100644 --- a/heqat/context.c +++ b/heqat/context.c @@ -1,4 +1,6 @@ /// @file heqat/context.c +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #define _GNU_SOURCE diff --git a/heqat/ctrl.c b/heqat/ctrl.c index 5334313..223c92f 100644 --- a/heqat/ctrl.c +++ b/heqat/ctrl.c @@ -1,4 +1,6 @@ /// @file heqat/ctrl.c +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 // QAT-API headers #include "cpa.h" diff --git a/heqat/include/heqat/bnops.h b/heqat/include/heqat/bnops.h index bcaf393..24a226a 100644 --- a/heqat/include/heqat/bnops.h +++ b/heqat/include/heqat/bnops.h @@ -1,32 +1,32 @@ -/** - * @file heqat/bnops.h - * - * @details - * In this file, functions for Big Number operations accelerated by the - * QuickAssist (QAT) co-processor are specified. - * - * @note - * Unless otherwise specified, Big numbers are represented by octet strings - * and stored in memory as pointers of type unsigned char*. On the QAT API the - * octect string is copied into a data structure of type CpaFlatBuffer. The octet - * strings representing Big Numbers are encoded with compliance to PKCA#1 v2.1, - * section 4, which is consistent with ASN.1 syntax. - * - * The largest number supported here has 8192 bits, i.e. numbers from 0 to - * 2^(8192)-1. If the number is N, then the bit length is defined by n = floor(log2(N))+1. - * The memory buffer b to hold such number N needs to have at least M = ceiling(n/8) - * bytes allocated. In general, it will be larger and a power of 2, e.g. total bytes - * allocated is T=128 for numbers having up to n=1024 bits, total bytes allocated is - * T=256 for numbers having up to n=2048 bits, and so forth. Finally, the big number N - * is stored in `big endian` format, i.e. the least significant byte (LSB) is located - * at index [T-1], whereas the most significant byte is stored at [T-M]. - * - * The API client is responsible for allocation and release of their memory spaces of - * the function arguments. Allocated memory spaces must be contiguous. Once a function - * is called, the ownership of the memory spaces is transfered to the function until - * their completion such that concurrent usage by the client during excution may result - * in undefined behavior. - */ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +/// @file heqat/bnops.h +/// +/// @details +/// In this file, functions for Big Number operations accelerated by the +/// QuickAssist (QAT) co-processor are specified. +/// +/// @note +/// Unless otherwise specified, Big numbers are represented by octet strings +/// and stored in memory as pointers of type unsigned char*. On the QAT API the +/// octect string is copied into a data structure of type CpaFlatBuffer. The octet +/// strings representing Big Numbers are encoded with compliance to PKCA#1 v2.1, +/// section 4, which is consistent with ASN.1 syntax. +/// +/// The largest number supported here has 8192 bits, i.e. numbers from 0 to +/// 2^(8192)-1. If the number is N, then the bit length is defined by n = floor(log2(N))+1. +/// The memory buffer b to hold such number N needs to have at least M = ceiling(n/8) +/// bytes allocated. In general, it will be larger and a power of 2, e.g. total bytes +/// allocated is T=128 for numbers having up to n=1024 bits, total bytes allocated is +/// T=256 for numbers having up to n=2048 bits, and so forth. Finally, the big number N +/// is stored in `big endian` format, i.e. the least significant byte (LSB) is located +/// at index [T-1], whereas the most significant byte is stored at [T-M]. +/// +/// The API client is responsible for allocation and release of their memory spaces of +/// the function arguments. Allocated memory spaces must be contiguous. Once a function +/// is called, the ownership of the memory spaces is transfered to the function until +/// their completion such that concurrent usage by the client during excution may result +/// in undefined behavior. // New compilers #pragma once diff --git a/heqat/include/heqat/common.h b/heqat/include/heqat/common.h index f382925..05e80a1 100644 --- a/heqat/include/heqat/common.h +++ b/heqat/include/heqat/common.h @@ -1,3 +1,5 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 /// @file heqat/common.h #include "heqat/common/consts.h" diff --git a/heqat/include/heqat/common/consts.h b/heqat/include/heqat/common/consts.h index 2de1a33..3082ee0 100644 --- a/heqat/include/heqat/common/consts.h +++ b/heqat/include/heqat/common/consts.h @@ -1,3 +1,5 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 /// @file heqat/common/consts.h #pragma once diff --git a/heqat/include/heqat/common/types.h b/heqat/include/heqat/common/types.h index cd7acec..cadac27 100644 --- a/heqat/include/heqat/common/types.h +++ b/heqat/include/heqat/common/types.h @@ -1,3 +1,5 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 /// @file heqat/common/types.h #pragma once diff --git a/heqat/include/heqat/common/utils.h b/heqat/include/heqat/common/utils.h index 30cb2ed..fb3cf59 100644 --- a/heqat/include/heqat/common/utils.h +++ b/heqat/include/heqat/common/utils.h @@ -1,3 +1,5 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 /// @file heqat/common/utils.h #pragma once diff --git a/heqat/include/heqat/context.h b/heqat/include/heqat/context.h index ba9391e..abe9be5 100644 --- a/heqat/include/heqat/context.h +++ b/heqat/include/heqat/context.h @@ -1,3 +1,5 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 /// @file heqat/context.h #pragma once diff --git a/heqat/include/heqat/heqat.h b/heqat/include/heqat/heqat.h index 9b5c7a7..2bba536 100644 --- a/heqat/include/heqat/heqat.h +++ b/heqat/include/heqat/heqat.h @@ -1,3 +1,5 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 /// @file heqat/heqat.h #include "heqat/common.h" diff --git a/heqat/include/heqat/misc.h b/heqat/include/heqat/misc.h index b366742..7ccd964 100644 --- a/heqat/include/heqat/misc.h +++ b/heqat/include/heqat/misc.h @@ -1,3 +1,5 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 /// @file heqat/misc.h #pragma once diff --git a/heqat/misc/CMakeLists.txt b/heqat/misc/CMakeLists.txt index 99325e5..397bb76 100644 --- a/heqat/misc/CMakeLists.txt +++ b/heqat/misc/CMakeLists.txt @@ -1,3 +1,6 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + # Add MISC source code set(HE_QAT_MISC_SRC ${CMAKE_CURRENT_LIST_DIR}/misc.cpp ${CMAKE_CURRENT_LIST_DIR}/utils.cpp diff --git a/heqat/misc/misc.cpp b/heqat/misc/misc.cpp index 2fd8157..d789395 100644 --- a/heqat/misc/misc.cpp +++ b/heqat/misc/misc.cpp @@ -1,4 +1,6 @@ /// @file heqat/misc/misc.cpp +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #include "heqat/misc.h" diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index b74b8a7..a5feede 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -1,4 +1,5 @@ - +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 ############################################################################### macro(heqat_create_executable sample_case language dependencies) diff --git a/samples/test_BIGNUMModExp.c b/samples/test_BIGNUMModExp.c index e5a0f3a..c496ea0 100644 --- a/samples/test_BIGNUMModExp.c +++ b/samples/test_BIGNUMModExp.c @@ -1,3 +1,5 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #include "heqat/heqat.h" diff --git a/samples/test_bnConversion.cpp b/samples/test_bnConversion.cpp index b884ac5..b6cb347 100644 --- a/samples/test_bnConversion.cpp +++ b/samples/test_bnConversion.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #include "heqat/heqat.h" diff --git a/samples/test_bnModExp.cpp b/samples/test_bnModExp.cpp index 26ad389..8428ff7 100644 --- a/samples/test_bnModExp.cpp +++ b/samples/test_bnModExp.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #include "heqat/heqat.h" diff --git a/samples/test_bnModExp_MT.cpp b/samples/test_bnModExp_MT.cpp index 66a6be1..d283f7e 100644 --- a/samples/test_bnModExp_MT.cpp +++ b/samples/test_bnModExp_MT.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #include "heqat/heqat.h" diff --git a/samples/test_context.c b/samples/test_context.c index 3e7449d..f318f59 100644 --- a/samples/test_context.c +++ b/samples/test_context.c @@ -1,3 +1,5 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #include "heqat/heqat.h" diff --git a/scripts/auto_find_qat_install.sh b/scripts/auto_find_qat_install.sh index 4150685..1f90d83 100755 --- a/scripts/auto_find_qat_install.sh +++ b/scripts/auto_find_qat_install.sh @@ -1 +1,4 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + for item in $(locate QAT/build); do [ -d $item ] && [ $(echo $item | grep $HOME) ] && echo ${item%/*}; done diff --git a/scripts/reset_asym_buffer_size.sh b/scripts/reset_asym_buffer_size.sh index 80b591e..2d7be43 100755 --- a/scripts/reset_asym_buffer_size.sh +++ b/scripts/reset_asym_buffer_size.sh @@ -1,3 +1,5 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 #!/bin/bash if [[ -z "${@}" ]]; then diff --git a/scripts/restart_devices.sh b/scripts/restart_devices.sh index fc26b0e..e9652aa 100755 --- a/scripts/restart_devices.sh +++ b/scripts/restart_devices.sh @@ -1,3 +1,5 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 #!/bin/bash # Refresh diff --git a/scripts/run.sh b/scripts/run.sh index dee46a0..c10f780 100755 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -1,3 +1,5 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 #!/bin/bash export HEQATLIB_INSTALL_DIR=$HEQATLIB_ROOT_DIR/install diff --git a/scripts/setup_devices.sh b/scripts/setup_devices.sh index c0f7475..5162daf 100755 --- a/scripts/setup_devices.sh +++ b/scripts/setup_devices.sh @@ -1,6 +1,5 @@ -# Copyright (C) 2022-2023 Intel Corporation +# Copyright (C) 2022 Intel Corporation # SPDX-License-Identifier: Apache-2.0 - #!/bin/bash # Refresh From 1efc1155ef50201f8033f2846a26da59b5e8dc34 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 28 Oct 2022 10:13:33 -0700 Subject: [PATCH 311/364] Update heqat submodule. Signed-off-by: Souza, Fillipe --- module/heqat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/heqat b/module/heqat index efb9be1..e8cb5bc 160000 --- a/module/heqat +++ b/module/heqat @@ -1 +1 @@ -Subproject commit efb9be1e8670f8fcd9a444bc148da6a794a2063d +Subproject commit e8cb5bcf1f1d6baf266cf812c83baa4520ff3626 From fb00c9dab4139524806b73563eb2d55dfda572a6 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 28 Oct 2022 10:18:09 -0700 Subject: [PATCH 312/364] Remove ICP variables dependency. Signed-off-by: Souza, Fillipe --- module/heqat.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/module/heqat.cmake b/module/heqat.cmake index 7988d8c..a282eb8 100644 --- a/module/heqat.cmake +++ b/module/heqat.cmake @@ -35,7 +35,8 @@ set(HEQAT_INC_DIR ${HEQAT_DESTDIR}/${CMAKE_INSTALL_PREFIX}/include) set(HEQAT_LIB_DIR ${HEQAT_DESTDIR}/${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) # Bring up CPA variables -include(${HEQAT_SRC_DIR}/icp/CMakeLists.txt) +#include(${HEQAT_SRC_DIR}/icp/CMakeLists.txt) +#list(APPEND HEQAT_INC_DIR ${ICP_INC_DIR}) # Create heqat library interface if(IPCL_SHARED) From b2083d4bf3e822d212c95777e8e7cb0d46c36e53 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 28 Oct 2022 10:36:04 -0700 Subject: [PATCH 313/364] Replace PRINT_ERR by HE_QAT_PRINT_ERR. Signed-off-by: Souza, Fillipe --- ipcl/mod_exp.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index 979cf8f..300d85a 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -147,7 +147,7 @@ static std::vector heQatBnModExp( exp_len_[i], bn_modulus_data_[i], nbits); #endif if (HE_QAT_STATUS_SUCCESS != status) { - PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); + HE_QAT_PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); } } getBnModExpRequest(batch_size); @@ -233,7 +233,7 @@ static std::vector heQatBnModExp( exp_len_[i], bn_modulus_data_[i], nbits); #endif if (HE_QAT_STATUS_SUCCESS != status) { - PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); + HE_QAT_PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); } } getBnModExpRequest(residue); @@ -343,7 +343,7 @@ static std::vector heQatBnModExp( status = HE_QAT_bnModExp(bn_remainder_, bn_base_, bn_exponent_, bn_modulus_, nbits); if (HE_QAT_STATUS_SUCCESS != status) { - PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); + HE_QAT_PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); } } getBnModExpRequest(IPCL_CRYPTO_MB_SIZE); @@ -429,7 +429,7 @@ static BigNumber heQatBnModExp(const BigNumber& base, const BigNumber& exponent, status = HE_QAT_bnModExp(bn_remainder_data_, bn_base_data_, bn_exponent_data_, bn_modulus_data_, nbits); if (HE_QAT_STATUS_SUCCESS != status) { - PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); + HE_QAT_PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); } getBnModExpRequest(1); From 00f68322a67a5400f8645ddbf4fa03259a402507 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 28 Oct 2022 10:36:55 -0700 Subject: [PATCH 314/364] Update module/heqat.cmake Signed-off-by: Souza, Fillipe --- module/heqat.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/heqat.cmake b/module/heqat.cmake index a282eb8..b3738e8 100644 --- a/module/heqat.cmake +++ b/module/heqat.cmake @@ -35,8 +35,8 @@ set(HEQAT_INC_DIR ${HEQAT_DESTDIR}/${CMAKE_INSTALL_PREFIX}/include) set(HEQAT_LIB_DIR ${HEQAT_DESTDIR}/${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) # Bring up CPA variables -#include(${HEQAT_SRC_DIR}/icp/CMakeLists.txt) -#list(APPEND HEQAT_INC_DIR ${ICP_INC_DIR}) +include(${HEQAT_SRC_DIR}/cmake/qatconfig.cmake) +list(APPEND HEQAT_INC_DIR ${ICP_INC_DIR}) # Create heqat library interface if(IPCL_SHARED) From 99a920182f01f41e2d9d89f5f0b1c91da324bf07 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Fri, 28 Oct 2022 12:05:16 -0700 Subject: [PATCH 315/364] Minor updates (#39) - Removed unneeded install configurations and comments - Renamed samples to test to avoid potential confusion vs examples --- cmake/he_qat/HE_QATConfig.cmake.in | 1 + cmake/qatconfig.cmake | 1 - heqat/CMakeLists.txt | 2 -- {samples => test}/CMakeLists.txt | 0 {samples => test}/test_BIGNUMModExp.c | 0 {samples => test}/test_bnConversion.cpp | 0 {samples => test}/test_bnModExp.cpp | 0 {samples => test}/test_bnModExp_MT.cpp | 0 {samples => test}/test_context.c | 0 9 files changed, 1 insertion(+), 3 deletions(-) rename {samples => test}/CMakeLists.txt (100%) rename {samples => test}/test_BIGNUMModExp.c (100%) rename {samples => test}/test_bnConversion.cpp (100%) rename {samples => test}/test_bnModExp.cpp (100%) rename {samples => test}/test_bnModExp_MT.cpp (100%) rename {samples => test}/test_context.c (100%) diff --git a/cmake/he_qat/HE_QATConfig.cmake.in b/cmake/he_qat/HE_QATConfig.cmake.in index 5267fd1..b9d40e1 100644 --- a/cmake/he_qat/HE_QATConfig.cmake.in +++ b/cmake/he_qat/HE_QATConfig.cmake.in @@ -10,6 +10,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/he_qatTargets.cmake) if(TARGET HE_QAT::he_qat) set(HE_QAT_FOUND TRUE) message(STATUS "Intel Homomorphic Encryption Acceleration Library for QAT found") + add_definitions(-DUSER_SPACE) else() message(STATUS "Intel Homomorphic Encryption Acceleraiton Library for QAT not found") endif() diff --git a/cmake/qatconfig.cmake b/cmake/qatconfig.cmake index 007ef08..0ccad6a 100644 --- a/cmake/qatconfig.cmake +++ b/cmake/qatconfig.cmake @@ -24,7 +24,6 @@ set(ICP_INC_DIR ${ICP_API_DIR}/include ${ICP_API_DIR}/include/dc ${ICP_API_DIR}/include/lac) -# Active macros for cpa_sample_utils add_definitions(-DDO_CRYPTO) add_definitions(-DUSER_SPACE) add_compile_options(-fPIC) diff --git a/heqat/CMakeLists.txt b/heqat/CMakeLists.txt index 481dc95..1adfacd 100644 --- a/heqat/CMakeLists.txt +++ b/heqat/CMakeLists.txt @@ -70,8 +70,6 @@ else() set_target_properties(he_qat PROPERTIES OUTPUT_NAME "he_qat") endif() -install(TARGETS he_qat DESTINATION ${CMAKE_INSTALL_LIBDIR}) - include(CMakePackageConfigHelpers) # config cmake config and target file diff --git a/samples/CMakeLists.txt b/test/CMakeLists.txt similarity index 100% rename from samples/CMakeLists.txt rename to test/CMakeLists.txt diff --git a/samples/test_BIGNUMModExp.c b/test/test_BIGNUMModExp.c similarity index 100% rename from samples/test_BIGNUMModExp.c rename to test/test_BIGNUMModExp.c diff --git a/samples/test_bnConversion.cpp b/test/test_bnConversion.cpp similarity index 100% rename from samples/test_bnConversion.cpp rename to test/test_bnConversion.cpp diff --git a/samples/test_bnModExp.cpp b/test/test_bnModExp.cpp similarity index 100% rename from samples/test_bnModExp.cpp rename to test/test_bnModExp.cpp diff --git a/samples/test_bnModExp_MT.cpp b/test/test_bnModExp_MT.cpp similarity index 100% rename from samples/test_bnModExp_MT.cpp rename to test/test_bnModExp_MT.cpp diff --git a/samples/test_context.c b/test/test_context.c similarity index 100% rename from samples/test_context.c rename to test/test_context.c From eb444b40d3691c1ea6c0130c4c3399fda62c74dc Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Fri, 28 Oct 2022 12:37:48 -0700 Subject: [PATCH 316/364] Update qat_integration with heqat updates (#141) * Remove any reference to ```cpa_sample_utils``` * Updated ipp-crypto patch to add ```-Wnostringop-overflow``` flag due to gcc-11/gcc-12 bug * Added ipcl-function to fetch ```icp_inc_dir``` include variables * Added ```-DUSER_SPACE``` flag when linking ```heqat``` * ippcrypto_patch to be excluded from precommit white space and EOF fixer * Removed reference to ``` heqat/cmake/qatconfig.cmake``` in module --- .pre-commit-config.yaml | 2 + CMakeLists.txt | 8 +- benchmark/main.cpp | 6 +- cmake/ipcl/ipcl-util.cmake | 26 ++++- cmake/ippcrypto_patch.patch | 173 ++++++++++++++++++++++++++++++++-- ipcl/CMakeLists.txt | 10 +- ipcl/bignum.cpp | 14 +-- ipcl/context.cpp | 110 ++++++++++----------- ipcl/include/ipcl/bignum.h | 2 +- ipcl/include/ipcl/context.hpp | 18 ++-- module/heqat | 2 +- module/heqat.cmake | 5 +- test/main.cpp | 18 ++-- 13 files changed, 285 insertions(+), 109 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2f41239..5f72fea 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,9 @@ repos: rev: v4.0.1 hooks: - id: trailing-whitespace + exclude: cmake/ippcrypto_patch.patch - id: end-of-file-fixer + exclude: cmake/ippcrypto_patch.patch - id: check-merge-conflict - id: mixed-line-ending - id: check-byte-order-marker diff --git a/CMakeLists.txt b/CMakeLists.txt index e1ead8b..a1fb8da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,7 +44,7 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) endif() set(CMAKE_C_FLAGS "-O2 -Wno-error=deprecated-declarations") -set(CMAKE_CXX_FLAGS "-O2 -fpermissive -Wno-error=deprecated-declarations") +set(CMAKE_CXX_FLAGS "-O2 -fpermissive -Wno-error=deprecated-declarations -Wstringop-overflow=1") set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ipcl;${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ipcl/ippcrypto") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) @@ -127,13 +127,13 @@ else() message(STATUS "Support RDRAND instruction: True") add_compile_definitions(IPCL_RNG_INSTR_RDRAND) else() - message(WARNING + message(WARNING "CPU doesn't support RDSEED and RDRAND instruction, using IPP-Crypto" - " S/W psuedo random number generator" + " S/W pseudo random number generator" ) endif() endif() - + set(IPCL_FORWARD_CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} diff --git a/benchmark/main.cpp b/benchmark/main.cpp index a08e372..915ed5b 100644 --- a/benchmark/main.cpp +++ b/benchmark/main.cpp @@ -1,8 +1,8 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include -#include +#include "benchmark/benchmark.h" +#include "ipcl/context.hpp" int main(int argc, char** argv) { #ifdef IPCL_USE_QAT @@ -13,7 +13,7 @@ int main(int argc, char** argv) { benchmark::Initialize(&argc, argv); benchmark::RunSpecifiedBenchmarks(); - + ipcl::terminateContext(); return 0; diff --git a/cmake/ipcl/ipcl-util.cmake b/cmake/ipcl/ipcl-util.cmake index ea47ee1..96646b3 100644 --- a/cmake/ipcl/ipcl-util.cmake +++ b/cmake/ipcl/ipcl-util.cmake @@ -88,7 +88,7 @@ function(ipcl_check_qat_service_status) if(${QAT_SERVICE_STATUS} EQUAL "1") message(STATUS "qat_service is ACTIVE") else() - message(WARNING + message(WARNING " qat_service is NOT ACTIVE!\n" " Since QAT is detected, compilation will continue however the" " qat_service need to be active to use the library.\n" @@ -97,4 +97,26 @@ function(ipcl_check_qat_service_status) ) endif() endfunction() - + +function(ipcl_define_icp_variables OutVariable) + set(ICP_ROOT $ENV{ICP_ROOT}) + set(ICP_BUILDOUTPUT_PATH ${ICP_ROOT}/build) + + set(ICP_BUILDSYSTEM_PATH ${ICP_ROOT}/quickassist/build_system) + set(ICP_API_DIR ${ICP_ROOT}/quickassist) + set(ICP_LAC_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer) + set(ICP_OSAL_DIR ${ICP_ROOT}/quickassist/utilities/oasl) + set(ICP_ADF_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/qat_direct) + set(CMN_ROOT ${ICP_ROOT}/quickassist/utilities/libusdm_drv) + set(CPA_SAMPLES_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/sample_code/functional) + + add_definitions(-DUSER_SPACE) + + set(${OutVariable} ${ICP_API_DIR}/include + ${ICP_LAC_DIR}/include + ${ICP_ADF_DIR}/include + ${CMN_ROOT} + ${ICP_API_DIR}/include/dc + ${ICP_API_DIR}/include/lac + ${CPA_SAMPLES_DIR}/include PARENT_SCOPE) +endfunction() diff --git a/cmake/ippcrypto_patch.patch b/cmake/ippcrypto_patch.patch index 9b607fe..ebc60cc 100644 --- a/cmake/ippcrypto_patch.patch +++ b/cmake/ippcrypto_patch.patch @@ -1,7 +1,6 @@ -# Copyright (C) 2021 Intel Corporation +# Copyright (C) 2022 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -# applicable to https://github.com/intel/ipp-crypto/releases/tag/ippcp_2021.6 diff --git a/CMakeLists.txt b/CMakeLists.txt index ddb61db..302ca95 100644 --- a/CMakeLists.txt @@ -11,9 +10,87 @@ index ddb61db..302ca95 100644 VERSION ${PROJECT_VERSION} LANGUAGES C CXX) +include(GNUInstallDirs) - + if("${CMAKE_BUILD_TYPE}" STREQUAL "") message(STATUS "CMAKE_BUILD_TYPE is unset, defaulting to Release") +diff --git a/sources/cmake/linux/Clang9.0.0.cmake b/sources/cmake/linux/Clang9.0.0.cmake +index b99d637..4a0c5bc 100644 +--- a/sources/cmake/linux/Clang9.0.0.cmake ++++ b/sources/cmake/linux/Clang9.0.0.cmake +@@ -100,7 +100,7 @@ if(${ARCH} MATCHES "ia32") + endif(${ARCH} MATCHES "ia32") + + # Optimization level = 3, no-debug definition (turns off asserts), warnings=errors +-set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -Werror") ++set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -Wno-stringop-overflow -Werror") + + set(w7_opt "${w7_opt} -march=pentium4 -msse2") + set(s8_opt "${s8_opt} -march=core2 -mssse3") +diff --git a/sources/cmake/linux/GNU8.2.0.cmake b/sources/cmake/linux/GNU8.2.0.cmake +index 9c848d5..30ad189 100644 +--- a/sources/cmake/linux/GNU8.2.0.cmake ++++ b/sources/cmake/linux/GNU8.2.0.cmake +@@ -96,7 +96,7 @@ if(${ARCH} MATCHES "ia32") + endif(${ARCH} MATCHES "ia32") + + # Optimization level = 3, no-debug definition (turns off asserts), warnings=errors +-set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -Werror") ++set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -Wno-stringop-overflow -Werror") + + set(w7_opt "${w7_opt} -march=pentium4 -msse2") + set(s8_opt "${s8_opt} -march=core2 -mssse3") +diff --git a/sources/cmake/linux/Intel19.0.0.cmake b/sources/cmake/linux/Intel19.0.0.cmake +index ce0ee06..bbe4acc 100644 +--- a/sources/cmake/linux/Intel19.0.0.cmake ++++ b/sources/cmake/linux/Intel19.0.0.cmake +@@ -99,7 +99,7 @@ if(CODE_COVERAGE) + endif() + + # Optimization level = 3, no-debug definition (turns off asserts), warning level = 3, treat warnings as errors +-set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -w3 -Werror") ++set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -w3 -Wno-stringop-overflow -Werror") + # DEBUG flags Optimization level = 0, generation maximum GDB information (-g3) + set (CMAKE_C_FLAGS_DEBUG " -O0 -g3") + +diff --git a/sources/cmake/linux/IntelLLVM2021.3.0.cmake b/sources/cmake/linux/IntelLLVM2021.3.0.cmake +index 73ab46a..bedc0a7 100644 +--- a/sources/cmake/linux/IntelLLVM2021.3.0.cmake ++++ b/sources/cmake/linux/IntelLLVM2021.3.0.cmake +@@ -95,7 +95,7 @@ if(CODE_COVERAGE) + endif() + + # Optimization level = 3, no-debug definition (turns off asserts), warning level = 3, treat warnings as errors +-set (CMAKE_C_FLAGS_RELEASE " -Ofast -DNDEBUG -Wall -Wno-unused-function -Wno-missing-braces -Werror") ++set (CMAKE_C_FLAGS_RELEASE " -Ofast -DNDEBUG -Wall -Wno-unused-function -Wno-missing-braces -Wno-stringop-overflow -Werror") + + # Alignment for structures on byte boundaries (= 16) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Zp16") +diff --git a/sources/cmake/macosx/AppleClang11.0.0.cmake b/sources/cmake/macosx/AppleClang11.0.0.cmake +index 0ca0d30..604ebf3 100644 +--- a/sources/cmake/macosx/AppleClang11.0.0.cmake ++++ b/sources/cmake/macosx/AppleClang11.0.0.cmake +@@ -99,7 +99,7 @@ if(${ARCH} MATCHES "ia32") + endif(${ARCH} MATCHES "ia32") + + # Optimization level = 3, no-debug definition (turns off asserts), warnings=errors +-set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -Werror") ++set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -Wno-stringop-overflow -Werror") + + set(w7_opt "${w7_opt} -march=pentium4 -msse2") + set(s8_opt "${s8_opt} -march=core2 -mssse3") +diff --git a/sources/cmake/macosx/Intel19.0.0.cmake b/sources/cmake/macosx/Intel19.0.0.cmake +index 1250802..ffdf8db 100644 +--- a/sources/cmake/macosx/Intel19.0.0.cmake ++++ b/sources/cmake/macosx/Intel19.0.0.cmake +@@ -86,7 +86,7 @@ if(CODE_COVERAGE) + endif() + + # Optimization level = 3, no-debug definition (turns off asserts), warning level = 3, treat warnings as errors +-set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -w3 -Werror") ++set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -w3 -Wno-stringop-overflow -Werror") + + # Compile for x64 + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch_only x86_64") diff --git a/sources/ippcp/CMakeLists.txt b/sources/ippcp/CMakeLists.txt index dd5ef41..b60357e 100644 --- a/sources/ippcp/CMakeLists.txt @@ -26,7 +103,7 @@ index dd5ef41..b60357e 100644 + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) list(APPEND IPPCP_LIB_DYNAMIC ${IPPCP_DYN_ITER}) endif(DYNAMIC_LIB AND NOT MERGED_BLD) - + @@ -407,7 +407,7 @@ foreach(opt ${PLATFORM_LIST}) set_target_properties(${IPPCP_ST_ITER} PROPERTIES PUBLIC_HEADER "${IPPCP_PUBLIC_HEADERS}") install(TARGETS ${IPPCP_ST_ITER} @@ -34,16 +111,16 @@ index dd5ef41..b60357e 100644 - PUBLIC_HEADER DESTINATION "include") + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) endif() - + list(APPEND IPPCP_LIB_STATIC ${IPPCP_ST_ITER}) @@ -482,7 +482,7 @@ if(MERGED_BLD) - + install(TARGETS ${IPPCP_LIB_MERGED} ARCHIVE DESTINATION "lib/${ARCH}/$<$:nonpic>" - PUBLIC_HEADER DESTINATION "include" + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} PRIVATE_HEADER DESTINATION "tools/${ARCH}/staticlib") - + set_source_files_properties(${DISPATCHER_C_SOURCES} pcpver.rc PROPERTIES INCLUDE_DIRECTORIES "${C_INCLUDE_DIRECTORIES}") @@ -521,7 +521,7 @@ if(MERGED_BLD) install(TARGETS ${IPPCP_LIB_PCS} @@ -52,7 +129,7 @@ index dd5ef41..b60357e 100644 - PUBLIC_HEADER DESTINATION "include" + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} PRIVATE_HEADER DESTINATION "tools/${ARCH}/staticlib") - + if(WIN32) diff --git a/sources/ippcp/crypto_mb/src/CMakeLists.txt b/sources/ippcp/crypto_mb/src/CMakeLists.txt index f75f448..2f43255 100644 @@ -71,7 +148,7 @@ index f75f448..2f43255 100644 - PUBLIC_HEADER DESTINATION "include/crypto_mb") + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/crypto_mb) endif() - + # Static library @@ -147,9 +147,9 @@ endif() if(MB_STANDALONE) @@ -85,3 +162,81 @@ index f75f448..2f43255 100644 - PUBLIC_HEADER DESTINATION "include/crypto_mb") + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/crypto_mb) endif() +diff --git a/sources/ippcp/crypto_mb/src/cmake/linux/Clang.cmake b/sources/ippcp/crypto_mb/src/cmake/linux/Clang.cmake +index 17bc125..77b14ee 100644 +--- a/sources/ippcp/crypto_mb/src/cmake/linux/Clang.cmake ++++ b/sources/ippcp/crypto_mb/src/cmake/linux/Clang.cmake +@@ -44,7 +44,7 @@ set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -fpic -fPIC") + # Enables important warning and error messages relevant to security during compilation + set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wall") + # Warnings=errors +-set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Werror") ++set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wno-stringop-overflow -Werror") + + # Linker flags + +diff --git a/sources/ippcp/crypto_mb/src/cmake/linux/GNU.cmake b/sources/ippcp/crypto_mb/src/cmake/linux/GNU.cmake +index b95f703..1be6ca7 100644 +--- a/sources/ippcp/crypto_mb/src/cmake/linux/GNU.cmake ++++ b/sources/ippcp/crypto_mb/src/cmake/linux/GNU.cmake +@@ -46,7 +46,7 @@ set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -fcf-protection=full") + # Enables important warning and error messages relevant to security during compilation + set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wall") + # Warnings=errors +-set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Werror") ++set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wno-stringop-overflow -Werror") + + # Linker flags + +diff --git a/sources/ippcp/crypto_mb/src/cmake/linux/Intel.cmake b/sources/ippcp/crypto_mb/src/cmake/linux/Intel.cmake +index 39862aa..35d49c1 100644 +--- a/sources/ippcp/crypto_mb/src/cmake/linux/Intel.cmake ++++ b/sources/ippcp/crypto_mb/src/cmake/linux/Intel.cmake +@@ -40,7 +40,7 @@ set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -fcf-protection=full") + # Enables important warning and error messages relevant to security during compilation + set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wall") + # Warnings=errors +-set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Werror") ++set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wno-stringop-overflow -Werror") + + # Linker flags + +diff --git a/sources/ippcp/crypto_mb/src/cmake/linux/IntelLLVM.cmake b/sources/ippcp/crypto_mb/src/cmake/linux/IntelLLVM.cmake +index 285c64a..b0f48bf 100644 +--- a/sources/ippcp/crypto_mb/src/cmake/linux/IntelLLVM.cmake ++++ b/sources/ippcp/crypto_mb/src/cmake/linux/IntelLLVM.cmake +@@ -40,7 +40,7 @@ set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -fcf-protection=full") + # Enables important warning and error messages relevant to security during compilation + set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wall") + # Warnings=errors +-set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Werror") ++set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wno-stringop-overflow -Werror") + + # Linker flags + +diff --git a/sources/ippcp/crypto_mb/src/cmake/macosx/AppleClang.cmake b/sources/ippcp/crypto_mb/src/cmake/macosx/AppleClang.cmake +index 5f6ff8c..fefd3a2 100644 +--- a/sources/ippcp/crypto_mb/src/cmake/macosx/AppleClang.cmake ++++ b/sources/ippcp/crypto_mb/src/cmake/macosx/AppleClang.cmake +@@ -40,7 +40,7 @@ set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -fpic -fPIC") + # Enables important warning and error messages relevant to security during compilation + set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wall") + # Warnings=errors +-set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Werror") ++set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wno-stringop-overflow -Werror") + + # Linker flags + +diff --git a/sources/ippcp/crypto_mb/src/cmake/macosx/Intel.cmake b/sources/ippcp/crypto_mb/src/cmake/macosx/Intel.cmake +index 1abac6e..40919a6 100644 +--- a/sources/ippcp/crypto_mb/src/cmake/macosx/Intel.cmake ++++ b/sources/ippcp/crypto_mb/src/cmake/macosx/Intel.cmake +@@ -33,7 +33,7 @@ set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -fpic -fPIC") + # Enables important warning and error messages relevant to security during compilation + set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wall") + # Warnings=errors +-set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Werror") ++set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wno-stringop-overflow -Werror") + + # Linker flags + diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index e7fcf02..27b1614 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -67,21 +67,15 @@ if(IPCL_DETECT_IFMA_RUNTIME) endif() if(IPCL_ENABLE_QAT) + ipcl_define_icp_variables(icp_inc_dir) target_include_directories(ipcl - PRIVATE "$" - PRIVATE $ + PUBLIC "$" ) target_include_directories(ipcl PRIVATE "$" PRIVATE $ ) - install(DIRECTORY ${ICP_INC_DIR}/ - DESTINATION ${IPCL_INSTALL_INCLUDEDIR}/icp - FILES_MATCHING - PATTERN "*.hpp" - PATTERN "*.h") - install(DIRECTORY ${HEQAT_INC_DIR}/ DESTINATION ${IPCL_INSTALL_INCLUDEDIR} FILES_MATCHING diff --git a/ipcl/bignum.cpp b/ipcl/bignum.cpp index 0f7768b..03045e6 100644 --- a/ipcl/bignum.cpp +++ b/ipcl/bignum.cpp @@ -18,7 +18,6 @@ #include #include - #include ////////////////////////////////////////////////////////////////////// @@ -540,8 +539,7 @@ bool BigNumber::toBin(unsigned char* data, int len, const BigNumber& bn) { return true; } -bool BigNumber::toBin(unsigned char** bin, int *len, const BigNumber& bn) -{ +bool BigNumber::toBin(unsigned char** bin, int* len, const BigNumber& bn) { if (NULL == bin) return false; if (NULL == len) return false; @@ -553,13 +551,15 @@ bool BigNumber::toBin(unsigned char** bin, int *len, const BigNumber& bn) // Revert it to big endian format int bitSizeLen = BITSIZE_WORD(bitSize) * 4; *len = bitSizeLen; - bin[0] = reinterpret_cast(malloc(bitSizeLen*sizeof(unsigned char))); - memset(bin[0],0,*len); - if(NULL == bin[0]) return false; + bin[0] = reinterpret_cast( + malloc(bitSizeLen * sizeof(unsigned char))); + memset(bin[0], 0, *len); + if (NULL == bin[0]) return false; unsigned char* data_out = bin[0]; unsigned char* bn_data_ = reinterpret_cast(ref_bn_data_); - for (int i = 0; i < bitSizeLen; i++) data_out[bitSizeLen - 1 - i] = bn_data_[i]; + for (int i = 0; i < bitSizeLen; i++) + data_out[bitSizeLen - 1 - i] = bn_data_[i]; return true; } diff --git a/ipcl/context.cpp b/ipcl/context.cpp index 7a920f7..359d11b 100644 --- a/ipcl/context.cpp +++ b/ipcl/context.cpp @@ -12,77 +12,77 @@ namespace ipcl { - ///> Default behavior is selected at runtime and implementation dependent - enum class RuntimeValue { DEFAULT, CPU, QAT, HYBRID }; - std::map runtimeMap = { - {"DEFAULT",RuntimeValue::DEFAULT}, {"default",RuntimeValue::DEFAULT}, - {"CPU",RuntimeValue::CPU}, {"cpu",RuntimeValue::CPU}, - {"QAT",RuntimeValue::QAT}, {"qat",RuntimeValue::QAT}, - {"HYBRID",RuntimeValue::HYBRID}, {"hybrid",RuntimeValue::HYBRID} - }; +///> Default behavior is selected at runtime and implementation dependent +enum class RuntimeValue { DEFAULT, CPU, QAT, HYBRID }; +std::map runtimeMap = { + {"DEFAULT", RuntimeValue::DEFAULT}, {"default", RuntimeValue::DEFAULT}, + {"CPU", RuntimeValue::CPU}, {"cpu", RuntimeValue::CPU}, + {"QAT", RuntimeValue::QAT}, {"qat", RuntimeValue::QAT}, + {"HYBRID", RuntimeValue::HYBRID}, {"hybrid", RuntimeValue::HYBRID}}; - enum class FeatureValue { AVX512IFMA, QAT4XXX }; - std::map hasFeatureMap = { - {"avx512",FeatureValue::AVX512IFMA}, {"avx512ifma",FeatureValue::AVX512IFMA}, - {"4xxx",FeatureValue::QAT4XXX}, {"qat_4xxx",FeatureValue::QAT4XXX} - }; +enum class FeatureValue { AVX512IFMA, QAT4XXX }; +std::map hasFeatureMap = { + {"avx512", FeatureValue::AVX512IFMA}, + {"avx512ifma", FeatureValue::AVX512IFMA}, + {"4xxx", FeatureValue::QAT4XXX}, + {"qat_4xxx", FeatureValue::QAT4XXX}}; #ifdef IPCL_USE_QAT - bool hasQAT = false; - static bool isUsingQAT = false; - static bool initializeQATContext() { - if (!isUsingQAT && - HE_QAT_STATUS_SUCCESS == acquire_qat_devices()) - return (isUsingQAT = true); - return false; - } +bool hasQAT = false; +static bool isUsingQAT = false; +static bool initializeQATContext() { + if (!isUsingQAT && HE_QAT_STATUS_SUCCESS == acquire_qat_devices()) + return (isUsingQAT = true); + return false; +} #endif - bool initializeContext(std::string runtime_choice) { +bool initializeContext(std::string runtime_choice) { #ifdef IPCL_USE_QAT - hasQAT = true; - switch (runtimeMap[runtime_choice]) { - case RuntimeValue::QAT: - return initializeQATContext(); - case RuntimeValue::CPU: - case RuntimeValue::HYBRID: - case RuntimeValue::DEFAULT: - default: - return true; - } -#else // Default behavior: CPU choice - return true; -#endif // IPCL_USE_QAT + hasQAT = true; + switch (runtimeMap[runtime_choice]) { + case RuntimeValue::QAT: + return initializeQATContext(); + case RuntimeValue::CPU: + case RuntimeValue::HYBRID: + case RuntimeValue::DEFAULT: + default: + return true; } +#else // Default behavior: CPU choice + return true; +#endif // IPCL_USE_QAT +} - bool terminateContext() { +bool terminateContext() { #ifdef IPCL_USE_QAT - if (isUsingQAT) { - if (HE_QAT_STATUS_SUCCESS == release_qat_devices()) { - isUsingQAT = false; - return true; - } - return false; - } return true; -#else // Default behavior: CPU choice - return true; -#endif // IPCL_USE_QAT + if (isUsingQAT) { + if (HE_QAT_STATUS_SUCCESS == release_qat_devices()) { + isUsingQAT = false; + return true; + } + return false; } + return true; +#else // Default behavior: CPU choice + return true; +#endif // IPCL_USE_QAT +} - bool isQATRunning() { +bool isQATRunning() { #ifdef IPCL_USE_QAT - return (HE_QAT_STATUS_RUNNING == get_qat_context_state()); + return (HE_QAT_STATUS_RUNNING == get_qat_context_state()); #else - return false; + return false; #endif - } - - bool isQATActive() { +} + +bool isQATActive() { #ifdef IPCL_USE_QAT - return (HE_QAT_STATUS_ACTIVE == get_qat_context_state()); + return (HE_QAT_STATUS_ACTIVE == get_qat_context_state()); #else - return false; + return false; #endif - } +} } // namespace ipcl diff --git a/ipcl/include/ipcl/bignum.h b/ipcl/include/ipcl/bignum.h index e07d393..c6531a1 100644 --- a/ipcl/include/ipcl/bignum.h +++ b/ipcl/include/ipcl/bignum.h @@ -125,7 +125,7 @@ class BigNumber { // Support QAT data format static bool fromBin(BigNumber& bn, const unsigned char* data, int len); static bool toBin(unsigned char* data, int len, const BigNumber& bn); - static bool toBin(unsigned char** data, int *len, const BigNumber& bn); + static bool toBin(unsigned char** data, int* len, const BigNumber& bn); protected: bool create(const Ipp32u* pData, int length, diff --git a/ipcl/include/ipcl/context.hpp b/ipcl/include/ipcl/context.hpp index c9492e2..f8cd856 100644 --- a/ipcl/include/ipcl/context.hpp +++ b/ipcl/include/ipcl/context.hpp @@ -11,20 +11,26 @@ namespace ipcl { /** - * Initialize device (CPU, QAT, or both) runtime context for the Paillier crypto services. - * @details It must be called if there is intent of using QAT devices for compute acceleration. - * @param[in] runtime_choice Acceptable values are "CPU", "cpu", "QAT", "qat", "HYBRID", "hybrid", "DEFAULT", "default". Anything other than the accepted values, including typos and absence thereof, will default to the "DEFAULT" runtime choice. - * @return true if runtime context has been properly initialized, false otherwise. + * Initialize device (CPU, QAT, or both) runtime context for the Paillier crypto + * services. + * @details It must be called if there is intent of using QAT devices for + * compute acceleration. + * @param[in] runtime_choice Acceptable values are "CPU", "cpu", "QAT", "qat", + * "HYBRID", "hybrid", "DEFAULT", "default". Anything other than the accepted + * values, including typos and absence thereof, will default to the "DEFAULT" + * runtime choice. + * @return true if runtime context has been properly initialized, false + * otherwise. */ bool initializeContext(std::string runtime_choice); /** * Terminate runtime context. - * @return true if runtime context has been properly terminated, false otherwise. + * @return true if runtime context has been properly terminated, false + * otherwise. */ bool terminateContext(void); - /** * Determine if QAT instances are running for IPCL. * @return true if QAT instances are active and running, false otherwise. diff --git a/module/heqat b/module/heqat index e8cb5bc..99a9201 160000 --- a/module/heqat +++ b/module/heqat @@ -1 +1 @@ -Subproject commit e8cb5bcf1f1d6baf266cf812c83baa4520ff3626 +Subproject commit 99a920182f01f41e2d9d89f5f0b1c91da324bf07 diff --git a/module/heqat.cmake b/module/heqat.cmake index b3738e8..08e3472 100644 --- a/module/heqat.cmake +++ b/module/heqat.cmake @@ -34,10 +34,6 @@ add_dependencies(ext_he_qat ext_ipp-crypto) set(HEQAT_INC_DIR ${HEQAT_DESTDIR}/${CMAKE_INSTALL_PREFIX}/include) set(HEQAT_LIB_DIR ${HEQAT_DESTDIR}/${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) -# Bring up CPA variables -include(${HEQAT_SRC_DIR}/cmake/qatconfig.cmake) -list(APPEND HEQAT_INC_DIR ${ICP_INC_DIR}) - # Create heqat library interface if(IPCL_SHARED) add_library(libhe_qat INTERFACE) @@ -56,6 +52,7 @@ if(IPCL_SHARED) DIRECTORY ${HEQAT_LIB_DIR}/ DESTINATION "${IPCL_INSTALL_LIBDIR}/heqat" USE_SOURCE_PERMISSIONS + PATTERN "cmake" EXCLUDE ) else() add_library(libhe_qat STATIC IMPORTED GLOBAL) diff --git a/test/main.cpp b/test/main.cpp index d3782c0..178b34d 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -1,23 +1,23 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include -#include - #include +#include "gtest/gtest.h" +#include "ipcl/context.hpp" + int main(int argc, char** argv) { #ifdef IPCL_USE_QAT ipcl::initializeContext("QAT"); - + if (ipcl::isQATActive()) - std::cout << "QAT Context: ACTIVE" << std::endl; - else + std::cout << "QAT Context: ACTIVE" << std::endl; + else std::cout << "Error: QAT Context INACTIVE." << std::endl; if (ipcl::isQATRunning()) - std::cout << "QAT Instances: RUNNING" << std::endl; - else + std::cout << "QAT Instances: RUNNING" << std::endl; + else std::cout << "Error: QAT Instances NOT RUNNING." << std::endl; #else ipcl::initializeContext("default"); @@ -33,7 +33,7 @@ int main(int argc, char** argv) { #ifdef IPCL_USE_QAT if (!ipcl::isQATActive()) std::cout << "QAT Context: INACTIVE" << std::endl; - else + else std::cout << "Error: QAT Context ACTIVE." << std::endl; if (!ipcl::isQATRunning()) std::cout << "QAT Instances: NOT RUNNING" << std::endl; From 6d180a2ddcfeb17cc8dddf2546a0f0e5ee6f07fd Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Fri, 28 Oct 2022 12:59:58 -0700 Subject: [PATCH 317/364] Cleanup deprecated compile definitions and cmake variables (#40) - Removed USER_SPACE and DO_CRYPTO compile definitions - Removed unused cmake flags (HE_QAT_BENCHMARK and HE_QAT_SAMPLES) --- CMakeLists.txt | 21 +-------------------- cmake/he_qat/HE_QATConfig.cmake.in | 1 - cmake/qatconfig.cmake | 4 ---- test/CMakeLists.txt | 6 +++--- 4 files changed, 4 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ef5073..0c4da07 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,10 +65,8 @@ option(HE_QAT_MISC "Enable miscellaneous features" ON) option(HE_QAT_SYNC "Enable synchronous mode execution" OFF) option(HE_QAT_MT "Enable interfaces for multithreaded programs" ON) option(HE_QAT_PERF "Show request performance" OFF) -option(HE_QAT_TEST "Enable testing" OFF) +option(HE_QAT_TEST "Enable testing" ON) option(HE_QAT_OMP "Enable tests using OpenMP" ON) -option(HE_QAT_SAMPLES "Enable examples" ON) -option(HE_QAT_BENCHMARK "Enable benchmark" OFF) option(HE_QAT_DOCS "Enable document building" ON) option(HE_QAT_SHARED "Build shared library" ON) @@ -170,26 +168,9 @@ include(cmake/qatconfig.cmake) # HE_QAT Library add_subdirectory(heqat) -if(HE_QAT_TEST) - include(cmake/gtest.cmake) -endif() -if(HE_QAT_BENCHMARK) - include(cmake/gbenchmark.cmake) -endif() - #Validation test examples -if(HE_QAT_SAMPLES) - add_subdirectory(samples) -endif() - if(HE_QAT_TEST) add_subdirectory(test) - add_custom_target(unittest COMMAND $ DEPENDS he_qat_unittest) -endif() - -if(HE_QAT_BENCHMARK) - add_subdirectory(benchmark) - add_custom_target(benchmark COMMAND $ DEPENDS he_qat_bench) endif() if(HE_QAT_DOCS) diff --git a/cmake/he_qat/HE_QATConfig.cmake.in b/cmake/he_qat/HE_QATConfig.cmake.in index b9d40e1..5267fd1 100644 --- a/cmake/he_qat/HE_QATConfig.cmake.in +++ b/cmake/he_qat/HE_QATConfig.cmake.in @@ -10,7 +10,6 @@ include(${CMAKE_CURRENT_LIST_DIR}/he_qatTargets.cmake) if(TARGET HE_QAT::he_qat) set(HE_QAT_FOUND TRUE) message(STATUS "Intel Homomorphic Encryption Acceleration Library for QAT found") - add_definitions(-DUSER_SPACE) else() message(STATUS "Intel Homomorphic Encryption Acceleraiton Library for QAT not found") endif() diff --git a/cmake/qatconfig.cmake b/cmake/qatconfig.cmake index 0ccad6a..398d1d9 100644 --- a/cmake/qatconfig.cmake +++ b/cmake/qatconfig.cmake @@ -24,10 +24,6 @@ set(ICP_INC_DIR ${ICP_API_DIR}/include ${ICP_API_DIR}/include/dc ${ICP_API_DIR}/include/lac) -add_definitions(-DDO_CRYPTO) -add_definitions(-DUSER_SPACE) -add_compile_options(-fPIC) - add_library(libadf_static STATIC IMPORTED GLOBAL) add_library(libosal_static STATIC IMPORTED GLOBAL) add_library(libqat_static STATIC IMPORTED GLOBAL) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a5feede..1c7f0e5 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 ############################################################################### -macro(heqat_create_executable sample_case language dependencies) +macro(heqat_create_executable test_case language dependencies) if(${language} STREQUAL "C" OR ${language} STREQUAL "c") set(extension "c") elseif(${language} STREQUAL "CXX" OR ${language} STREQUAL "cxx") @@ -11,8 +11,8 @@ macro(heqat_create_executable sample_case language dependencies) message(FATAL_ERROR "Error language not supported. Options: C or CXX.") endif() - set(target sample_${sample_case}) - add_executable(${target} test_${sample_case}.${extension}) + set(target test_${test_case}) + add_executable(${target} test_${test_case}.${extension}) target_include_directories(${target} PUBLIC ${HE_QAT_INC_DIR}) From 68c5af5db7a67941c0819e25cbcc99970b2f1bbd Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Fri, 28 Oct 2022 13:06:29 -0700 Subject: [PATCH 318/364] Removed depracated compile-definitions (#142) --- cmake/ipcl/ipcl-util.cmake | 6 +----- ipcl/CMakeLists.txt | 4 ++-- module/heqat | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/cmake/ipcl/ipcl-util.cmake b/cmake/ipcl/ipcl-util.cmake index 96646b3..ba42b22 100644 --- a/cmake/ipcl/ipcl-util.cmake +++ b/cmake/ipcl/ipcl-util.cmake @@ -101,16 +101,12 @@ endfunction() function(ipcl_define_icp_variables OutVariable) set(ICP_ROOT $ENV{ICP_ROOT}) set(ICP_BUILDOUTPUT_PATH ${ICP_ROOT}/build) - set(ICP_BUILDSYSTEM_PATH ${ICP_ROOT}/quickassist/build_system) set(ICP_API_DIR ${ICP_ROOT}/quickassist) set(ICP_LAC_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer) set(ICP_OSAL_DIR ${ICP_ROOT}/quickassist/utilities/oasl) set(ICP_ADF_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/qat_direct) set(CMN_ROOT ${ICP_ROOT}/quickassist/utilities/libusdm_drv) - set(CPA_SAMPLES_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/sample_code/functional) - - add_definitions(-DUSER_SPACE) set(${OutVariable} ${ICP_API_DIR}/include ${ICP_LAC_DIR}/include @@ -118,5 +114,5 @@ function(ipcl_define_icp_variables OutVariable) ${CMN_ROOT} ${ICP_API_DIR}/include/dc ${ICP_API_DIR}/include/lac - ${CPA_SAMPLES_DIR}/include PARENT_SCOPE) + PARENT_SCOPE) endfunction() diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 27b1614..70adefd 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -55,7 +55,7 @@ install(DIRECTORY ${IPPCRYPTO_INC_DIR}/ # include and install definition of cpu_features if(IPCL_DETECT_IFMA_RUNTIME) target_include_directories(ipcl - PUBLIC $ + PUBLIC $ PRIVATE $ ) install(DIRECTORY ${CPUFEATURES_INC_DIR}/ @@ -69,7 +69,7 @@ endif() if(IPCL_ENABLE_QAT) ipcl_define_icp_variables(icp_inc_dir) target_include_directories(ipcl - PUBLIC "$" + PRIVATE "$" ) target_include_directories(ipcl PRIVATE "$" diff --git a/module/heqat b/module/heqat index 99a9201..6d180a2 160000 --- a/module/heqat +++ b/module/heqat @@ -1 +1 @@ -Subproject commit 99a920182f01f41e2d9d89f5f0b1c91da324bf07 +Subproject commit 6d180a2ddcfeb17cc8dddf2546a0f0e5ee6f07fd From d94bcc3e097a51bbff3435808d27530628d7629a Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 28 Oct 2022 12:57:47 -0700 Subject: [PATCH 319/364] Update submodule. Signed-off-by: Souza, Fillipe --- module/heqat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/heqat b/module/heqat index 6d180a2..99a9201 160000 --- a/module/heqat +++ b/module/heqat @@ -1 +1 @@ -Subproject commit 6d180a2ddcfeb17cc8dddf2546a0f0e5ee6f07fd +Subproject commit 99a920182f01f41e2d9d89f5f0b1c91da324bf07 From c86dedc47bf6c4fa2711776b09bc32505929f1a0 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Fri, 28 Oct 2022 13:47:17 -0700 Subject: [PATCH 320/364] Update submodule --- module/heqat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/heqat b/module/heqat index 99a9201..6d180a2 160000 --- a/module/heqat +++ b/module/heqat @@ -1 +1 @@ -Subproject commit 99a920182f01f41e2d9d89f5f0b1c91da324bf07 +Subproject commit 6d180a2ddcfeb17cc8dddf2546a0f0e5ee6f07fd From 418008dc1a64279cbb2ca31b0c136dd892197a3e Mon Sep 17 00:00:00 2001 From: sejunkim Date: Fri, 28 Oct 2022 13:48:11 -0700 Subject: [PATCH 321/364] Removed HE_QAT_SAMPLES flag in heqat.cmake and replaced with HE_QAT_TEST=OFF --- module/heqat.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/heqat.cmake b/module/heqat.cmake index 08e3472..d4a68cb 100644 --- a/module/heqat.cmake +++ b/module/heqat.cmake @@ -23,7 +23,7 @@ ExternalProject_Add( -DHE_QAT_MISC=OFF -DHE_QAT_DOCS=${IPCL_DOCS} -DHE_QAT_SHARED=${IPCL_SHARED} - -DHE_QAT_SAMPLES=OFF + -DHE_QAT_TEST=OFF -DCMAKE_BUILD_TYPE=${HEQAT_BUILD_TYPE} UPDATE_COMMAND "" EXCLUDE_FROM_ALL TRUE From 5d1906bb9bb8fb0b3e2b26307d8aca28e2484828 Mon Sep 17 00:00:00 2001 From: Fillipe Souza Date: Fri, 28 Oct 2022 15:25:44 -0700 Subject: [PATCH 322/364] Clean-up and bug fix. (#41) * Update Contributors. Signed-off-by: Souza, Fillipe * Fix handing behavior with multithread interface. Signed-off-by: Souza, Fillipe * Some clean up. Signed-off-by: Souza, Fillipe Signed-off-by: Souza, Fillipe --- README.md | 9 +- cmake/qatconfig.cmake | 4 + heqat/bnops.c | 53 ++------- heqat/cb.c | 2 +- heqat/context.c | 23 ++-- heqat/ctrl.c | 262 ++++++++++++++++++------------------------ scripts/run.sh | 2 +- 7 files changed, 141 insertions(+), 214 deletions(-) diff --git a/README.md b/README.md index fda4847..3b202d9 100644 --- a/README.md +++ b/README.md @@ -314,7 +314,10 @@ TODO # Contributors -Fillipe Dias M. de Souza (Lead) -Sejun Kim -Pengfei Zhao +Main contributors to this project, sorted by alphabetical order of last name are: + - [Fillipe Dias M. de Souza](https://www.linkedin.com/in/fillipe-d-m-de-souza-a8281820) (lead) + - [Xiaoran Fang](https://github.com/fangxiaoran) + - [Jingyi Jin](https://www.linkedin.com/in/jingyi-jin-655735) + - [Sejun Kim](https://www.linkedin.com/in/sejun-kim-2b1b4866) + - [Pengfei Zhao](https://github.com/justalittlenoob) diff --git a/cmake/qatconfig.cmake b/cmake/qatconfig.cmake index 398d1d9..bf9dee3 100644 --- a/cmake/qatconfig.cmake +++ b/cmake/qatconfig.cmake @@ -24,6 +24,10 @@ set(ICP_INC_DIR ${ICP_API_DIR}/include ${ICP_API_DIR}/include/dc ${ICP_API_DIR}/include/lac) +#add_definitions(-DDO_CRYPTO) +add_definitions(-DUSER_SPACE) +add_compile_options(-fPIC) + add_library(libadf_static STATIC IMPORTED GLOBAL) add_library(libosal_static STATIC IMPORTED GLOBAL) add_library(libqat_static STATIC IMPORTED GLOBAL) diff --git a/heqat/bnops.c b/heqat/bnops.c index c0a45b8..396a500 100644 --- a/heqat/bnops.c +++ b/heqat/bnops.c @@ -2,10 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 /// @file heqat/bnops.c -#include "cpa.h" -#include "cpa_cy_im.h" -#include "cpa_cy_ln.h" -#include "icp_sal_poll.h" +#include +#include +#include +#include #include "heqat/bnops.h" #include "heqat/common/consts.h" @@ -52,7 +52,7 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, static unsigned long long req_count = 0; // Unpack data and copy to QAT friendly memory space - int len = (nbits + 7) >> 3; // nbits / 8; + int len = (nbits + 7) >> 3; if (NULL == r) return HE_QAT_STATUS_INVALID_PARAM; if (NULL == b) return HE_QAT_STATUS_INVALID_PARAM; @@ -63,10 +63,6 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, Cpa8U* pModulus = NULL; Cpa8U* pExponent = NULL; - // TODO(fdiasmor): Try it with 8-byte alignment. - //CpaStatus status = CPA_STATUS_FAIL; - // status = PHYS_CONTIG_ALLOC(&pBase, len); - //status = PHYS_CONTIG_ALLOC_ALIGNED(&pBase, len, 8); HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; status = HE_QAT_MEM_ALLOC_CONTIG(&pBase, len, BYTE_ALIGNMENT_8); if (HE_QAT_STATUS_SUCCESS == status && NULL != pBase) { @@ -76,8 +72,6 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, return HE_QAT_STATUS_FAIL; } - // status = PHYS_CONTIG_ALLOC(&pExponent, len); - //status = PHYS_CONTIG_ALLOC_ALIGNED(&pExponent, len, 8); status = HE_QAT_MEM_ALLOC_CONTIG(&pExponent, len, BYTE_ALIGNMENT_8); if (HE_QAT_STATUS_SUCCESS == status && NULL != pExponent) { memcpy(pExponent, e, len); @@ -86,8 +80,6 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, return HE_QAT_STATUS_FAIL; } - // status = PHYS_CONTIG_ALLOC(&pModulus, len); - //status = PHYS_CONTIG_ALLOC_ALIGNED(&pModulus, len, 8); status = HE_QAT_MEM_ALLOC_CONTIG(&pModulus, len, BYTE_ALIGNMENT_8); if (HE_QAT_STATUS_SUCCESS == status && NULL != pModulus) { memcpy(pModulus, m, len); @@ -120,8 +112,6 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, op_data->modulus.dataLenInBytes = len; request->op_data = (void*)op_data; - // status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); - //status = PHYS_CONTIG_ALLOC_ALIGNED(&request->op_result.pData, len, 8); status = HE_QAT_MEM_ALLOC_CONTIG(&request->op_result.pData, len, BYTE_ALIGNMENT_8); if (HE_QAT_STATUS_SUCCESS == status && NULL != request->op_result.pData) { request->op_result.dataLenInBytes = len; @@ -170,16 +160,11 @@ HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, in return HE_QAT_STATUS_FAIL; } - // TODO: @fdiasmor Try it with 8-byte alignment. - //CpaStatus status = CPA_STATUS_FAIL; HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; - //status = PHYS_CONTIG_ALLOC(&pBase, len); - //status = PHYS_CONTIG_ALLOC(&pBase, len); status = HE_QAT_MEM_ALLOC_CONTIG(&pBase, len, BYTE_ALIGNMENT_8); if (HE_QAT_STATUS_SUCCESS == status && NULL != pBase) { if (!BN_bn2binpad(b, pBase, len)) { HE_QAT_PRINT_ERR("BN_bn2binpad (base) failed in bnModExpPerformOp.\n"); - //PHYS_CONTIG_FREE(pBase); HE_QAT_MEM_FREE_CONTIG(pBase); return HE_QAT_STATUS_FAIL; } @@ -188,12 +173,10 @@ HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, in return HE_QAT_STATUS_FAIL; } - //status = PHYS_CONTIG_ALLOC(&pExponent, len); status = HE_QAT_MEM_ALLOC_CONTIG(&pExponent, len, BYTE_ALIGNMENT_8); if (HE_QAT_STATUS_SUCCESS == status && NULL != pExponent) { if (!BN_bn2binpad(e, pExponent, len)) { HE_QAT_PRINT_ERR("BN_bn2binpad (exponent) failed in bnModExpPerformOp.\n"); - //PHYS_CONTIG_FREE(pExponent); HE_QAT_MEM_FREE_CONTIG(pExponent); return HE_QAT_STATUS_FAIL; } @@ -202,12 +185,10 @@ HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, in return HE_QAT_STATUS_FAIL; } - //status = PHYS_CONTIG_ALLOC(&pModulus, len); status = HE_QAT_MEM_ALLOC_CONTIG(&pModulus, len, BYTE_ALIGNMENT_8); if (HE_QAT_STATUS_SUCCESS == status && NULL != pModulus) { if (!BN_bn2binpad(m, pModulus, len)) { HE_QAT_PRINT_ERR("BN_bn2binpad failed in bnModExpPerformOp.\n"); - //PHYS_CONTIG_FREE(pModulus); HE_QAT_MEM_FREE_CONTIG(pModulus); return HE_QAT_STATUS_FAIL; } @@ -231,7 +212,6 @@ HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, in op_data->modulus.dataLenInBytes = len; request->op_data = (void*)op_data; - //status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); status = HE_QAT_MEM_ALLOC_CONTIG(&request->op_result.pData, len, BYTE_ALIGNMENT_8); if (HE_QAT_STATUS_SUCCESS == status && NULL != request->op_result.pData) { request->op_result.dataLenInBytes = len; @@ -248,6 +228,7 @@ HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, in request->op_output = (void*)r; request->id = req_count++; + // Ensure calls are synchronized at exit (blocking) pthread_mutex_init(&request->mutex, NULL); pthread_cond_init(&request->ready, NULL); @@ -267,7 +248,6 @@ void getBnModExpRequest(unsigned int batch_size) { double time_taken = 0.0; gettimeofday(&start_time, NULL); #endif -// while (j < batch_size) { do { // Buffer read may be safe for single-threaded blocking calls only. // Note: Not tested on multithreaded environment. @@ -307,20 +287,17 @@ void getBnModExpRequest(unsigned int batch_size) { // Move forward to wait for the next request that will be offloaded pthread_mutex_unlock(&task->mutex); - // Fix segmentation fault? free(he_qat_buffer.data[block_at_index]); he_qat_buffer.data[block_at_index] = NULL; block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; -// j++; -// } - } while (++j < batch_size); // number of null pointers equal batch size ? + } while (++j < batch_size); #ifdef HE_QAT_PERF gettimeofday(&end_time, NULL); time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; time_taken = - (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; + (time_taken + (end_time.tv_usec - start_time.tv_usec)); HE_QAT_PRINT("Batch Wall Time: %.1lfus\n", time_taken); #endif @@ -350,10 +327,6 @@ HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, Cpa8U* pModulus = NULL; Cpa8U* pExponent = NULL; - // TODO(fdiasmor): Try it with 8-byte alignment. - //CpaStatus status = CPA_STATUS_FAIL; - // status = PHYS_CONTIG_ALLOC(&pBase, len); - //status = PHYS_CONTIG_ALLOC_ALIGNED(&pBase, len, 8); HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; status = HE_QAT_MEM_ALLOC_CONTIG(&pBase, len, BYTE_ALIGNMENT_8); if (HE_QAT_STATUS_SUCCESS == status && NULL != pBase) { @@ -363,8 +336,6 @@ HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, return HE_QAT_STATUS_FAIL; } - // status = PHYS_CONTIG_ALLOC(&pExponent, len); - // status = PHYS_CONTIG_ALLOC_ALIGNED(&pExponent, len, 8); status = HE_QAT_MEM_ALLOC_CONTIG(&pExponent, len, BYTE_ALIGNMENT_8); if (HE_QAT_STATUS_SUCCESS == status && NULL != pExponent) { memcpy(pExponent, e, len); @@ -373,8 +344,6 @@ HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, return HE_QAT_STATUS_FAIL; } - // status = PHYS_CONTIG_ALLOC(&pModulus, len); - //status = PHYS_CONTIG_ALLOC_ALIGNED(&pModulus, len, 8); status = HE_QAT_MEM_ALLOC_CONTIG(&pModulus, len, BYTE_ALIGNMENT_8); if (HE_QAT_STATUS_SUCCESS == status && NULL != pModulus) { memcpy(pModulus, m, len); @@ -383,8 +352,6 @@ HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, return HE_QAT_STATUS_FAIL; } - // HE_QAT_TaskRequest request = - // HE_QAT_PACK_MODEXP_REQUEST(pBase, pExponent, pModulus, r) // Pack it as a QAT Task Request HE_QAT_TaskRequest* request = (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); @@ -409,8 +376,6 @@ HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, op_data->modulus.dataLenInBytes = len; request->op_data = (void*)op_data; - // status = PHYS_CONTIG_ALLOC(&request->op_result.pData, len); - //status = PHYS_CONTIG_ALLOC_ALIGNED(&request->op_result.pData, len, 8); status = HE_QAT_MEM_ALLOC_CONTIG(&request->op_result.pData, len, BYTE_ALIGNMENT_8); if (HE_QAT_STATUS_SUCCESS == status && NULL != request->op_result.pData) { request->op_result.dataLenInBytes = len; @@ -532,7 +497,7 @@ void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size) // outstanding.buffer[_buffer_id].count--; - free(outstanding.buffer[_buffer_id].data[next_data_out]); + free(outstanding.buffer[_buffer_id].data[next_data_out]); outstanding.buffer[_buffer_id].data[next_data_out] = NULL; // Update for next thread on the next external iteration diff --git a/heqat/cb.c b/heqat/cb.c index 9dfab79..9ec2ee8 100644 --- a/heqat/cb.c +++ b/heqat/cb.c @@ -1,6 +1,6 @@ -/// @file heqat/cb.c // Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 +/// @file heqat/cb.c // QAT-API headers #include diff --git a/heqat/context.c b/heqat/context.c index d6d354b..f38f44e 100644 --- a/heqat/context.c +++ b/heqat/context.c @@ -1,6 +1,6 @@ -/// @file heqat/context.c // Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 +/// @file heqat/context.c #define _GNU_SOURCE @@ -98,7 +98,7 @@ static CpaInstanceHandle get_qat_instance() { HE_QAT_PRINT("\tbusAddress: %d\n",info.physInstId.busAddress); HE_QAT_PRINT("\tkptAcHandle: %d\n",info.physInstId.kptAcHandle); #endif - } + } HE_QAT_PRINT_DBG("Next Instance: %d.\n", nextInstance); if (status == CPA_STATUS_SUCCESS) @@ -116,9 +116,8 @@ static CpaInstanceHandle get_qat_instance() { } nextInstance = ((nextInstance + 1) % numInstances); -#ifdef HE_QAT_DEBUG - printf("Next Instance: %d.\n", nextInstance); -#endif + HE_QAT_PRINT_DBG("Next Instance: %d.\n", nextInstance); + return cyInstHandles[nextInstance]; } @@ -140,24 +139,20 @@ HE_QAT_STATUS acquire_qat_devices() { if (CPA_STATUS_SUCCESS != status) { pthread_mutex_unlock(&context_lock); HE_QAT_PRINT_ERR("Failed to initialized memory driver.\n"); - return HE_QAT_STATUS_FAIL; // HEQAT_STATUS_ERROR + return HE_QAT_STATUS_FAIL; } HE_QAT_PRINT_DBG("QAT memory successfully initialized.\n"); - // Not sure if for multiple instances the id will need to be specified, e.g. - // "SSL1" status = icp_sal_userStartMultiProcess("SSL", CPA_FALSE); if (CPA_STATUS_SUCCESS != status) { pthread_mutex_unlock(&context_lock); HE_QAT_PRINT_ERR("Failed to start SAL user process SSL\n"); qaeMemDestroy(); - return HE_QAT_STATUS_FAIL; // HE_QAT_STATUS_FAIL + return HE_QAT_STATUS_FAIL; } HE_QAT_PRINT_DBG("SAL user process successfully started.\n"); - // Potential out-of-scope hazard for segmentation fault - CpaInstanceHandle _inst_handle[HE_QAT_NUM_ACTIVE_INSTANCES]; // = NULL; - // TODO: @fdiasmor Create a CyGetInstance that retrieves more than one. + CpaInstanceHandle _inst_handle[HE_QAT_NUM_ACTIVE_INSTANCES]; for (unsigned int i = 0; i < HE_QAT_NUM_ACTIVE_INSTANCES; i++) { _inst_handle[i] = get_qat_instance(); if (_inst_handle[i] == NULL) { @@ -228,7 +223,6 @@ HE_QAT_STATUS acquire_qat_devices() { he_qat_config->running = 0; he_qat_config->active = 0; - // Work on this pthread_create(&he_qat_runner, NULL, start_instances, (void*)he_qat_config); HE_QAT_PRINT_DBG("Created processing threads.\n"); @@ -277,8 +271,7 @@ HE_QAT_STATUS release_qat_devices() { stop_instances(he_qat_config); HE_QAT_PRINT_DBG("Stopped polling and processing threads.\n"); - // Deactivate context (this will cause the buffer manager thread to be - // terminated) + // Deactivate context (this will terminate buffer manager thread context_state = HE_QAT_STATUS_INACTIVE; // Stop QAT SSL service diff --git a/heqat/ctrl.c b/heqat/ctrl.c index 223c92f..7c62aa1 100644 --- a/heqat/ctrl.c +++ b/heqat/ctrl.c @@ -1,12 +1,12 @@ -/// @file heqat/ctrl.c // Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 +/// @file heqat/ctrl.c // QAT-API headers -#include "cpa.h" -#include "cpa_cy_im.h" -#include "cpa_cy_ln.h" -#include "icp_sal_poll.h" +#include +#include +#include +#include // Global variables used to hold measured performance numbers. #ifdef HE_QAT_PERF @@ -25,7 +25,6 @@ double time_taken = 0.0; #include "heqat/common/utils.h" #include "heqat/common/consts.h" #include "heqat/common/types.h" -//#include "heqat/bnops.h" // Warn user on selected execution mode #ifdef HE_QAT_SYNC_MODE @@ -51,14 +50,12 @@ static unsigned long max_pending = (2 * NUM_PKE_SLICES * HE_QAT_NUM_ACTIVE_INSTA /// @param[out] _buffer Either `he_qat_buffer` or `outstanding` buffer. /// @param[in] args Work request packaged in a custom data structure. void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { -#ifdef HE_QAT_DEBUG - printf("Lock write request\n"); -#endif + HE_QAT_PRINT_DBG("Lock write request\n"); + pthread_mutex_lock(&_buffer->mutex); -#ifdef HE_QAT_DEBUG - printf("Wait lock write request. [buffer size: %d]\n", _buffer->count); -#endif + HE_QAT_PRINT_DBG("Wait lock write request. [buffer size: %d]\n", _buffer->count); + while (_buffer->count >= HE_QAT_BUFFER_SIZE) pthread_cond_wait(&_buffer->any_free_slot, &_buffer->mutex); @@ -72,9 +69,7 @@ void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { pthread_cond_signal(&_buffer->any_more_data); pthread_mutex_unlock(&_buffer->mutex); -#ifdef HE_QAT_DEBUG - printf("Unlocked write request. [buffer size: %d]\n", _buffer->count); -#endif + HE_QAT_PRINT_DBG("Unlocked write request. [buffer size: %d]\n", _buffer->count); } /// @brief Populates internal buffer with a list of work request. @@ -83,19 +78,16 @@ void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { /// @param[in] _requests list of requests retrieved from the buffer (`outstanding`) holding outstanding requests. static void submit_request_list(HE_QAT_RequestBuffer* _buffer, HE_QAT_TaskRequestList* _requests) { -#ifdef HE_QAT_DEBUG - printf("Lock submit request list\n"); -#endif + HE_QAT_PRINT_DBG("Lock submit request list\n"); + if (0 == _requests->count) return; pthread_mutex_lock(&_buffer->mutex); -#ifdef HE_QAT_DEBUG - printf( + HE_QAT_PRINT_DBG( "Wait lock submit request list. [internal buffer size: %d] [num " "requests: %u]\n", _buffer->count, _requests->count); -#endif // Wait until buffer can accomodate the number of input requests while (_buffer->count >= HE_QAT_BUFFER_SIZE || @@ -103,7 +95,7 @@ static void submit_request_list(HE_QAT_RequestBuffer* _buffer, pthread_cond_wait(&_buffer->any_free_slot, &_buffer->mutex); assert(_buffer->count < HE_QAT_BUFFER_SIZE); - assert(_requests->count <= (HE_QAT_BUFFER_SIZE - _buffer->count)); + //assert(_requests->count <= (HE_QAT_BUFFER_SIZE - _buffer->count)); for (unsigned int i = 0; i < _requests->count; i++) { _buffer->data[_buffer->next_free_slot++] = _requests->request[i]; @@ -115,10 +107,9 @@ static void submit_request_list(HE_QAT_RequestBuffer* _buffer, pthread_cond_signal(&_buffer->any_more_data); pthread_mutex_unlock(&_buffer->mutex); -#ifdef HE_QAT_DEBUG - printf("Unlocked submit request list. [internal buffer size: %d]\n", + + HE_QAT_PRINT_DBG("Unlocked submit request list. [internal buffer size: %d]\n", _buffer->count); -#endif } /// @brief Retrieve multiple requests from the outstanding buffer. @@ -141,17 +132,14 @@ static void read_request_list(HE_QAT_TaskRequestList* _requests, pthread_cond_wait(&_buffer->any_more_data, &_buffer->mutex); assert(_buffer->count > 0); - // assert(_buffer->count <= HE_QAT_BUFFER_SIZE); + assert(_buffer->count <= HE_QAT_BUFFER_SIZE); unsigned int count = (_buffer->count < max_requests) ? _buffer->count : max_requests; - //for (unsigned int i = 0; i < _buffer->count; i++) { for (unsigned int i = 0; i < count; i++) { _requests->request[i] = _buffer->data[_buffer->next_data_slot++]; _buffer->next_data_slot %= HE_QAT_BUFFER_SIZE; } - //_requests->count = _buffer->count; - //_buffer->count = 0; _requests->count = count; _buffer->count -= count; @@ -173,8 +161,8 @@ static void pull_outstanding_requests(HE_QAT_TaskRequestList* _requests, HE_QAT_ if (NULL == _requests) return; _requests->count = 0; - // for now, only one thread can change next_ready_buffer - // so no need for sync tools + // For now, only one thread can change next_ready_buffer + // so no need for synchronization objects // Select an outstanding buffer to pull requests and add them into the // processing queue (internal buffer) @@ -254,7 +242,7 @@ static void pull_outstanding_requests(HE_QAT_TaskRequestList* _requests, HE_QAT_ /// disactive (val=0) the scheduler. void* schedule_requests(void* context_state) { if (NULL == context_state) { - printf("Failed at buffer_manager: argument is NULL.\n"); + HE_QAT_PRINT_DBG("Failed at buffer_manager: argument is NULL.\n"); pthread_exit(NULL); } @@ -266,7 +254,7 @@ void* schedule_requests(void* context_state) { } outstanding_requests.count = 0; - // this thread should receive signal from context to exit + // This thread should receive signal from context to exit *active = HE_QAT_STATUS_RUNNING; while (HE_QAT_STATUS_INACTIVE != *active) { // Collect a set of requests from the outstanding buffer @@ -284,7 +272,7 @@ void* schedule_requests(void* context_state) { /// values to start and poll responses from the accelerator. static void* start_inst_polling(void* _inst_config) { if (NULL == _inst_config) { - printf( + HE_QAT_PRINT_ERR( "Failed at start_inst_polling: argument is NULL.\n"); //,__FUNC__); pthread_exit(NULL); } @@ -293,9 +281,7 @@ static void* start_inst_polling(void* _inst_config) { if (NULL == config->inst_handle) return NULL; -#ifdef HE_QAT_DEBUG - printf("Instance ID %d Polling\n",config->inst_id); -#endif + HE_QAT_PRINT_DBG("Instance ID %d Polling\n",config->inst_id); // What is harmful for polling without performing any operation? config->polling = 1; @@ -333,22 +319,23 @@ void* start_instances(void* _config) { static unsigned int next_instance = 0; if (NULL == _config) { - printf("Failed in start_instances: _config is NULL.\n"); + HE_QAT_PRINT_ERR("Failed in start_instances: _config is NULL.\n"); pthread_exit(NULL); } HE_QAT_Config* config = (HE_QAT_Config*)_config; instance_count = config->count; - printf("Instance Count: %d\n",instance_count); + HE_QAT_PRINT_DBG("Instance Count: %d\n",instance_count); pthread_t* polling_thread = (pthread_t *) malloc(sizeof(pthread_t)*instance_count); if (NULL == polling_thread) { - printf("Failed in start_instances: polling_thread is NULL.\n"); + HE_QAT_PRINT_ERR("Failed in start_instances: polling_thread is NULL.\n"); pthread_exit(NULL); } + unsigned* request_count_per_instance = (unsigned *) malloc(sizeof(unsigned)*instance_count); if (NULL == request_count_per_instance) { - printf("Failed in start_instances: polling_thread is NULL.\n"); + HE_QAT_PRINT_ERR("Failed in start_instances: polling_thread is NULL.\n"); pthread_exit(NULL); } for (unsigned i = 0; i < instance_count; i++) { @@ -356,7 +343,6 @@ void* start_instances(void* _config) { } CpaStatus status = CPA_STATUS_FAIL; - for (unsigned int j = 0; j < config->count; j++) { // Start from zero or restart after stop_perform_op pthread_mutex_lock(&config->inst_config[j].mutex); @@ -370,7 +356,7 @@ void* start_instances(void* _config) { status = cpaCyStartInstance(config->inst_config[j].inst_handle); config->inst_config[j].status = status; if (CPA_STATUS_SUCCESS == status) { - printf("Cpa CyInstance has successfully started.\n"); + HE_QAT_PRINT_DBG("Cpa CyInstance has successfully started.\n"); status = cpaCySetAddressTranslation(config->inst_config[j].inst_handle, HE_QAT_virtToPhys); @@ -381,18 +367,17 @@ void* start_instances(void* _config) { if (CPA_STATUS_SUCCESS != status) pthread_exit(NULL); - printf("Instance ID: %d\n",config->inst_config[j].inst_id); + HE_QAT_PRINT_DBG("Instance ID: %d\n",config->inst_config[j].inst_id); // Start QAT instance and start polling - //pthread_t polling_thread; if (pthread_create(&polling_thread[j], config->inst_config[j].attr, start_inst_polling, (void*)&(config->inst_config[j])) != 0) { - printf("Failed at creating and starting polling thread.\n"); + HE_QAT_PRINT_ERR("Failed at creating and starting polling thread.\n"); pthread_exit(NULL); } if (pthread_detach(polling_thread[j]) != 0) { - printf("Failed at detaching polling thread.\n"); + HE_QAT_PRINT_ERR("Failed at detaching polling thread.\n"); pthread_exit(NULL); } @@ -410,41 +395,35 @@ void* start_instances(void* _config) { config->running = 1; config->active = 1; while (config->running) { -#ifdef HE_QAT_DEBUG - printf("Try reading request from buffer. Inst #%d\n", next_instance); -#endif + HE_QAT_PRINT_DBG("Try reading request from buffer. Inst #%d\n", next_instance); + unsigned long pending = request_count - response_count; unsigned long available = max_pending - ((pending < max_pending)?pending:max_pending); -#ifdef HE_QAT_DEBUG - printf("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", + + HE_QAT_PRINT_DBG("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", request_count,response_count,pending,available); -#endif + while (available < restart_threshold) { - HE_QAT_PRINT_DBG("[WAIT]\n"); - - // argument passed in microseconds - //OS_SLEEP(RESTART_LATENCY_MICROSEC); - HE_QAT_SLEEP(RESTART_LATENCY_MICROSEC, HE_QAT_MICROSEC); - pending = request_count - response_count; - available = max_pending - ((pending < max_pending)?pending:max_pending); -#ifdef HE_QAT_DEBUG - printf("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", + HE_QAT_PRINT_DBG("[WAIT]\n"); + + // argument passed in microseconds + HE_QAT_SLEEP(RESTART_LATENCY_MICROSEC, HE_QAT_MICROSEC); + pending = request_count - response_count; + available = max_pending - ((pending < max_pending)?pending:max_pending); + HE_QAT_PRINT_DBG("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", request_count,response_count,pending,available); -#endif - } -#ifdef HE_QAT_DEBUG - printf("[SUBMIT] request_count: %lu response_count: %lu pending: %lu available: %lu\n", + } + HE_QAT_PRINT_DBG("[SUBMIT] request_count: %lu response_count: %lu pending: %lu available: %lu\n", request_count,response_count,pending,available); -#endif + unsigned int max_requests = available; // Try consume maximum amount of data from butter to perform requested operation read_request_list(&outstanding_requests, &he_qat_buffer, max_requests); -#ifdef HE_QAT_DEBUG - printf("Offloading %u requests to the accelerator.\n", outstanding_requests.count); -#endif - for (unsigned int i = 0; i < outstanding_requests.count; i++) { + HE_QAT_PRINT_DBG("Offloading %u requests to the accelerator.\n", outstanding_requests.count); + + for (unsigned int i = 0; i < outstanding_requests.count; i++) { HE_QAT_TaskRequest* request = outstanding_requests.request[i]; #ifdef HE_QAT_SYNC_MODE COMPLETION_INIT(&request->callback); @@ -456,9 +435,7 @@ void* start_instances(void* _config) { switch (request->op_type) { // Select appropriate action case HE_QAT_OP_MODEXP: -#ifdef HE_QAT_DEBUG - printf("Offload request using instance #%d\n", next_instance); -#endif + HE_QAT_PRINT_DBG("Offload request using instance #%d\n", next_instance); #ifdef HE_QAT_PERF gettimeofday(&request->start, NULL); #endif @@ -472,16 +449,14 @@ void* start_instances(void* _config) { break; case HE_QAT_OP_NONE: default: -#ifdef HE_QAT_DEBUG - printf("HE_QAT_OP_NONE to instance #%d\n", next_instance); -#endif + HE_QAT_PRINT_DBG("HE_QAT_OP_NONE to instance #%d\n", next_instance); retry = HE_QAT_MAX_RETRY; break; } if (CPA_STATUS_RETRY == status) { - printf("CPA requested RETRY\n"); - printf("RETRY count = %u\n",retry); + HE_QAT_PRINT_DBG("CPA requested RETRY\n"); + HE_QAT_PRINT_DBG("RETRY count = %u\n",retry); pthread_exit(NULL); // halt the whole system } @@ -497,14 +472,15 @@ void* start_instances(void* _config) { // Wake up any blocked call to stop_perform_op, signaling that now it is // safe to terminate running instances. Check if this detereorate // performance. - pthread_cond_signal(&config->inst_config[next_instance].ready); // Prone to the lost wake-up problem + // TODO(fdiasmor): Check if prone to the lost wake-up problem. + pthread_cond_signal(&config->inst_config[next_instance].ready); #ifdef HE_QAT_SYNC_MODE // Wait until the callback function has been called if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { request->op_status = CPA_STATUS_FAIL; request->request_status = HE_QAT_STATUS_FAIL; // Review it - printf("Failed in COMPLETION WAIT\n"); + HE_QAT_PRINT_ERR("Failed in COMPLETION WAIT\n"); } // Destroy synchronization object @@ -513,12 +489,10 @@ void* start_instances(void* _config) { } else { request->op_status = CPA_STATUS_FAIL; request->request_status = HE_QAT_STATUS_FAIL; // Review it - printf("Request Submission FAILED\n"); + HE_QAT_PRINT_ERR("Request Submission FAILED\n"); } -#ifdef HE_QAT_DEBUG - printf("Offloading completed by instance #%d\n", next_instance-1); -#endif + HE_QAT_PRINT_DBG("Offloading completed by instance #%d\n", next_instance-1); // Reset pointer outstanding_requests.request[i] = NULL; @@ -545,7 +519,7 @@ void* start_instances(void* _config) { /// instance. void* start_perform_op(void* _inst_config) { if (NULL == _inst_config) { - printf("Failed in start_perform_op: _inst_config is NULL.\n"); + HE_QAT_PRINT_ERR("Failed in start_perform_op: _inst_config is NULL.\n"); pthread_exit(NULL); } @@ -563,7 +537,7 @@ void* start_perform_op(void* _inst_config) { status = cpaCyStartInstance(config->inst_handle); config->status = status; if (CPA_STATUS_SUCCESS == status) { - printf("Cpa CyInstance has successfully started.\n"); + HE_QAT_PRINT_DBG("Cpa CyInstance has successfully started.\n"); status = cpaCySetAddressTranslation(config->inst_handle, HE_QAT_virtToPhys); } @@ -577,12 +551,12 @@ void* start_perform_op(void* _inst_config) { pthread_t polling_thread; if (pthread_create(&polling_thread, config->attr, start_inst_polling, (void*)config) != 0) { - printf("Failed at creating and starting polling thread.\n"); + HE_QAT_PRINT_ERR("Failed at creating and starting polling thread.\n"); pthread_exit(NULL); } if (pthread_detach(polling_thread) != 0) { - printf("Failed at detaching polling thread.\n"); + HE_QAT_PRINT_ERR("Failed at detaching polling thread.\n"); pthread_exit(NULL); } @@ -595,30 +569,27 @@ void* start_perform_op(void* _inst_config) { config->running = 1; config->active = 1; while (config->running) { -#ifdef HE_QAT_DEBUG - printf("Try reading request from buffer. Inst #%d\n", config->inst_id); -#endif + HE_QAT_PRINT_DBG("Try reading request from buffer. Inst #%d\n", config->inst_id); + unsigned long pending = request_count - response_count; unsigned long available = max_pending - ((pending < max_pending)?pending:max_pending); -#ifdef HE_QAT_DEBUG - printf("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", + + HE_QAT_PRINT_DBG("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", request_count,response_count,pending,available); -#endif + while (available < restart_threshold) { -#ifdef HE_QAT_DEBUG - printf("[WAIT]\n"); -#endif - // argument passed in microseconds - //OS_SLEEP(650); - HE_QAT_SLEEP(650,HE_QAT_MICROSEC); - pending = request_count - response_count; - available = max_pending - ((pending < max_pending)?pending:max_pending); + HE_QAT_PRINT_DBG("[WAIT]\n"); + + HE_QAT_SLEEP(650,HE_QAT_MICROSEC); + + pending = request_count - response_count; + available = max_pending - ((pending < max_pending)?pending:max_pending); } -#ifdef HE_QAT_DEBUG - printf("[SUBMIT] request_count: %lu response_count: %lu pending: %lu available: %lu\n", + HE_QAT_PRINT_DBG("[SUBMIT] request_count: %lu response_count: %lu pending: %lu available: %lu\n", request_count,response_count,pending,available); -#endif + unsigned int max_requests = available; + // Try consume maximum amount of data from butter to perform requested operation read_request_list(&outstanding_requests, &he_qat_buffer, max_requests); @@ -630,13 +601,12 @@ void* start_perform_op(void* _inst_config) { // pthread_cond_signal(&config->ready); // continue; // } -#ifdef HE_QAT_DEBUG - printf("Offloading %u requests to the accelerator.\n", outstanding_requests.count); -#endif - for (unsigned int i = 0; i < outstanding_requests.count; i++) { - HE_QAT_TaskRequest* request = outstanding_requests.request[i]; + HE_QAT_PRINT_DBG("Offloading %u requests to the accelerator.\n", outstanding_requests.count); + + for (unsigned int i = 0; i < outstanding_requests.count; i++) { + HE_QAT_TaskRequest* request = outstanding_requests.request[i]; #ifdef HE_QAT_SYNC_MODE - COMPLETION_INIT(&request->callback); + COMPLETION_INIT(&request->callback); #endif unsigned retry = 0; do { @@ -644,10 +614,8 @@ void* start_perform_op(void* _inst_config) { switch (request->op_type) { // Select appropriate action case HE_QAT_OP_MODEXP: - //if (retry > 0) printf("Try offloading again last request\n"); -#ifdef HE_QAT_DEBUG - printf("Offload request using instance #%d\n", config->inst_id); -#endif + //if (retry > 0) HE_QAT_PRINT_DBG("Try offloading again last request\n"); + HE_QAT_PRINT_DBG("Offload request using instance #%d\n", config->inst_id); #ifdef HE_QAT_PERF gettimeofday(&request->start, NULL); #endif @@ -661,18 +629,15 @@ void* start_perform_op(void* _inst_config) { break; case HE_QAT_OP_NONE: default: -#ifdef HE_QAT_DEBUG - printf("HE_QAT_OP_NONE to instance #%d\n", config->inst_id); -#endif + HE_QAT_PRINT_DBG("HE_QAT_OP_NONE to instance #%d\n", config->inst_id); retry = HE_QAT_MAX_RETRY; break; } if (CPA_STATUS_RETRY == status) { - printf("CPA requested RETRY\n"); - printf("RETRY count: %u\n",retry); - //OS_SLEEP(600); - HE_QAT_SLEEP(600, HE_QAT_MICROSEC); + HE_QAT_PRINT_DBG("CPA requested RETRY\n"); + HE_QAT_PRINT_DBG("RETRY count: %u\n",retry); + HE_QAT_SLEEP(600, HE_QAT_MICROSEC); } } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); @@ -681,13 +646,14 @@ void* start_perform_op(void* _inst_config) { if (CPA_STATUS_SUCCESS == status) { // Global tracking of number of requests request_count += 1; - //printf("retry_count = %d\n",retry_count); + + HE_QAT_PRINT_DBG("retry_count = %d\n",retry_count); #ifdef HE_QAT_SYNC_MODE // Wait until the callback function has been called if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { request->op_status = CPA_STATUS_FAIL; request->request_status = HE_QAT_STATUS_FAIL; // Review it - printf("Failed in COMPLETION WAIT\n"); + HE_QAT_PRINT_ERR("Failed in COMPLETION WAIT\n"); } // Destroy synchronization object @@ -708,11 +674,10 @@ void* start_perform_op(void* _inst_config) { // Wake up any blocked call to stop_perform_op, signaling that now it is // safe to terminate running instances. Check if this detereorate // performance. - pthread_cond_signal( - &config->ready); // Prone to the lost wake-up problem -#ifdef HE_QAT_DEBUG - printf("Offloading completed by instance #%d\n", config->inst_id); -#endif + // TODO(fdiasmor): Check if prone to the lost wake-up problem. + pthread_cond_signal(&config->ready); + + HE_QAT_PRINT_DBG("Offloading completed by instance #%d\n", config->inst_id); } pthread_exit(NULL); } @@ -734,36 +699,33 @@ void stop_perform_op(HE_QAT_InstConfig* config, unsigned num_inst) { CpaStatus status = CPA_STATUS_FAIL; for (unsigned i = 0; i < num_inst; i++) { pthread_mutex_lock(&config[i].mutex); -#ifdef HE_QAT_DEBUG - printf("Try teardown HE QAT instance #%d.\n", i); -#endif - while (0 == config[i].active) { + + HE_QAT_PRINT_DBG("Try teardown HE QAT instance #%d.\n", i); + + while (0 == config[i].active) { pthread_cond_wait(&config[i].ready, &config[i].mutex); } - if (CPA_STATUS_SUCCESS == config[i].status && config[i].active) { -#ifdef HE_QAT_DEBUG - printf("Stop polling and running threads #%d\n", i); -#endif - config[i].polling = 0; + + if (CPA_STATUS_SUCCESS == config[i].status && config[i].active) { + HE_QAT_PRINT_DBG("Stop polling and running threads #%d\n", i); + + config[i].polling = 0; config[i].running = 0; - //OS_SLEEP(10); - HE_QAT_SLEEP(10, HE_QAT_MICROSEC); -#ifdef HE_QAT_DEBUG - printf("Stop cpaCyInstance #%d\n", i); -#endif + + HE_QAT_SLEEP(10, HE_QAT_MICROSEC); + + HE_QAT_PRINT_DBG("Stop cpaCyInstance #%d\n", i); if (config[i].inst_handle == NULL) continue; -#ifdef HE_QAT_DEBUG - printf("cpaCyStopInstance\n"); -#endif - status = cpaCyStopInstance(config[i].inst_handle); + + HE_QAT_PRINT_DBG("cpaCyStopInstance\n"); + status = cpaCyStopInstance(config[i].inst_handle); if (CPA_STATUS_SUCCESS != status) { - printf("Failed to stop QAT instance #%d\n", i); + HE_QAT_PRINT_ERR("Failed to stop QAT instance #%d\n", i); } } pthread_cond_signal(&config[i].ready); pthread_mutex_unlock(&config[i].mutex); } - //} return; } diff --git a/scripts/run.sh b/scripts/run.sh index c10f780..88fad28 100755 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -8,7 +8,7 @@ export LD_LIBRARY_PATH=$HEQATLIB_INSTALL_DIR/lib:$ICP_ROOT/build:$LD_LIBRARY_PAT pushd $HEQATLIB_INSTALL_DIR/bin -for app in $(ls sample_*) +for app in $(ls test_*) do echo "*****************************************************************" echo "* [START] RUNNING TEST SAMPLE $app *" From 74481ca0c628b3344804db71bfb73560f654f02a Mon Sep 17 00:00:00 2001 From: Fillipe Souza Date: Fri, 28 Oct 2022 15:35:32 -0700 Subject: [PATCH 323/364] Code clang-formatting. (#42) Signed-off-by: Souza, Fillipe Signed-off-by: Souza, Fillipe --- heqat/bnops.c | 77 +-- heqat/cb.c | 57 ++- heqat/common/utils.c | 12 +- heqat/context.c | 87 ++-- heqat/ctrl.c | 711 ++++++++++++++++------------ heqat/include/heqat/bnops.h | 156 +++--- heqat/include/heqat/common.h | 1 - heqat/include/heqat/common/consts.h | 3 +- heqat/include/heqat/common/types.h | 148 ++++-- heqat/include/heqat/common/utils.h | 92 ++-- heqat/include/heqat/heqat.h | 5 +- heqat/include/heqat/misc.h | 4 +- heqat/misc/bignum.cpp | 1 - heqat/misc/misc.cpp | 1 - 14 files changed, 753 insertions(+), 602 deletions(-) diff --git a/heqat/bnops.c b/heqat/bnops.c index 396a500..43b6673 100644 --- a/heqat/bnops.c +++ b/heqat/bnops.c @@ -33,15 +33,17 @@ extern HE_QAT_RequestBuffer he_qat_buffer; extern HE_QAT_OutstandingBuffer outstanding; // Callback functions -extern void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut); -extern void HE_QAT_bnModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut); +extern void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, + void* pOpData, CpaFlatBuffer* pOut); +extern void HE_QAT_bnModExpCallback(void* pCallbackTag, CpaStatus status, + void* pOpData, CpaFlatBuffer* pOut); /// @brief Thread-safe producer implementation for the shared request buffer. -/// @details Fill internal or outstanding buffer with incoming work requests. +/// @details Fill internal or outstanding buffer with incoming work requests. /// This function is implemented in he_qat_ctrl.c. extern void submit_request(HE_QAT_RequestBuffer* _buffer, void* args); -/* +/* * ************************************************************************** * Implementation of Functions for the Single Interface Support * ************************************************************************** @@ -50,7 +52,7 @@ extern void submit_request(HE_QAT_RequestBuffer* _buffer, void* args); HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, unsigned char* e, unsigned char* m, int nbits) { static unsigned long long req_count = 0; - + // Unpack data and copy to QAT friendly memory space int len = (nbits + 7) >> 3; @@ -65,7 +67,7 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; status = HE_QAT_MEM_ALLOC_CONTIG(&pBase, len, BYTE_ALIGNMENT_8); - if (HE_QAT_STATUS_SUCCESS == status && NULL != pBase) { + if (HE_QAT_STATUS_SUCCESS == status && NULL != pBase) { memcpy(pBase, b, len); } else { HE_QAT_PRINT_ERR("Contiguous memory allocation failed for pBase.\n"); @@ -101,7 +103,8 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)calloc(1, sizeof(CpaCyLnModExpOpData)); if (NULL == op_data) { - HE_QAT_PRINT_ERR("Cpa memory allocation failed in bnModExpPerformOp.\n"); + HE_QAT_PRINT_ERR( + "Cpa memory allocation failed in bnModExpPerformOp.\n"); return HE_QAT_STATUS_FAIL; } op_data->base.pData = pBase; @@ -112,7 +115,8 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, op_data->modulus.dataLenInBytes = len; request->op_data = (void*)op_data; - status = HE_QAT_MEM_ALLOC_CONTIG(&request->op_result.pData, len, BYTE_ALIGNMENT_8); + status = HE_QAT_MEM_ALLOC_CONTIG(&request->op_result.pData, len, + BYTE_ALIGNMENT_8); if (HE_QAT_STATUS_SUCCESS == status && NULL != request->op_result.pData) { request->op_result.dataLenInBytes = len; } else { @@ -126,9 +130,9 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, request->callback_func = (void*)HE_QAT_bnModExpCallback; request->op_status = status; request->op_output = (void*)r; - + request->id = req_count++; - + // Ensure calls are synchronized at exit (blocking) pthread_mutex_init(&request->mutex, NULL); pthread_cond_init(&request->ready, NULL); @@ -141,11 +145,12 @@ HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, return HE_QAT_STATUS_SUCCESS; } -HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int nbits) { +HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, + int nbits) { static unsigned long long req_count = 0; - + // Unpack data and copy to QAT friendly memory space - int len = (nbits + 7) >> 3; + int len = (nbits + 7) >> 3; Cpa8U* pBase = NULL; Cpa8U* pModulus = NULL; @@ -164,7 +169,8 @@ HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, in status = HE_QAT_MEM_ALLOC_CONTIG(&pBase, len, BYTE_ALIGNMENT_8); if (HE_QAT_STATUS_SUCCESS == status && NULL != pBase) { if (!BN_bn2binpad(b, pBase, len)) { - HE_QAT_PRINT_ERR("BN_bn2binpad (base) failed in bnModExpPerformOp.\n"); + HE_QAT_PRINT_ERR( + "BN_bn2binpad (base) failed in bnModExpPerformOp.\n"); HE_QAT_MEM_FREE_CONTIG(pBase); return HE_QAT_STATUS_FAIL; } @@ -176,7 +182,8 @@ HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, in status = HE_QAT_MEM_ALLOC_CONTIG(&pExponent, len, BYTE_ALIGNMENT_8); if (HE_QAT_STATUS_SUCCESS == status && NULL != pExponent) { if (!BN_bn2binpad(e, pExponent, len)) { - HE_QAT_PRINT_ERR("BN_bn2binpad (exponent) failed in bnModExpPerformOp.\n"); + HE_QAT_PRINT_ERR( + "BN_bn2binpad (exponent) failed in bnModExpPerformOp.\n"); HE_QAT_MEM_FREE_CONTIG(pExponent); return HE_QAT_STATUS_FAIL; } @@ -212,7 +219,8 @@ HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, in op_data->modulus.dataLenInBytes = len; request->op_data = (void*)op_data; - status = HE_QAT_MEM_ALLOC_CONTIG(&request->op_result.pData, len, BYTE_ALIGNMENT_8); + status = HE_QAT_MEM_ALLOC_CONTIG(&request->op_result.pData, len, + BYTE_ALIGNMENT_8); if (HE_QAT_STATUS_SUCCESS == status && NULL != request->op_result.pData) { request->op_result.dataLenInBytes = len; } else { @@ -226,9 +234,9 @@ HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, in request->callback_func = (void*)HE_QAT_BIGNUMModExpCallback; request->op_status = status; request->op_output = (void*)r; - + request->id = req_count++; - + // Ensure calls are synchronized at exit (blocking) pthread_mutex_init(&request->mutex, NULL); pthread_cond_init(&request->ready, NULL); @@ -254,8 +262,7 @@ void getBnModExpRequest(unsigned int batch_size) { HE_QAT_TaskRequest* task = (HE_QAT_TaskRequest*)he_qat_buffer.data[block_at_index]; - if (NULL == task) - continue; + if (NULL == task) continue; // Block and synchronize: Wait for the most recently offloaded request // to complete processing @@ -291,20 +298,19 @@ void getBnModExpRequest(unsigned int batch_size) { he_qat_buffer.data[block_at_index] = NULL; block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; - } while (++j < batch_size); + } while (++j < batch_size); #ifdef HE_QAT_PERF gettimeofday(&end_time, NULL); time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; - time_taken = - (time_taken + (end_time.tv_usec - start_time.tv_usec)); + time_taken = (time_taken + (end_time.tv_usec - start_time.tv_usec)); HE_QAT_PRINT("Batch Wall Time: %.1lfus\n", time_taken); #endif return; } -/* +/* * ************************************************************************** * Implementation of Functions for the Multithreading Interface Support * ************************************************************************** @@ -314,7 +320,7 @@ HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, unsigned char* b, unsigned char* e, unsigned char* m, int nbits) { static unsigned long long req_count = 0; - + // Unpack data and copy to QAT friendly memory space int len = (nbits + 7) >> 3; @@ -376,7 +382,8 @@ HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, op_data->modulus.dataLenInBytes = len; request->op_data = (void*)op_data; - status = HE_QAT_MEM_ALLOC_CONTIG(&request->op_result.pData, len, BYTE_ALIGNMENT_8); + status = HE_QAT_MEM_ALLOC_CONTIG(&request->op_result.pData, len, + BYTE_ALIGNMENT_8); if (HE_QAT_STATUS_SUCCESS == status && NULL != request->op_result.pData) { request->op_result.dataLenInBytes = len; } else { @@ -407,7 +414,7 @@ HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id) { if (NULL == _buffer_id) return HE_QAT_STATUS_INVALID_PARAM; - + HE_QAT_PRINT_DBG("acquire_bnModExp_buffer #%u\n", _buffer_id); pthread_mutex_lock(&outstanding.mutex); @@ -442,10 +449,11 @@ HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id) { return HE_QAT_STATUS_SUCCESS; } -void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size) { +void release_bnModExp_buffer(unsigned int _buffer_id, + unsigned int _batch_size) { unsigned int next_data_out = outstanding.buffer[_buffer_id].next_data_out; unsigned int j = 0; - + HE_QAT_PRINT_DBG("release_bnModExp_buffer #%u\n", _buffer_id); #ifdef HE_QAT_PERF @@ -461,12 +469,13 @@ void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size) if (NULL == task) continue; - HE_QAT_PRINT_DBG("BatchSize %u Buffer #%u Request #%u Waiting\n", _batch_size, - _buffer_id, j); + HE_QAT_PRINT_DBG("BatchSize %u Buffer #%u Request #%u Waiting\n", + _batch_size, _buffer_id, j); // Block and synchronize: Wait for the most recently offloaded request - // to complete processing. Mutex only needed for the conditional variable. - pthread_mutex_lock(&task->mutex); + // to complete processing. Mutex only needed for the conditional + // variable. + pthread_mutex_lock(&task->mutex); while (HE_QAT_STATUS_READY != task->request_status) pthread_cond_wait(&task->ready, &task->mutex); @@ -497,7 +506,7 @@ void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size) // outstanding.buffer[_buffer_id].count--; - free(outstanding.buffer[_buffer_id].data[next_data_out]); + free(outstanding.buffer[_buffer_id].data[next_data_out]); outstanding.buffer[_buffer_id].data[next_data_out] = NULL; // Update for next thread on the next external iteration diff --git a/heqat/cb.c b/heqat/cb.c index 9ec2ee8..90c72a2 100644 --- a/heqat/cb.c +++ b/heqat/cb.c @@ -15,26 +15,33 @@ #include "heqat/common/utils.h" // Global variables -static pthread_mutex_t response_mutex; ///< It protects against race condition on response_count due to concurrent callback events. -extern volatile unsigned long response_count; ///< It counts the number of requests completed by the accelerator. +static pthread_mutex_t + response_mutex; ///< It protects against race condition on response_count + ///< due to concurrent callback events. +extern volatile unsigned long + response_count; ///< It counts the number of requests completed by the + ///< accelerator. -/// @brief Callback implementation for the API HE_QAT_BIGNUMModExp(...) -/// Callback function for the interface HE_QAT_BIGNUMModExp(). It performs +/// @brief Callback implementation for the API HE_QAT_BIGNUMModExp(...) +/// Callback function for the interface HE_QAT_BIGNUMModExp(). It performs /// any data post-processing required after the modular exponentiation. -/// @param[in] pCallbackTag work request package containing the original input data and other resources for post-processing. +/// @param[in] pCallbackTag work request package containing the original input +/// data and other resources for post-processing. /// @param[in] status CPA_STATUS of the performed operation, e.g. CyLnModExp(). -/// @param[in] pOpData original input data passed to accelerator to perform the target operation (cannot be NULL). -/// @param[out] pOut output returned by the accelerator after executing the target operation. -void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut) -{ +/// @param[in] pOpData original input data passed to accelerator to perform the +/// target operation (cannot be NULL). +/// @param[out] pOut output returned by the accelerator after executing the +/// target operation. +void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, + void* pOpData, CpaFlatBuffer* pOut) { HE_QAT_TaskRequest* request = NULL; // Check if input data for the op is available and do something if (NULL != pCallbackTag) { // Read request data request = (HE_QAT_TaskRequest*)pCallbackTag; - - pthread_mutex_lock(&response_mutex); + + pthread_mutex_lock(&response_mutex); // Global track of reponses by accelerator response_count += 1; pthread_mutex_unlock(&response_mutex); @@ -50,11 +57,10 @@ void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, void* pOp BIGNUM* r = BN_bin2bn(request->op_result.pData, request->op_result.dataLenInBytes, (BIGNUM*)request->op_output); - if (NULL == r) - request->request_status = HE_QAT_STATUS_FAIL; + if (NULL == r) request->request_status = HE_QAT_STATUS_FAIL; #ifdef HE_QAT_PERF gettimeofday(&request->end, NULL); -#endif +#endif } else { request->request_status = HE_QAT_STATUS_FAIL; } @@ -70,23 +76,26 @@ void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, void* pOp return; } -/// @brief Callback implementation for the API HE_QAT_bnModExp(...) -/// Callback function for the interface HE_QAT_bnModExp(). It performs +/// @brief Callback implementation for the API HE_QAT_bnModExp(...) +/// Callback function for the interface HE_QAT_bnModExp(). It performs /// any data post-processing required after the modular exponentiation. -/// @param[in] pCallbackTag work request package containing the original input data and other resources for post-processing. +/// @param[in] pCallbackTag work request package containing the original input +/// data and other resources for post-processing. /// @param[in] status CPA_STATUS of the performed operation, e.g. CyLnModExp(). -/// @param[in] pOpData original input data passed to accelerator to perform the target operation (cannot be NULL). -/// @param[out] pOut output returned by the accelerator after executing the target operation. -void HE_QAT_bnModExpCallback(void* pCallbackTag, CpaStatus status, void* pOpData, CpaFlatBuffer* pOut) -{ +/// @param[in] pOpData original input data passed to accelerator to perform the +/// target operation (cannot be NULL). +/// @param[out] pOut output returned by the accelerator after executing the +/// target operation. +void HE_QAT_bnModExpCallback(void* pCallbackTag, CpaStatus status, + void* pOpData, CpaFlatBuffer* pOut) { HE_QAT_TaskRequest* request = NULL; - + // Check if input data for the op is available and do something if (NULL != pCallbackTag) { // Read request data request = (HE_QAT_TaskRequest*)pCallbackTag; - - pthread_mutex_lock(&response_mutex); + + pthread_mutex_lock(&response_mutex); // Global track of reponses by accelerator response_count += 1; pthread_mutex_unlock(&response_mutex); diff --git a/heqat/common/utils.c b/heqat/common/utils.c index d7df63f..0eea595 100644 --- a/heqat/common/utils.c +++ b/heqat/common/utils.c @@ -17,7 +17,7 @@ BIGNUM* generateTestBNData(int nbits) { if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { BN_free(bn); HE_QAT_PRINT_ERR("Error while generating BN random number: %lu\n", - ERR_get_error()); + ERR_get_error()); return NULL; } @@ -37,8 +37,8 @@ unsigned char* paddingZeros(BIGNUM* bn, int nbits) { int len = bytes_left + num_bytes; if (!(bin = (unsigned char*)OPENSSL_zalloc(len))) return NULL; - HE_QAT_PRINT_DBG("Padding bn with %d bytes to total %d bytes\n", - bytes_left, len); + HE_QAT_PRINT_DBG("Padding bn with %d bytes to total %d bytes\n", bytes_left, + len); BN_bn2binpad(bn, bin, len); if (ERR_get_error()) { @@ -54,8 +54,7 @@ void showHexBN(BIGNUM* bn, int nbits) { unsigned char* bin = (unsigned char*)OPENSSL_zalloc(len); if (!bin) return; if (BN_bn2binpad(bn, bin, len)) { - for (size_t i = 0; i < len; i++) - HE_QAT_PRINT("%2.2x", bin[i]); + for (size_t i = 0; i < len; i++) HE_QAT_PRINT("%2.2x", bin[i]); HE_QAT_PRINT("\n"); } OPENSSL_free(bin); @@ -64,8 +63,7 @@ void showHexBN(BIGNUM* bn, int nbits) { void showHexBin(unsigned char* bin, int len) { if (!bin) return; - for (size_t i = 0; i < len; i++) - HE_QAT_PRINT("%2.2x", bin[i]); + for (size_t i = 0; i < len; i++) HE_QAT_PRINT("%2.2x", bin[i]); HE_QAT_PRINT("\n"); return; } diff --git a/heqat/context.c b/heqat/context.c index f38f44e..eb0cd9b 100644 --- a/heqat/context.c +++ b/heqat/context.c @@ -30,11 +30,11 @@ static volatile HE_QAT_STATUS context_state = HE_QAT_STATUS_INACTIVE; static pthread_mutex_t context_lock; // Global variable declarations -static pthread_t buffer_manager; -static pthread_t he_qat_runner; -static pthread_attr_t he_qat_inst_attr[HE_QAT_NUM_ACTIVE_INSTANCES]; +static pthread_t buffer_manager; +static pthread_t he_qat_runner; +static pthread_attr_t he_qat_inst_attr[HE_QAT_NUM_ACTIVE_INSTANCES]; static HE_QAT_InstConfig he_qat_inst_config[HE_QAT_NUM_ACTIVE_INSTANCES]; -static HE_QAT_Config* he_qat_config = NULL; +static HE_QAT_Config* he_qat_config = NULL; // External global variables extern HE_QAT_RequestBuffer he_qat_buffer; @@ -43,14 +43,17 @@ extern HE_QAT_OutstandingBuffer outstanding; /*********** Internal Services ***********/ // Start scheduler of work requests (consumer) extern void* schedule_requests(void* state); -// Activate cpaCyInstances to run on background and poll responses from QAT accelerator +// Activate cpaCyInstances to run on background and poll responses from QAT +// accelerator extern void* start_instances(void* _inst_config); -// Stop a running group of cpaCyInstances started with the "start_instances" service +// Stop a running group of cpaCyInstances started with the "start_instances" +// service extern void stop_instances(HE_QAT_Config* _config); -// Stop running individual QAT instances from a list of cpaCyInstances (called by "stop_instances") +// Stop running individual QAT instances from a list of cpaCyInstances (called +// by "stop_instances") extern void stop_perform_op(void* _inst_config, unsigned num_inst); -// Activate a cpaCyInstance to run on background and poll responses from QAT accelerator -// WARNING: Deprecated when "start_instances" becomes default. +// Activate a cpaCyInstance to run on background and poll responses from QAT +// accelerator WARNING: Deprecated when "start_instances" becomes default. extern void* start_perform_op(void* _inst_config); static Cpa16U numInstances = 0; @@ -74,29 +77,31 @@ static CpaInstanceHandle get_qat_instance() { HE_QAT_PRINT_ERR("No CyInstances Found (%d).\n", numInstances); return NULL; } - + HE_QAT_PRINT_DBG("Found %d CyInstances.\n", numInstances); if ((status == CPA_STATUS_SUCCESS) && (numInstances > 0)) { status = cpaCyGetInstances(numInstances, cyInstHandles); - + // List instances and their characteristics for (unsigned int i = 0; i < numInstances; i++) { - status = cpaCyInstanceGetInfo2(cyInstHandles[i],&info); - if (CPA_STATUS_SUCCESS != status) - return NULL; -#ifdef HE_QAT_DEBUG - HE_QAT_PRINT("Vendor Name: %s\n",info.vendorName); - HE_QAT_PRINT("Part Name: %s\n",info.partName); - HE_QAT_PRINT("Inst Name: %s\n",info.instName); - HE_QAT_PRINT("Inst ID: %s\n",info.instID); - HE_QAT_PRINT("Node Affinity: %u\n",info.nodeAffinity); + status = cpaCyInstanceGetInfo2(cyInstHandles[i], &info); + if (CPA_STATUS_SUCCESS != status) return NULL; +#ifdef HE_QAT_DEBUG + HE_QAT_PRINT("Vendor Name: %s\n", info.vendorName); + HE_QAT_PRINT("Part Name: %s\n", info.partName); + HE_QAT_PRINT("Inst Name: %s\n", info.instName); + HE_QAT_PRINT("Inst ID: %s\n", info.instID); + HE_QAT_PRINT("Node Affinity: %u\n", info.nodeAffinity); HE_QAT_PRINT("Physical Instance:\n"); - HE_QAT_PRINT("\tpackageId: %d\n",info.physInstId.packageId); - HE_QAT_PRINT("\tacceleratorId: %d\n",info.physInstId.acceleratorId); - HE_QAT_PRINT("\texecutionEngineId: %d\n",info.physInstId.executionEngineId); - HE_QAT_PRINT("\tbusAddress: %d\n",info.physInstId.busAddress); - HE_QAT_PRINT("\tkptAcHandle: %d\n",info.physInstId.kptAcHandle); + HE_QAT_PRINT("\tpackageId: %d\n", info.physInstId.packageId); + HE_QAT_PRINT("\tacceleratorId: %d\n", + info.physInstId.acceleratorId); + HE_QAT_PRINT("\texecutionEngineId: %d\n", + info.physInstId.executionEngineId); + HE_QAT_PRINT("\tbusAddress: %d\n", info.physInstId.busAddress); + HE_QAT_PRINT("\tkptAcHandle: %d\n", + info.physInstId.kptAcHandle); #endif } HE_QAT_PRINT_DBG("Next Instance: %d.\n", nextInstance); @@ -128,10 +133,11 @@ HE_QAT_STATUS acquire_qat_devices() { pthread_mutex_lock(&context_lock); - // Handle cases where acquire_qat_devices() is called when already active and running - if (HE_QAT_STATUS_ACTIVE == context_state) { - pthread_mutex_unlock(&context_lock); - return HE_QAT_STATUS_SUCCESS; + // Handle cases where acquire_qat_devices() is called when already active + // and running + if (HE_QAT_STATUS_ACTIVE == context_state) { + pthread_mutex_unlock(&context_lock); + return HE_QAT_STATUS_SUCCESS; } // Initialize QAT memory pool allocator @@ -139,7 +145,7 @@ HE_QAT_STATUS acquire_qat_devices() { if (CPA_STATUS_SUCCESS != status) { pthread_mutex_unlock(&context_lock); HE_QAT_PRINT_ERR("Failed to initialized memory driver.\n"); - return HE_QAT_STATUS_FAIL; + return HE_QAT_STATUS_FAIL; } HE_QAT_PRINT_DBG("QAT memory successfully initialized.\n"); @@ -148,7 +154,7 @@ HE_QAT_STATUS acquire_qat_devices() { pthread_mutex_unlock(&context_lock); HE_QAT_PRINT_ERR("Failed to start SAL user process SSL\n"); qaeMemDestroy(); - return HE_QAT_STATUS_FAIL; + return HE_QAT_STATUS_FAIL; } HE_QAT_PRINT_DBG("SAL user process successfully started.\n"); @@ -217,7 +223,7 @@ HE_QAT_STATUS acquire_qat_devices() { he_qat_inst_config[i].attr = &he_qat_inst_attr[i]; } - he_qat_config = (HE_QAT_Config *) malloc(sizeof(HE_QAT_Config)); + he_qat_config = (HE_QAT_Config*)malloc(sizeof(HE_QAT_Config)); he_qat_config->inst_config = he_qat_inst_config; he_qat_config->count = HE_QAT_NUM_ACTIVE_INSTANCES; he_qat_config->running = 0; @@ -252,7 +258,7 @@ HE_QAT_STATUS acquire_qat_devices() { "manager thread.\n"); return HE_QAT_STATUS_FAIL; } - + pthread_mutex_unlock(&context_lock); return HE_QAT_STATUS_SUCCESS; @@ -262,10 +268,10 @@ HE_QAT_STATUS acquire_qat_devices() { /// Release QAT instances and tear down QAT execution environment. HE_QAT_STATUS release_qat_devices() { pthread_mutex_lock(&context_lock); - + if (HE_QAT_STATUS_INACTIVE == context_state) { - pthread_mutex_unlock(&context_lock); - return HE_QAT_STATUS_SUCCESS; + pthread_mutex_unlock(&context_lock); + return HE_QAT_STATUS_SUCCESS; } stop_instances(he_qat_config); @@ -291,9 +297,6 @@ HE_QAT_STATUS release_qat_devices() { } /// @brief Retrieve and read context state. -/// @return Possible return values are HE_QAT_STATUS_ACTIVE, -/// HE_QAT_STATUS_RUNNING, and HE_QAT_STATUS_INACTIVE. -HE_QAT_STATUS get_qat_context_state() { - return context_state; -} - +/// @return Possible return values are HE_QAT_STATUS_ACTIVE, +/// HE_QAT_STATUS_RUNNING, and HE_QAT_STATUS_INACTIVE. +HE_QAT_STATUS get_qat_context_state() { return context_state; } diff --git a/heqat/ctrl.c b/heqat/ctrl.c index 7c62aa1..597df14 100644 --- a/heqat/ctrl.c +++ b/heqat/ctrl.c @@ -34,28 +34,45 @@ double time_taken = 0.0; #endif // Global buffer for the runtime environment -HE_QAT_RequestBuffer he_qat_buffer; ///< This the internal buffer that holds and serializes the requests to the accelerator. -HE_QAT_OutstandingBuffer outstanding; ///< This is the data structure that holds outstanding requests from separate active threads calling the API. -volatile unsigned long response_count = 0; ///< Counter of processed requests and it is used to help control throttling. -static volatile unsigned long request_count = 0; ///< Counter of received requests and it is used to help control throttling. -static unsigned long restart_threshold = NUM_PKE_SLICES * HE_QAT_NUM_ACTIVE_INSTANCES; ///< Number of concurrent requests allowed to be sent to accelerator at once. -static unsigned long max_pending = (2 * NUM_PKE_SLICES * HE_QAT_NUM_ACTIVE_INSTANCES); ///< Number of requests sent to the accelerator that are pending completion. +HE_QAT_RequestBuffer + he_qat_buffer; ///< This the internal buffer that holds and serializes the + ///< requests to the accelerator. +HE_QAT_OutstandingBuffer + outstanding; ///< This is the data structure that holds outstanding + ///< requests from separate active threads calling the API. +volatile unsigned long response_count = + 0; ///< Counter of processed requests and it is used to help control + ///< throttling. +static volatile unsigned long request_count = + 0; ///< Counter of received requests and it is used to help control + ///< throttling. +static unsigned long restart_threshold = + NUM_PKE_SLICES * + HE_QAT_NUM_ACTIVE_INSTANCES; ///< Number of concurrent requests allowed to + ///< be sent to accelerator at once. +static unsigned long max_pending = + (2 * NUM_PKE_SLICES * + HE_QAT_NUM_ACTIVE_INSTANCES); ///< Number of requests sent to the + ///< accelerator that are pending + ///< completion. /// @brief Populate internal buffer with incoming requests from API calls. -/// @details This function is called from the main APIs to submit requests to -/// a shared internal buffer for processing on QAT. It is a thread-safe implementation -/// of the producer for the either the internal buffer or the outstanding buffer to -/// host incoming requests. Depending on the buffer type, the submitted request -/// is either ready to be scheduled or to be processed by the accelerator. +/// @details This function is called from the main APIs to submit requests to +/// a shared internal buffer for processing on QAT. It is a thread-safe +/// implementation of the producer for the either the internal buffer or the +/// outstanding buffer to host incoming requests. Depending on the buffer type, +/// the submitted request is either ready to be scheduled or to be processed by +/// the accelerator. /// @param[out] _buffer Either `he_qat_buffer` or `outstanding` buffer. /// @param[in] args Work request packaged in a custom data structure. void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { HE_QAT_PRINT_DBG("Lock write request\n"); - + pthread_mutex_lock(&_buffer->mutex); - HE_QAT_PRINT_DBG("Wait lock write request. [buffer size: %d]\n", _buffer->count); - + HE_QAT_PRINT_DBG("Wait lock write request. [buffer size: %d]\n", + _buffer->count); + while (_buffer->count >= HE_QAT_BUFFER_SIZE) pthread_cond_wait(&_buffer->any_free_slot, &_buffer->mutex); @@ -69,17 +86,23 @@ void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { pthread_cond_signal(&_buffer->any_more_data); pthread_mutex_unlock(&_buffer->mutex); - HE_QAT_PRINT_DBG("Unlocked write request. [buffer size: %d]\n", _buffer->count); + HE_QAT_PRINT_DBG("Unlocked write request. [buffer size: %d]\n", + _buffer->count); } /// @brief Populates internal buffer with a list of work request. -/// @details This function is called by the request scheduler thread. It is a thread-safe implementation of the producer for the shared internal request buffer. This buffer stores and serializes the offloading of requests that are ready to be processed by the accelerator. -/// @param[out] _buffer reference pointer to the internal buffer `he_qat_buffer`. -/// @param[in] _requests list of requests retrieved from the buffer (`outstanding`) holding outstanding requests. +/// @details This function is called by the request scheduler thread. It is a +/// thread-safe implementation of the producer for the shared internal request +/// buffer. This buffer stores and serializes the offloading of requests that +/// are ready to be processed by the accelerator. +/// @param[out] _buffer reference pointer to the internal buffer +/// `he_qat_buffer`. +/// @param[in] _requests list of requests retrieved from the buffer +/// (`outstanding`) holding outstanding requests. static void submit_request_list(HE_QAT_RequestBuffer* _buffer, HE_QAT_TaskRequestList* _requests) { HE_QAT_PRINT_DBG("Lock submit request list\n"); - + if (0 == _requests->count) return; pthread_mutex_lock(&_buffer->mutex); @@ -95,7 +118,7 @@ static void submit_request_list(HE_QAT_RequestBuffer* _buffer, pthread_cond_wait(&_buffer->any_free_slot, &_buffer->mutex); assert(_buffer->count < HE_QAT_BUFFER_SIZE); - //assert(_requests->count <= (HE_QAT_BUFFER_SIZE - _buffer->count)); + // assert(_requests->count <= (HE_QAT_BUFFER_SIZE - _buffer->count)); for (unsigned int i = 0; i < _requests->count; i++) { _buffer->data[_buffer->next_free_slot++] = _requests->request[i]; @@ -107,22 +130,27 @@ static void submit_request_list(HE_QAT_RequestBuffer* _buffer, pthread_cond_signal(&_buffer->any_more_data); pthread_mutex_unlock(&_buffer->mutex); - - HE_QAT_PRINT_DBG("Unlocked submit request list. [internal buffer size: %d]\n", - _buffer->count); + + HE_QAT_PRINT_DBG( + "Unlocked submit request list. [internal buffer size: %d]\n", + _buffer->count); } /// @brief Retrieve multiple requests from the outstanding buffer. -/// @details Thread-safe consumer implementation for the outstanding request buffer. -/// Read requests from outstanding buffer (requests ready to be scheduled) to later pass -/// them to the internal buffer `he_qat_buffer`. As those requests move from the outstanding -/// buffer into the internal buffer, their state changes from ready-to-be-scheduled to -/// ready-to-be-processed. This function is supported both in single-threaded or multi-threaded mode. +/// @details Thread-safe consumer implementation for the outstanding request +/// buffer. Read requests from outstanding buffer (requests ready to be +/// scheduled) to later pass them to the internal buffer `he_qat_buffer`. As +/// those requests move from the outstanding buffer into the internal buffer, +/// their state changes from ready-to-be-scheduled to ready-to-be-processed. +/// This function is supported both in single-threaded or multi-threaded mode. /// @param[out] _requests list of requests retrieved from internal buffer. -/// @param[in] _buffer buffer of type HE_QAT_RequestBuffer, typically the internal buffer in current implementation. -/// @param[in] max_requests maximum number of requests to retrieve from internal buffer, if available. +/// @param[in] _buffer buffer of type HE_QAT_RequestBuffer, typically the +/// internal buffer in current implementation. +/// @param[in] max_requests maximum number of requests to retrieve from internal +/// buffer, if available. static void read_request_list(HE_QAT_TaskRequestList* _requests, - HE_QAT_RequestBuffer* _buffer, unsigned int max_requests) { + HE_QAT_RequestBuffer* _buffer, + unsigned int max_requests) { if (NULL == _requests) return; pthread_mutex_lock(&_buffer->mutex); @@ -134,7 +162,8 @@ static void read_request_list(HE_QAT_TaskRequestList* _requests, assert(_buffer->count > 0); assert(_buffer->count <= HE_QAT_BUFFER_SIZE); - unsigned int count = (_buffer->count < max_requests) ? _buffer->count : max_requests; + unsigned int count = + (_buffer->count < max_requests) ? _buffer->count : max_requests; for (unsigned int i = 0; i < count; i++) { _requests->request[i] = _buffer->data[_buffer->next_data_slot++]; @@ -150,14 +179,22 @@ static void read_request_list(HE_QAT_TaskRequestList* _requests, } /// @brief Read requests from the outstanding buffer. -/// @details Thread-safe consumer implementation for the outstanding request buffer. -/// Retrieve work requests from outstanding buffer (requests ready to be scheduled) to later on pass them to the internal buffer `he_qat_buffer`. As those requests move from the outstanding buffer into the internal buffer, their state changes from ready-to-be-scheduled to ready-to-be-processed. +/// @details Thread-safe consumer implementation for the outstanding request +/// buffer. Retrieve work requests from outstanding buffer (requests ready to be +/// scheduled) to later on pass them to the internal buffer `he_qat_buffer`. As +/// those requests move from the outstanding buffer into the internal buffer, +/// their state changes from ready-to-be-scheduled to ready-to-be-processed. /// This function is supported in single-threaded or multi-threaded mode. -/// @param[out] _requests list of work requests retrieved from outstanding buffer. -/// @param[in] _outstanding_buffer outstanding buffer holding requests in ready-to-be-scheduled state. -/// @param[in] max_num_requests maximum number of requests to retrieve from outstanding buffer if available. -static void pull_outstanding_requests(HE_QAT_TaskRequestList* _requests, HE_QAT_OutstandingBuffer* _outstanding_buffer, unsigned int max_num_requests) -{ +/// @param[out] _requests list of work requests retrieved from outstanding +/// buffer. +/// @param[in] _outstanding_buffer outstanding buffer holding requests in +/// ready-to-be-scheduled state. +/// @param[in] max_num_requests maximum number of requests to retrieve from +/// outstanding buffer if available. +static void pull_outstanding_requests( + HE_QAT_TaskRequestList* _requests, + HE_QAT_OutstandingBuffer* _outstanding_buffer, + unsigned int max_num_requests) { if (NULL == _requests) return; _requests->count = 0; @@ -190,10 +227,10 @@ static void pull_outstanding_requests(HE_QAT_TaskRequestList* _requests, HE_QAT_ if (!any_ready) return; // Extract outstanding requests from outstanding buffer - // (this is the only function that reads from outstanding buffer, + // (this is the only function that reads from outstanding buffer, // from a single thread) pthread_mutex_lock(&_outstanding_buffer->buffer[index].mutex); - + // This conditional waiting may not be required // Wait while buffer is empty while (_outstanding_buffer->buffer[index].count <= 0) { @@ -235,10 +272,13 @@ static void pull_outstanding_requests(HE_QAT_TaskRequestList* _requests, HE_QAT_ return; } -/// @brief Schedule outstanding requests to the internal buffer and be ready for processing. -/// @details Schedule outstanding requests from outstanding buffers to the internal buffer, -/// from which requests are ready to be submitted to the device for processing. -/// @param[in] context_state A volatile integer variable used to activate (val>0) or +/// @brief Schedule outstanding requests to the internal buffer and be ready for +/// processing. +/// @details Schedule outstanding requests from outstanding buffers to the +/// internal buffer, from which requests are ready to be submitted to the device +/// for processing. +/// @param[in] context_state A volatile integer variable used to activate +/// (val>0) or /// disactive (val=0) the scheduler. void* schedule_requests(void* context_state) { if (NULL == context_state) { @@ -268,8 +308,9 @@ void* schedule_requests(void* context_state) { } /// @brief Poll responses from a specific QAT instance. -/// @param[in] _inst_config Instance configuration containing the parameter -/// values to start and poll responses from the accelerator. +/// @param[in] _inst_config Instance configuration containing the parameter +/// values to start and poll responses from the +/// accelerator. static void* start_inst_polling(void* _inst_config) { if (NULL == _inst_config) { HE_QAT_PRINT_ERR( @@ -281,13 +322,13 @@ static void* start_inst_polling(void* _inst_config) { if (NULL == config->inst_handle) return NULL; - HE_QAT_PRINT_DBG("Instance ID %d Polling\n",config->inst_id); + HE_QAT_PRINT_DBG("Instance ID %d Polling\n", config->inst_id); // What is harmful for polling without performing any operation? config->polling = 1; while (config->polling) { icp_sal_CyPollInstance(config->inst_handle, 0); - //OS_SLEEP(50); + // OS_SLEEP(50); HE_QAT_SLEEP(50, HE_QAT_MICROSEC); } @@ -295,29 +336,37 @@ static void* start_inst_polling(void* _inst_config) { } /// @brief -/// Initialize and start multiple instances, their polling thread, +/// Initialize and start multiple instances, their polling thread, /// and a single processing thread. -/// +/// /// @details -/// It initializes multiple QAT instances and launches their respective independent -/// polling threads that will listen to responses to requests sent to the accelerators -/// concurrently. Then, it becomes the thread that collect the incoming requests stored -/// in a shared buffer and send them to the accelerator for processing. This is the only -/// processing thread for requests handled by multiple instances -- unlike when using -/// multiple instances with the `start_perform_op` function, in which case each instance -/// has a separate processing thread. The implementation of the multiple instance support -/// using `start_perform_op` is obsolete and slower. The way is using this function, which -/// delivers better performance. The scheduling of request offloads uses a -/// round-robin approach. It collects multiple requests from the internal buffer and then -/// send them to the multiple accelerator instances to process in a round-robin fashion. -/// It was designed to support processing requests of different operation types but -/// currently only supports Modular Exponentiation. +/// It initializes multiple QAT instances and launches their respective +/// independent +/// polling threads that will listen to responses to requests sent to the +/// accelerators concurrently. Then, it becomes the thread that collect +/// the incoming requests stored in a shared buffer and send them to the +/// accelerator +/// for processing. This is the only processing thread for requests handled +/// by multiple instances -- unlike when using +/// multiple instances with the `start_perform_op` function, in which case +/// each instance +/// has a separate processing thread. The implementation of the multiple +/// instance support using `start_perform_op` is obsolete and slower. The way +/// is +/// using this function, which delivers better performance. The scheduling of +/// request offloads uses a round-robin approach. It collects multiple +/// requests from the internal buffer and then send them to the multiple +/// accelerator instances to process in a round-robin fashion. It was designed +/// to support +/// processing requests of different operation types but currently only +/// supports Modular Exponentiation. /// -/// @param[in] _config Data structure containing the configuration of multiple instances. +/// @param[in] _config Data structure containing the configuration of multiple +/// instances. void* start_instances(void* _config) { static unsigned int instance_count = 0; static unsigned int next_instance = 0; - + if (NULL == _config) { HE_QAT_PRINT_ERR("Failed in start_instances: _config is NULL.\n"); pthread_exit(NULL); @@ -326,16 +375,20 @@ void* start_instances(void* _config) { HE_QAT_Config* config = (HE_QAT_Config*)_config; instance_count = config->count; - HE_QAT_PRINT_DBG("Instance Count: %d\n",instance_count); - pthread_t* polling_thread = (pthread_t *) malloc(sizeof(pthread_t)*instance_count); + HE_QAT_PRINT_DBG("Instance Count: %d\n", instance_count); + pthread_t* polling_thread = + (pthread_t*)malloc(sizeof(pthread_t) * instance_count); if (NULL == polling_thread) { - HE_QAT_PRINT_ERR("Failed in start_instances: polling_thread is NULL.\n"); + HE_QAT_PRINT_ERR( + "Failed in start_instances: polling_thread is NULL.\n"); pthread_exit(NULL); } - - unsigned* request_count_per_instance = (unsigned *) malloc(sizeof(unsigned)*instance_count); + + unsigned* request_count_per_instance = + (unsigned*)malloc(sizeof(unsigned) * instance_count); if (NULL == request_count_per_instance) { - HE_QAT_PRINT_ERR("Failed in start_instances: polling_thread is NULL.\n"); + HE_QAT_PRINT_ERR( + "Failed in start_instances: polling_thread is NULL.\n"); pthread_exit(NULL); } for (unsigned i = 0; i < instance_count; i++) { @@ -343,49 +396,50 @@ void* start_instances(void* _config) { } CpaStatus status = CPA_STATUS_FAIL; - for (unsigned int j = 0; j < config->count; j++) { + for (unsigned int j = 0; j < config->count; j++) { // Start from zero or restart after stop_perform_op pthread_mutex_lock(&config->inst_config[j].mutex); - while (config->inst_config[j].active) - pthread_cond_wait(&config->inst_config[j].ready, - &config->inst_config[j].mutex); - + while (config->inst_config[j].active) + pthread_cond_wait(&config->inst_config[j].ready, + &config->inst_config[j].mutex); + // assert(0 == config->active); // assert(NULL == config->inst_handle); - + status = cpaCyStartInstance(config->inst_config[j].inst_handle); config->inst_config[j].status = status; if (CPA_STATUS_SUCCESS == status) { HE_QAT_PRINT_DBG("Cpa CyInstance has successfully started.\n"); - status = - cpaCySetAddressTranslation(config->inst_config[j].inst_handle, - HE_QAT_virtToPhys); + status = cpaCySetAddressTranslation( + config->inst_config[j].inst_handle, HE_QAT_virtToPhys); } - + pthread_cond_signal(&config->inst_config[j].ready); pthread_mutex_unlock(&config->inst_config[j].mutex); - + if (CPA_STATUS_SUCCESS != status) pthread_exit(NULL); - HE_QAT_PRINT_DBG("Instance ID: %d\n",config->inst_config[j].inst_id); - - // Start QAT instance and start polling - if (pthread_create(&polling_thread[j], config->inst_config[j].attr, start_inst_polling, - (void*)&(config->inst_config[j])) != 0) { - HE_QAT_PRINT_ERR("Failed at creating and starting polling thread.\n"); - pthread_exit(NULL); - } - - if (pthread_detach(polling_thread[j]) != 0) { - HE_QAT_PRINT_ERR("Failed at detaching polling thread.\n"); - pthread_exit(NULL); - } - - config->inst_config[j].active = 1; - config->inst_config[j].running = 1; - - } // for loop - + HE_QAT_PRINT_DBG("Instance ID: %d\n", config->inst_config[j].inst_id); + + // Start QAT instance and start polling + if (pthread_create(&polling_thread[j], config->inst_config[j].attr, + start_inst_polling, + (void*)&(config->inst_config[j])) != 0) { + HE_QAT_PRINT_ERR( + "Failed at creating and starting polling thread.\n"); + pthread_exit(NULL); + } + + if (pthread_detach(polling_thread[j]) != 0) { + HE_QAT_PRINT_ERR("Failed at detaching polling thread.\n"); + pthread_exit(NULL); + } + + config->inst_config[j].active = 1; + config->inst_config[j].running = 1; + + } // for loop + HE_QAT_TaskRequestList outstanding_requests; for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { outstanding_requests.request[i] = NULL; @@ -395,110 +449,125 @@ void* start_instances(void* _config) { config->running = 1; config->active = 1; while (config->running) { - HE_QAT_PRINT_DBG("Try reading request from buffer. Inst #%d\n", next_instance); - - unsigned long pending = request_count - response_count; - unsigned long available = max_pending - ((pending < max_pending)?pending:max_pending); - - HE_QAT_PRINT_DBG("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", - request_count,response_count,pending,available); - - while (available < restart_threshold) { + HE_QAT_PRINT_DBG("Try reading request from buffer. Inst #%d\n", + next_instance); + + unsigned long pending = request_count - response_count; + unsigned long available = + max_pending - ((pending < max_pending) ? pending : max_pending); + + HE_QAT_PRINT_DBG( + "[CHECK] request_count: %lu response_count: %lu pending: %lu " + "available: %lu\n", + request_count, response_count, pending, available); + + while (available < restart_threshold) { HE_QAT_PRINT_DBG("[WAIT]\n"); - - // argument passed in microseconds + + // argument passed in microseconds HE_QAT_SLEEP(RESTART_LATENCY_MICROSEC, HE_QAT_MICROSEC); pending = request_count - response_count; - available = max_pending - ((pending < max_pending)?pending:max_pending); - HE_QAT_PRINT_DBG("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", - request_count,response_count,pending,available); - } - HE_QAT_PRINT_DBG("[SUBMIT] request_count: %lu response_count: %lu pending: %lu available: %lu\n", - request_count,response_count,pending,available); - - unsigned int max_requests = available; - - // Try consume maximum amount of data from butter to perform requested operation + available = + max_pending - ((pending < max_pending) ? pending : max_pending); + HE_QAT_PRINT_DBG( + "[CHECK] request_count: %lu response_count: %lu pending: %lu " + "available: %lu\n", + request_count, response_count, pending, available); + } + HE_QAT_PRINT_DBG( + "[SUBMIT] request_count: %lu response_count: %lu pending: %lu " + "available: %lu\n", + request_count, response_count, pending, available); + + unsigned int max_requests = available; + + // Try consume maximum amount of data from butter to perform requested + // operation read_request_list(&outstanding_requests, &he_qat_buffer, max_requests); - HE_QAT_PRINT_DBG("Offloading %u requests to the accelerator.\n", outstanding_requests.count); - - for (unsigned int i = 0; i < outstanding_requests.count; i++) { - HE_QAT_TaskRequest* request = outstanding_requests.request[i]; + HE_QAT_PRINT_DBG("Offloading %u requests to the accelerator.\n", + outstanding_requests.count); + + for (unsigned int i = 0; i < outstanding_requests.count; i++) { + HE_QAT_TaskRequest* request = outstanding_requests.request[i]; #ifdef HE_QAT_SYNC_MODE - COMPLETION_INIT(&request->callback); + COMPLETION_INIT(&request->callback); #endif - unsigned retry = 0; - do { - // Realize the type of operation from data - switch (request->op_type) { - // Select appropriate action - case HE_QAT_OP_MODEXP: - HE_QAT_PRINT_DBG("Offload request using instance #%d\n", next_instance); + unsigned retry = 0; + do { + // Realize the type of operation from data + switch (request->op_type) { + // Select appropriate action + case HE_QAT_OP_MODEXP: + HE_QAT_PRINT_DBG("Offload request using instance #%d\n", + next_instance); #ifdef HE_QAT_PERF - gettimeofday(&request->start, NULL); + gettimeofday(&request->start, NULL); #endif - status = cpaCyLnModExp( - config->inst_config[next_instance].inst_handle, - (CpaCyGenFlatBufCbFunc) - request->callback_func, // lnModExpCallback, - (void*)request, (CpaCyLnModExpOpData*)request->op_data, - &request->op_result); - retry++; - break; - case HE_QAT_OP_NONE: - default: - HE_QAT_PRINT_DBG("HE_QAT_OP_NONE to instance #%d\n", next_instance); - retry = HE_QAT_MAX_RETRY; - break; - } - - if (CPA_STATUS_RETRY == status) { - HE_QAT_PRINT_DBG("CPA requested RETRY\n"); - HE_QAT_PRINT_DBG("RETRY count = %u\n",retry); - pthread_exit(NULL); // halt the whole system - } - - } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); - - // Ensure every call to perform operation is blocking for each endpoint - if (CPA_STATUS_SUCCESS == status) { - // Global tracking of number of requests - request_count += 1; - request_count_per_instance[next_instance] += 1; - next_instance = (next_instance + 1) % instance_count; - - // Wake up any blocked call to stop_perform_op, signaling that now it is - // safe to terminate running instances. Check if this detereorate - // performance. - // TODO(fdiasmor): Check if prone to the lost wake-up problem. - pthread_cond_signal(&config->inst_config[next_instance].ready); + status = cpaCyLnModExp( + config->inst_config[next_instance].inst_handle, + (CpaCyGenFlatBufCbFunc) + request->callback_func, // lnModExpCallback, + (void*)request, (CpaCyLnModExpOpData*)request->op_data, + &request->op_result); + retry++; + break; + case HE_QAT_OP_NONE: + default: + HE_QAT_PRINT_DBG("HE_QAT_OP_NONE to instance #%d\n", + next_instance); + retry = HE_QAT_MAX_RETRY; + break; + } + + if (CPA_STATUS_RETRY == status) { + HE_QAT_PRINT_DBG("CPA requested RETRY\n"); + HE_QAT_PRINT_DBG("RETRY count = %u\n", retry); + pthread_exit(NULL); // halt the whole system + } + + } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); + + // Ensure every call to perform operation is blocking for each + // endpoint + if (CPA_STATUS_SUCCESS == status) { + // Global tracking of number of requests + request_count += 1; + request_count_per_instance[next_instance] += 1; + next_instance = (next_instance + 1) % instance_count; + + // Wake up any blocked call to stop_perform_op, signaling that + // now it is safe to terminate running instances. Check if this + // detereorate performance. + // TODO(fdiasmor): Check if prone to the lost wake-up problem. + pthread_cond_signal(&config->inst_config[next_instance].ready); #ifdef HE_QAT_SYNC_MODE - // Wait until the callback function has been called - if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { + // Wait until the callback function has been called + if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { + request->op_status = CPA_STATUS_FAIL; + request->request_status = HE_QAT_STATUS_FAIL; // Review it + HE_QAT_PRINT_ERR("Failed in COMPLETION WAIT\n"); + } + + // Destroy synchronization object + COMPLETION_DESTROY(&request->callback); +#endif + } else { request->op_status = CPA_STATUS_FAIL; request->request_status = HE_QAT_STATUS_FAIL; // Review it - HE_QAT_PRINT_ERR("Failed in COMPLETION WAIT\n"); + HE_QAT_PRINT_ERR("Request Submission FAILED\n"); } - // Destroy synchronization object - COMPLETION_DESTROY(&request->callback); -#endif - } else { - request->op_status = CPA_STATUS_FAIL; - request->request_status = HE_QAT_STATUS_FAIL; // Review it - HE_QAT_PRINT_ERR("Request Submission FAILED\n"); - } + HE_QAT_PRINT_DBG("Offloading completed by instance #%d\n", + next_instance - 1); - HE_QAT_PRINT_DBG("Offloading completed by instance #%d\n", next_instance-1); + // Reset pointer + outstanding_requests.request[i] = NULL; + request = NULL; - // Reset pointer - outstanding_requests.request[i] = NULL; - request = NULL; - - }// for loop over batch of requests + } // for loop over batch of requests outstanding_requests.count = 0; } pthread_exit(NULL); @@ -506,16 +575,18 @@ void* start_instances(void* _config) { /// @brief /// Start independent processing and polling threads for an instance. -/// +/// /// @details -/// It initializes a QAT instance and launches its polling thread to listen -/// to responses (request outputs) from the accelerator. It is also reponsible -/// to collect requests from the internal buffer and send them to the accelerator -/// periodiacally. It was designed to extend to receiving and offloading -/// requests of different operation types but currently only supports Modular -/// Exponentiation. +/// It initializes a QAT instance and launches its polling thread to listen +/// to responses (request outputs) from the accelerator. It is also +/// reponsible +/// to collect requests from the internal buffer and send them to the +/// accelerator periodiacally. It was designed to extend to receiving +/// and offloading requests of different operation types but currently only +/// supports Modular Exponentiation. /// -/// @param[in] _inst_config Data structure containing the configuration of a single +/// @param[in] _inst_config Data structure containing the configuration of a +/// single /// instance. void* start_perform_op(void* _inst_config) { if (NULL == _inst_config) { @@ -559,7 +630,7 @@ void* start_perform_op(void* _inst_config) { HE_QAT_PRINT_ERR("Failed at detaching polling thread.\n"); pthread_exit(NULL); } - + HE_QAT_TaskRequestList outstanding_requests; for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { outstanding_requests.request[i] = NULL; @@ -569,128 +640,143 @@ void* start_perform_op(void* _inst_config) { config->running = 1; config->active = 1; while (config->running) { - HE_QAT_PRINT_DBG("Try reading request from buffer. Inst #%d\n", config->inst_id); - - unsigned long pending = request_count - response_count; - unsigned long available = max_pending - ((pending < max_pending)?pending:max_pending); - - HE_QAT_PRINT_DBG("[CHECK] request_count: %lu response_count: %lu pending: %lu available: %lu\n", - request_count,response_count,pending,available); - - while (available < restart_threshold) { - HE_QAT_PRINT_DBG("[WAIT]\n"); - - HE_QAT_SLEEP(650,HE_QAT_MICROSEC); - - pending = request_count - response_count; - available = max_pending - ((pending < max_pending)?pending:max_pending); - } - HE_QAT_PRINT_DBG("[SUBMIT] request_count: %lu response_count: %lu pending: %lu available: %lu\n", - request_count,response_count,pending,available); - - unsigned int max_requests = available; - - // Try consume maximum amount of data from butter to perform requested operation + HE_QAT_PRINT_DBG("Try reading request from buffer. Inst #%d\n", + config->inst_id); + + unsigned long pending = request_count - response_count; + unsigned long available = + max_pending - ((pending < max_pending) ? pending : max_pending); + + HE_QAT_PRINT_DBG( + "[CHECK] request_count: %lu response_count: %lu pending: %lu " + "available: %lu\n", + request_count, response_count, pending, available); + + while (available < restart_threshold) { + HE_QAT_PRINT_DBG("[WAIT]\n"); + + HE_QAT_SLEEP(650, HE_QAT_MICROSEC); + + pending = request_count - response_count; + available = + max_pending - ((pending < max_pending) ? pending : max_pending); + } + HE_QAT_PRINT_DBG( + "[SUBMIT] request_count: %lu response_count: %lu pending: %lu " + "available: %lu\n", + request_count, response_count, pending, available); + + unsigned int max_requests = available; + + // Try consume maximum amount of data from butter to perform requested + // operation read_request_list(&outstanding_requests, &he_qat_buffer, max_requests); -// // Try consume data from butter to perform requested operation -// HE_QAT_TaskRequest* request = -// (HE_QAT_TaskRequest*)read_request(&he_qat_buffer); -// -// if (NULL == request) { -// pthread_cond_signal(&config->ready); -// continue; -// } - HE_QAT_PRINT_DBG("Offloading %u requests to the accelerator.\n", outstanding_requests.count); - - for (unsigned int i = 0; i < outstanding_requests.count; i++) { + // // Try consume data from butter to perform requested operation + // HE_QAT_TaskRequest* request = + // (HE_QAT_TaskRequest*)read_request(&he_qat_buffer); + // + // if (NULL == request) { + // pthread_cond_signal(&config->ready); + // continue; + // } + HE_QAT_PRINT_DBG("Offloading %u requests to the accelerator.\n", + outstanding_requests.count); + + for (unsigned int i = 0; i < outstanding_requests.count; i++) { HE_QAT_TaskRequest* request = outstanding_requests.request[i]; #ifdef HE_QAT_SYNC_MODE COMPLETION_INIT(&request->callback); #endif - unsigned retry = 0; - do { - // Realize the type of operation from data - switch (request->op_type) { - // Select appropriate action - case HE_QAT_OP_MODEXP: - //if (retry > 0) HE_QAT_PRINT_DBG("Try offloading again last request\n"); - HE_QAT_PRINT_DBG("Offload request using instance #%d\n", config->inst_id); + unsigned retry = 0; + do { + // Realize the type of operation from data + switch (request->op_type) { + // Select appropriate action + case HE_QAT_OP_MODEXP: + // if (retry > 0) HE_QAT_PRINT_DBG("Try offloading again + // last request\n"); + HE_QAT_PRINT_DBG("Offload request using instance #%d\n", + config->inst_id); #ifdef HE_QAT_PERF - gettimeofday(&request->start, NULL); + gettimeofday(&request->start, NULL); #endif - status = cpaCyLnModExp( - config->inst_handle, - (CpaCyGenFlatBufCbFunc) - request->callback_func, // lnModExpCallback, - (void*)request, (CpaCyLnModExpOpData*)request->op_data, - &request->op_result); - retry++; - break; - case HE_QAT_OP_NONE: - default: - HE_QAT_PRINT_DBG("HE_QAT_OP_NONE to instance #%d\n", config->inst_id); - retry = HE_QAT_MAX_RETRY; - break; - } - - if (CPA_STATUS_RETRY == status) { - HE_QAT_PRINT_DBG("CPA requested RETRY\n"); - HE_QAT_PRINT_DBG("RETRY count: %u\n",retry); - HE_QAT_SLEEP(600, HE_QAT_MICROSEC); - } - - } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); - - // Ensure every call to perform operation is blocking for each endpoint - if (CPA_STATUS_SUCCESS == status) { - // Global tracking of number of requests - request_count += 1; - - HE_QAT_PRINT_DBG("retry_count = %d\n",retry_count); + status = cpaCyLnModExp( + config->inst_handle, + (CpaCyGenFlatBufCbFunc) + request->callback_func, // lnModExpCallback, + (void*)request, (CpaCyLnModExpOpData*)request->op_data, + &request->op_result); + retry++; + break; + case HE_QAT_OP_NONE: + default: + HE_QAT_PRINT_DBG("HE_QAT_OP_NONE to instance #%d\n", + config->inst_id); + retry = HE_QAT_MAX_RETRY; + break; + } + + if (CPA_STATUS_RETRY == status) { + HE_QAT_PRINT_DBG("CPA requested RETRY\n"); + HE_QAT_PRINT_DBG("RETRY count: %u\n", retry); + HE_QAT_SLEEP(600, HE_QAT_MICROSEC); + } + + } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); + + // Ensure every call to perform operation is blocking for each + // endpoint + if (CPA_STATUS_SUCCESS == status) { + // Global tracking of number of requests + request_count += 1; + + HE_QAT_PRINT_DBG("retry_count = %d\n", retry_count); #ifdef HE_QAT_SYNC_MODE - // Wait until the callback function has been called - if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { + // Wait until the callback function has been called + if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { + request->op_status = CPA_STATUS_FAIL; + request->request_status = HE_QAT_STATUS_FAIL; // Review it + HE_QAT_PRINT_ERR("Failed in COMPLETION WAIT\n"); + } + + // Destroy synchronization object + COMPLETION_DESTROY(&request->callback); +#endif + } else { request->op_status = CPA_STATUS_FAIL; request->request_status = HE_QAT_STATUS_FAIL; // Review it - HE_QAT_PRINT_ERR("Failed in COMPLETION WAIT\n"); } - // Destroy synchronization object - COMPLETION_DESTROY(&request->callback); -#endif - } else { - request->op_status = CPA_STATUS_FAIL; - request->request_status = HE_QAT_STATUS_FAIL; // Review it - } - - // Reset pointer - outstanding_requests.request[i] = NULL; - request = NULL; + // Reset pointer + outstanding_requests.request[i] = NULL; + request = NULL; - }// for loop over batch of requests + } // for loop over batch of requests outstanding_requests.count = 0; - - // Wake up any blocked call to stop_perform_op, signaling that now it is + + // Wake up any blocked call to stop_perform_op, signaling that now it is // safe to terminate running instances. Check if this detereorate // performance. - // TODO(fdiasmor): Check if prone to the lost wake-up problem. - pthread_cond_signal(&config->ready); - - HE_QAT_PRINT_DBG("Offloading completed by instance #%d\n", config->inst_id); + // TODO(fdiasmor): Check if prone to the lost wake-up problem. + pthread_cond_signal(&config->ready); + + HE_QAT_PRINT_DBG("Offloading completed by instance #%d\n", + config->inst_id); } pthread_exit(NULL); } -/// @brief +/// @brief /// Stop specified number of instances from running. -/// +/// /// @details -/// Stop first 'num_inst' number of cpaCyInstance(s), including their polling -/// and running threads. Stop runnning and polling instances. +/// Stop first 'num_inst' number of cpaCyInstance(s), including their +/// polling and running threads. Stop runnning and polling instances. /// Release QAT instances handles. /// -/// @param[in] config List of all created QAT instances and their configurations. +/// @param[in] config List of all created QAT instances and their +/// configurations. /// @param[in] num_inst Unsigned integer number indicating first number of /// instances to be terminated. void stop_perform_op(HE_QAT_InstConfig* config, unsigned num_inst) { @@ -699,26 +785,26 @@ void stop_perform_op(HE_QAT_InstConfig* config, unsigned num_inst) { CpaStatus status = CPA_STATUS_FAIL; for (unsigned i = 0; i < num_inst; i++) { pthread_mutex_lock(&config[i].mutex); - - HE_QAT_PRINT_DBG("Try teardown HE QAT instance #%d.\n", i); - - while (0 == config[i].active) { + + HE_QAT_PRINT_DBG("Try teardown HE QAT instance #%d.\n", i); + + while (0 == config[i].active) { pthread_cond_wait(&config[i].ready, &config[i].mutex); } - - if (CPA_STATUS_SUCCESS == config[i].status && config[i].active) { + + if (CPA_STATUS_SUCCESS == config[i].status && config[i].active) { HE_QAT_PRINT_DBG("Stop polling and running threads #%d\n", i); - - config[i].polling = 0; + + config[i].polling = 0; config[i].running = 0; - - HE_QAT_SLEEP(10, HE_QAT_MICROSEC); - - HE_QAT_PRINT_DBG("Stop cpaCyInstance #%d\n", i); + + HE_QAT_SLEEP(10, HE_QAT_MICROSEC); + + HE_QAT_PRINT_DBG("Stop cpaCyInstance #%d\n", i); if (config[i].inst_handle == NULL) continue; - - HE_QAT_PRINT_DBG("cpaCyStopInstance\n"); - status = cpaCyStopInstance(config[i].inst_handle); + + HE_QAT_PRINT_DBG("cpaCyStopInstance\n"); + status = cpaCyStopInstance(config[i].inst_handle); if (CPA_STATUS_SUCCESS != status) { HE_QAT_PRINT_ERR("Failed to stop QAT instance #%d\n", i); } @@ -730,16 +816,15 @@ void stop_perform_op(HE_QAT_InstConfig* config, unsigned num_inst) { return; } -/// @brief Stop all running instances. +/// @brief Stop all running instances. /// @details /// Stop all running instances after calling `start_instances()`. -/// It will set the states of the instances to terminate gracefully. +/// It will set the states of the instances to terminate gracefully. /// @param[in] _config All QAT instances configurations holding their states. void stop_instances(HE_QAT_Config* _config) { if (NULL == _config) return; if (_config->active) _config->active = 0; if (_config->running) _config->running = 0; stop_perform_op(_config->inst_config, _config->count); - return ; + return; } - diff --git a/heqat/include/heqat/bnops.h b/heqat/include/heqat/bnops.h index 24a226a..c773370 100644 --- a/heqat/include/heqat/bnops.h +++ b/heqat/include/heqat/bnops.h @@ -1,32 +1,34 @@ // Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 /// @file heqat/bnops.h -/// -/// @details -/// In this file, functions for Big Number operations accelerated by the +/// +/// @details +/// In this file, functions for Big Number operations accelerated by the /// QuickAssist (QAT) co-processor are specified. -/// +/// /// @note -/// Unless otherwise specified, Big numbers are represented by octet strings -/// and stored in memory as pointers of type unsigned char*. On the QAT API the -/// octect string is copied into a data structure of type CpaFlatBuffer. The octet -/// strings representing Big Numbers are encoded with compliance to PKCA#1 v2.1, -/// section 4, which is consistent with ASN.1 syntax. -/// -/// The largest number supported here has 8192 bits, i.e. numbers from 0 to -/// 2^(8192)-1. If the number is N, then the bit length is defined by n = floor(log2(N))+1. -/// The memory buffer b to hold such number N needs to have at least M = ceiling(n/8) -/// bytes allocated. In general, it will be larger and a power of 2, e.g. total bytes -/// allocated is T=128 for numbers having up to n=1024 bits, total bytes allocated is -/// T=256 for numbers having up to n=2048 bits, and so forth. Finally, the big number N -/// is stored in `big endian` format, i.e. the least significant byte (LSB) is located -/// at index [T-1], whereas the most significant byte is stored at [T-M]. -/// -/// The API client is responsible for allocation and release of their memory spaces of -/// the function arguments. Allocated memory spaces must be contiguous. Once a function -/// is called, the ownership of the memory spaces is transfered to the function until -/// their completion such that concurrent usage by the client during excution may result -/// in undefined behavior. +/// Unless otherwise specified, Big numbers are represented by octet strings +/// and stored in memory as pointers of type unsigned char*. On the QAT API +/// the octect string is copied into a data structure of type CpaFlatBuffer. The +/// octet strings representing Big Numbers are encoded with compliance to PKCA#1 +/// v2.1, section 4, which is consistent with ASN.1 syntax. +/// +/// The largest number supported here has 8192 bits, i.e. numbers from 0 to +/// 2^(8192)-1. If the number is N, then the bit length is defined by n = +/// floor(log2(N))+1. The memory buffer b to hold such number N needs to +/// have at least M = ceiling(n/8) bytes allocated. In general, it will be +/// larger and a power of 2, e.g. total bytes allocated is T=128 for +/// numbers having up to n=1024 bits, total bytes allocated is T=256 for +/// numbers having up to n=2048 bits, and so forth. Finally, the big number +/// N is stored in `big endian` format, i.e. the least significant byte +/// (LSB) is located at index [T-1], whereas the most significant byte is +/// stored at [T-M]. +/// +/// The API client is responsible for allocation and release of their memory +/// spaces of the function arguments. Allocated memory spaces must be +/// contiguous. Once a function is called, the ownership of the memory spaces is +/// transfered to the function until their completion such that concurrent usage +/// by the client during excution may result in undefined behavior. // New compilers #pragma once @@ -44,29 +46,31 @@ extern "C" { #include /// @brief Performs modular exponentiation using BIGNUM data structure. -/// +/// /// @details -/// Perform big number modular exponentiation operation accelerated with QAT for input data -/// using OpenSSL BIGNUM data structure. Create QAT contiguous memory space. -/// Copy BIGNUM binary data and package it into a request (HE_QAT_Request data structure) and -/// call producer function to submit request to the internal buffer. +/// Perform big number modular exponentiation operation accelerated with QAT for +/// input data using OpenSSL BIGNUM data structure. Create QAT contiguous memory +/// space. Copy BIGNUM binary data and package it into a request (HE_QAT_Request +/// data structure) and call producer function to submit request to the internal +/// buffer. /// /// @param[out] r Remainder number of the modular exponentiation operation. /// @param[in] b Base number of the modular exponentiation operation. /// @param[in] e Exponent number of the modular exponentiation operation. /// @param[in] m Modulus number of the modular exponentiation operation. /// @param[in] nbits Number of bits (bit precision) of input/output big numbers. -HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, int nbits); +HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, + int nbits); -/// @brief Performs big number modular exponentiation for input data (an octet string) -/// in primitive type format (unsigned char *). -/// +/// @brief Performs big number modular exponentiation for input data (an octet +/// string) in primitive type format (unsigned char *). +/// /// @details -/// Perform big number modular exponentiation operation accelerated with QAT for -/// input data as an octet string of unsigned chars. Create QAT contiguous memory -/// space. Upon call it copies input data and package it into a request, then calls -/// producer function to submit request to internal buffer. -/// +/// Perform big number modular exponentiation operation accelerated with QAT for +/// input data as an octet string of unsigned chars. Create QAT contiguous +/// memory space. Upon call it copies input data and package it into a request, +/// then calls producer function to submit request to internal buffer. +/// /// @param[out] r Remainder number of the modular exponentiation operation. /// @param[in] b Base number of the modular exponentiation operation. /// @param[in] e Exponent number of the modular exponentiation operation. @@ -75,63 +79,71 @@ HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, in HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, unsigned char* e, unsigned char* m, int nbits); -/// @brief -/// It waits for number of requests sent by HE_QAT_bnModExp or HE_QAT_BIGNUMModExp -/// to complete. -/// +/// @brief +/// It waits for number of requests sent by HE_QAT_bnModExp or +/// HE_QAT_BIGNUMModExp to complete. +/// /// @details -/// This function is blocking and works as a barrier. The purpose of this function -/// is to wait for all outstanding requests to complete processing. It will also -/// release all temporary memory allocated used to support the submission and -/// processing of the requests. It monitors outstanding requests to be completed -/// and then it deallocates buffer holding outstanding request. +/// This function is blocking and works as a barrier. The purpose of this +/// function is to wait for all outstanding requests to complete processing. It +/// will also release all temporary memory allocated used to support the +/// submission and processing of the requests. It monitors outstanding requests +/// to be completed and then it deallocates buffer holding outstanding request. /// -/// @param[in] num_requests Number of requests to wait for processing completion. +/// @param[in] num_requests Number of requests to wait for processing +/// completion. void getBnModExpRequest(unsigned int num_requests); -/** +/** * - * Interfaces for the Multithreading Support + * Interfaces for the Multithreading Support * **/ -/// @brief Performs big number modular exponentiation for input data (an octet string) -/// in primitive type format (unsigned char *). Same as HE_QAT_bnModExp with -/// multithreading support. -/// +/// @brief Performs big number modular exponentiation for input data (an octet +/// string) in primitive type format (unsigned char *). Same as HE_QAT_bnModExp +/// with multithreading support. +/// /// @details -/// Perform big number modular exponentiation operation accelerated with QAT for -/// input data as an octet string of unsigned chars. Create QAT contiguous memory -/// space. Upon call it copies input data and package it into a request, then calls -/// producer function to submit request to internal buffer. -/// -/// @param[in] _buffer_id Buffer ID of the reserved buffer for the caller's thread. +/// Perform big number modular exponentiation operation accelerated with QAT for +/// input data as an octet string of unsigned chars. Create QAT contiguous +/// memory space. Upon call it copies input data and package it into a request, +/// then calls producer function to submit request to internal buffer. +/// +/// @param[in] _buffer_id Buffer ID of the reserved buffer for the caller's +/// thread. /// @param[out] r Remainder number of the modular exponentiation operation. /// @param[in] b Base number of the modular exponentiation operation. /// @param[in] e Exponent number of the modular exponentiation operation. /// @param[in] m Modulus number of the modular exponentiation operation. /// @param[in] nbits Number of bits (bit precision) of input/output big numbers. HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, - unsigned char* b, unsigned char* e, unsigned char* m, int nbits); + unsigned char* b, unsigned char* e, + unsigned char* m, int nbits); /// @brief Reserve/acquire buffer for multithreading support. /// -/// @details Try to acquire an available buffer to store outstanding work requests sent by caller. -/// If none is available, it blocks further processing and waits until another caller's concurrent -/// thread releases one. This function must be called before -/// calling HE_QAT_bnModExp_MT(.). +/// @details Try to acquire an available buffer to store outstanding work +/// requests sent by caller. +/// If none is available, it blocks further processing and waits until +/// another caller's concurrent thread releases one. This function must +/// be called before calling HE_QAT_bnModExp_MT(.). /// -/// @param[out] _buffer_id Memory space address allocated by caller to hold the buffer ID of the buffer used to store caller's outstanding requests. +/// @param[out] _buffer_id Memory space address allocated by caller to hold the +/// buffer ID of the buffer used to store caller's outstanding requests. HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id); -/// @brief Wait for request processing to complete and release previously acquired buffer. +/// @brief Wait for request processing to complete and release previously +/// acquired buffer. /// -/// @details Caution: It assumes acquire_bnModExp_buffer(&_buffer_id) to be called first -/// to secure and be assigned an outstanding buffer for the target thread. -/// Equivalent to getBnModExpRequests() for the multithreading support interfaces. +/// @details Caution: It assumes acquire_bnModExp_buffer(&_buffer_id) to be +/// called first to secure and be assigned an outstanding buffer for the target +/// thread. Equivalent to getBnModExpRequests() for the multithreading support +/// interfaces. /// -/// param[in] _buffer_id Buffer ID of the buffer to be released/unlock for reuse by the next concurrent thread. -/// param[in] _batch_size Total number of requests to wait for completion before releasing the buffer. +/// param[in] _buffer_id Buffer ID of the buffer to be released/unlock for reuse +/// by the next concurrent thread. param[in] _batch_size Total number of +/// requests to wait for completion before releasing the buffer. void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size); #ifdef __cplusplus diff --git a/heqat/include/heqat/common.h b/heqat/include/heqat/common.h index 05e80a1..cfbb717 100644 --- a/heqat/include/heqat/common.h +++ b/heqat/include/heqat/common.h @@ -11,4 +11,3 @@ #include "heqat/misc.h" #endif #endif - diff --git a/heqat/include/heqat/common/consts.h b/heqat/include/heqat/common/consts.h index 3082ee0..4b7c63d 100644 --- a/heqat/include/heqat/common/consts.h +++ b/heqat/include/heqat/common/consts.h @@ -15,5 +15,4 @@ #define RESTART_LATENCY_MICROSEC 600 #define NUM_PKE_SLICES 6 -#endif // _HE_QAT_CONST_H_ - +#endif // _HE_QAT_CONST_H_ diff --git a/heqat/include/heqat/common/types.h b/heqat/include/heqat/common/types.h index cadac27..aa9dab1 100644 --- a/heqat/include/heqat/common/types.h +++ b/heqat/include/heqat/common/types.h @@ -25,16 +25,12 @@ extern "C" { #include "heqat/common/consts.h" -struct completion_struct -{ +struct completion_struct { sem_t semaphore; }; // Type definitions -typedef enum { - HE_QAT_SYNC = 1, - HE_QAT_ASYNC = 2 -} HE_QAT_EXEC_MODE; +typedef enum { HE_QAT_SYNC = 1, HE_QAT_ASYNC = 2 } HE_QAT_EXEC_MODE; typedef enum { HE_QAT_STATUS_ACTIVE = 3, @@ -46,14 +42,14 @@ typedef enum { HE_QAT_STATUS_INACTIVE = -2 } HE_QAT_STATUS; -typedef enum { - HE_QAT_OP_NONE = 0, ///< No Operation (NO OP) - HE_QAT_OP_MODEXP = 1 ///< QAT Modular Exponentiation +typedef enum { + HE_QAT_OP_NONE = 0, ///< No Operation (NO OP) + HE_QAT_OP_MODEXP = 1 ///< QAT Modular Exponentiation } HE_QAT_OP; -typedef enum { +typedef enum { HE_QAT_NANOSEC = 1000000000, - HE_QAT_MICROSEC = 1000000, + HE_QAT_MICROSEC = 1000000, HE_QAT_MILLISEC = 1000, HE_QAT_SEC = 1 } HE_QAT_TIME_UNIT; @@ -61,70 +57,120 @@ typedef enum { typedef pthread_t HE_QAT_Inst; typedef struct { - void* data[HE_QAT_BUFFER_SIZE]; ///< Stores work requests ready to be sent to the accelerator. - volatile unsigned int count; ///< Tracks the number of occupied entries/slots in the data[] buffer. + void* data[HE_QAT_BUFFER_SIZE]; ///< Stores work requests ready to be sent + ///< to the accelerator. + volatile unsigned int count; ///< Tracks the number of occupied + ///< entries/slots in the data[] buffer. // nextin index of the next free slot for a request - unsigned int next_free_slot; ///< Index of the next slot available to store a new request. + unsigned int next_free_slot; ///< Index of the next slot available to store + ///< a new request. // nextout index of next request to be processed - unsigned int next_data_slot; ///< Index of the next slot containing request ready to be consumed for processing. + unsigned int next_data_slot; ///< Index of the next slot containing request + ///< ready to be consumed for processing. // index of next output data to be read by a thread waiting // for all the request to complete processing - unsigned int next_data_out; ///< Index of the next slot containing request whose processing has been completed and its output is ready to be consumed by the caller. - pthread_mutex_t mutex; ///< Synchronization object used to control access to the buffer. - pthread_cond_t any_more_data; ///< Conditional variable used to synchronize the consumption of data in buffer (wait until more data is available to be consumed). - pthread_cond_t any_free_slot; ///< Conditional variable used to synchronize the provision of free slots in buffer (wait until enough slots are available to add more data in buffer). + unsigned int + next_data_out; ///< Index of the next slot containing request whose + ///< processing has been completed and its output is + ///< ready to be consumed by the caller. + pthread_mutex_t mutex; ///< Synchronization object used to control access + ///< to the buffer. + pthread_cond_t + any_more_data; ///< Conditional variable used to synchronize the + ///< consumption of data in buffer (wait until more data + ///< is available to be consumed). + pthread_cond_t any_free_slot; ///< Conditional variable used to synchronize + ///< the provision of free slots in buffer + ///< (wait until enough slots are available + ///< to add more data in buffer). } HE_QAT_RequestBuffer; typedef struct { - HE_QAT_RequestBuffer buffer[HE_QAT_BUFFER_COUNT]; ///< Buffers to support concurrent threads with less sync overhead. Stores incoming request from different threads. - unsigned int busy_count; ///< Counts number of currently occupied buffers. - unsigned int next_free_buffer; ///< Next in: index of the next free slot for a request. - int free_buffer[HE_QAT_BUFFER_COUNT]; ///< Keeps track of buffers that are available (any value > 0 means the buffer at index i is available). The next_free_buffer does not necessarily mean that the buffer is already released from usage. - unsigned int next_ready_buffer; ///< Next out: index of next request to be processed. - int ready_buffer[HE_QAT_BUFFER_COUNT]; ///< Keeps track of buffers that are ready (any value > 0 means the buffer at index i is ready). The next_ready_buffer does not necessarily mean that the buffer is not busy at any time instance. - pthread_mutex_t mutex; ///< Used for synchronization of concurrent access of an object of the type - pthread_cond_t any_ready_buffer; ///< Conditional variable used to synchronize the consumption of the contents in the buffers storing outstanding requests and ready to be scheduled to move to the internal buffer. - pthread_cond_t any_free_buffer; ///< Conditional variable used to synchronize the provisioning of buffers to store incoming requests from concurrent threads. + HE_QAT_RequestBuffer + buffer[HE_QAT_BUFFER_COUNT]; ///< Buffers to support concurrent threads + ///< with less sync overhead. Stores + ///< incoming request from different + ///< threads. + unsigned int busy_count; ///< Counts number of currently occupied buffers. + unsigned int next_free_buffer; ///< Next in: index of the next free slot + ///< for a request. + int free_buffer + [HE_QAT_BUFFER_COUNT]; ///< Keeps track of buffers that are available + ///< (any value > 0 means the buffer at index i + ///< is available). The next_free_buffer does + ///< not necessarily mean that the buffer is + ///< already released from usage. + unsigned int next_ready_buffer; ///< Next out: index of next request to be + ///< processed. + int ready_buffer + [HE_QAT_BUFFER_COUNT]; ///< Keeps track of buffers that are ready (any + ///< value > 0 means the buffer at index i is + ///< ready). The next_ready_buffer does not + ///< necessarily mean that the buffer is not + ///< busy at any time instance. + pthread_mutex_t mutex; ///< Used for synchronization of concurrent access + ///< of an object of the type + pthread_cond_t + any_ready_buffer; ///< Conditional variable used to synchronize the + ///< consumption of the contents in the buffers + ///< storing outstanding requests and ready to be + ///< scheduled to move to the internal buffer. + pthread_cond_t + any_free_buffer; ///< Conditional variable used to synchronize the + ///< provisioning of buffers to store incoming + ///< requests from concurrent threads. } HE_QAT_OutstandingBuffer; typedef struct { - int inst_id; ///< QAT instance ID. - CpaInstanceHandle inst_handle; ///< Handle of this QAT instance. - pthread_attr_t* attr; ///< Unused member. - HE_QAT_RequestBuffer* he_qat_buffer; ///< Unused member. + int inst_id; ///< QAT instance ID. + CpaInstanceHandle inst_handle; ///< Handle of this QAT instance. + pthread_attr_t* attr; ///< Unused member. + HE_QAT_RequestBuffer* he_qat_buffer; ///< Unused member. pthread_mutex_t mutex; pthread_cond_t ready; - volatile int active; ///< State of this QAT instance. - volatile int polling; ///< State of this QAT instance's polling thread (any value different from 0 indicates that it is running). - volatile int running; ///< State of this QAT instance's processing thread (any value different from 0 indicates that it is running). - CpaStatus status; ///< Status of the latest activity by this QAT instance. + volatile int active; ///< State of this QAT instance. + volatile int + polling; ///< State of this QAT instance's polling thread (any value + ///< different from 0 indicates that it is running). + volatile int + running; ///< State of this QAT instance's processing thread (any value + ///< different from 0 indicates that it is running). + CpaStatus status; ///< Status of the latest activity by this QAT instance. } HE_QAT_InstConfig; typedef struct { - HE_QAT_InstConfig *inst_config; ///< List of the QAT instance's configurations. - volatile int active; ///< Value different from 0 indicates all QAT instances are created and active. - volatile int running; ///< Value different from 0 indicates all created QAT instances are running. - unsigned int count; ///< Total number of created QAT instances. + HE_QAT_InstConfig* + inst_config; ///< List of the QAT instance's configurations. + volatile int active; ///< Value different from 0 indicates all QAT + ///< instances are created and active. + volatile int running; ///< Value different from 0 indicates all created QAT + ///< instances are running. + unsigned int count; ///< Total number of created QAT instances. } HE_QAT_Config; // One for each consumer typedef struct { - unsigned long long id; ///< Work request ID. + unsigned long long id; ///< Work request ID. // sem_t callback; - struct completion_struct callback; ///< Synchronization object. - HE_QAT_OP op_type; ///< Work type: type of operation to be offloaded to QAT. - CpaStatus op_status; ///< Status of the operation after completion. - CpaFlatBuffer op_result; ///< Output of the operation in contiguous memory. + struct completion_struct callback; ///< Synchronization object. + HE_QAT_OP + op_type; ///< Work type: type of operation to be offloaded to QAT. + CpaStatus op_status; ///< Status of the operation after completion. + CpaFlatBuffer op_result; ///< Output of the operation in contiguous memory. // CpaCyLnModExpOpData op_data; - void* op_data; ///< Input data packaged in QAT's data structure for the target type of operation. - void* op_output; ///< Pointer to the memory space where to store the output for the caller. - void* callback_func; ///< Pointer to the callback function. - volatile HE_QAT_STATUS request_status; + void* op_data; ///< Input data packaged in QAT's data structure for the + ///< target type of operation. + void* op_output; ///< Pointer to the memory space where to store the output + ///< for the caller. + void* callback_func; ///< Pointer to the callback function. + volatile HE_QAT_STATUS request_status; pthread_mutex_t mutex; pthread_cond_t ready; #ifdef HE_QAT_PERF - struct timeval start; ///< Time when the request was first received from the caller. - struct timeval end; ///< Time when the request completed processing and callback function was triggered. + struct timeval + start; ///< Time when the request was first received from the caller. + struct timeval end; ///< Time when the request completed processing and + ///< callback function was triggered. #endif } HE_QAT_TaskRequest; diff --git a/heqat/include/heqat/common/utils.h b/heqat/include/heqat/common/utils.h index fb3cf59..182e28b 100644 --- a/heqat/include/heqat/common/utils.h +++ b/heqat/include/heqat/common/utils.h @@ -33,36 +33,34 @@ extern "C" { // 5 seconds #ifndef TIMEOUT_MS -#define TIMEOUT_MS 5000 +#define TIMEOUT_MS 5000 #endif // Printing Functions #ifdef HE_QAT_DEBUG -#define HE_QAT_PRINT_DBG(args...) \ - do \ - { \ - printf("%s(): ", __func__); \ - printf(args); \ - fflush(stdout); \ +#define HE_QAT_PRINT_DBG(args...) \ + do { \ + printf("%s(): ", __func__); \ + printf(args); \ + fflush(stdout); \ } while (0) #else -#define HE_QAT_PRINT_DBG(args...) { } +#define HE_QAT_PRINT_DBG(args...) \ + {} #endif #ifndef HE_QAT_PRINT -#define HE_QAT_PRINT(args...) \ - do \ - { \ - printf(args); \ +#define HE_QAT_PRINT(args...) \ + do { \ + printf(args); \ } while (0) #endif #ifndef HE_QAT_PRINT_ERR -#define HE_QAT_PRINT_ERR(args...) \ - do \ - { \ - printf("%s(): ", __func__); \ - printf(args); \ +#define HE_QAT_PRINT_ERR(args...) \ + do { \ + printf("%s(): ", __func__); \ + printf(args); \ } while (0) #endif @@ -78,19 +76,19 @@ extern "C" { /// size for the given alignment and stores the address of the memory /// allocated in the pointer. Memory allocated by this function is /// guaranteed to be physically contiguous. -/// +/// /// @param[out] ppMemAddr address of pointer where address will be stored /// @param[in] sizeBytes the size of the memory to be allocated -/// @param[in] alignment the alignment of the memory to be allocated (non-zero) +/// @param[in] alignment the alignment of the memory to be allocated +/// (non-zero) /// @param[in] node the allocate memory that is local to cpu(node) -/// +/// /// @retval HE_QAT_STATUS_FAIL Failed to allocate memory. /// @retval HE_QAT_STATUS_SUCCESS Memory successfully allocated. -static __inline HE_QAT_STATUS HE_QAT_memAllocContig(void **ppMemAddr, - Cpa32U sizeBytes, - Cpa32U alignment, - Cpa32U node) -{ +static __inline HE_QAT_STATUS HE_QAT_memAllocContig(void** ppMemAddr, + Cpa32U sizeBytes, + Cpa32U alignment, + Cpa32U node) { *ppMemAddr = qaeMemAllocNUMA(sizeBytes, node, alignment); if (NULL == *ppMemAddr) { return HE_QAT_STATUS_FAIL; @@ -98,60 +96,56 @@ static __inline HE_QAT_STATUS HE_QAT_memAllocContig(void **ppMemAddr, return HE_QAT_STATUS_SUCCESS; } #define HE_QAT_MEM_ALLOC_CONTIG(ppMemAddr, sizeBytes, alignment) \ - HE_QAT_memAllocContig((void *)(ppMemAddr), (sizeBytes), (alignment), 0) - + HE_QAT_memAllocContig((void*)(ppMemAddr), (sizeBytes), (alignment), 0) /// @brief -/// This function and associated macro frees the memory at the given address -/// and resets the pointer to NULL. The memory must have been allocated by -/// the function Mem_Alloc_Contig(). -/// +/// This function and associated macro frees the memory at the given +/// address and resets the pointer to NULL. The memory must have been +/// allocated by the function Mem_Alloc_Contig(). +/// /// @param[out] ppMemAddr address of pointer where mem address is stored. /// If pointer is NULL, the function will exit silently -static __inline void HE_QAT_memFreeContig(void **ppMemAddr) -{ +static __inline void HE_QAT_memFreeContig(void** ppMemAddr) { if (NULL != *ppMemAddr) { qaeMemFreeNUMA(ppMemAddr); *ppMemAddr = NULL; } } -#define HE_QAT_MEM_FREE_CONTIG(pMemAddr) \ - HE_QAT_memFreeContig((void *)&pMemAddr) - +#define HE_QAT_MEM_FREE_CONTIG(pMemAddr) HE_QAT_memFreeContig((void*)&pMemAddr) /// @brief Sleep for time unit. /// @param[in] time Unsigned integer representing amount of time. -/// @param[in] unit Time unit of the amount of time passed in the first parameter. Unit values can be HE_QAT_NANOSEC (nano seconds), HE_QAT_MICROSEC (micro seconds), HE_QAT_MILLISEC (milli seconds), or HE_QAT_SEC (seconds). -static __inline HE_QAT_STATUS HE_QAT_sleep(unsigned int time, HE_QAT_TIME_UNIT unit) -{ +/// @param[in] unit Time unit of the amount of time passed in the first +/// parameter. Unit values can be HE_QAT_NANOSEC (nano seconds), HE_QAT_MICROSEC +/// (micro seconds), HE_QAT_MILLISEC (milli seconds), or HE_QAT_SEC (seconds). +static __inline HE_QAT_STATUS HE_QAT_sleep(unsigned int time, + HE_QAT_TIME_UNIT unit) { int ret = 0; struct timespec resTime, remTime; resTime.tv_sec = time / unit; - resTime.tv_nsec = (time % unit) * (HE_QAT_NANOSEC/unit); + resTime.tv_nsec = (time % unit) * (HE_QAT_NANOSEC / unit); do { - ret = nanosleep(&resTime, &remTime); - resTime = remTime; + ret = nanosleep(&resTime, &remTime); + resTime = remTime; } while ((0 != ret) && (EINTR == errno)); if (0 != ret) { - HE_QAT_PRINT_ERR("nano sleep failed with code %d\n", ret); - return HE_QAT_STATUS_FAIL; + HE_QAT_PRINT_ERR("nano sleep failed with code %d\n", ret); + return HE_QAT_STATUS_FAIL; } else { - return HE_QAT_STATUS_SUCCESS; + return HE_QAT_STATUS_SUCCESS; } } -#define HE_QAT_SLEEP(time, timeUnit) \ - HE_QAT_sleep((time), (timeUnit)) +#define HE_QAT_SLEEP(time, timeUnit) HE_QAT_sleep((time), (timeUnit)) /// @brief /// This function returns the physical address for a given virtual address. /// In case of error 0 is returned. /// @param[in] virtAddr Virtual address /// @retval CpaPhysicalAddr Physical address or 0 in case of error -static __inline CpaPhysicalAddr HE_QAT_virtToPhys(void *virtAddr) -{ +static __inline CpaPhysicalAddr HE_QAT_virtToPhys(void* virtAddr) { return (CpaPhysicalAddr)qaeVirtToPhysNUMA(virtAddr); } diff --git a/heqat/include/heqat/heqat.h b/heqat/include/heqat/heqat.h index 2bba536..c5ab5d7 100644 --- a/heqat/include/heqat/heqat.h +++ b/heqat/include/heqat/heqat.h @@ -3,6 +3,5 @@ /// @file heqat/heqat.h #include "heqat/common.h" -#include "heqat/context.h" -#include "heqat/bnops.h" - +#include "heqat/context.h" +#include "heqat/bnops.h" diff --git a/heqat/include/heqat/misc.h b/heqat/include/heqat/misc.h index 7ccd964..9a396bc 100644 --- a/heqat/include/heqat/misc.h +++ b/heqat/include/heqat/misc.h @@ -7,7 +7,7 @@ #ifndef HE_QAT_MISC_H_ #define HE_QAT_MISC_H_ -#include "heqat/common/consts.h" +#include "heqat/common/consts.h" #include "heqat/common/types.h" #ifdef __cplusplus @@ -33,6 +33,6 @@ HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, /// represented in nbits. HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, const BigNumber& bn); -#endif // __cpluscplus +#endif // __cpluscplus #endif // HE_QAT_MISC_H_ diff --git a/heqat/misc/bignum.cpp b/heqat/misc/bignum.cpp index 8a5a869..c47a278 100644 --- a/heqat/misc/bignum.cpp +++ b/heqat/misc/bignum.cpp @@ -20,7 +20,6 @@ #include #include - ////////////////////////////////////////////////////////////////////// // // BigNumber diff --git a/heqat/misc/misc.cpp b/heqat/misc/misc.cpp index d789395..16b19aa 100644 --- a/heqat/misc/misc.cpp +++ b/heqat/misc/misc.cpp @@ -39,4 +39,3 @@ HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, return HE_QAT_STATUS_SUCCESS; } - From b18ae00d7c272780e72773a3a299fc6e2b2f8ed5 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 28 Oct 2022 15:37:23 -0700 Subject: [PATCH 324/364] Update heqat submodule. Signed-off-by: Souza, Fillipe --- module/heqat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/heqat b/module/heqat index 6d180a2..74481ca 160000 --- a/module/heqat +++ b/module/heqat @@ -1 +1 @@ -Subproject commit 6d180a2ddcfeb17cc8dddf2546a0f0e5ee6f07fd +Subproject commit 74481ca0c628b3344804db71bfb73560f654f02a From 008f5155df4f7a8614db2f6a9d894cdc243e7db4 Mon Sep 17 00:00:00 2001 From: "Souza, Fillipe" Date: Fri, 28 Oct 2022 16:02:13 -0700 Subject: [PATCH 325/364] Remove submodule. Signed-off-by: Souza, Fillipe --- .gitmodules | 4 ---- module/heqat | 1 - 2 files changed, 5 deletions(-) delete mode 100644 .gitmodules delete mode 160000 module/heqat diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index dc5f7b8..0000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "module/heqat"] - path = module/heqat - url = https://github.com/intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.project-destiny.git - branch = main diff --git a/module/heqat b/module/heqat deleted file mode 160000 index 74481ca..0000000 --- a/module/heqat +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 74481ca0c628b3344804db71bfb73560f654f02a From aac0eb428dcd04942f08a8f6b14d5ab9736be48d Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Sat, 29 Oct 2022 16:15:55 -0700 Subject: [PATCH 326/364] Fix IPP-Crypto compile error after applying patch (#144) * Major updates - Removed ```-Wno-stringop-overflow``` when using Clang (unsupported in LLVM) - Added ```-Wno-error=deprecated-copy``` flag when compiling with clang>=11 - Added Intel Compiler error when using version greater than 2021.3 - Moved patch file under dedicated folder ```cmake/patch``` * Minor updates - Replaced bool with Ipp8u* in keygen to avoid warning - Updated gtest version to ```release-1.12.1``` --- .pre-commit-config.yaml | 4 +- CMakeLists.txt | 13 +- cmake/gtest.cmake | 8 +- cmake/ippcrypto.cmake | 2 +- cmake/ippcrypto_patch.patch | 242 ------------------------------ cmake/patch/ippcrypto_patch.patch | 125 +++++++++++++++ ipcl/keygen.cpp | 2 +- module/heqat.cmake | 3 +- 8 files changed, 142 insertions(+), 257 deletions(-) delete mode 100644 cmake/ippcrypto_patch.patch create mode 100644 cmake/patch/ippcrypto_patch.patch diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5f72fea..1605958 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,9 +7,9 @@ repos: rev: v4.0.1 hooks: - id: trailing-whitespace - exclude: cmake/ippcrypto_patch.patch + exclude: cmake/patch/ippcrypto_patch.patch - id: end-of-file-fixer - exclude: cmake/ippcrypto_patch.patch + exclude: cmake/patch/ippcrypto_patch.patch - id: check-merge-conflict - id: mixed-line-ending - id: check-byte-order-marker diff --git a/CMakeLists.txt b/CMakeLists.txt index a1fb8da..52a1d95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,12 +43,21 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "/opt/intel/ipcl") endif() -set(CMAKE_C_FLAGS "-O2 -Wno-error=deprecated-declarations") -set(CMAKE_CXX_FLAGS "-O2 -fpermissive -Wno-error=deprecated-declarations -Wstringop-overflow=1") +set(CMAKE_C_FLAGS "-O2 -Wno-error=deprecated-declarations -Wno-error=deprecated-copy") +set(CMAKE_CXX_FLAGS "-O2 -fpermissive -Wno-error=deprecated-declarations -Wno-error=deprecated-copy") set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ipcl;${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ipcl/ippcrypto") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) +# Compiler version check - icx/icpx-2021.3.0 is supported +if(CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM") + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 2021.3.0) + message(FATAL_ERROR + " ${CMAKE_CXX_COMPILER_ID}-${CMAKE_CXX_COMPILER_VERSION} is not supported." + " Please refer to Intel IPP-Crypto (https://github.com/intel/ipp-crypto" + " for more information.") + endif() +endif() #--------------------------------------------------- option(IPCL_TEST "Enable testing" ON) diff --git a/cmake/gtest.cmake b/cmake/gtest.cmake index b5d9dc5..cdfb1df 100644 --- a/cmake/gtest.cmake +++ b/cmake/gtest.cmake @@ -5,7 +5,7 @@ include(ExternalProject) set(GTEST_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_gtest) set(GTEST_GIT_REPO_URL https://github.com/google/googletest.git) -set(GTEST_GIT_LABEL release-1.10.0) +set(GTEST_GIT_LABEL release-1.12.1) set(GTEST_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS} -fPIC") ExternalProject_Add( @@ -21,12 +21,6 @@ ExternalProject_Add( INSTALL_COMMAND "" ) -# install( -# DIRECTORY ${GTEST_DESTDIR}/${CMAKE_INSTALL_PREFIX}/ -# DESTINATION "." -# USE_SOURCE_PERMISSIONS -# ) - ExternalProject_Get_Property(ext_gtest SOURCE_DIR BINARY_DIR) add_library(libgtest INTERFACE) diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake index 28ed163..5c53183 100644 --- a/cmake/ippcrypto.cmake +++ b/cmake/ippcrypto.cmake @@ -35,7 +35,7 @@ ExternalProject_Add( -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DCMAKE_INSTALL_INCLUDEDIR=${IPPCRYPTO_DEST_INCLUDE_DIR} UPDATE_COMMAND "" - PATCH_COMMAND git apply ${CMAKE_CURRENT_LIST_DIR}/ippcrypto_patch.patch + PATCH_COMMAND git apply ${CMAKE_CURRENT_LIST_DIR}/patch/ippcrypto_patch.patch INSTALL_COMMAND make DESTDIR=${IPPCRYPTO_DESTDIR} install ) diff --git a/cmake/ippcrypto_patch.patch b/cmake/ippcrypto_patch.patch deleted file mode 100644 index ebc60cc..0000000 --- a/cmake/ippcrypto_patch.patch +++ /dev/null @@ -1,242 +0,0 @@ -# Copyright (C) 2022 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index ddb61db..302ca95 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -54,6 +54,7 @@ endif() - project(${PROJECT_NAME} - VERSION ${PROJECT_VERSION} - LANGUAGES C CXX) -+include(GNUInstallDirs) - - if("${CMAKE_BUILD_TYPE}" STREQUAL "") - message(STATUS "CMAKE_BUILD_TYPE is unset, defaulting to Release") -diff --git a/sources/cmake/linux/Clang9.0.0.cmake b/sources/cmake/linux/Clang9.0.0.cmake -index b99d637..4a0c5bc 100644 ---- a/sources/cmake/linux/Clang9.0.0.cmake -+++ b/sources/cmake/linux/Clang9.0.0.cmake -@@ -100,7 +100,7 @@ if(${ARCH} MATCHES "ia32") - endif(${ARCH} MATCHES "ia32") - - # Optimization level = 3, no-debug definition (turns off asserts), warnings=errors --set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -Werror") -+set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -Wno-stringop-overflow -Werror") - - set(w7_opt "${w7_opt} -march=pentium4 -msse2") - set(s8_opt "${s8_opt} -march=core2 -mssse3") -diff --git a/sources/cmake/linux/GNU8.2.0.cmake b/sources/cmake/linux/GNU8.2.0.cmake -index 9c848d5..30ad189 100644 ---- a/sources/cmake/linux/GNU8.2.0.cmake -+++ b/sources/cmake/linux/GNU8.2.0.cmake -@@ -96,7 +96,7 @@ if(${ARCH} MATCHES "ia32") - endif(${ARCH} MATCHES "ia32") - - # Optimization level = 3, no-debug definition (turns off asserts), warnings=errors --set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -Werror") -+set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -Wno-stringop-overflow -Werror") - - set(w7_opt "${w7_opt} -march=pentium4 -msse2") - set(s8_opt "${s8_opt} -march=core2 -mssse3") -diff --git a/sources/cmake/linux/Intel19.0.0.cmake b/sources/cmake/linux/Intel19.0.0.cmake -index ce0ee06..bbe4acc 100644 ---- a/sources/cmake/linux/Intel19.0.0.cmake -+++ b/sources/cmake/linux/Intel19.0.0.cmake -@@ -99,7 +99,7 @@ if(CODE_COVERAGE) - endif() - - # Optimization level = 3, no-debug definition (turns off asserts), warning level = 3, treat warnings as errors --set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -w3 -Werror") -+set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -w3 -Wno-stringop-overflow -Werror") - # DEBUG flags Optimization level = 0, generation maximum GDB information (-g3) - set (CMAKE_C_FLAGS_DEBUG " -O0 -g3") - -diff --git a/sources/cmake/linux/IntelLLVM2021.3.0.cmake b/sources/cmake/linux/IntelLLVM2021.3.0.cmake -index 73ab46a..bedc0a7 100644 ---- a/sources/cmake/linux/IntelLLVM2021.3.0.cmake -+++ b/sources/cmake/linux/IntelLLVM2021.3.0.cmake -@@ -95,7 +95,7 @@ if(CODE_COVERAGE) - endif() - - # Optimization level = 3, no-debug definition (turns off asserts), warning level = 3, treat warnings as errors --set (CMAKE_C_FLAGS_RELEASE " -Ofast -DNDEBUG -Wall -Wno-unused-function -Wno-missing-braces -Werror") -+set (CMAKE_C_FLAGS_RELEASE " -Ofast -DNDEBUG -Wall -Wno-unused-function -Wno-missing-braces -Wno-stringop-overflow -Werror") - - # Alignment for structures on byte boundaries (= 16) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Zp16") -diff --git a/sources/cmake/macosx/AppleClang11.0.0.cmake b/sources/cmake/macosx/AppleClang11.0.0.cmake -index 0ca0d30..604ebf3 100644 ---- a/sources/cmake/macosx/AppleClang11.0.0.cmake -+++ b/sources/cmake/macosx/AppleClang11.0.0.cmake -@@ -99,7 +99,7 @@ if(${ARCH} MATCHES "ia32") - endif(${ARCH} MATCHES "ia32") - - # Optimization level = 3, no-debug definition (turns off asserts), warnings=errors --set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -Werror") -+set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -Wno-stringop-overflow -Werror") - - set(w7_opt "${w7_opt} -march=pentium4 -msse2") - set(s8_opt "${s8_opt} -march=core2 -mssse3") -diff --git a/sources/cmake/macosx/Intel19.0.0.cmake b/sources/cmake/macosx/Intel19.0.0.cmake -index 1250802..ffdf8db 100644 ---- a/sources/cmake/macosx/Intel19.0.0.cmake -+++ b/sources/cmake/macosx/Intel19.0.0.cmake -@@ -86,7 +86,7 @@ if(CODE_COVERAGE) - endif() - - # Optimization level = 3, no-debug definition (turns off asserts), warning level = 3, treat warnings as errors --set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -w3 -Werror") -+set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -w3 -Wno-stringop-overflow -Werror") - - # Compile for x64 - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch_only x86_64") -diff --git a/sources/ippcp/CMakeLists.txt b/sources/ippcp/CMakeLists.txt -index dd5ef41..b60357e 100644 ---- a/sources/ippcp/CMakeLists.txt -+++ b/sources/ippcp/CMakeLists.txt -@@ -378,7 +378,7 @@ foreach(opt ${PLATFORM_LIST}) - install(TARGETS ${IPPCP_DYN_ITER} - LIBRARY DESTINATION "lib/${ARCH}/$<$:nonpic>" - RUNTIME DESTINATION "lib/${ARCH}/$<$:nonpic>" -- PUBLIC_HEADER DESTINATION "include") -+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) - list(APPEND IPPCP_LIB_DYNAMIC ${IPPCP_DYN_ITER}) - endif(DYNAMIC_LIB AND NOT MERGED_BLD) - -@@ -407,7 +407,7 @@ foreach(opt ${PLATFORM_LIST}) - set_target_properties(${IPPCP_ST_ITER} PROPERTIES PUBLIC_HEADER "${IPPCP_PUBLIC_HEADERS}") - install(TARGETS ${IPPCP_ST_ITER} - ARCHIVE DESTINATION "lib/${ARCH}/$<$:nonpic>" -- PUBLIC_HEADER DESTINATION "include") -+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) - endif() - - list(APPEND IPPCP_LIB_STATIC ${IPPCP_ST_ITER}) -@@ -482,7 +482,7 @@ if(MERGED_BLD) - - install(TARGETS ${IPPCP_LIB_MERGED} - ARCHIVE DESTINATION "lib/${ARCH}/$<$:nonpic>" -- PUBLIC_HEADER DESTINATION "include" -+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - PRIVATE_HEADER DESTINATION "tools/${ARCH}/staticlib") - - set_source_files_properties(${DISPATCHER_C_SOURCES} pcpver.rc PROPERTIES INCLUDE_DIRECTORIES "${C_INCLUDE_DIRECTORIES}") -@@ -521,7 +521,7 @@ if(MERGED_BLD) - install(TARGETS ${IPPCP_LIB_PCS} - LIBRARY DESTINATION "lib/${ARCH}/$<$:nonpic>" - RUNTIME DESTINATION "lib/${ARCH}/$<$:nonpic>" -- PUBLIC_HEADER DESTINATION "include" -+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - PRIVATE_HEADER DESTINATION "tools/${ARCH}/staticlib") - - if(WIN32) -diff --git a/sources/ippcp/crypto_mb/src/CMakeLists.txt b/sources/ippcp/crypto_mb/src/CMakeLists.txt -index f75f448..2f43255 100644 ---- a/sources/ippcp/crypto_mb/src/CMakeLists.txt -+++ b/sources/ippcp/crypto_mb/src/CMakeLists.txt -@@ -117,12 +117,12 @@ if (MB_STANDALONE) # standalone crypto_mb's cmake run - install(TARGETS ${MB_DYN_LIB_TARGET} - LIBRARY DESTINATION "lib" - RUNTIME DESTINATION "lib" -- PUBLIC_HEADER DESTINATION "include/crypto_mb") -+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/crypto_mb) - elseif (DYNAMIC_LIB) # build from ippcp's cmake - install(TARGETS ${MB_DYN_LIB_TARGET} - LIBRARY DESTINATION "lib/intel64" - RUNTIME DESTINATION "lib/intel64" -- PUBLIC_HEADER DESTINATION "include/crypto_mb") -+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/crypto_mb) - endif() - - # Static library -@@ -147,9 +147,9 @@ endif() - if(MB_STANDALONE) - install(TARGETS ${MB_STATIC_LIB_TARGET} - ARCHIVE DESTINATION "lib" -- PUBLIC_HEADER DESTINATION "include/crypto_mb") -+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/crypto_mb) - else() - install(TARGETS ${MB_STATIC_LIB_TARGET} - ARCHIVE DESTINATION "lib/intel64" -- PUBLIC_HEADER DESTINATION "include/crypto_mb") -+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/crypto_mb) - endif() -diff --git a/sources/ippcp/crypto_mb/src/cmake/linux/Clang.cmake b/sources/ippcp/crypto_mb/src/cmake/linux/Clang.cmake -index 17bc125..77b14ee 100644 ---- a/sources/ippcp/crypto_mb/src/cmake/linux/Clang.cmake -+++ b/sources/ippcp/crypto_mb/src/cmake/linux/Clang.cmake -@@ -44,7 +44,7 @@ set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -fpic -fPIC") - # Enables important warning and error messages relevant to security during compilation - set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wall") - # Warnings=errors --set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Werror") -+set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wno-stringop-overflow -Werror") - - # Linker flags - -diff --git a/sources/ippcp/crypto_mb/src/cmake/linux/GNU.cmake b/sources/ippcp/crypto_mb/src/cmake/linux/GNU.cmake -index b95f703..1be6ca7 100644 ---- a/sources/ippcp/crypto_mb/src/cmake/linux/GNU.cmake -+++ b/sources/ippcp/crypto_mb/src/cmake/linux/GNU.cmake -@@ -46,7 +46,7 @@ set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -fcf-protection=full") - # Enables important warning and error messages relevant to security during compilation - set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wall") - # Warnings=errors --set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Werror") -+set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wno-stringop-overflow -Werror") - - # Linker flags - -diff --git a/sources/ippcp/crypto_mb/src/cmake/linux/Intel.cmake b/sources/ippcp/crypto_mb/src/cmake/linux/Intel.cmake -index 39862aa..35d49c1 100644 ---- a/sources/ippcp/crypto_mb/src/cmake/linux/Intel.cmake -+++ b/sources/ippcp/crypto_mb/src/cmake/linux/Intel.cmake -@@ -40,7 +40,7 @@ set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -fcf-protection=full") - # Enables important warning and error messages relevant to security during compilation - set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wall") - # Warnings=errors --set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Werror") -+set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wno-stringop-overflow -Werror") - - # Linker flags - -diff --git a/sources/ippcp/crypto_mb/src/cmake/linux/IntelLLVM.cmake b/sources/ippcp/crypto_mb/src/cmake/linux/IntelLLVM.cmake -index 285c64a..b0f48bf 100644 ---- a/sources/ippcp/crypto_mb/src/cmake/linux/IntelLLVM.cmake -+++ b/sources/ippcp/crypto_mb/src/cmake/linux/IntelLLVM.cmake -@@ -40,7 +40,7 @@ set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -fcf-protection=full") - # Enables important warning and error messages relevant to security during compilation - set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wall") - # Warnings=errors --set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Werror") -+set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wno-stringop-overflow -Werror") - - # Linker flags - -diff --git a/sources/ippcp/crypto_mb/src/cmake/macosx/AppleClang.cmake b/sources/ippcp/crypto_mb/src/cmake/macosx/AppleClang.cmake -index 5f6ff8c..fefd3a2 100644 ---- a/sources/ippcp/crypto_mb/src/cmake/macosx/AppleClang.cmake -+++ b/sources/ippcp/crypto_mb/src/cmake/macosx/AppleClang.cmake -@@ -40,7 +40,7 @@ set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -fpic -fPIC") - # Enables important warning and error messages relevant to security during compilation - set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wall") - # Warnings=errors --set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Werror") -+set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wno-stringop-overflow -Werror") - - # Linker flags - -diff --git a/sources/ippcp/crypto_mb/src/cmake/macosx/Intel.cmake b/sources/ippcp/crypto_mb/src/cmake/macosx/Intel.cmake -index 1abac6e..40919a6 100644 ---- a/sources/ippcp/crypto_mb/src/cmake/macosx/Intel.cmake -+++ b/sources/ippcp/crypto_mb/src/cmake/macosx/Intel.cmake -@@ -33,7 +33,7 @@ set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -fpic -fPIC") - # Enables important warning and error messages relevant to security during compilation - set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wall") - # Warnings=errors --set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Werror") -+set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wno-stringop-overflow -Werror") - - # Linker flags - diff --git a/cmake/patch/ippcrypto_patch.patch b/cmake/patch/ippcrypto_patch.patch new file mode 100644 index 0000000..6dfff68 --- /dev/null +++ b/cmake/patch/ippcrypto_patch.patch @@ -0,0 +1,125 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index ddb61db..302ca95 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -54,6 +54,7 @@ endif() + project(${PROJECT_NAME} + VERSION ${PROJECT_VERSION} + LANGUAGES C CXX) ++include(GNUInstallDirs) + + if("${CMAKE_BUILD_TYPE}" STREQUAL "") + message(STATUS "CMAKE_BUILD_TYPE is unset, defaulting to Release") +diff --git a/sources/cmake/linux/GNU8.2.0.cmake b/sources/cmake/linux/GNU8.2.0.cmake +index 9c848d5..30ad189 100644 +--- a/sources/cmake/linux/GNU8.2.0.cmake ++++ b/sources/cmake/linux/GNU8.2.0.cmake +@@ -96,7 +96,7 @@ if(${ARCH} MATCHES "ia32") + endif(${ARCH} MATCHES "ia32") + + # Optimization level = 3, no-debug definition (turns off asserts), warnings=errors +-set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -Werror") ++set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -Wno-stringop-overflow -Werror") + + set(w7_opt "${w7_opt} -march=pentium4 -msse2") + set(s8_opt "${s8_opt} -march=core2 -mssse3") +diff --git a/sources/ippcp/CMakeLists.txt b/sources/ippcp/CMakeLists.txt +index dd5ef41..b60357e 100644 +--- a/sources/ippcp/CMakeLists.txt ++++ b/sources/ippcp/CMakeLists.txt +@@ -378,7 +378,7 @@ foreach(opt ${PLATFORM_LIST}) + install(TARGETS ${IPPCP_DYN_ITER} + LIBRARY DESTINATION "lib/${ARCH}/$<$:nonpic>" + RUNTIME DESTINATION "lib/${ARCH}/$<$:nonpic>" +- PUBLIC_HEADER DESTINATION "include") ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + list(APPEND IPPCP_LIB_DYNAMIC ${IPPCP_DYN_ITER}) + endif(DYNAMIC_LIB AND NOT MERGED_BLD) + +@@ -407,7 +407,7 @@ foreach(opt ${PLATFORM_LIST}) + set_target_properties(${IPPCP_ST_ITER} PROPERTIES PUBLIC_HEADER "${IPPCP_PUBLIC_HEADERS}") + install(TARGETS ${IPPCP_ST_ITER} + ARCHIVE DESTINATION "lib/${ARCH}/$<$:nonpic>" +- PUBLIC_HEADER DESTINATION "include") ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + endif() + + list(APPEND IPPCP_LIB_STATIC ${IPPCP_ST_ITER}) +@@ -482,7 +482,7 @@ if(MERGED_BLD) + + install(TARGETS ${IPPCP_LIB_MERGED} + ARCHIVE DESTINATION "lib/${ARCH}/$<$:nonpic>" +- PUBLIC_HEADER DESTINATION "include" ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + PRIVATE_HEADER DESTINATION "tools/${ARCH}/staticlib") + + set_source_files_properties(${DISPATCHER_C_SOURCES} pcpver.rc PROPERTIES INCLUDE_DIRECTORIES "${C_INCLUDE_DIRECTORIES}") +@@ -521,7 +521,7 @@ if(MERGED_BLD) + install(TARGETS ${IPPCP_LIB_PCS} + LIBRARY DESTINATION "lib/${ARCH}/$<$:nonpic>" + RUNTIME DESTINATION "lib/${ARCH}/$<$:nonpic>" +- PUBLIC_HEADER DESTINATION "include" ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + PRIVATE_HEADER DESTINATION "tools/${ARCH}/staticlib") + + if(WIN32) +diff --git a/sources/ippcp/crypto_mb/src/CMakeLists.txt b/sources/ippcp/crypto_mb/src/CMakeLists.txt +index f75f448..2f43255 100644 +--- a/sources/ippcp/crypto_mb/src/CMakeLists.txt ++++ b/sources/ippcp/crypto_mb/src/CMakeLists.txt +@@ -117,12 +117,12 @@ if (MB_STANDALONE) # standalone crypto_mb's cmake run + install(TARGETS ${MB_DYN_LIB_TARGET} + LIBRARY DESTINATION "lib" + RUNTIME DESTINATION "lib" +- PUBLIC_HEADER DESTINATION "include/crypto_mb") ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/crypto_mb) + elseif (DYNAMIC_LIB) # build from ippcp's cmake + install(TARGETS ${MB_DYN_LIB_TARGET} + LIBRARY DESTINATION "lib/intel64" + RUNTIME DESTINATION "lib/intel64" +- PUBLIC_HEADER DESTINATION "include/crypto_mb") ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/crypto_mb) + endif() + + # Static library +@@ -147,9 +147,9 @@ endif() + if(MB_STANDALONE) + install(TARGETS ${MB_STATIC_LIB_TARGET} + ARCHIVE DESTINATION "lib" +- PUBLIC_HEADER DESTINATION "include/crypto_mb") ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/crypto_mb) + else() + install(TARGETS ${MB_STATIC_LIB_TARGET} + ARCHIVE DESTINATION "lib/intel64" +- PUBLIC_HEADER DESTINATION "include/crypto_mb") ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/crypto_mb) + endif() +diff --git a/sources/ippcp/crypto_mb/src/cmake/linux/GNU.cmake b/sources/ippcp/crypto_mb/src/cmake/linux/GNU.cmake +index b95f703..1be6ca7 100644 +--- a/sources/ippcp/crypto_mb/src/cmake/linux/GNU.cmake ++++ b/sources/ippcp/crypto_mb/src/cmake/linux/GNU.cmake +@@ -46,7 +46,7 @@ set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -fcf-protection=full") + # Enables important warning and error messages relevant to security during compilation + set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wall") + # Warnings=errors +-set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Werror") ++set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wno-stringop-overflow -Werror") + + # Linker flags + +diff --git a/sources/ippcp/crypto_mb/src/cmake/linux/Intel.cmake b/sources/ippcp/crypto_mb/src/cmake/linux/Intel.cmake +index 39862aa..35d49c1 100644 +--- a/sources/ippcp/crypto_mb/src/cmake/linux/Intel.cmake ++++ b/sources/ippcp/crypto_mb/src/cmake/linux/Intel.cmake +@@ -40,7 +40,7 @@ set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -fcf-protection=full") + # Enables important warning and error messages relevant to security during compilation + set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wall") + # Warnings=errors +-set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Werror") ++set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wno-stringop-overflow -Werror") + + # Linker flags + diff --git a/ipcl/keygen.cpp b/ipcl/keygen.cpp index f2d712e..41301d0 100644 --- a/ipcl/keygen.cpp +++ b/ipcl/keygen.cpp @@ -17,7 +17,7 @@ BigNumber getPrimeBN(int max_bits) { ippsPrimeInit(max_bits, reinterpret_cast(prime_ctx.data())); #if defined(IPCL_RNG_INSTR_RDSEED) || defined(IPCL_RNG_INSTR_RDRAND) - bool rand_param = NULL; + Ipp8u* rand_param = NULL; #else auto buff = std::vector(prime_size); auto rand_param = buff.data(); diff --git a/module/heqat.cmake b/module/heqat.cmake index d4a68cb..2960ee4 100644 --- a/module/heqat.cmake +++ b/module/heqat.cmake @@ -17,13 +17,12 @@ ExternalProject_Add( ext_he_qat SOURCE_DIR ${HEQAT_SRC_DIR} PREFIX ${HEQAT_PREFIX} - # INSTALL_DIR ${HEQAT_DESTDIR} CMAKE_ARGS ${HEQAT_CXX_FLAGS} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DHE_QAT_MISC=OFF -DHE_QAT_DOCS=${IPCL_DOCS} -DHE_QAT_SHARED=${IPCL_SHARED} - -DHE_QAT_TEST=OFF + -DHE_QAT_TEST=OFF -DCMAKE_BUILD_TYPE=${HEQAT_BUILD_TYPE} UPDATE_COMMAND "" EXCLUDE_FROM_ALL TRUE From fb379f16f2d29c9a98b73e7f528508276ab31ba7 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Sun, 30 Oct 2022 15:44:14 -0700 Subject: [PATCH 327/364] Cmake rule: one cmakelists per target (#145) --- module/heqat/heqat/CMakeLists.txt | 13 ++++++++----- module/heqat/heqat/common/CMakeLists.txt | 8 -------- module/heqat/heqat/misc/CMakeLists.txt | 9 --------- 3 files changed, 8 insertions(+), 22 deletions(-) delete mode 100644 module/heqat/heqat/common/CMakeLists.txt delete mode 100644 module/heqat/heqat/misc/CMakeLists.txt diff --git a/module/heqat/heqat/CMakeLists.txt b/module/heqat/heqat/CMakeLists.txt index 1adfacd..6b870ca 100644 --- a/module/heqat/heqat/CMakeLists.txt +++ b/module/heqat/heqat/CMakeLists.txt @@ -6,6 +6,10 @@ set(HE_QAT_SRC ${HE_QAT_SRC_DIR}/cb.c ${HE_QAT_SRC_DIR}/context.c ${HE_QAT_SRC_DIR}/ctrl.c ${HE_QAT_SRC_DIR}/bnops.c + ${HE_QAT_SRC_DIR}/misc/misc.cpp + ${HE_QAT_SRC_DIR}/misc/utils.cpp + ${HE_QAT_SRC_DIR}/misc/bignum.cpp + ${HE_QAT_SRC_DIR}/common/utils.c ) # Common utility functions, types and constants @@ -24,15 +28,15 @@ endif() add_library(HE_QAT::he_qat ALIAS he_qat) -target_include_directories(he_qat - PUBLIC $ #Public headers +target_include_directories(he_qat + PUBLIC $ #Public headers PUBLIC $ #Public headers PUBLIC ${ICP_INC_DIR} ) install(DIRECTORY ${HE_QAT_INC_DIR}/ DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ - FILES_MATCHING + FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h") @@ -52,7 +56,7 @@ else() endif() if(HE_QAT_MISC) - target_include_directories(he_qat PRIVATE ${IPPCP_DIR}/../../../include) + target_include_directories(he_qat PRIVATE ${IPPCP_DIR}/../../../include) target_link_directories(he_qat PUBLIC ${IPPCP_DIR}/lib/intel64) if(HE_QAT_SHARED) target_link_libraries(he_qat PRIVATE IPPCP::ippcp) @@ -110,4 +114,3 @@ install(FILES ${HE_QAT_CONFIG_FILENAME} export(EXPORT he_qatTargets FILE ${HE_QAT_TARGET_FILENAME}) - diff --git a/module/heqat/heqat/common/CMakeLists.txt b/module/heqat/heqat/common/CMakeLists.txt deleted file mode 100644 index cd35730..0000000 --- a/module/heqat/heqat/common/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) 2022 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -# Source files -set(COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/utils.c) -list(APPEND HE_QAT_SRC ${COMMON_SRC}) -set(HE_QAT_SRC ${HE_QAT_SRC} PARENT_SCOPE) - diff --git a/module/heqat/heqat/misc/CMakeLists.txt b/module/heqat/heqat/misc/CMakeLists.txt deleted file mode 100644 index 397bb76..0000000 --- a/module/heqat/heqat/misc/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (C) 2022 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -# Add MISC source code -set(HE_QAT_MISC_SRC ${CMAKE_CURRENT_LIST_DIR}/misc.cpp - ${CMAKE_CURRENT_LIST_DIR}/utils.cpp - ${CMAKE_CURRENT_LIST_DIR}/bignum.cpp) -list(APPEND HE_QAT_SRC ${HE_QAT_MISC_SRC}) -set(HE_QAT_SRC ${HE_QAT_SRC} PARENT_SCOPE) From a71ab1999c543b874d0ee0c224a3ccaf29119e21 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Sun, 30 Oct 2022 16:11:48 -0700 Subject: [PATCH 328/364] Minor fixes (#146) - Renamed libhe_qat library name to he_qat - Removed unused "add_subdirectory" in module/heqat/heqat/CMakeLists.txt - Removed unit-test and benchmark explicit dependency to heqat --- benchmark/CMakeLists.txt | 7 ------- ipcl/CMakeLists.txt | 4 ++-- module/heqat.cmake | 18 +++++++++--------- module/heqat/CMakeLists.txt | 20 +++++++++----------- module/heqat/heqat/CMakeLists.txt | 11 ++++------- test/CMakeLists.txt | 7 ------- 6 files changed, 24 insertions(+), 43 deletions(-) diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 1b843db..00662dc 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -12,12 +12,5 @@ target_include_directories(bench_ipcl PRIVATE ) target_link_libraries(bench_ipcl PRIVATE - # ipcl Threads::Threads libgbenchmark ipcl -pthread libgbenchmark ) - -# enable QAT unittests -if(IPCL_ENABLE_QAT) - target_link_libraries(bench_ipcl PRIVATE libhe_qat) - target_include_directories(bench_ipcl PRIVATE "$") -endif() diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 70adefd..e03c83c 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -98,13 +98,13 @@ if(IPCL_SHARED) target_link_libraries(ipcl PRIVATE libcpu_features) endif() if(IPCL_ENABLE_QAT) - target_link_libraries(ipcl PRIVATE libhe_qat udev z) + target_link_libraries(ipcl PRIVATE he_qat udev z) endif() else() ipcl_create_archive(ipcl libippcrypto::ippcp) ipcl_create_archive(ipcl libippcrypto::crypto_mb) if(IPCL_ENABLE_QAT) - ipcl_create_archive(ipcl libhe_qat) + ipcl_create_archive(ipcl he_qat) target_link_libraries(ipcl PRIVATE udev z) endif() if(IPCL_DETECT_IFMA_RUNTIME) diff --git a/module/heqat.cmake b/module/heqat.cmake index 2960ee4..a26a272 100644 --- a/module/heqat.cmake +++ b/module/heqat.cmake @@ -35,17 +35,17 @@ set(HEQAT_LIB_DIR ${HEQAT_DESTDIR}/${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDI # Create heqat library interface if(IPCL_SHARED) - add_library(libhe_qat INTERFACE) - add_dependencies(libhe_qat ext_he_qat) + add_library(he_qat INTERFACE) + add_dependencies(he_qat ext_he_qat) ExternalProject_Get_Property(ext_he_qat SOURCE_DIR BINARY_DIR) if(CMAKE_BUILD_TYPE STREQUAL "Debug") - target_link_libraries(libhe_qat INTERFACE ${HEQAT_LIB_DIR}/libhe_qat_debug.so) + target_link_libraries(he_qat INTERFACE ${HEQAT_LIB_DIR}/libhe_qat_debug.so) else() - target_link_libraries(libhe_qat INTERFACE ${HEQAT_LIB_DIR}/libhe_qat.so) + target_link_libraries(he_qat INTERFACE ${HEQAT_LIB_DIR}/libhe_qat.so) endif() - target_include_directories(libhe_qat SYSTEM INTERFACE ${HEQAT_INC_DIR}) + target_include_directories(he_qat SYSTEM INTERFACE ${HEQAT_INC_DIR}) install( DIRECTORY ${HEQAT_LIB_DIR}/ @@ -54,17 +54,17 @@ if(IPCL_SHARED) PATTERN "cmake" EXCLUDE ) else() - add_library(libhe_qat STATIC IMPORTED GLOBAL) - add_dependencies(libhe_qat ext_he_qat) + add_library(he_qat STATIC IMPORTED GLOBAL) + add_dependencies(he_qat ext_he_qat) ExternalProject_Get_Property(ext_he_qat SOURCE_DIR BINARY_DIR) if (CMAKE_BUILD_TYPE STREQUAL "Debug") - set_target_properties(libhe_qat PROPERTIES + set_target_properties(he_qat PROPERTIES IMPORTED_LOCATION ${HEQAT_LIB_DIR}/libhe_qat_debug.a INCLUDE_DIRECTORIES ${HEQAT_INC_DIR}) else() - set_target_properties(libhe_qat PROPERTIES + set_target_properties(he_qat PROPERTIES IMPORTED_LOCATION ${HEQAT_LIB_DIR}/libhe_qat.a INCLUDE_DIRECTORIES ${HEQAT_INC_DIR}) endif() diff --git a/module/heqat/CMakeLists.txt b/module/heqat/CMakeLists.txt index 0c4da07..19269a5 100644 --- a/module/heqat/CMakeLists.txt +++ b/module/heqat/CMakeLists.txt @@ -3,12 +3,12 @@ cmake_minimum_required(VERSION 3.13) -# The hekat or heqat (transcribed HqA.t) was an ancient Egyptian volume unit +# The hekat or heqat (transcribed HqA.t) was an ancient Egyptian volume unit # used to measure grain, bread, and beer. project(HE_QAT VERSION 1.3.2 LANGUAGES C CXX) -include(CheckCCompilerFlag) -include(CheckCXXCompilerFlag) +include(CheckCCompilerFlag) +include(CheckCXXCompilerFlag) include(CMakePackageConfigHelpers) if(CMAKE_BUILD_TYPE) @@ -28,9 +28,9 @@ else() set(CMAKE_BUILD_TYPE Release) endif() -set(CMAKE_C_STANDARD 99) -set(CMAKE_C_STANDARD_REQUIRED ON) -set(CMAKE_CXX_STANDARD 11) +set(CMAKE_C_STANDARD 99) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_C_FLAGS "-O2 -Wunused-variable -Wunused-function") @@ -60,7 +60,6 @@ include(GNUInstallDirs) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) # ------------------------------------------------------------------- - option(HE_QAT_MISC "Enable miscellaneous features" ON) option(HE_QAT_SYNC "Enable synchronous mode execution" OFF) option(HE_QAT_MT "Enable interfaces for multithreaded programs" ON) @@ -83,8 +82,8 @@ endif() # Why? set(HE_QAT_CMAKE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/he_qat") -set(HE_QAT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) -set(HE_QAT_SRC_DIR ${HE_QAT_ROOT_DIR}/heqat) +set(HE_QAT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(HE_QAT_SRC_DIR ${HE_QAT_ROOT_DIR}/heqat) set(HE_QAT_INC_DIR ${HE_QAT_ROOT_DIR}/heqat/include) if(HE_QAT_OMP) @@ -146,7 +145,7 @@ if(NOT HE_QAT_SHARED) message(STATUS "OPENSSL_USE_STATIC_LIBS TRUE") else() set(OPENSSL_USE_STATIC_LIBS FALSE) - message(STATUS "OPENSSL_USE_STATIC_LIBS FALSE") + message(STATUS "OPENSSL_USE_STATIC_LIBS FALSE") endif() find_package(OpenSSL REQUIRED) @@ -185,4 +184,3 @@ if(HE_QAT_DOCS) endif() endif() endif() - diff --git a/module/heqat/heqat/CMakeLists.txt b/module/heqat/heqat/CMakeLists.txt index 6b870ca..0955f9c 100644 --- a/module/heqat/heqat/CMakeLists.txt +++ b/module/heqat/heqat/CMakeLists.txt @@ -6,18 +6,15 @@ set(HE_QAT_SRC ${HE_QAT_SRC_DIR}/cb.c ${HE_QAT_SRC_DIR}/context.c ${HE_QAT_SRC_DIR}/ctrl.c ${HE_QAT_SRC_DIR}/bnops.c - ${HE_QAT_SRC_DIR}/misc/misc.cpp - ${HE_QAT_SRC_DIR}/misc/utils.cpp - ${HE_QAT_SRC_DIR}/misc/bignum.cpp ${HE_QAT_SRC_DIR}/common/utils.c ) -# Common utility functions, types and constants -add_subdirectory(common) - # Helper functions for ippcrypto's BigNumber class if(HE_QAT_MISC) - add_subdirectory(misc) + list(APPEND HE_QAT_SRC ${HE_QAT_SRC_DIR}/misc/misc.cpp + ${HE_QAT_SRC_DIR}/misc/utils.cpp + ${HE_QAT_SRC_DIR}/misc/bignum.cpp +) endif() if(HE_QAT_SHARED) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5794dff..fe6c6e9 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -13,11 +13,4 @@ target_include_directories(unittest_ipcl PRIVATE ) target_link_libraries(unittest_ipcl PRIVATE ipcl -pthread libgtest - # ipcl Threads::Threads libgtest ) - -# enable QAT unittests -if(IPCL_ENABLE_QAT) - target_link_libraries(unittest_ipcl PRIVATE libhe_qat) - target_include_directories(unittest_ipcl PRIVATE "$") -endif() From 25f1a957ee6ddccf585d48eeb7e2b360d795d2cf Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Mon, 31 Oct 2022 09:12:26 -0700 Subject: [PATCH 329/364] Build heqat as subdirectory (#147) * Fix static build bug - Set ```HE_QAT_MISC``` off as duplicate ```bignum``` source and headers are causing problems --- CMakeLists.txt | 15 ++- cmake/ippcrypto.cmake | 25 +++-- ipcl/CMakeLists.txt | 27 +++-- module/heqat/CMakeLists.txt | 167 ++++++++++++++++-------------- module/heqat/heqat/CMakeLists.txt | 18 ++-- 5 files changed, 134 insertions(+), 118 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 52a1d95..5a085c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,7 +75,7 @@ if(IPCL_ENABLE_QAT) ipcl_detect_qat() if(IPCL_FOUND_QAT) add_compile_definitions(IPCL_USE_QAT) - set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ipcl/heqat") + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/heqat") if(IPCL_USE_QAT_LITE) add_compile_definitions(IPCL_USE_QAT_LITE) message(STATUS "QAT Lite enabled - IPCL_USE_QAT_LITE set to ON") @@ -173,12 +173,6 @@ set(CMAKE_THREAD_PREFER_PTHREAD ON) find_package(Threads REQUIRED) # find package: OpenSSL config -if(IPCL_SHARED) - set(OPENSSL_USE_STATIC_LIBS TRUE) - message(STATUS "OPENSSL_USE_STATIC_LIBS: TRUE" ) -else() - message(STATUS "OPENSSL_USE_STATIC_LIBS: FALSE" ) -endif() find_package(OpenSSL REQUIRED) # External dependencies @@ -188,7 +182,12 @@ if(IPCL_DETECT_IFMA_RUNTIME) endif() if(IPCL_ENABLE_QAT) - include(module/heqat.cmake) + # preset values for including HE_QAT + set(HE_QAT_MISC OFF) # revisit later on + set(HE_QAT_DOCS ${IPCL_DOCS}) + set(HE_QAT_SHARED ${IPCL_SHARED}) + set(HE_QAT_TEST OFF) + add_subdirectory(module/heqat) endif() if(IPCL_TEST) diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake index 5c53183..4f9b743 100644 --- a/cmake/ippcrypto.cmake +++ b/cmake/ippcrypto.cmake @@ -42,13 +42,18 @@ ExternalProject_Add( set(IPPCRYPTO_INC_DIR ${IPPCRYPTO_DESTDIR}/${CMAKE_INSTALL_PREFIX}/include) set(IPPCRYPTO_LIB_DIR ${IPPCRYPTO_DESTDIR}/${CMAKE_INSTALL_PREFIX}/lib/${IPPCRYPTO_ARCH}) if(IPCL_SHARED) - add_library(libippcrypto INTERFACE) - add_dependencies(libippcrypto ext_ipp-crypto) + add_library(IPPCP INTERFACE) + add_library(IPPCP::ippcp ALIAS IPPCP) + + add_dependencies(IPPCP ext_ipp-crypto) ExternalProject_Get_Property(ext_ipp-crypto SOURCE_DIR BINARY_DIR) - target_link_libraries(libippcrypto INTERFACE ${IPPCRYPTO_LIB_DIR}/libippcp.so ${IPPCRYPTO_LIB_DIR}/libcrypto_mb.so) - target_include_directories(libippcrypto SYSTEM INTERFACE ${IPPCRYPTO_INC_DIR}) + target_link_libraries(IPPCP INTERFACE + ${IPPCRYPTO_LIB_DIR}/libippcp.so + ${IPPCRYPTO_LIB_DIR}/libcrypto_mb.so + ) + target_include_directories(IPPCP SYSTEM INTERFACE ${IPPCRYPTO_INC_DIR}) install( DIRECTORY ${IPPCRYPTO_LIB_DIR}/ @@ -57,20 +62,20 @@ if(IPCL_SHARED) ) else() - add_library(libippcrypto::ippcp STATIC IMPORTED GLOBAL) - add_library(libippcrypto::crypto_mb STATIC IMPORTED GLOBAL) + add_library(IPPCP::ippcp STATIC IMPORTED GLOBAL) + add_library(IPPCP::crypto_mb STATIC IMPORTED GLOBAL) - add_dependencies(libippcrypto::ippcp ext_ipp-crypto) - add_dependencies(libippcrypto::crypto_mb ext_ipp-crypto) + add_dependencies(IPPCP::ippcp ext_ipp-crypto) + add_dependencies(IPPCP::crypto_mb ext_ipp-crypto) find_package(OpenSSL REQUIRED) - set_target_properties(libippcrypto::ippcp PROPERTIES + set_target_properties(IPPCP::ippcp PROPERTIES IMPORTED_LOCATION ${IPPCRYPTO_LIB_DIR}/libippcp.a INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} ) - set_target_properties(libippcrypto::crypto_mb PROPERTIES + set_target_properties(IPPCP::crypto_mb PROPERTIES IMPORTED_LOCATION ${IPPCRYPTO_LIB_DIR}/libcrypto_mb.a INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} ) diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index e03c83c..6afdf3b 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -71,16 +71,12 @@ if(IPCL_ENABLE_QAT) target_include_directories(ipcl PRIVATE "$" ) + + target_include_directories(ipcl - PRIVATE "$" - PRIVATE $ + PRIVATE "$" + PRIVATE $ ) - - install(DIRECTORY ${HEQAT_INC_DIR}/ - DESTINATION ${IPCL_INSTALL_INCLUDEDIR} - FILES_MATCHING - PATTERN "*.hpp" - PATTERN "*.h") endif() find_package(OpenSSL REQUIRED) @@ -93,20 +89,21 @@ if(IPCL_ENABLE_OMP) endif() if(IPCL_SHARED) - target_link_libraries(ipcl PRIVATE libippcrypto) + target_link_libraries(ipcl PRIVATE IPPCP::ippcp) if(IPCL_DETECT_IFMA_RUNTIME) - target_link_libraries(ipcl PRIVATE libcpu_features) + target_link_libraries(ipcl PRIVATE libcpu_features) endif() if(IPCL_ENABLE_QAT) target_link_libraries(ipcl PRIVATE he_qat udev z) endif() else() - ipcl_create_archive(ipcl libippcrypto::ippcp) - ipcl_create_archive(ipcl libippcrypto::crypto_mb) + ipcl_create_archive(ipcl IPPCP::crypto_mb) + ipcl_create_archive(ipcl IPPCP::ippcp) if(IPCL_ENABLE_QAT) - ipcl_create_archive(ipcl he_qat) - target_link_libraries(ipcl PRIVATE udev z) - endif() + ipcl_create_archive(ipcl he_qat) + target_link_libraries(ipcl PRIVATE udev z) + endif() + if(IPCL_DETECT_IFMA_RUNTIME) ipcl_create_archive(ipcl libcpu_features) endif() diff --git a/module/heqat/CMakeLists.txt b/module/heqat/CMakeLists.txt index 19269a5..571bde1 100644 --- a/module/heqat/CMakeLists.txt +++ b/module/heqat/CMakeLists.txt @@ -10,64 +10,83 @@ project(HE_QAT VERSION 1.3.2 LANGUAGES C CXX) include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) include(CMakePackageConfigHelpers) +include(GNUInstallDirs) -if(CMAKE_BUILD_TYPE) - set(RELEASE_TYPES - Debug - Release - RelWithDebInfo - MinSizeRel) - list(FIND RELEASE_TYPES ${CMAKE_BUILD_TYPE} INDEX_FOUND) - if(${INDEX_FOUND} EQUAL -1) - message( - FATAL_ERROR - "CMAKE_BUILD_TYPE must be one of Debug, Release, RelWithDebInfo, or MinSizeRel" - ) - endif() -else() - set(CMAKE_BUILD_TYPE Release) +set(HE_QAT_STANDALONE ON) +if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) # built under IPCL + set(HE_QAT_STANDALONE OFF) endif() -set(CMAKE_C_STANDARD 99) -set(CMAKE_C_STANDARD_REQUIRED ON) -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(CMAKE_C_FLAGS "-O2 -Wunused-variable -Wunused-function") -set(CMAKE_CXX_FLAGS "-O2 -Wunused-variable -Wunused-function -fpermissive") +if(HE_QAT_STANDALONE) + if(CMAKE_BUILD_TYPE) + set(RELEASE_TYPES + Debug + Release + RelWithDebInfo + MinSizeRel) + list(FIND RELEASE_TYPES ${CMAKE_BUILD_TYPE} INDEX_FOUND) + if(${INDEX_FOUND} EQUAL -1) + message( + FATAL_ERROR + "CMAKE_BUILD_TYPE must be one of Debug, Release, RelWithDebInfo, or MinSizeRel" + ) + endif() + else() + set(CMAKE_BUILD_TYPE Release) + endif() -# What does it do? -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + set(CMAKE_C_STANDARD 99) + set(CMAKE_C_STANDARD_REQUIRED ON) + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED ON) -# When to use it? To build with shared libraries. -set(CMAKE_POSITION_INDEPENDENT_CODE ON) + set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) + set(CMAKE_INSTALL_MESSAGE LAZY) -# Why? -set(CMAKE_INSTALL_MESSAGE LAZY) + set(CMAKE_C_FLAGS "-O2 -Wunused-variable -Wunused-function") + set(CMAKE_CXX_FLAGS "-O2 -Wunused-variable -Wunused-function -fpermissive") + if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_LIST_DIR}/install) + endif() +endif() -# Why? -set(CMAKE_INSTALL_RPATH "\$ORIGIN") +set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/heqat") -if(NOT CMAKE_INSTALL_PREFIX) - set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_LIST_DIR}/install) -endif() message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") -# Which features or functions does it bring? -include(GNUInstallDirs) - -# Location where to unpack and pack static libraries set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) # ------------------------------------------------------------------- -option(HE_QAT_MISC "Enable miscellaneous features" ON) -option(HE_QAT_SYNC "Enable synchronous mode execution" OFF) -option(HE_QAT_MT "Enable interfaces for multithreaded programs" ON) -option(HE_QAT_PERF "Show request performance" OFF) -option(HE_QAT_TEST "Enable testing" ON) -option(HE_QAT_OMP "Enable tests using OpenMP" ON) -option(HE_QAT_DOCS "Enable document building" ON) -option(HE_QAT_SHARED "Build shared library" ON) +if(HE_QAT_STANDALONE) # standalone + option(HE_QAT_MISC "Enable miscellaneous features" ON) + option(HE_QAT_SYNC "Enable synchronous mode execution" OFF) + option(HE_QAT_MT "Enable interfaces for multithreaded programs" ON) + option(HE_QAT_PERF "Show request performance" OFF) + option(HE_QAT_TEST "Enable testing" ON) + option(HE_QAT_OMP "Enable tests using OpenMP" ON) + option(HE_QAT_DOCS "Enable document building" ON) + option(HE_QAT_SHARED "Build shared library" ON) + + set(HE_QAT_FORWARD_CMAKE_ARGS + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -DCMAKE_C_STANDARD=${CMAKE_C_STANDARD} + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} + -DCMAKE_CXX_STANDARD_REQUIRED=${CMAKE_CXX_STANDARD_REQUIRED} + -DCMAKE_CXX_EXTENSIONS=${CMAKE_CXX_EXTENSIONS} + -DCMAKE_EXPORT_COMPILE_COMMANDS=${CMAKE_EXPORT_COMPILE_COMMANDS} + -DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE} + -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + ) +else() + option(HE_QAT_SYNC "Enable synchronous mode execution" OFF) + option(HE_QAT_MT "Enable interfaces for multithreaded programs" ON) + option(HE_QAT_PERF "Show request performance" OFF) + option(HE_QAT_OMP "Enable tests using OpenMP" ON) + set(HE_QAT_FORWARD_CMAKE_ARGS ${IPCL_FORWARD_CMAKE_ARGS}) +endif() if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(HE_QAT_DEBUG ON) @@ -85,6 +104,11 @@ set(HE_QAT_CMAKE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/he_qat") set(HE_QAT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) set(HE_QAT_SRC_DIR ${HE_QAT_ROOT_DIR}/heqat) set(HE_QAT_INC_DIR ${HE_QAT_ROOT_DIR}/heqat/include) +if(NOT HE_QAT_STANDALONE) + set(HE_QAT_INC_DIR ${HE_QAT_INC_DIR} PARENT_SCOPE) +endif() +set(HE_QAT_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}) +set(HE_QAT_INSTALL_LIBDIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/heqat) if(HE_QAT_OMP) find_package(OpenMP REQUIRED) @@ -102,20 +126,27 @@ if(HE_QAT_MT) endif() if(HE_QAT_MISC) - # IPP Crypto installation - if(IPPCP_PREFIX_PATH) - list(APPEND CMAKE_PREFIX_PATH "${IPPCP_PREFIX_PATH}") - set(IPPCP_DIR "${IPPCP_PREFIX_PATH}/../../../") - message(STATUS "IPPCP_DIR=${IPPCP_DIR}") + if(HE_QAT_STANDALONE) + # IPP Crypto installation + if(IPPCP_PREFIX_PATH) + list(APPEND CMAKE_PREFIX_PATH "${IPPCP_PREFIX_PATH}") + set(IPPCP_DIR "${IPPCP_PREFIX_PATH}/../../../") + message(STATUS "IPPCP_DIR=${IPPCP_DIR}") + else() + # Default to this + set(IPPCP_DIR "/opt/ipp-crypto") + set(IPPCP_PREFIX_PATH "${IPPCP_DIR}/lib/cmake") + list(APPEND CMAKE_PREFIX_PATH "${IPPCP_PREFIX_PATH}") + message(STATUS "Else IPPCP_DIR=${IPPCP_DIR}") + endif() + find_package(IPPCP REQUIRED) + message(STATUS "IPPCP_LIBRARIES ${IPPCP_LIBRARIES}") + set(IPPCP_INC_DIR ${IPPCP_DIR}/../../../include) + set(IPPCP_LIB_DIR ${IPPCP_DIR}/lib/intel64) else() - # Default to this - set(IPPCP_DIR "/opt/ipp-crypto") - set(IPPCP_PREFIX_PATH "${IPPCP_DIR}/lib/cmake") - list(APPEND CMAKE_PREFIX_PATH "${IPPCP_PREFIX_PATH}") - message(STATUS "Else IPPCP_DIR=${IPPCP_DIR}") + set(IPPCP_INC_DIR ${IPPCRYPTO_INC_DIR}/ippcrypto) + set(IPPCP_LIB_DIR ${IPPCRYPTO_LIB_DIR}) endif() - find_package(IPPCP REQUIRED) - message(STATUS "IPPCP_LIBRARIES ${IPPCP_LIBRARIES}") endif() if(HE_QAT_SYNC) @@ -126,27 +157,7 @@ if(HE_QAT_PERF) add_definitions(-DHE_QAT_PERF) endif() -set(HE_QAT_FORWARD_CMAKE_ARGS - -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} - -DCMAKE_C_STANDARD=${CMAKE_C_STANDARD} - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} - -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} - -DCMAKE_CXX_STANDARD_REQUIRED=${CMAKE_CXX_STANDARD_REQUIRED} - -DCMAKE_CXX_EXTENSIONS=${CMAKE_CXX_EXTENSIONS} - -DCMAKE_EXPORT_COMPILE_COMMANDS=${CMAKE_EXPORT_COMPILE_COMMANDS} - -DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE} - -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -) - -#OpenSSL installation -if(NOT HE_QAT_SHARED) - set(OPENSSL_USE_STATIC_LIBS TRUE) - message(STATUS "OPENSSL_USE_STATIC_LIBS TRUE") -else() - set(OPENSSL_USE_STATIC_LIBS FALSE) - message(STATUS "OPENSSL_USE_STATIC_LIBS FALSE") -endif() +# OpenSSL installation find_package(OpenSSL REQUIRED) # External dependencies diff --git a/module/heqat/heqat/CMakeLists.txt b/module/heqat/heqat/CMakeLists.txt index 0955f9c..d05886a 100644 --- a/module/heqat/heqat/CMakeLists.txt +++ b/module/heqat/heqat/CMakeLists.txt @@ -32,7 +32,7 @@ target_include_directories(he_qat ) install(DIRECTORY ${HE_QAT_INC_DIR}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h") @@ -52,13 +52,17 @@ else() heqat_create_archive(he_qat libusdm_drv_static) endif() +if(NOT HE_QAT_STANDALONE) + add_dependencies(he_qat IPPCP::ippcp) +endif() + if(HE_QAT_MISC) - target_include_directories(he_qat PRIVATE ${IPPCP_DIR}/../../../include) - target_link_directories(he_qat PUBLIC ${IPPCP_DIR}/lib/intel64) + target_include_directories(he_qat PRIVATE ${IPPCP_INC_DIR}) + target_link_directories(he_qat PRIVATE ${IPPCP_LIB_DIR}) if(HE_QAT_SHARED) target_link_libraries(he_qat PRIVATE IPPCP::ippcp) else() - heqat_create_archive (he_qat IPPCP::ippcp) + heqat_create_archive(he_qat IPPCP::ippcp) endif() endif() @@ -100,9 +104,9 @@ configure_package_config_file( install( TARGETS he_qat EXPORT he_qatTargets - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ARCHIVE DESTINATION ${HE_QAT_INSTALL_LIBDIR} + LIBRARY DESTINATION ${HE_QAT_INSTALL_LIBDIR} + RUNTIME DESTINATION ${HE_QAT_INSTALL_LIBDIR} ) install(FILES ${HE_QAT_CONFIG_FILENAME} From 6793d823f458f0b2624402f9d37d676278158548 Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Tue, 1 Nov 2022 01:46:04 +0800 Subject: [PATCH 330/364] Add support for hybrid ModExp (method#1) (#140) * modExp: Add support for hybrid * ipcl.hpp: include mod_exp.hpp * unit tests: Add modexp hybrid * example: Add hybrid modexp * benchmark: Add hybrid modexp benchmark * common.hpp: Add IPCL_QAT_MODEXP_BATCH_SIZE * modExp: Remove 2 unused qat modexp functions * mod_exp.cpp: Refactor ippModExp & add 2 wrapper functions(ippSBModExpWrapper & ippMBModExpWrapper) Co-authored-by: Sejun Kim --- benchmark/CMakeLists.txt | 3 +- benchmark/bench_hybrid.cpp | 201 ++++++++++++++++++++ benchmark/bench_ops.cpp | 1 - example/test.cpp | 15 +- ipcl/include/ipcl/common.hpp | 1 + ipcl/include/ipcl/ipcl.hpp | 1 + ipcl/include/ipcl/mod_exp.hpp | 12 ++ ipcl/mod_exp.cpp | 347 ++++++++++------------------------ test/test_cryptography.cpp | 10 +- test/test_ops.cpp | 40 +++- 10 files changed, 372 insertions(+), 259 deletions(-) create mode 100644 benchmark/bench_hybrid.cpp diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 00662dc..b88783c 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -3,7 +3,8 @@ set(IPCL_BENCH_SRC main.cpp bench_cryptography.cpp - bench_ops.cpp) + bench_ops.cpp + bench_hybrid.cpp) add_executable(bench_ipcl ${IPCL_BENCH_SRC}) target_include_directories(bench_ipcl PRIVATE diff --git a/benchmark/bench_hybrid.cpp b/benchmark/bench_hybrid.cpp new file mode 100644 index 0000000..8ecfcd0 --- /dev/null +++ b/benchmark/bench_hybrid.cpp @@ -0,0 +1,201 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include + +#include + +#include "ipcl/ipcl.hpp" + +#define MODEXP_ARG_MIN 0 +#define MODEXP_ARG_MAX 512 +#define MODEXP_ARG_STEP 64 + +constexpr bool Enable_DJN = true; + +// P_BN comes from ISO_IEC_18033_6_Compliance +const BigNumber P_BN = + "0xff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c" + "8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b4" + "0a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff76" + "4dd8b091f11a0943a2dd2b983b0df02f4c4d00b413"; + +// Q_BN comes from ISO_IEC_18033_6_Compliance +const BigNumber Q_BN = + "0xdacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d" + "9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de70" + "72a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49b" + "aa0f610bad100cdf47cc86e5034e2a0b2179e04ec7"; + +// R_BN comes from ISO_IEC_18033_6_Compliance +const BigNumber R_BN = + "0x57fb19590c31dc7c034b2a889cf4037ce3db799909c1eb0adb6199d8e96791daca9018" + "891f34309daff32dced4af7d793d16734d055e28023acab7295956bfbfdf62bf0ccb2ed3" + "1d5d176ca8b404e93007565fb6b72c33a512b4dc4f719231d62e27e34c3733929af32247" + "f88c20d1ee77096cc80d3d642464054c815b35878ba812349c8bdc3c6b645daf1a0de609" + "65f44dcf705681032480f1eeba82243196b96903becdc0df0801d4120cbd6db1c4b2841a" + "27991c44a43750c24ed0825718ad14cfb9c6b40b78ff3d25f71741f2def1c9d420d4b0fa" + "1e0a02e7851b5ec6a81133a368b80d1500b0f28fc653d2e6ff4366236dbf80ae3b4beae3" + "5e04579f2c"; + +const BigNumber HS_BN = + "0x7788f6e8f57d3488cf9e0c7f4c19521de9aa172bf35924c7827a1189d6c688ac078f77" + "7efcfc230e34f1fa5ae8d9d2ed5b062257618e0a0a485b0084b3fd39080031ea739bb48c" + "dcce4ad41704ed930d40f53a1cc5d7f70bcb379f17a912b0ad14fabe8fc10213dcd1eabd" + "9175ee9bf66c31e9af9703c9d92fa5c8d36279459631ba7e9d4571a10960f8e8d031b267" + "22f6ae6f618895b9ce4fce926c8f54169168f6bb3e033861e08c2eca2161198481bc7c52" + "3a38310be22f4dd7d028dc6b774e5cb8e6f33b24168697743b7deff411510e27694bf2e8" + "0258b325fd97370f5110f54d8d7580b45ae3db26da4e3b0409f0cfbc56d9d9856b66d8bf" + "46e727dc3148f70362d05faea743621e3841c94c78d53ee7e7fdef61022dd56922368991" + "f843ca0aebf8436e5ec7e737c7ce72ac58f138bb11a3035fe96cc5a7b1aa9d565cb8a317" + "f42564482dd3c842c5ee9fb523c165a8507ecee1ac4f185bdbcb7a51095c4c46bfe15aec" + "3dfd77e1fd2b0003596df83bbb0d5521f16e2301ec2d4aafe25e4479ee965d8bb30a689a" + "6f38ba710222fff7cf359d0f317b8e268f40f576c04262a595cdfc9a07b72978b9564ace" + "699208291da7024e86b6eeb1458658852f10794c677b53db8577af272233722ad4579d7a" + "074e57217e1c57d11862f74486c7f2987e4d09cd6fb2923569b577de50e89e6965a27e18" + "7a8a341a7282b385ef"; + +// (qatModExp, ippModExp) +static void customArgs(benchmark::internal::Benchmark* b) { + for (int i = MODEXP_ARG_MIN; i <= MODEXP_ARG_MAX; i += MODEXP_ARG_STEP) { + int j = MODEXP_ARG_MAX - i; + b->Args({i, j}); + } +} + +static void BM_Hybrid_ModExp(benchmark::State& state) { + ipcl::setHybridModExpOff(); + + int64_t qat_size = state.range(0); + int64_t ipp_size = state.range(1); + int64_t dsize = ipp_size + qat_size; + + BigNumber n = P_BN * Q_BN; + int n_length = n.BitSize(); + ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); + ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + + std::vector r_bn_v(dsize, R_BN); + pub_key->setRandom(r_bn_v); + pub_key->setHS(HS_BN); + + std::vector exp_bn_v(dsize); + for (size_t i = 0; i < dsize; i++) + exp_bn_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); + + ipcl::PlainText pt(exp_bn_v); + + BigNumber lambda = priv_key->getLambda(); + std::vector pow(dsize, lambda); + std::vector m(dsize, n * n); + + ipcl::CipherText ct = pub_key->encrypt(pt); + std::vector res(dsize); + ipcl::setHybridModExp(dsize, qat_size); + for (auto _ : state) res = ipcl::modExp(ct.getTexts(), pow, m); // decryptRAW + + delete pub_key; + delete priv_key; +} +BENCHMARK(BM_Hybrid_ModExp)->Unit(benchmark::kMicrosecond)->Apply(customArgs); + +static void BM_Hybrid_Encrypt(benchmark::State& state) { + // need to reset, otherwise will be affected by the previous benchmark + // (i.e. BM_Hybrid_ModExp) + ipcl::setHybridModExpOff(); + + int64_t qat_size = state.range(0); + int64_t ipp_size = state.range(1); + int64_t dsize = ipp_size + qat_size; + + BigNumber n = P_BN * Q_BN; + int n_length = n.BitSize(); + ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); + ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + + std::vector r_bn_v(dsize, R_BN); + pub_key->setRandom(r_bn_v); + pub_key->setHS(HS_BN); + + std::vector exp_bn_v(dsize); + for (size_t i = 0; i < dsize; i++) + exp_bn_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); + ipcl::PlainText pt(exp_bn_v); + + ipcl::CipherText ct; + ipcl::setHybridModExp(dsize, qat_size); + for (auto _ : state) ct = pub_key->encrypt(pt); + + delete pub_key; + delete priv_key; +} +BENCHMARK(BM_Hybrid_Encrypt)->Unit(benchmark::kMicrosecond)->Apply(customArgs); + +static void BM_Hybrid_Decrypt(benchmark::State& state) { + // need to reset, otherwise will be affected by the previous benchmark + // (i.e. BM_Hybrid_Encrypt) + ipcl::setHybridModExpOff(); + + int64_t qat_size = state.range(0); + int64_t ipp_size = state.range(1); + int64_t dsize = ipp_size + qat_size; + + BigNumber n = P_BN * Q_BN; + int n_length = n.BitSize(); + ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); + ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + + std::vector r_bn_v(dsize, R_BN); + pub_key->setRandom(r_bn_v); + pub_key->setHS(HS_BN); + + std::vector exp_bn_v(dsize); + for (size_t i = 0; i < dsize; i++) + exp_bn_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); + + ipcl::PlainText pt(exp_bn_v), dt; + ipcl::CipherText ct = pub_key->encrypt(pt); + ipcl::setHybridModExp(dsize, qat_size); + for (auto _ : state) dt = priv_key->decrypt(ct); + + delete pub_key; + delete priv_key; +} +BENCHMARK(BM_Hybrid_Decrypt)->Unit(benchmark::kMicrosecond)->Apply(customArgs); + +static void BM_Hybrid_MulCTPT(benchmark::State& state) { + // need to reset, otherwise will be affected by the previous benchmark + // (i.e. BM_Hybrid_Decrypt) + ipcl::setHybridModExpOff(); + + int64_t qat_size = state.range(0); + int64_t ipp_size = state.range(1); + int64_t dsize = ipp_size + qat_size; + + BigNumber n = P_BN * Q_BN; + int n_length = n.BitSize(); + ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); + ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + + std::vector r_bn_v(dsize, R_BN); + pub_key->setRandom(r_bn_v); + pub_key->setHS(HS_BN); + + std::vector exp_bn1_v(dsize), exp_bn2_v(dsize); + for (int i = 0; i < dsize; i++) { + exp_bn1_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); + exp_bn2_v[i] = Q_BN + BigNumber((unsigned int)(i * 1024)); + } + + ipcl::PlainText pt1(exp_bn1_v); + ipcl::PlainText pt2(exp_bn2_v); + + ipcl::CipherText ct1 = pub_key->encrypt(pt1); + ipcl::CipherText product; + ipcl::setHybridModExp(dsize, qat_size); + for (auto _ : state) product = ct1 * pt2; + + delete pub_key; + delete priv_key; +} +BENCHMARK(BM_Hybrid_MulCTPT)->Unit(benchmark::kMicrosecond)->Apply(customArgs); diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index dc26354..cb0acfd 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -3,7 +3,6 @@ #include -#include #include #include "ipcl/ipcl.hpp" diff --git a/example/test.cpp b/example/test.cpp index b3e052f..d5120eb 100644 --- a/example/test.cpp +++ b/example/test.cpp @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 #include -#include #include #include #include @@ -10,11 +9,12 @@ int main() { ipcl::initializeContext("QAT"); - const uint32_t num_values = 9; + const uint32_t num_total = 19; + const uint32_t num_qat = 10; ipcl::keyPair key = ipcl::generateKeypair(2048, true); - std::vector exp_value(num_values); + std::vector exp_value(num_total); ipcl::PlainText pt; ipcl::CipherText ct; ipcl::PlainText dt; @@ -23,15 +23,20 @@ int main() { std::mt19937 rng(dev()); std::uniform_int_distribution dist(0, UINT_MAX); - for (int i = 0; i < num_values; i++) { + for (int i = 0; i < num_total; i++) { exp_value[i] = dist(rng); } pt = ipcl::PlainText(exp_value); + + ipcl::setHybridModExp(num_total, num_qat); + ct = key.pub_key->encrypt(pt); dt = key.priv_key->decrypt(ct); - for (int i = 0; i < num_values; i++) { + ipcl::setHybridModExpOff(); + + for (int i = 0; i < num_total; i++) { std::vector v = dt.getElementVec(i); bool chk = v[0] == exp_value[i]; std::cout << (chk ? "pass" : "fail") << std::endl; diff --git a/ipcl/include/ipcl/common.hpp b/ipcl/include/ipcl/common.hpp index e15d44e..296e11c 100644 --- a/ipcl/include/ipcl/common.hpp +++ b/ipcl/include/ipcl/common.hpp @@ -9,6 +9,7 @@ namespace ipcl { constexpr int IPCL_CRYPTO_MB_SIZE = 8; +constexpr int IPCL_QAT_MODEXP_BATCH_SIZE = 1024; /** * Random generator wrapper.Generates a random unsigned Big Number of the diff --git a/ipcl/include/ipcl/ipcl.hpp b/ipcl/include/ipcl/ipcl.hpp index 98b9a37..2117c70 100644 --- a/ipcl/include/ipcl/ipcl.hpp +++ b/ipcl/include/ipcl/ipcl.hpp @@ -5,6 +5,7 @@ #define IPCL_INCLUDE_IPCL_IPCL_HPP_ #include "ipcl/context.hpp" +#include "ipcl/mod_exp.hpp" #include "ipcl/pri_key.hpp" namespace ipcl { diff --git a/ipcl/include/ipcl/mod_exp.hpp b/ipcl/include/ipcl/mod_exp.hpp index cf081e7..06176a1 100644 --- a/ipcl/include/ipcl/mod_exp.hpp +++ b/ipcl/include/ipcl/mod_exp.hpp @@ -10,6 +10,18 @@ namespace ipcl { +/** + * Set the number of mod exp operatiions + * @param[in] total total number of mod exp operations. + * @param[in] qat number of mod exp operations using QAT + */ +void setHybridModExp(int total, int qat); + +/** + * Turn off hybrid mod exp. + */ +void setHybridModExpOff(); + /** * Modular exponentiation for multi BigNumber * @param[in] base base of the exponentiation diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index 300d85a..0912aa0 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -12,14 +12,34 @@ #ifdef IPCL_USE_QAT #include #include + +#include //NOLINT #endif #include "ipcl/util.hpp" namespace ipcl { +static int g_hybrid_modexp_total = 0; +static int g_hybrid_modexp_qat = 0; + +void setHybridModExp(int total, int qat) { +#ifdef IPCL_USE_QAT + ERROR_CHECK((qat <= total) && (qat >= 0), + "setQatFlowSize: input size is incorrect"); + g_hybrid_modexp_total = total; + g_hybrid_modexp_qat = qat; +#endif // IPCL_USE_QAT +} + +void setHybridModExpOff() { #ifdef IPCL_USE_QAT + g_hybrid_modexp_total = 0; + g_hybrid_modexp_qat = 0; +#endif // IPCL_USE_QAT +} +#ifdef IPCL_USE_QAT // Multiple input QAT ModExp interface to offload computation to QAT static std::vector heQatBnModExp( const std::vector& base, const std::vector& exponent, @@ -274,184 +294,6 @@ static std::vector heQatBnModExp( return remainder; } - -// Multiple input QAT ModExp interface to offload computation to QAT -static std::vector heQatBnModExp( - const std::vector& base, const std::vector& exponent, - const std::vector& modulus) { - static unsigned int counter = 0; - int nbits = modulus.front().BitSize(); - int length = BITSIZE_WORD(nbits) * 4; - nbits = 8 * length; - - HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; - - // TODO(fdiasmor): Try replace calloc by alloca to see impact on performance. - unsigned char* bn_base_data_[IPCL_CRYPTO_MB_SIZE]; - unsigned char* bn_exponent_data_[IPCL_CRYPTO_MB_SIZE]; - unsigned char* bn_modulus_data_[IPCL_CRYPTO_MB_SIZE]; - unsigned char* bn_remainder_data_[IPCL_CRYPTO_MB_SIZE]; - for (int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - bn_base_data_[i] = reinterpret_cast( - malloc(length * sizeof(unsigned char))); - bn_exponent_data_[i] = reinterpret_cast( - malloc(length * sizeof(unsigned char))); - bn_modulus_data_[i] = reinterpret_cast( - malloc(length * sizeof(unsigned char))); - bn_remainder_data_[i] = reinterpret_cast( - malloc(length * sizeof(unsigned char))); - - ERROR_CHECK( - bn_base_data_[i] != nullptr && bn_exponent_data_[i] != nullptr && - bn_modulus_data_[i] != nullptr && bn_remainder_data_[i] != nullptr, - "qatMultiBuffExp: alloc memory for error"); - - memset(bn_base_data_[i], 0, length); - memset(bn_exponent_data_[i], 0, length); - memset(bn_modulus_data_[i], 0, length); - memset(bn_remainder_data_[i], 0, length); - } - - // TODO(fdiasmor): Define and use IPCL_QAT_BATCH_SIZE instead of - // IPCL_CRYPTO_MB_SIZE. - for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - bool ret = BigNumber::toBin(bn_base_data_[i], length, base[i]); - if (!ret) { - printf("bn_base_data_: failed at bigNumberToBin()\n"); - exit(1); - } - ret = BigNumber::toBin(bn_exponent_data_[i], length, exponent[i]); - if (!ret) { - printf("bn_exponent_data_: failed at bigNumberToBin()\n"); - exit(1); - } - ret = BigNumber::toBin(bn_modulus_data_[i], length, modulus[i]); - if (!ret) { - printf("bn_modulus_data_: failed at bigNumberToBin()\n"); - exit(1); - } - - unsigned char* bn_base_ = - reinterpret_cast(bn_base_data_[i]); - unsigned char* bn_exponent_ = - reinterpret_cast(bn_exponent_data_[i]); - unsigned char* bn_modulus_ = - reinterpret_cast(bn_modulus_data_[i]); - unsigned char* bn_remainder_ = - reinterpret_cast(bn_remainder_data_[i]); - - status = HE_QAT_bnModExp(bn_remainder_, bn_base_, bn_exponent_, bn_modulus_, - nbits); - if (HE_QAT_STATUS_SUCCESS != status) { - HE_QAT_PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); - } - } - getBnModExpRequest(IPCL_CRYPTO_MB_SIZE); - - std::vector remainder(IPCL_CRYPTO_MB_SIZE, 0); - // Collect results and pack them into BigNumber - for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - unsigned char* bn_remainder_ = bn_remainder_data_[i]; - bool ret = BigNumber::fromBin(remainder[i], bn_remainder_, length); - if (!ret) { - printf("bn_remainder_data_: failed at bignumbertobin()\n"); - exit(1); - } - } - - for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - free(bn_base_data_[i]); - bn_base_data_[i] = NULL; - free(bn_exponent_data_[i]); - bn_exponent_data_[i] = NULL; - free(bn_modulus_data_[i]); - bn_modulus_data_[i] = NULL; - } - - for (unsigned int i = 0; i < IPCL_CRYPTO_MB_SIZE; i++) { - free(bn_remainder_data_[i]); - bn_remainder_data_[i] = NULL; - } - - return remainder; -} - -// Single input QAT ModExp interface to offload computation to QAT -static BigNumber heQatBnModExp(const BigNumber& base, const BigNumber& exponent, - const BigNumber& modulus) { - static unsigned int counter = 0; - int nbits = modulus.BitSize(); - int length = BITSIZE_WORD(nbits) * 4; - nbits = 8 * length; - - HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; - - // TODO(fdiasmor): Try replace calloc by alloca to see impact on performance. - unsigned char* bn_base_data_ = NULL; - unsigned char* bn_exponent_data_ = NULL; - unsigned char* bn_modulus_data_ = NULL; - unsigned char* bn_remainder_data_ = NULL; - - bn_base_data_ = - reinterpret_cast(malloc(length * sizeof(unsigned char))); - bn_exponent_data_ = - reinterpret_cast(malloc(length * sizeof(unsigned char))); - bn_modulus_data_ = - reinterpret_cast(malloc(length * sizeof(unsigned char))); - bn_remainder_data_ = - reinterpret_cast(malloc(length * sizeof(unsigned char))); - - ERROR_CHECK(bn_base_data_ != nullptr && bn_exponent_data_ != nullptr && - bn_modulus_data_ != nullptr && bn_remainder_data_ != nullptr, - "qatMultiBuffExp: alloc memory for error"); - - memset(bn_base_data_, 0, length); - memset(bn_exponent_data_, 0, length); - memset(bn_modulus_data_, 0, length); - memset(bn_remainder_data_, 0, length); - - bool ret = BigNumber::toBin(bn_base_data_, length, base); - if (!ret) { - printf("bn_base_data_: failed at bignumbertobin()\n"); - exit(1); - } - ret = BigNumber::toBin(bn_exponent_data_, length, exponent); - if (!ret) { - printf("bn_exponent_data_: failed at bignumbertobin()\n"); - exit(1); - } - ret = BigNumber::toBin(bn_modulus_data_, length, modulus); - if (!ret) { - printf("bn_modulus_data_: failed at bignumbertobin()\n"); - exit(1); - } - - status = HE_QAT_bnModExp(bn_remainder_data_, bn_base_data_, bn_exponent_data_, - bn_modulus_data_, nbits); - if (HE_QAT_STATUS_SUCCESS != status) { - HE_QAT_PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); - } - getBnModExpRequest(1); - - // Collect result and pack it into BigNumber - BigNumber remainder; - ret = BigNumber::fromBin(remainder, bn_remainder_data_, length); - if (!ret) { - printf("bn_remainder_data_: failed at bignumbertobin()\n"); - exit(1); - } - - free(bn_base_data_); - bn_base_data_ = NULL; - free(bn_exponent_data_); - bn_exponent_data_ = NULL; - free(bn_modulus_data_); - bn_modulus_data_ = NULL; - free(bn_remainder_data_); - bn_remainder_data_ = NULL; - - return remainder; -} #endif // IPCL_USE_QAT static std::vector ippMBModExp(const std::vector& base, @@ -603,83 +445,19 @@ std::vector qatModExp(const std::vector& base, std::size_t worksize = base.size(); std::vector remainder(worksize); - // remainder = heQatBnModExp(base, exp, mod); - remainder = heQatBnModExp(base, exp, mod, 1024); + remainder = heQatBnModExp(base, exp, mod, IPCL_QAT_MODEXP_BATCH_SIZE); return remainder; #else ERROR_CHECK(false, "qatModExp: Need to turn on IPCL_ENABLE_QAT"); #endif // IPCL_USE_QAT } -std::vector ippModExp(const std::vector& base, - const std::vector& exp, - const std::vector& mod) { +static std::vector ippMBModExpWrapper( + const std::vector& base, const std::vector& exp, + const std::vector& mod) { std::size_t v_size = base.size(); std::vector res(v_size); -#ifdef IPCL_RUNTIME_MOD_EXP - - // If there is only 1 big number, we don't need to use MBModExp - if (v_size == 1) { - res[0] = ippSBModExp(base[0], exp[0], mod[0]); - return res; - } - - if (has_avx512ifma) { - std::size_t remainder = v_size % IPCL_CRYPTO_MB_SIZE; - std::size_t num_chunk = - (v_size + IPCL_CRYPTO_MB_SIZE - 1) / IPCL_CRYPTO_MB_SIZE; -#ifdef IPCL_USE_OMP - int omp_remaining_threads = OMPUtilities::MaxThreads; -#pragma omp parallel for num_threads( \ - OMPUtilities::assignOMPThreads(omp_remaining_threads, num_chunk)) -#endif // IPCL_USE_OMP - for (std::size_t i = 0; i < num_chunk; i++) { - std::size_t chunk_size = IPCL_CRYPTO_MB_SIZE; - if ((i == (num_chunk - 1)) && (remainder > 0)) chunk_size = remainder; - - std::size_t chunk_offset = i * IPCL_CRYPTO_MB_SIZE; - - auto base_start = base.begin() + chunk_offset; - auto base_end = base_start + chunk_size; - - auto exp_start = exp.begin() + chunk_offset; - auto exp_end = exp_start + chunk_size; - - auto mod_start = mod.begin() + chunk_offset; - auto mod_end = mod_start + chunk_size; - - auto base_chunk = std::vector(base_start, base_end); - auto exp_chunk = std::vector(exp_start, exp_end); - auto mod_chunk = std::vector(mod_start, mod_end); - - auto tmp = ippMBModExp(base_chunk, exp_chunk, mod_chunk); - std::copy(tmp.begin(), tmp.end(), res.begin() + chunk_offset); - } - - return res; - - } else { -#ifdef IPCL_USE_OMP - int omp_remaining_threads = OMPUtilities::MaxThreads; -#pragma omp parallel for num_threads( \ - OMPUtilities::assignOMPThreads(omp_remaining_threads, v_size)) -#endif // IPCL_USE_OMP - for (int i = 0; i < v_size; i++) - res[i] = ippSBModExp(base[i], exp[i], mod[i]); - return res; - } - -#else - -#ifdef IPCL_CRYPTO_MB_MOD_EXP - - // If there is only 1 big number, we don't need to use MBModExp - if (v_size == 1) { - res[0] = ippSBModExp(base[0], exp[0], mod[0]); - return res; - } - std::size_t remainder = v_size % IPCL_CRYPTO_MB_SIZE; std::size_t num_chunk = (v_size + IPCL_CRYPTO_MB_SIZE - 1) / IPCL_CRYPTO_MB_SIZE; @@ -713,8 +491,13 @@ std::vector ippModExp(const std::vector& base, } return res; +} -#else +static std::vector ippSBModExpWrapper( + const std::vector& base, const std::vector& exp, + const std::vector& mod) { + std::size_t v_size = base.size(); + std::vector res(v_size); #ifdef IPCL_USE_OMP int omp_remaining_threads = OMPUtilities::MaxThreads; @@ -723,8 +506,33 @@ std::vector ippModExp(const std::vector& base, #endif // IPCL_USE_OMP for (int i = 0; i < v_size; i++) res[i] = ippSBModExp(base[i], exp[i], mod[i]); + return res; +} + +std::vector ippModExp(const std::vector& base, + const std::vector& exp, + const std::vector& mod) { + std::size_t v_size = base.size(); + std::vector res(v_size); + // If there is only 1 big number, we don't need to use MBModExp + if (v_size == 1) { + res[0] = ippSBModExp(base[0], exp[0], mod[0]); + return res; + } + +#ifdef IPCL_RUNTIME_MOD_EXP + if (has_avx512ifma) { + return ippMBModExpWrapper(base, exp, mod); + } else { + return ippSBModExpWrapper(base, exp, mod); + } +#else +#ifdef IPCL_CRYPTO_MB_MOD_EXP + return ippMBModExpWrapper(base, exp, mod); +#else + return ippSBModExpWrapper(base, exp, mod); #endif // IPCL_CRYPTO_MB_MOD_EXP #endif // IPCL_RUNTIME_MOD_EXP } @@ -733,7 +541,50 @@ std::vector modExp(const std::vector& base, const std::vector& exp, const std::vector& mod) { #ifdef IPCL_USE_QAT - return qatModExp(base, exp, mod); + if ((g_hybrid_modexp_total == 0) || + (g_hybrid_modexp_total == g_hybrid_modexp_qat)) { + // use QAT only + return qatModExp(base, exp, mod); + } else if (g_hybrid_modexp_qat == 0) { + // use IPP only + return ippModExp(base, exp, mod); + } else { + // use QAT & IPP together + std::size_t v_size = base.size(); + std::vector res(v_size); + + ERROR_CHECK(g_hybrid_modexp_total == v_size, + "modExp: hybrid modexp size is incorrect"); + auto qat_base_start = base.begin(); + auto qat_base_end = qat_base_start + g_hybrid_modexp_qat; + + auto qat_exp_start = exp.begin(); + auto qat_exp_end = qat_exp_start + g_hybrid_modexp_qat; + + auto qat_mod_start = mod.begin(); + auto qat_mod_end = qat_mod_start + g_hybrid_modexp_qat; + + auto qat_base = std::vector(qat_base_start, qat_base_end); + auto qat_exp = std::vector(qat_exp_start, qat_exp_end); + auto qat_mod = std::vector(qat_mod_start, qat_mod_end); + + auto ipp_base = std::vector(qat_base_end, base.end()); + auto ipp_exp = std::vector(qat_exp_end, exp.end()); + auto ipp_mod = std::vector(qat_mod_end, mod.end()); + + std::vector qat_res, ipp_res; + std::thread qat_thread([&] { + qat_res = qatModExp(qat_base, qat_exp, qat_mod); + std::copy(qat_res.begin(), qat_res.end(), res.begin()); + }); + + ipp_res = ippModExp(ipp_base, ipp_exp, ipp_mod); + std::copy(ipp_res.begin(), ipp_res.end(), + res.begin() + g_hybrid_modexp_qat); + + qat_thread.join(); + return res; + } #else return ippModExp(base, exp, mod); #endif // IPCL_USE_QAT diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index bac47db..4551ec7 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -2,17 +2,18 @@ // SPDX-License-Identifier: Apache-2.0 #include -#include #include #include #include "gtest/gtest.h" #include "ipcl/ipcl.hpp" -constexpr int SELF_DEF_NUM_VALUES = 9; +constexpr int SELF_DEF_NUM_VALUES = 19; +constexpr int SELF_DEF_QAT_FLOW_SIZE = 10; TEST(CryptoTest, CryptoTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; ipcl::keyPair key = ipcl::generateKeypair(2048, true); @@ -30,6 +31,9 @@ TEST(CryptoTest, CryptoTest) { } pt = ipcl::PlainText(exp_value); + + ipcl::setHybridModExp(num_values, num_qat); + ct = key.pub_key->encrypt(pt); dt = key.priv_key->decrypt(ct); @@ -151,6 +155,8 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { ipcl::PlainText pt; ipcl::CipherText ct; + ipcl::setHybridModExpOff(); + key.pub_key->setRandom(ir_bn_v); pt = ipcl::PlainText(pt_bn_v); diff --git a/test/test_ops.cpp b/test/test_ops.cpp index 74064fe..340e337 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -2,14 +2,14 @@ // SPDX-License-Identifier: Apache-2.0 #include -#include #include #include #include "gtest/gtest.h" #include "ipcl/ipcl.hpp" -constexpr int SELF_DEF_NUM_VALUES = 7; +constexpr int SELF_DEF_NUM_VALUES = 17; +constexpr int SELF_DEF_QAT_FLOW_SIZE = 10; void CtPlusCt(ipcl::CipherText& res, const ipcl::CipherText& ct1, const ipcl::CipherText& ct2, const ipcl::keyPair key) { @@ -125,6 +125,7 @@ void PtMultiplyCtArray(ipcl::CipherText& res, const ipcl::PlainText& pt2, TEST(OperationTest, CtPlusCtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -143,6 +144,8 @@ TEST(OperationTest, CtPlusCtTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridModExp(num_values, num_qat); + ct1 = key.pub_key->encrypt(pt1); ct2 = key.pub_key->encrypt(pt2); @@ -166,6 +169,7 @@ TEST(OperationTest, CtPlusCtTest) { TEST(OperationTest, CtPlusCtArrayTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -184,6 +188,8 @@ TEST(OperationTest, CtPlusCtArrayTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridModExp(num_values, num_qat); + ct1 = key.pub_key->encrypt(pt1); ct2 = key.pub_key->encrypt(pt2); @@ -207,6 +213,7 @@ TEST(OperationTest, CtPlusCtArrayTest) { TEST(OperationTest, CtPlusPtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -225,6 +232,8 @@ TEST(OperationTest, CtPlusPtTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridModExp(num_values, num_qat); + ct1 = key.pub_key->encrypt(pt1); CtPlusPt(ct_sum, ct1, pt2, key); @@ -247,6 +256,7 @@ TEST(OperationTest, CtPlusPtTest) { TEST(OperationTest, CtPlusPtArrayTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -265,6 +275,8 @@ TEST(OperationTest, CtPlusPtArrayTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridModExp(num_values, num_qat); + ct1 = key.pub_key->encrypt(pt1); CtPlusPtArray(ct_sum, ct1, pt2, key); @@ -287,6 +299,7 @@ TEST(OperationTest, CtPlusPtArrayTest) { TEST(OperationTest, CtMultiplyPtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -305,6 +318,8 @@ TEST(OperationTest, CtMultiplyPtTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridModExp(num_values, num_qat); + ct1 = key.pub_key->encrypt(pt1); CtMultiplyPt(ct_product, ct1, pt2, key); @@ -327,6 +342,7 @@ TEST(OperationTest, CtMultiplyPtTest) { TEST(OperationTest, CtMultiplyZeroPtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -346,6 +362,8 @@ TEST(OperationTest, CtMultiplyZeroPtTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridModExp(num_values, num_qat); + ct1 = key.pub_key->encrypt(pt1); CtMultiplyPt(ct_product, ct1, pt2, key); @@ -368,6 +386,7 @@ TEST(OperationTest, CtMultiplyZeroPtTest) { TEST(OperationTest, CtMultiplyPtArrayTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -386,6 +405,8 @@ TEST(OperationTest, CtMultiplyPtArrayTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridModExp(num_values, num_qat); + ct1 = key.pub_key->encrypt(pt1); CtMultiplyPtArray(ct_product, ct1, pt2, key); @@ -408,6 +429,7 @@ TEST(OperationTest, CtMultiplyPtArrayTest) { TEST(OperationTest, AddSubTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -426,6 +448,8 @@ TEST(OperationTest, AddSubTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridModExp(num_values, num_qat); + ct1 = key.pub_key->encrypt(pt1); ct2 = key.pub_key->encrypt(pt2); @@ -449,6 +473,7 @@ TEST(OperationTest, AddSubTest) { TEST(OperationTest, PtPlusCtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -467,6 +492,8 @@ TEST(OperationTest, PtPlusCtTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridModExp(num_values, num_qat); + ct1 = key.pub_key->encrypt(pt1); PtPlusCt(ct_sum, pt2, ct1, key); @@ -489,6 +516,7 @@ TEST(OperationTest, PtPlusCtTest) { TEST(OperationTest, PtPlusCtArrayTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -507,6 +535,8 @@ TEST(OperationTest, PtPlusCtArrayTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridModExp(num_values, num_qat); + ct1 = key.pub_key->encrypt(pt1); PtPlusCtArray(ct_sum, pt2, ct1, key); @@ -529,6 +559,7 @@ TEST(OperationTest, PtPlusCtArrayTest) { TEST(OperationTest, PtMultiplyCtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -547,6 +578,8 @@ TEST(OperationTest, PtMultiplyCtTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridModExp(num_values, num_qat); + ct1 = key.pub_key->encrypt(pt1); PtMultiplyCt(ct_product, pt2, ct1, key); @@ -569,6 +602,7 @@ TEST(OperationTest, PtMultiplyCtTest) { TEST(OperationTest, PtMultiplyCtArrayTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -587,6 +621,8 @@ TEST(OperationTest, PtMultiplyCtArrayTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridModExp(num_values, num_qat); + ct1 = key.pub_key->encrypt(pt1); PtMultiplyCtArray(ct_product, pt2, ct1, key); From 9357fadbfd7680be7c5c769eae0dc69a72ac8e40 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Mon, 31 Oct 2022 23:30:50 -0700 Subject: [PATCH 331/364] Skmono/detect rdseed runtime (#148) * add runtime rng support * Enable rng selection on runtime with cpu_features - Add option to select preferred rng with environment variables --- CMakeLists.txt | 50 ++++++++++++++++++++------------------ cmake/cpufeatures.cmake | 1 - ipcl/CMakeLists.txt | 8 +++--- ipcl/common.cpp | 20 +++++++++++++++ ipcl/include/ipcl/util.hpp | 16 +++++++++--- ipcl/mod_exp.cpp | 8 +++--- 6 files changed, 66 insertions(+), 37 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a085c0..a3d1499 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,7 +68,7 @@ option(IPCL_ENABLE_OMP "Enable OpenMP testing/benchmarking" ON) option(IPCL_THREAD_COUNT "The max number of threads used by OpenMP(If the value is OFF/0, it is determined at runtime)" OFF) option(IPCL_DOCS "Enable document building" OFF) option(IPCL_SHARED "Build shared library" ON) -option(IPCL_DETECT_IFMA_RUNTIME "Detect AVX512/IFMA instructions during runtime" OFF) +option(IPCL_DETECT_CPU_RUNTIME "Detect CPU supported instructions during runtime" OFF) option(IPCL_DEBUG_DISABLE_AVX512IFMA "(Debugging) Disable usage of AVX512IFMA instructions" OFF) if(IPCL_ENABLE_QAT) @@ -92,13 +92,14 @@ if(IPCL_ENABLE_OMP) endif() endif() -if(IPCL_DETECT_IFMA_RUNTIME) - add_compile_definitions(IPCL_RUNTIME_MOD_EXP) +if(IPCL_DETECT_CPU_RUNTIME) + # add_compile_definitions(IPCL_RUNTIME_MOD_EXP) + add_compile_definitions(IPCL_RUNTIME_DETECT_CPU_FEATURES) set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ipcl/cpufeatures") else() - # check whether cpu support avx512 flag + # check whether cpu support avx512ifma instructions if(IPCL_DEBUG_DISABLE_AVX512IFMA) - message(STATUS "Support AVX512IFMA: False") + message(STATUS "Support AVX512IFMA instruction: False") else() ipcl_detect_lscpu_flag("avx512ifma" FALSE) if(IPCL_FOUND_avx512ifma) @@ -106,6 +107,24 @@ else() message(STATUS "Support AVX512IFMA instruction: True") endif() endif() + + # check whether cpu support rdseed/rdrand instructions + ipcl_detect_lscpu_flag("rdseed" FALSE) + if(IPCL_FOUND_rdseed) + message(STATUS "Support RDSEED instruction: True") + add_compile_definitions(IPCL_RNG_INSTR_RDSEED) + else() + ipcl_detect_lscpu_flag("rdrand" FALSE) + if(IPCL_FOUND_rdrand) + message(STATUS "Support RDRAND instruction: True") + add_compile_definitions(IPCL_RNG_INSTR_RDRAND) + else() + message(WARNING + "CPU doesn't support RDSEED and RDRAND instruction, using IPP-Crypto" + " S/W pseudo random number generator" + ) + endif() + endif() endif() message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") @@ -123,25 +142,9 @@ else() endif() message(STATUS "IPCL_DOCS: ${IPCL_DOCS}") message(STATUS "IPCL_SHARED: ${IPCL_SHARED}") -message(STATUS "IPCL_DETECT_IFMA_RUNTIME: ${IPCL_DETECT_IFMA_RUNTIME}") +message(STATUS "IPCL_DETECT_CPU_RUNTIME: ${IPCL_DETECT_CPU_RUNTIME}") # check whether cpu support rdseed or rdrand instruction -ipcl_detect_lscpu_flag("rdseed" FALSE) -if(IPCL_FOUND_rdseed) - message(STATUS "Support RDSEED instruction: True") - add_compile_definitions(IPCL_RNG_INSTR_RDSEED) -else() - ipcl_detect_lscpu_flag("rdrand" FALSE) - if(IPCL_FOUND_rdrand) - message(STATUS "Support RDRAND instruction: True") - add_compile_definitions(IPCL_RNG_INSTR_RDRAND) - else() - message(WARNING - "CPU doesn't support RDSEED and RDRAND instruction, using IPP-Crypto" - " S/W pseudo random number generator" - ) - endif() -endif() set(IPCL_FORWARD_CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} @@ -177,7 +180,8 @@ find_package(OpenSSL REQUIRED) # External dependencies include(cmake/ippcrypto.cmake) -if(IPCL_DETECT_IFMA_RUNTIME) + +if(IPCL_DETECT_CPU_RUNTIME) include(cmake/cpufeatures.cmake) endif() diff --git a/cmake/cpufeatures.cmake b/cmake/cpufeatures.cmake index 1526750..189dd8e 100644 --- a/cmake/cpufeatures.cmake +++ b/cmake/cpufeatures.cmake @@ -25,7 +25,6 @@ ExternalProject_Add( INSTALL_COMMAND make DESTDIR=${CPUFEATURES_DESTDIR} install ) - set(CPUFEATURES_INC_DIR ${CPUFEATURES_DESTDIR}/${CMAKE_INSTALL_PREFIX}/include) set(CPUFEATURES_LIB_DIR ${CPUFEATURES_DESTDIR}/${CMAKE_INSTALL_PREFIX}/lib) diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 6afdf3b..6f15293 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -53,7 +53,7 @@ install(DIRECTORY ${IPPCRYPTO_INC_DIR}/ PATTERN "*.h") # include and install definition of cpu_features -if(IPCL_DETECT_IFMA_RUNTIME) +if(IPCL_DETECT_CPU_RUNTIME) target_include_directories(ipcl PUBLIC $ PRIVATE $ @@ -90,7 +90,7 @@ endif() if(IPCL_SHARED) target_link_libraries(ipcl PRIVATE IPPCP::ippcp) - if(IPCL_DETECT_IFMA_RUNTIME) + if(IPCL_DETECT_CPU_RUNTIME) target_link_libraries(ipcl PRIVATE libcpu_features) endif() if(IPCL_ENABLE_QAT) @@ -104,8 +104,8 @@ else() target_link_libraries(ipcl PRIVATE udev z) endif() - if(IPCL_DETECT_IFMA_RUNTIME) - ipcl_create_archive(ipcl libcpu_features) + if(IPCL_DETECT_CPU_RUNTIME) + ipcl_create_archive(ipcl libcpu_features) endif() endif() diff --git a/ipcl/common.cpp b/ipcl/common.cpp index 90209eb..565002d 100644 --- a/ipcl/common.cpp +++ b/ipcl/common.cpp @@ -5,11 +5,21 @@ #include +#include + #include "ipcl/util.hpp" namespace ipcl { IppStatus ippGenRandom(Ipp32u* rand, int bits, void* ctx) { +#ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES + if (has_rdseed) + return ippsTRNGenRDSEED(rand, bits, ctx); + else if (has_rdrand) + return ippsPRNGenRDRAND(rand, bits, ctx); + else + return ippsPRNGen(rand, bits, ctx); +#else #ifdef IPCL_RNG_INSTR_RDSEED return ippsTRNGenRDSEED(rand, bits, ctx); #elif defined(IPCL_RNG_INSTR_RDRAND) @@ -17,9 +27,18 @@ IppStatus ippGenRandom(Ipp32u* rand, int bits, void* ctx) { #else return ippsPRNGen(rand, bits, ctx); #endif +#endif // IPCL_RUNTIME_IPP_RNG } IppStatus ippGenRandomBN(IppsBigNumState* rand, int bits, void* ctx) { +#ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES + if (has_rdseed) + return ippsTRNGenRDSEED_BN(rand, bits, ctx); + else if (has_rdrand) + return ippsPRNGenRDRAND_BN(rand, bits, ctx); + else + return ippsPRNGen_BN(rand, bits, ctx); +#else #ifdef IPCL_RNG_INSTR_RDSEED return ippsTRNGenRDSEED_BN(rand, bits, ctx); #elif defined(IPCL_RNG_INSTR_RDRAND) @@ -27,6 +46,7 @@ IppStatus ippGenRandomBN(IppsBigNumState* rand, int bits, void* ctx) { #else return ippsPRNGen_BN(rand, bits, ctx); #endif +#endif // IPCL_RUNTIME_IPP_RNG } BigNumber getRandomBN(int bits) { diff --git a/ipcl/include/ipcl/util.hpp b/ipcl/include/ipcl/util.hpp index 202e277..c2ea76a 100644 --- a/ipcl/include/ipcl/util.hpp +++ b/ipcl/include/ipcl/util.hpp @@ -4,9 +4,9 @@ #ifndef IPCL_INCLUDE_IPCL_UTIL_HPP_ #define IPCL_INCLUDE_IPCL_UTIL_HPP_ -#ifdef IPCL_RUNTIME_MOD_EXP +#ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES #include -#endif // IPCL_RUNTIME_MOD_EXP +#endif // IPCL_RUNTIME_DETECT_CPU_FEATURES #include #include @@ -71,13 +71,21 @@ class OMPUtilities { #endif // IPCL_USE_OMP -#ifdef IPCL_RUNTIME_MOD_EXP +#ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES static const bool disable_avx512ifma = (std::getenv("IPCL_DISABLE_AVX512IFMA") != nullptr); +static const bool prefer_rdrand = + (std::getenv("IPCL_PREFER_RDRAND") != nullptr); +static const bool prefer_ipp_prng = + (std::getenv("IPCL_PREFER_IPP_PRNG") != nullptr); static const cpu_features::X86Features features = cpu_features::GetX86Info().features; static const bool has_avx512ifma = features.avx512ifma && !disable_avx512ifma; -#endif // IPCL_RUNTIME_MOD_EXP +static const bool has_rdseed = + features.rdseed && !prefer_rdrand && !prefer_ipp_prng; +static const bool has_rdrand = features.rdrnd && prefer_rdrand; + +#endif // IPCL_RUNTIME_DETECT_CPU_FEATURES } // namespace ipcl diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index 0912aa0..abea9ed 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -522,19 +522,17 @@ std::vector ippModExp(const std::vector& base, return res; } -#ifdef IPCL_RUNTIME_MOD_EXP +#ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES if (has_avx512ifma) { return ippMBModExpWrapper(base, exp, mod); } else { return ippSBModExpWrapper(base, exp, mod); } -#else -#ifdef IPCL_CRYPTO_MB_MOD_EXP +#elif IPCL_CRYPTO_MB_MOD_EXP return ippMBModExpWrapper(base, exp, mod); #else return ippSBModExpWrapper(base, exp, mod); -#endif // IPCL_CRYPTO_MB_MOD_EXP -#endif // IPCL_RUNTIME_MOD_EXP +#endif // IPCL_RUNTIME_DETECT_CPU_FEATURES } std::vector modExp(const std::vector& base, From aa1864869f28042edb2c5b5a62ff80ae34f47d7d Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Sat, 5 Nov 2022 06:28:53 +0800 Subject: [PATCH 332/364] Add hybrid mode (#149) * Major updates - modexp - Change setHybridModExp input parameter - Add setHybridMode interface - Add getHybridRatio & isHybridOptimal - Make global variable ```g_hybrid_qat``` thread local - cmake: Turn off IPCL_ENABLE_OMP, when IPCL_THREAD_COUNT=1 - encrypt, decrypt, multiply: Add special hybrid qat ratio, when OPTIMAL mode is used - unit test, benchmark, example: Updated with new setHybridModExp/setHybridMode interface * Minor updates: - Fix ```isHybridOptimal``` to ```isHybridOptimal()``` - Add ```bench_hybrid.cpp``` to benchmark target when ```IPCL_ENABLE_QAT=ON``` - Replaced 0 to 10 scale of hybrid benchmark to 0 to 100 scale to be inline with hybrid ratio Co-authored-by: sejunkim --- CMakeLists.txt | 4 ++ benchmark/CMakeLists.txt | 13 +++-- benchmark/bench_hybrid.cpp | 89 ++++++++++++++++++++++++----------- example/test.cpp | 7 ++- ipcl/ciphertext.cpp | 9 ++++ ipcl/include/ipcl/common.hpp | 6 +++ ipcl/include/ipcl/mod_exp.hpp | 47 ++++++++++++++++-- ipcl/mod_exp.cpp | 85 +++++++++++++++++++++------------ ipcl/pri_key.cpp | 8 ++++ ipcl/pub_key.cpp | 8 ++++ test/CMakeLists.txt | 8 ++-- test/test_cryptography.cpp | 10 ++-- test/test_ops.cpp | 52 ++++++++++---------- 13 files changed, 243 insertions(+), 103 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a3d1499..78ac4f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,10 @@ if(IPCL_ENABLE_QAT) endif() endif() +if(IPCL_THREAD_COUNT LESS_EQUAL 1) + set(IPCL_ENABLE_OMP OFF) +endif() + if(IPCL_ENABLE_OMP) add_compile_definitions(IPCL_USE_OMP) if(IPCL_THREAD_COUNT) diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index b88783c..cadb1f6 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -1,15 +1,20 @@ # Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -set(IPCL_BENCH_SRC main.cpp +set(IPCL_BENCH_SRC + main.cpp bench_cryptography.cpp bench_ops.cpp - bench_hybrid.cpp) +) + +if(IPCL_ENABLE_QAT) + list(APPEND IPCL_BENCH_SRC bench_hybrid.cpp) +endif() add_executable(bench_ipcl ${IPCL_BENCH_SRC}) target_include_directories(bench_ipcl PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${IPCL_INC_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${IPCL_INC_DIR} ) target_link_libraries(bench_ipcl PRIVATE diff --git a/benchmark/bench_hybrid.cpp b/benchmark/bench_hybrid.cpp index 8ecfcd0..d911301 100644 --- a/benchmark/bench_hybrid.cpp +++ b/benchmark/bench_hybrid.cpp @@ -7,9 +7,16 @@ #include "ipcl/ipcl.hpp" -#define MODEXP_ARG_MIN 0 -#define MODEXP_ARG_MAX 512 -#define MODEXP_ARG_STEP 64 +#define BENCH_HYBRID_DETAIL 1 + +#define INPUT_BN_NUM_MAX 256 +#define INPUT_BN_NUM_MIN 16 +#define INPUT_BN_NUM_GROWTH_RATE 2 + +// scale it from [0, 1] to [0, 100] +#define HYBRID_QAT_RATIO_MAX 100 +#define HYBRID_QAT_RATIO_MIN 0 +#define HYBRID_QAT_RATIO_STEP 10 constexpr bool Enable_DJN = true; @@ -55,20 +62,26 @@ const BigNumber HS_BN = "074e57217e1c57d11862f74486c7f2987e4d09cd6fb2923569b577de50e89e6965a27e18" "7a8a341a7282b385ef"; -// (qatModExp, ippModExp) +// (data_size, qat_ratio) static void customArgs(benchmark::internal::Benchmark* b) { - for (int i = MODEXP_ARG_MIN; i <= MODEXP_ARG_MAX; i += MODEXP_ARG_STEP) { - int j = MODEXP_ARG_MAX - i; - b->Args({i, j}); + for (int i = INPUT_BN_NUM_MIN; i <= INPUT_BN_NUM_MAX; + i *= INPUT_BN_NUM_GROWTH_RATE) { +#if BENCH_HYBRID_DETAIL + for (int j = HYBRID_QAT_RATIO_MIN; j <= HYBRID_QAT_RATIO_MAX; + j += HYBRID_QAT_RATIO_STEP) { + b->Args({i, j}); + } +#else + b->Args({i}); +#endif } } static void BM_Hybrid_ModExp(benchmark::State& state) { - ipcl::setHybridModExpOff(); + ipcl::setHybridOff(); - int64_t qat_size = state.range(0); - int64_t ipp_size = state.range(1); - int64_t dsize = ipp_size + qat_size; + int64_t dsize = state.range(0); + float qat_ratio = state.range(1) * 0.01; // scale it back BigNumber n = P_BN * Q_BN; int n_length = n.BitSize(); @@ -91,7 +104,13 @@ static void BM_Hybrid_ModExp(benchmark::State& state) { ipcl::CipherText ct = pub_key->encrypt(pt); std::vector res(dsize); - ipcl::setHybridModExp(dsize, qat_size); + +#if BENCH_HYBRID_DETAIL + ipcl::setHybridRatio(qat_ratio); +#else + ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); +#endif + for (auto _ : state) res = ipcl::modExp(ct.getTexts(), pow, m); // decryptRAW delete pub_key; @@ -102,11 +121,10 @@ BENCHMARK(BM_Hybrid_ModExp)->Unit(benchmark::kMicrosecond)->Apply(customArgs); static void BM_Hybrid_Encrypt(benchmark::State& state) { // need to reset, otherwise will be affected by the previous benchmark // (i.e. BM_Hybrid_ModExp) - ipcl::setHybridModExpOff(); + ipcl::setHybridOff(); - int64_t qat_size = state.range(0); - int64_t ipp_size = state.range(1); - int64_t dsize = ipp_size + qat_size; + int64_t dsize = state.range(0); + float qat_ratio = state.range(1) * 0.01; // scale it back BigNumber n = P_BN * Q_BN; int n_length = n.BitSize(); @@ -121,9 +139,14 @@ static void BM_Hybrid_Encrypt(benchmark::State& state) { for (size_t i = 0; i < dsize; i++) exp_bn_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); ipcl::PlainText pt(exp_bn_v); - ipcl::CipherText ct; - ipcl::setHybridModExp(dsize, qat_size); + +#if BENCH_HYBRID_DETAIL + ipcl::setHybridRatio(qat_ratio); +#else + ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); +#endif + for (auto _ : state) ct = pub_key->encrypt(pt); delete pub_key; @@ -134,11 +157,10 @@ BENCHMARK(BM_Hybrid_Encrypt)->Unit(benchmark::kMicrosecond)->Apply(customArgs); static void BM_Hybrid_Decrypt(benchmark::State& state) { // need to reset, otherwise will be affected by the previous benchmark // (i.e. BM_Hybrid_Encrypt) - ipcl::setHybridModExpOff(); + ipcl::setHybridOff(); - int64_t qat_size = state.range(0); - int64_t ipp_size = state.range(1); - int64_t dsize = ipp_size + qat_size; + int64_t dsize = state.range(0); + float qat_ratio = state.range(1) * 0.01; // scale it back BigNumber n = P_BN * Q_BN; int n_length = n.BitSize(); @@ -155,7 +177,13 @@ static void BM_Hybrid_Decrypt(benchmark::State& state) { ipcl::PlainText pt(exp_bn_v), dt; ipcl::CipherText ct = pub_key->encrypt(pt); - ipcl::setHybridModExp(dsize, qat_size); + +#if BENCH_HYBRID_DETAIL + ipcl::setHybridRatio(qat_ratio); +#else + ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); +#endif + for (auto _ : state) dt = priv_key->decrypt(ct); delete pub_key; @@ -166,11 +194,10 @@ BENCHMARK(BM_Hybrid_Decrypt)->Unit(benchmark::kMicrosecond)->Apply(customArgs); static void BM_Hybrid_MulCTPT(benchmark::State& state) { // need to reset, otherwise will be affected by the previous benchmark // (i.e. BM_Hybrid_Decrypt) - ipcl::setHybridModExpOff(); + ipcl::setHybridOff(); - int64_t qat_size = state.range(0); - int64_t ipp_size = state.range(1); - int64_t dsize = ipp_size + qat_size; + int64_t dsize = state.range(0); + float qat_ratio = state.range(1) * 0.01; // scale it back BigNumber n = P_BN * Q_BN; int n_length = n.BitSize(); @@ -192,7 +219,13 @@ static void BM_Hybrid_MulCTPT(benchmark::State& state) { ipcl::CipherText ct1 = pub_key->encrypt(pt1); ipcl::CipherText product; - ipcl::setHybridModExp(dsize, qat_size); + +#if BENCH_HYBRID_DETAIL + ipcl::setHybridRatio(qat_ratio); +#else + ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); +#endif + for (auto _ : state) product = ct1 * pt2; delete pub_key; diff --git a/example/test.cpp b/example/test.cpp index d5120eb..035f063 100644 --- a/example/test.cpp +++ b/example/test.cpp @@ -9,8 +9,7 @@ int main() { ipcl::initializeContext("QAT"); - const uint32_t num_total = 19; - const uint32_t num_qat = 10; + const uint32_t num_total = 20; ipcl::keyPair key = ipcl::generateKeypair(2048, true); @@ -29,12 +28,12 @@ int main() { pt = ipcl::PlainText(exp_value); - ipcl::setHybridModExp(num_total, num_qat); + ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); ct = key.pub_key->encrypt(pt); dt = key.priv_key->decrypt(ct); - ipcl::setHybridModExpOff(); + ipcl::setHybridOff(); for (int i = 0; i < num_total; i++) { std::vector v = dt.getElementVec(i); diff --git a/ipcl/ciphertext.cpp b/ipcl/ciphertext.cpp index efcdc66..91c0016 100644 --- a/ipcl/ciphertext.cpp +++ b/ipcl/ciphertext.cpp @@ -149,6 +149,15 @@ std::vector CipherText::raw_mul( const std::vector& a, const std::vector& b) const { std::size_t v_size = a.size(); std::vector sq(v_size, m_pubkey->getNSQ()); + + // If hybrid OPTIMAL mode is used, use a special ratio + if (isHybridOptimal()) { + float qat_ratio = (v_size <= IPCL_WORKLOAD_SIZE_THRESHOLD) + ? IPCL_HYBRID_MODEXP_RATIO_FULL + : IPCL_HYBRID_MODEXP_RATIO_MULTIPLY; + setHybridRatio(qat_ratio); + } + return modExp(a, b, sq); } diff --git a/ipcl/include/ipcl/common.hpp b/ipcl/include/ipcl/common.hpp index 296e11c..1281198 100644 --- a/ipcl/include/ipcl/common.hpp +++ b/ipcl/include/ipcl/common.hpp @@ -11,6 +11,12 @@ namespace ipcl { constexpr int IPCL_CRYPTO_MB_SIZE = 8; constexpr int IPCL_QAT_MODEXP_BATCH_SIZE = 1024; +constexpr int IPCL_WORKLOAD_SIZE_THRESHOLD = 128; + +constexpr float IPCL_HYBRID_MODEXP_RATIO_FULL = 1.0; +constexpr float IPCL_HYBRID_MODEXP_RATIO_ENCRYPT = 0.25; +constexpr float IPCL_HYBRID_MODEXP_RATIO_DECRYPT = 0.12; +constexpr float IPCL_HYBRID_MODEXP_RATIO_MULTIPLY = 0.18; /** * Random generator wrapper.Generates a random unsigned Big Number of the * specified bit length diff --git a/ipcl/include/ipcl/mod_exp.hpp b/ipcl/include/ipcl/mod_exp.hpp index 06176a1..7f41b11 100644 --- a/ipcl/include/ipcl/mod_exp.hpp +++ b/ipcl/include/ipcl/mod_exp.hpp @@ -10,17 +10,56 @@ namespace ipcl { +/** + * Hybrid mode type + */ +enum class HybridMode { + OPTIMAL = 95, + QAT = 100, + PREF_QAT90 = 90, + PREF_QAT80 = 80, + PREF_QAT70 = 70, + PREF_QAT60 = 60, + HALF = 50, + PREF_IPP60 = 40, + PREF_IPP70 = 30, + PREF_IPP80 = 20, + PREF_IPP90 = 10, + IPP = 0, + UNDEFINED = -1 +}; + +/** + * Set hybrid mode + * @param[in] mode The type of hybrid mode + */ +void setHybridMode(HybridMode mode); + /** * Set the number of mod exp operatiions - * @param[in] total total number of mod exp operations. - * @param[in] qat number of mod exp operations using QAT + * @param[in] Proportion calculated with QAT */ -void setHybridModExp(int total, int qat); +void setHybridRatio(float qat_ratio); /** * Turn off hybrid mod exp. */ -void setHybridModExpOff(); +void setHybridOff(); + +/** + * Get current hybrid qat ratio + */ +float getHybridRatio(); + +/** + * Get current hybrid mode + */ +HybridMode getHybridMode(); + +/** + * Whether current hybrid mode is OPTIMAL + */ +bool isHybridOptimal(); /** * Modular exponentiation for multi BigNumber diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index abea9ed..290ef66 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -8,37 +8,63 @@ #include #include #include +#include //NOLINT #ifdef IPCL_USE_QAT #include #include - -#include //NOLINT #endif #include "ipcl/util.hpp" namespace ipcl { -static int g_hybrid_modexp_total = 0; -static int g_hybrid_modexp_qat = 0; +static thread_local struct { + float ratio; + HybridMode mode; +} g_hybrid_params = {0.0, HybridMode::UNDEFINED}; -void setHybridModExp(int total, int qat) { +static inline float scale_down(int value, float scale = 100.0) { + return value / scale; +} + +static inline int scale_up(float value, int scale = 100) { + return value * scale; +} + +void setHybridRatio(float ratio) { #ifdef IPCL_USE_QAT - ERROR_CHECK((qat <= total) && (qat >= 0), - "setQatFlowSize: input size is incorrect"); - g_hybrid_modexp_total = total; - g_hybrid_modexp_qat = qat; + ERROR_CHECK((ratio <= 1.0) && (ratio >= 0), + "setHybridRatio: Hybrid modexp qat ratio is NOT correct"); + g_hybrid_params.ratio = ratio; + g_hybrid_params.mode = HybridMode::UNDEFINED; #endif // IPCL_USE_QAT } -void setHybridModExpOff() { +void setHybridMode(HybridMode mode) { #ifdef IPCL_USE_QAT - g_hybrid_modexp_total = 0; - g_hybrid_modexp_qat = 0; + g_hybrid_params.mode = mode; + int mode_value = static_cast::type>(mode); + float ratio = scale_down(mode_value); + setHybridRatio(ratio); #endif // IPCL_USE_QAT } +void setHybridOff() { +#ifdef IPCL_USE_QAT + g_hybrid_params.mode = HybridMode::UNDEFINED; + g_hybrid_params.ratio = 0.0; +#endif // IPCL_USE_QAT +} + +float getHybridRatio() { return g_hybrid_params.ratio; } + +HybridMode getHybridMode() { return g_hybrid_params.mode; } + +bool isHybridOptimal() { + return (g_hybrid_params.mode == HybridMode::OPTIMAL) ? true : false; +} + #ifdef IPCL_USE_QAT // Multiple input QAT ModExp interface to offload computation to QAT static std::vector heQatBnModExp( @@ -441,12 +467,7 @@ std::vector qatModExp(const std::vector& base, const std::vector& exp, const std::vector& mod) { #ifdef IPCL_USE_QAT - // TODO(fdiasmor): Slice with custom batches, test OMP - std::size_t worksize = base.size(); - std::vector remainder(worksize); - - remainder = heQatBnModExp(base, exp, mod, IPCL_QAT_MODEXP_BATCH_SIZE); - return remainder; + return heQatBnModExp(base, exp, mod, IPCL_QAT_MODEXP_BATCH_SIZE); #else ERROR_CHECK(false, "qatModExp: Need to turn on IPCL_ENABLE_QAT"); #endif // IPCL_USE_QAT @@ -539,28 +560,34 @@ std::vector modExp(const std::vector& base, const std::vector& exp, const std::vector& mod) { #ifdef IPCL_USE_QAT - if ((g_hybrid_modexp_total == 0) || - (g_hybrid_modexp_total == g_hybrid_modexp_qat)) { +// if QAT is ON, OMP is OFF --> use QAT only +#if !defined(IPCL_USE_OMP) + return qatModExp(base, exp, mod); +#else + ERROR_CHECK(g_hybrid_params.ratio >= 0.0 && g_hybrid_params.ratio <= 1.0, + "modExp: hybrid modexp qat ratio is incorrect"); + std::size_t v_size = base.size(); + std::size_t hybrid_qat_size = + static_cast(g_hybrid_params.ratio * v_size); + + if (hybrid_qat_size == v_size) { // use QAT only return qatModExp(base, exp, mod); - } else if (g_hybrid_modexp_qat == 0) { + } else if (hybrid_qat_size == 0) { // use IPP only return ippModExp(base, exp, mod); } else { // use QAT & IPP together - std::size_t v_size = base.size(); std::vector res(v_size); - ERROR_CHECK(g_hybrid_modexp_total == v_size, - "modExp: hybrid modexp size is incorrect"); auto qat_base_start = base.begin(); - auto qat_base_end = qat_base_start + g_hybrid_modexp_qat; + auto qat_base_end = qat_base_start + hybrid_qat_size; auto qat_exp_start = exp.begin(); - auto qat_exp_end = qat_exp_start + g_hybrid_modexp_qat; + auto qat_exp_end = qat_exp_start + hybrid_qat_size; auto qat_mod_start = mod.begin(); - auto qat_mod_end = qat_mod_start + g_hybrid_modexp_qat; + auto qat_mod_end = qat_mod_start + hybrid_qat_size; auto qat_base = std::vector(qat_base_start, qat_base_end); auto qat_exp = std::vector(qat_exp_start, qat_exp_end); @@ -577,12 +604,12 @@ std::vector modExp(const std::vector& base, }); ipp_res = ippModExp(ipp_base, ipp_exp, ipp_mod); - std::copy(ipp_res.begin(), ipp_res.end(), - res.begin() + g_hybrid_modexp_qat); + std::copy(ipp_res.begin(), ipp_res.end(), res.begin() + hybrid_qat_size); qat_thread.join(); return res; } +#endif // IPCL_USE_OMP #else return ippModExp(base, exp, mod); #endif // IPCL_USE_QAT diff --git a/ipcl/pri_key.cpp b/ipcl/pri_key.cpp index 9a781fd..09b4984 100644 --- a/ipcl/pri_key.cpp +++ b/ipcl/pri_key.cpp @@ -62,6 +62,14 @@ PlainText PrivateKey::decrypt(const CipherText& ct) const { std::vector pt_bn(ct_size); std::vector ct_bn = ct.getTexts(); + // If hybrid OPTIMAL mode is used, use a special ratio + if (isHybridOptimal()) { + float qat_ratio = (ct_size <= IPCL_WORKLOAD_SIZE_THRESHOLD) + ? IPCL_HYBRID_MODEXP_RATIO_FULL + : IPCL_HYBRID_MODEXP_RATIO_DECRYPT; + setHybridRatio(qat_ratio); + } + if (m_enable_crt) decryptCRT(pt_bn, ct_bn); else diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index 8e1a73c..581d830 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -121,6 +121,14 @@ CipherText PublicKey::encrypt(const PlainText& pt, bool make_secure) const { ERROR_CHECK(pt_size > 0, "encrypt: Cannot encrypt empty PlainText"); std::vector ct_bn_v(pt_size); + // If hybrid OPTIMAL mode is used, use a special ratio + if (isHybridOptimal()) { + float qat_ratio = (pt_size <= IPCL_WORKLOAD_SIZE_THRESHOLD) + ? IPCL_HYBRID_MODEXP_RATIO_FULL + : IPCL_HYBRID_MODEXP_RATIO_ENCRYPT; + setHybridRatio(qat_ratio); + } + ct_bn_v = raw_encrypt(pt.getTexts(), make_secure); return CipherText(this, ct_bn_v); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index fe6c6e9..4d7550d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -2,9 +2,11 @@ # SPDX-License-Identifier: Apache-2.0 # Unit tests -set(IPCL_UNITTEST_SRC main.cpp -test_cryptography.cpp -test_ops.cpp) +set(IPCL_UNITTEST_SRC + main.cpp + test_cryptography.cpp + test_ops.cpp +) add_executable(unittest_ipcl ${IPCL_UNITTEST_SRC}) target_include_directories(unittest_ipcl PRIVATE diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index 4551ec7..24d4fb9 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -8,12 +8,12 @@ #include "gtest/gtest.h" #include "ipcl/ipcl.hpp" -constexpr int SELF_DEF_NUM_VALUES = 19; -constexpr int SELF_DEF_QAT_FLOW_SIZE = 10; +constexpr int SELF_DEF_NUM_VALUES = 18; +constexpr float SELF_DEF_HYBRID_QAT_RATIO = 0.5; TEST(CryptoTest, CryptoTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; - const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048, true); @@ -32,7 +32,7 @@ TEST(CryptoTest, CryptoTest) { pt = ipcl::PlainText(exp_value); - ipcl::setHybridModExp(num_values, num_qat); + ipcl::setHybridRatio(qat_ratio); ct = key.pub_key->encrypt(pt); dt = key.priv_key->decrypt(ct); @@ -155,7 +155,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { ipcl::PlainText pt; ipcl::CipherText ct; - ipcl::setHybridModExpOff(); + ipcl::setHybridOff(); key.pub_key->setRandom(ir_bn_v); diff --git a/test/test_ops.cpp b/test/test_ops.cpp index 340e337..7a33a1e 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -8,8 +8,8 @@ #include "gtest/gtest.h" #include "ipcl/ipcl.hpp" -constexpr int SELF_DEF_NUM_VALUES = 17; -constexpr int SELF_DEF_QAT_FLOW_SIZE = 10; +constexpr int SELF_DEF_NUM_VALUES = 14; +constexpr float SELF_DEF_HYBRID_QAT_RATIO = 0.5; void CtPlusCt(ipcl::CipherText& res, const ipcl::CipherText& ct1, const ipcl::CipherText& ct2, const ipcl::keyPair key) { @@ -125,7 +125,7 @@ void PtMultiplyCtArray(ipcl::CipherText& res, const ipcl::PlainText& pt2, TEST(OperationTest, CtPlusCtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; - const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -144,7 +144,7 @@ TEST(OperationTest, CtPlusCtTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); - ipcl::setHybridModExp(num_values, num_qat); + ipcl::setHybridRatio(qat_ratio); ct1 = key.pub_key->encrypt(pt1); ct2 = key.pub_key->encrypt(pt2); @@ -169,7 +169,7 @@ TEST(OperationTest, CtPlusCtTest) { TEST(OperationTest, CtPlusCtArrayTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; - const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -188,7 +188,7 @@ TEST(OperationTest, CtPlusCtArrayTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); - ipcl::setHybridModExp(num_values, num_qat); + ipcl::setHybridRatio(qat_ratio); ct1 = key.pub_key->encrypt(pt1); ct2 = key.pub_key->encrypt(pt2); @@ -213,7 +213,7 @@ TEST(OperationTest, CtPlusCtArrayTest) { TEST(OperationTest, CtPlusPtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; - const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -232,7 +232,7 @@ TEST(OperationTest, CtPlusPtTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); - ipcl::setHybridModExp(num_values, num_qat); + ipcl::setHybridRatio(qat_ratio); ct1 = key.pub_key->encrypt(pt1); @@ -256,7 +256,7 @@ TEST(OperationTest, CtPlusPtTest) { TEST(OperationTest, CtPlusPtArrayTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; - const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -275,7 +275,7 @@ TEST(OperationTest, CtPlusPtArrayTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); - ipcl::setHybridModExp(num_values, num_qat); + ipcl::setHybridRatio(qat_ratio); ct1 = key.pub_key->encrypt(pt1); @@ -299,7 +299,7 @@ TEST(OperationTest, CtPlusPtArrayTest) { TEST(OperationTest, CtMultiplyPtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; - const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -318,7 +318,7 @@ TEST(OperationTest, CtMultiplyPtTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); - ipcl::setHybridModExp(num_values, num_qat); + ipcl::setHybridRatio(qat_ratio); ct1 = key.pub_key->encrypt(pt1); @@ -342,7 +342,7 @@ TEST(OperationTest, CtMultiplyPtTest) { TEST(OperationTest, CtMultiplyZeroPtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; - const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -362,7 +362,7 @@ TEST(OperationTest, CtMultiplyZeroPtTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); - ipcl::setHybridModExp(num_values, num_qat); + ipcl::setHybridRatio(qat_ratio); ct1 = key.pub_key->encrypt(pt1); @@ -386,7 +386,7 @@ TEST(OperationTest, CtMultiplyZeroPtTest) { TEST(OperationTest, CtMultiplyPtArrayTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; - const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -405,7 +405,7 @@ TEST(OperationTest, CtMultiplyPtArrayTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); - ipcl::setHybridModExp(num_values, num_qat); + ipcl::setHybridRatio(qat_ratio); ct1 = key.pub_key->encrypt(pt1); @@ -429,7 +429,7 @@ TEST(OperationTest, CtMultiplyPtArrayTest) { TEST(OperationTest, AddSubTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; - const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -448,7 +448,7 @@ TEST(OperationTest, AddSubTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); - ipcl::setHybridModExp(num_values, num_qat); + ipcl::setHybridRatio(qat_ratio); ct1 = key.pub_key->encrypt(pt1); ct2 = key.pub_key->encrypt(pt2); @@ -473,7 +473,7 @@ TEST(OperationTest, AddSubTest) { TEST(OperationTest, PtPlusCtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; - const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -492,7 +492,7 @@ TEST(OperationTest, PtPlusCtTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); - ipcl::setHybridModExp(num_values, num_qat); + ipcl::setHybridRatio(qat_ratio); ct1 = key.pub_key->encrypt(pt1); @@ -516,7 +516,7 @@ TEST(OperationTest, PtPlusCtTest) { TEST(OperationTest, PtPlusCtArrayTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; - const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -535,7 +535,7 @@ TEST(OperationTest, PtPlusCtArrayTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); - ipcl::setHybridModExp(num_values, num_qat); + ipcl::setHybridRatio(qat_ratio); ct1 = key.pub_key->encrypt(pt1); @@ -559,7 +559,7 @@ TEST(OperationTest, PtPlusCtArrayTest) { TEST(OperationTest, PtMultiplyCtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; - const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -578,7 +578,7 @@ TEST(OperationTest, PtMultiplyCtTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); - ipcl::setHybridModExp(num_values, num_qat); + ipcl::setHybridRatio(qat_ratio); ct1 = key.pub_key->encrypt(pt1); @@ -602,7 +602,7 @@ TEST(OperationTest, PtMultiplyCtTest) { TEST(OperationTest, PtMultiplyCtArrayTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; - const uint32_t num_qat = SELF_DEF_QAT_FLOW_SIZE; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -621,7 +621,7 @@ TEST(OperationTest, PtMultiplyCtArrayTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); - ipcl::setHybridModExp(num_values, num_qat); + ipcl::setHybridRatio(qat_ratio); ct1 = key.pub_key->encrypt(pt1); From 5cb2e228df066d32052e34ae4ad30ddc672b6457 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Mon, 7 Nov 2022 14:49:06 -0800 Subject: [PATCH 333/364] IPCL 2.0 documentation (#150) * IPCL v2.0 Documentation - Added QAT details on README - Added QAT details on example/README - Added more examples for basic usage - Minor fixes - const for context mapping --- README.md | 55 +++++----- example/CMakeLists.txt | 7 +- example/README.md | 43 +++++--- example/example_add_mul.cpp | 100 ++++++++++++++++++ .../{test.cpp => example_encrypt_decrypt.cpp} | 26 +++-- example/example_hybridmode.cpp | 96 +++++++++++++++++ ipcl/context.cpp | 8 +- ipcl/include/ipcl/context.hpp | 2 +- ipcl/include/ipcl/mod_exp.hpp | 2 +- ipcl/mod_exp.cpp | 2 +- 10 files changed, 280 insertions(+), 61 deletions(-) create mode 100644 example/example_add_mul.cpp rename example/{test.cpp => example_encrypt_decrypt.cpp} (63%) create mode 100644 example/example_hybridmode.cpp diff --git a/README.md b/README.md index 47c0993..932bf11 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Intel Paillier Cryptosystem Library -Intel Paillier Cryptosystem Library is an open-source library which provides accelerated performance of a partial homomorphic encryption (HE), named Paillier cryptosystem, by utilizing IntelĀ® [Integrated Performance Primitives Cryptography](https://github.com/intel/ipp-crypto) technologies on Intel CPUs supporting the AVX512IFMA instructions. The library is written in modern standard C++ and provides the essential API for the Paillier cryptosystem scheme. Intel Paillier Cryptosystem Library is certified for ISO compliance. +Intel Paillier Cryptosystem Library is an open-source library which provides accelerated performance of a partial homomorphic encryption (HE), named Paillier cryptosystem, by utilizing IntelĀ® [Integrated Performance Primitives Cryptography](https://github.com/intel/ipp-crypto) technologies on Intel CPUs supporting the AVX512IFMA instructions and IntelĀ® [Quickassist Technology](https://01.org/intel-quickassist-technology). The library is written in modern standard C++ and provides the essential API for the Paillier cryptosystem scheme. Intel Paillier Cryptosystem Library is certified for ISO compliance. ## Contents - [Intel Paillier Cryptosystem Library](#intel-paillier-cryptosystem-library) @@ -8,9 +8,9 @@ Intel Paillier Cryptosystem Library is an open-source library which provides acc - [Building the Library](#building-the-library) - [Prerequisites](#prerequisites) - [Dependencies](#dependencies) - - [Downloading](#downloading) - [Instructions](#instructions) - [Installing and Using Example](#installing-and-using-example) + - [Compiling for QAT](#compiling-for-qat) - [Testing and Benchmarking](#testing-and-benchmarking) - [Python Extension](#python-extension) - [Standardization](#standardization) @@ -27,19 +27,21 @@ As a public key encryption scheme, Paillier cryptosystem has three stages: - Encryption with public key - Decryption with private key -For increased security, typically the key length is at least 1024 bits, but recommendation is 2048 bits or larger. To handle such large size integers, conventional implementations of the Paillier cryptosystem utilizes the GNU Multiple Precision Arithmetic Library (GMP). The essential computation of the scheme relies on the modular exponentiation, and our library takes advantage of the multi-buffer modular exponentiation function (```mbx_exp_mb8```) of IPP-Crypto library, which is enabled in AVX512IFMA instruction sets supporting SKUs, such as Intel Icelake Xeon CPUs. +For increased security, typically the key length is at least 1024 bits, but recommendation is 2048 bits or larger. To handle such large size integers, conventional implementations of the Paillier cryptosystem utilizes the GNU Multiple Precision Arithmetic Library (GMP). The essential computation of the scheme relies on the modular exponentiation, and our library takes advantage of two Intel features - the multi-buffer modular exponentiation function (```mbx_exp_mb8```) of IPP-Crypto library, which is enabled in AVX512IFMA instruction sets supporting SKUs, such as Intel Icelake/Sapphire Rapid XeonĀ® scalable processors and the modular exponentiation operation (```cpaCyLnModExp```) of Quickassist Technology library for QAT devices. ## Building the Library ### Prerequisites For best performance, especially due to the multi-buffer modular exponentiation function, the library is to be used on AVX512IFMA enabled systems, as listed below in Intel CPU codenames: - Intel Cannon Lake - Intel Ice Lake + - Intel Sapphire Rapids -The library can be built and used without AVX512IFMA, as if the instruction set is not detected on the system, it will automatically switch to non multi-buffer modular exponentiation. +The library can be built and used without AVX512IFMA and/or QAT, if the features are not supported. But for better performance, it is recommended to use the library on Intel XeonĀ® scalable processors - Ice Lake-SP or Sapphire Rapids-SP Xeon CPUs while fully utilizing the features. The following operating systems have been tested and deemed to be fully functional. - Ubuntu 18.04 and higher - Red Hat Enterprise Linux 8.1 and higher + - CentOS Stream We will keep working on adding more supported operating systems. ### Dependencies @@ -48,7 +50,10 @@ Must have dependencies include: cmake >= 3.15.1 git pthread -g++ >= 7.0 or clang >= 10.0 +Intel C++ Compiler Classic 2021.3 for Linux* OS +Intel oneAPI DPC++/C++ Compiler for Linux* OS >= 2021.3 +g++ >= 8.0 +clang >= 10.0 ``` The following libraries and tools are also required, @@ -58,31 +63,19 @@ OpenSSL >= 1.1.0 numa >= 2.0.12 ``` -For ```nasm```, please refer to the [Netwide Assembler](https://nasm.us/) for installation details. - On Ubuntu, ```OpenSSL``` and ```numa``` can be installed with: ```bash sudo apt update -sudo apt install libssl-dev -sudo apt install libnuma-dev -``` -For RHEL, ```OpenSSL``` needs to be built and installed from source as the static libraries are missing when installed through the package managers. Please refer to [OpenSSL Project](https://github.com/openssl/openssl) for installation details for static libraries. ```numa``` can be installed with: -``` -sudo yum install numactl-devel -``` -### Downloading -Pull source code from git repository with all submodules. There are two ways to do it: -- Clone source code with all submodules at once +sudo apt install nasm # for Ubuntu 20.04 or higher +sudo apt install libssl-dev libnuma-dev ``` -git clone --recursive https://github.com/intel/pailliercryptolib.git -cd pailliercryptolib -``` -- Clone source code, then pull submodules +For Ubuntu 18.04, RHEL and CentOS, please refer to the [Netwide Assembler webpage](https://nasm.us/) for installation details. + +For RHEL and CentOS, the required libraries can be installed via: ``` -git clone https://github.com/intel/pailliercryptolib.git -cd pailliercryptolib -git submodule update --init +sudo yum install numactl-devel openssl-devel ``` + ### Instructions The library can be built using the following commands: ```bash @@ -102,26 +95,27 @@ It is possible to pass additional options to enable more features. The following |`IPCL_THREAD_COUNT` | Integer | OFF | explicitly set max number of threads| |`IPCL_DOCS` | ON/OFF | OFF | build doxygen documentation | |`IPCL_SHARED` | ON/OFF | ON | build shared library | -|`IPCL_DETECT_IFMA_RUNTIME`| ON/OFF | OFF | detects AVX512IFMA during runtime | +|`IPCL_DETECT_CPU_RUNTIME` | ON/OFF | OFF | detects CPU supported instructions (AVX512IFMA, rdseed, rdrand) during runtime | -If ```IPCL_DETECT_IFMA_RUNTIME``` flag is set to ```ON```, it will determine whether the system supports the AVX512IFMA instructions on runtime. It is still possible to disable IFMA exclusive feature (multi-buffer modular exponentiation) during runtime by setting up the environment variable ```IPCL_DISABLE_AVX512IFMA=1```. +If ```IPCL_DETECT_CPU_RUNTIME``` flag is ```ON```, it will determine whether the system supports the AVX512IFMA instructions on runtime. It is still possible to disable IFMA exclusive feature (multi-buffer modular exponentiation) during runtime by setting up the environment variable ```IPCL_DISABLE_AVX512IFMA=1```. ### Installing and Using Example For installing and using the library externally, see [example/README.md](./example/README.md). ## Compiling for QAT -Install QAT software stack following the [instructions from the HE QAT Lib](https://github.com/intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.project-destiny/tree/development#installing-qat-software-stack). The current QAT support is not multithreading safe; therefore, `IPCL_ENABLE_OMP` must be set to `OFF`. +Install QAT software stack following the [Building the HE QAT Library](./module/heqat/README.md#building-the-library). ```bash export IPCL_DIR=$(pwd) export ICP_ROOT=$HOME/QAT -cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DIPCL_ENABLE_QAT=ON -DIPCL_ENABLE_OMP=OFF +cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DIPCL_ENABLE_QAT=ON cmake --build build -j ``` +For more details, please refer to the [HEQAT Readme](./module/heqat/README.md). ## Testing and Benchmarking -To run a set of unit tests via [Googletest](https://github.com/google/googletest), configure and build library with `-DIPCL_TEST=ON` (see [Instructions](#instructions)). +To run a set of unit tests via [GoogleTest](https://github.com/google/googletest), configure and build library with `-DIPCL_TEST=ON` (see [Instructions](#instructions)). Then, run ```bash cmake --build build --target unittest @@ -140,8 +134,7 @@ The executables are located at `${IPCL_ROOT}/build/test/unittest_ipcl` and `${IP Alongside the Intel Paillier Cryptosystem Library, we provide a Python extension package utilizing this library as a backend. For installation and usage detail, refer to [Intel Paillier Cryptosystem Library - Python](https://github.com/intel/pailliercryptolib_python). # Standardization -This library is certified for ISO compliance with the homomorphic encryption standards [ISO/IEC 18033-6](https://www.iso.org/standard/67740.html) by Dekra. - +This library is certified for ISO compliance with the homomorphic encryption standards [ISO/IEC 18033-6](https://www.iso.org/standard/67740.html) by [Dekra](https://www.dekra.com). # Contributors Main contributors to this project, sorted by alphabetical order of last name are: - [Flavio Bergamaschi](https://www.linkedin.com/in/flavio-bergamaschi) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 83314d7..9e2de3a 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -11,5 +11,8 @@ set(CMAKE_CXX_EXTENSIONS OFF) find_package(IPCL 2.0.0 REQUIRED HINTS ${IPCL_HINT_DIR}) -add_executable(test test.cpp) -target_link_libraries(test PRIVATE IPCL::ipcl) +set(examples encrypt_decrypt add_mul hybridmode) +foreach(ex IN LISTS examples) + add_executable(example_${ex} example_${ex}.cpp) + target_link_libraries(example_${ex} PRIVATE IPCL::ipcl) +endforeach() diff --git a/example/README.md b/example/README.md index 0bfe98c..b117c41 100644 --- a/example/README.md +++ b/example/README.md @@ -7,8 +7,9 @@ This document provides an example program for using the Intel Paillier Cryptosys - [Installation](#installation) - [Linking and Running Applications](#linking-and-running-applications) - [Building with CMake](#building-with-cmake) - - [Manually Compiling](#manually-compiling) - [Using Intel Paillier Cryptosystem Library](#using-intel-paillier-cryptosystem-library) + - [Enabling QAT usage](#enabling-qat-usage) + - [Hybrid mode configuration](#hybrid-mode-configuration) - [Data handling](#data-handling) - [```ipcl::PlainText``` Constructor](#ipclplaintext-constructor) - [Accessing data](#accessing-data) @@ -34,7 +35,7 @@ For more details about the build configuration options, please refer to the buil Before proceeding after the library is installed, it is useful to setup an environment variable to point to the installation location. ```bash -export IPCL_DIR=/path/to/install/ +export IPCL_DIR=/path/to/ipcl/install/ ``` ### Building with CMake @@ -42,26 +43,44 @@ A more convenient way to use the library is via the `find_package` functionality In your external applications, add the following lines to your `CMakeLists.txt`. ```bash -find_package(IPCL 1.1.4 +find_package(IPCL 2.0.0 HINTS ${IPCL_HINT_DIR} REQUIRED) target_link_libraries(${TARGET} IPCL::ipcl) ``` -If the library is installed globally, `IPCL_DIR` or `IPCL_HINT_DIR` flag is not needed. If `IPCL_DIR` is properly set, `IPCL_HINT_DIR` is not needed as well. Otherwise `IPCL_HINT_DIR` should be the directory containing `IPCLCOnfig.cmake`, under `${CMAKE_INSTALL_PREFIX}/lib/cmake/ipcl-1.1.4/` +If the library is installed globally, `IPCL_DIR` or `IPCL_HINT_DIR` flag is not needed. If environment variable `IPCL_DIR` is set, `IPCL_HINT_DIR` is not needed as well. Otherwise `IPCL_HINT_DIR` should be the directory containing `IPCLCOnfig.cmake`, under `${CMAKE_INSTALL_PREFIX}/lib/cmake/ipcl-2.0.0/` -### Manually Compiling -In order to directly use `g++` or `clang++` to compile an example code, it can be done by: -```bash -# gcc -g++ test.cpp -o test -L${IPCL_DIR}/lib -I${IPCL_DIR}/include -lipcl -fopenmp -lnuma -lcrypto +## Using Intel Paillier Cryptosystem Library + +### Enabling QAT usage +When QAT is enabled while building the library with the flag ```IPCL_ENABLE_QAT=ON```, it is essential to initialize and release the HE QAT context. +```C++ +// Initialize HE QAT context +ipcl::initializeContext("QAT"); + +// perform IPCL operations +auto ct = key.pub_key->encrypt(pt); +auto dec_pt = key.priv_key->decrypt(ct); -# clang -clang++ test.cpp -o test -L${IPCL_DIR}/lib -I${IPCL_DIR}/include -lipcl -fopenmp -lnuma -lcrypto +// Release HE QAT context +ipcl::terminateContext(); ``` +If QAT is disabled, ```ipcl::initializeContext("QAT")``` statement will not do anything, thus safe to include in any codes using the library. +### Hybrid mode configuration +The main accelerated operation - modular exponentiation - can be performed by either IPP-Crypto or the HE QAT. Our library provides a configurable method to distribute the workload between these two methods. +```C++ +// Use optimal mode +ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); -## Using Intel Paillier Cryptosystem Library +// Use IPP-Crypto modexp only +ipcl::setHybridMode(ipcl::HybridMode::IPP); + +// Use QAT modexp only +ipcl::setHybridMode(ipcl::HybridMode::QAT); +``` +By default, the hybrid mode is set to ```ipcl::HybridMode::OPTIMAL```. For more details about the modes, please refer to [```mod_exp.hpp```](../ipcl/include/ipcl/mod_exp.hpp#L16). ### Data handling The library uses a container - ```ipcl::PlainText``` for encryption inputs and decryption outputs as well as plaintext HE operations. diff --git a/example/example_add_mul.cpp b/example/example_add_mul.cpp new file mode 100644 index 0000000..6d9ec22 --- /dev/null +++ b/example/example_add_mul.cpp @@ -0,0 +1,100 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +/* + Example of encryption and decryption +*/ +#include +#include +#include +#include + +#include "ipcl/ipcl.hpp" + +int main() { + ipcl::initializeContext("QAT"); + + const uint32_t num_total = 20; + + ipcl::keyPair key = ipcl::generateKeypair(2048, true); + + std::vector x(num_total); + std::vector y(num_total); + + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, + UINT_MAX >> 16); + + for (int i = 0; i < num_total; i++) { + x[i] = dist(rng); + y[i] = dist(rng); + } + + ipcl::PlainText pt_x = ipcl::PlainText(x); + ipcl::PlainText pt_y = ipcl::PlainText(y); + + ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); + + ipcl::CipherText ct_x = key.pub_key->encrypt(pt_x); + ipcl::CipherText ct_y = key.pub_key->encrypt(pt_y); + + // Perform enc(x) + enc(y) + std::cout << "--- IPCL CipherText + CipherText ---" << std::endl; + ipcl::CipherText ct_add_ctx_cty = ct_x + ct_y; + ipcl::PlainText dt_add_ctx_cty = key.priv_key->decrypt(ct_add_ctx_cty); + + // verify result + bool verify = true; + for (int i = 0; i < num_total; i++) { + std::vector v = dt_add_ctx_cty.getElementVec(i); + if (v[0] != (x[i] + y[i])) { + verify = false; + break; + } + } + std::cout << "Test (x + y) == dec(enc(x) + enc(y)) -- " + << (verify ? "pass" : "fail") << std::endl + << std::endl; + + // Perform enc(x) + y + std::cout << "--- IPCL CipherText + PlainText ---" << std::endl; + ipcl::CipherText ct_add_ctx_pty = ct_x + pt_y; + ipcl::PlainText dt_add_ctx_pty = key.priv_key->decrypt(ct_add_ctx_pty); + + // verify result + verify = true; + for (int i = 0; i < num_total; i++) { + std::vector v = dt_add_ctx_pty.getElementVec(i); + if (v[0] != (x[i] + y[i])) { + verify = false; + break; + } + } + std::cout << "Test (x + y) == dec(enc(x) + y) -- " + << (verify ? "pass" : "fail") << std::endl + << std::endl; + + // Perform enc(x) * y + std::cout << "--- IPCL CipherText * PlainText ---" << std::endl; + ipcl::CipherText ct_mul_ctx_pty = ct_x * pt_y; + ipcl::PlainText dt_mul_ctx_pty = key.priv_key->decrypt(ct_mul_ctx_pty); + + // verify result + verify = true; + for (int i = 0; i < num_total; i++) { + std::vector v = dt_mul_ctx_pty.getElementVec(i); + if (v[0] != (x[i] * y[i])) { + verify = false; + break; + } + } + std::cout << "Test (x * y) == dec(enc(x) * y) -- " + << (verify ? "pass" : "fail") << std::endl; + + ipcl::setHybridOff(); + + delete key.pub_key; + delete key.priv_key; + ipcl::terminateContext(); +} diff --git a/example/test.cpp b/example/example_encrypt_decrypt.cpp similarity index 63% rename from example/test.cpp rename to example/example_encrypt_decrypt.cpp index 035f063..e8c0c7e 100644 --- a/example/test.cpp +++ b/example/example_encrypt_decrypt.cpp @@ -1,11 +1,16 @@ // Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 +/* + Example of encryption and decryption +*/ #include -#include +#include #include #include +#include "ipcl/ipcl.hpp" + int main() { ipcl::initializeContext("QAT"); @@ -14,9 +19,6 @@ int main() { ipcl::keyPair key = ipcl::generateKeypair(2048, true); std::vector exp_value(num_total); - ipcl::PlainText pt; - ipcl::CipherText ct; - ipcl::PlainText dt; std::random_device dev; std::mt19937 rng(dev()); @@ -26,20 +28,26 @@ int main() { exp_value[i] = dist(rng); } - pt = ipcl::PlainText(exp_value); + ipcl::PlainText pt = ipcl::PlainText(exp_value); ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); - ct = key.pub_key->encrypt(pt); - dt = key.priv_key->decrypt(ct); + ipcl::CipherText ct = key.pub_key->encrypt(pt); + ipcl::PlainText dt = key.priv_key->decrypt(ct); ipcl::setHybridOff(); + // verify result + bool verify = true; for (int i = 0; i < num_total; i++) { std::vector v = dt.getElementVec(i); - bool chk = v[0] == exp_value[i]; - std::cout << (chk ? "pass" : "fail") << std::endl; + if (v[0] != exp_value[i]) { + verify = false; + break; + } } + std::cout << "Test pt == dec(enc(pt)) -- " << (verify ? "pass" : "fail") + << std::endl; delete key.pub_key; delete key.priv_key; diff --git a/example/example_hybridmode.cpp b/example/example_hybridmode.cpp new file mode 100644 index 0000000..4feaa1e --- /dev/null +++ b/example/example_hybridmode.cpp @@ -0,0 +1,96 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +/* + Example of encryption and decryption +*/ +#include // NOLINT [build/c++11] +#include +#include +#include +#include + +#include "ipcl/ipcl.hpp" + +typedef std::chrono::high_resolution_clock::time_point tVar; +#define tNow() std::chrono::high_resolution_clock::now() +#define tStart(t) t = tNow() +#define tEnd(t) \ + std::chrono::duration_cast(tNow() - t).count() + +int main() { + ipcl::initializeContext("QAT"); + tVar t; + double elapsed(0.); + + const uint32_t num_total = 64; + + ipcl::keyPair key = ipcl::generateKeypair(2048, true); + + std::vector exp_value(num_total); + + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + BigNumber bigNum = + "0xff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c" + "8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b4" + "0a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff76" + "4dd8b091f11a0943a2dd2b983b0df02f4c4d00b413acaabc1dc57faa9fd6a4274c4d5887" + "65a1d3311c22e57d8101431b07eb3ddcb05d77d9a742ac2322fe6a063bd1e05acb13b0fe" + "91c70115c2b1eee1155e072527011a5f849de7072a1ce8e6b71db525fbcda7a89aaed46d" + "27aca5eaeaf35a26270a4a833c5cda681ffd49baa0f610bad100cdf47cc86e5034e2a0b2" + "179e04ec7"; + + for (int i = 0; i < num_total; i++) { + exp_value[i] = bigNum - dist(rng); + } + + ipcl::PlainText pt = ipcl::PlainText(exp_value); + + // Encrypt/Decrypt - IPP-Crypto only mode + ipcl::setHybridMode(ipcl::HybridMode::IPP); + tStart(t); + ipcl::CipherText ct = key.pub_key->encrypt(pt); + elapsed = tEnd(t); + std::cout << " Encrypt - HybridMode::IPP = " << elapsed << "ms" + << std::endl; + tStart(t); + ipcl::PlainText dt = key.priv_key->decrypt(ct); + elapsed = tEnd(t); + std::cout << " Decrypt - HybridMode::IPP = " << elapsed << "ms" + << std::endl + << std::endl; + + // Encrypt/Decrypt - QAT only mode + ipcl::setHybridMode(ipcl::HybridMode::QAT); + tStart(t); + ct = key.pub_key->encrypt(pt); + elapsed = tEnd(t); + std::cout << " Encrypt - HybridMode::QAT = " << elapsed << "ms" + << std::endl; + tStart(t); + dt = key.priv_key->decrypt(ct); + elapsed = tEnd(t); + std::cout << " Decrypt - HybridMode::QAT = " << elapsed << "ms" + << std::endl + << std::endl; + + // Encrypt/Decrypt - OPTIMAL mode + ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); + tStart(t); + ct = key.pub_key->encrypt(pt); + elapsed = tEnd(t); + std::cout << " Encrypt - HybridMode::OPTIMAL = " << elapsed << "ms" + << std::endl; + tStart(t); + dt = key.priv_key->decrypt(ct); + elapsed = tEnd(t); + std::cout << " Decrypt - HybridMode::OPTIMAL = " << elapsed << "ms" + << std::endl + << std::endl; + + delete key.pub_key; + delete key.priv_key; + ipcl::terminateContext(); +} diff --git a/ipcl/context.cpp b/ipcl/context.cpp index 359d11b..5b4f5cb 100644 --- a/ipcl/context.cpp +++ b/ipcl/context.cpp @@ -14,14 +14,14 @@ namespace ipcl { ///> Default behavior is selected at runtime and implementation dependent enum class RuntimeValue { DEFAULT, CPU, QAT, HYBRID }; -std::map runtimeMap = { +const std::map runtimeMap = { {"DEFAULT", RuntimeValue::DEFAULT}, {"default", RuntimeValue::DEFAULT}, {"CPU", RuntimeValue::CPU}, {"cpu", RuntimeValue::CPU}, {"QAT", RuntimeValue::QAT}, {"qat", RuntimeValue::QAT}, {"HYBRID", RuntimeValue::HYBRID}, {"hybrid", RuntimeValue::HYBRID}}; enum class FeatureValue { AVX512IFMA, QAT4XXX }; -std::map hasFeatureMap = { +const std::map hasFeatureMap = { {"avx512", FeatureValue::AVX512IFMA}, {"avx512ifma", FeatureValue::AVX512IFMA}, {"4xxx", FeatureValue::QAT4XXX}, @@ -37,10 +37,10 @@ static bool initializeQATContext() { } #endif -bool initializeContext(std::string runtime_choice) { +bool initializeContext(const std::string runtime_choice) { #ifdef IPCL_USE_QAT hasQAT = true; - switch (runtimeMap[runtime_choice]) { + switch (runtimeMap.at(runtime_choice) 1) { case RuntimeValue::QAT: return initializeQATContext(); case RuntimeValue::CPU: diff --git a/ipcl/include/ipcl/context.hpp b/ipcl/include/ipcl/context.hpp index f8cd856..c528a0a 100644 --- a/ipcl/include/ipcl/context.hpp +++ b/ipcl/include/ipcl/context.hpp @@ -22,7 +22,7 @@ namespace ipcl { * @return true if runtime context has been properly initialized, false * otherwise. */ -bool initializeContext(std::string runtime_choice); +bool initializeContext(const std::string runtime_choice); /** * Terminate runtime context. diff --git a/ipcl/include/ipcl/mod_exp.hpp b/ipcl/include/ipcl/mod_exp.hpp index 7f41b11..c93700e 100644 --- a/ipcl/include/ipcl/mod_exp.hpp +++ b/ipcl/include/ipcl/mod_exp.hpp @@ -57,7 +57,7 @@ float getHybridRatio(); HybridMode getHybridMode(); /** - * Whether current hybrid mode is OPTIMAL + * Check current hybrid mode is OPTIMAL */ bool isHybridOptimal(); diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index 290ef66..7de6140 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -22,7 +22,7 @@ namespace ipcl { static thread_local struct { float ratio; HybridMode mode; -} g_hybrid_params = {0.0, HybridMode::UNDEFINED}; +} g_hybrid_params = {0.0, HybridMode::OPTIMAL}; static inline float scale_down(int value, float scale = 100.0) { return value / scale; From c9e26ace64f6aa021c548bb08a17f3f564e280b9 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Mon, 7 Nov 2022 14:49:27 -0800 Subject: [PATCH 334/364] Type fix --- ipcl/context.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipcl/context.cpp b/ipcl/context.cpp index 5b4f5cb..d64f581 100644 --- a/ipcl/context.cpp +++ b/ipcl/context.cpp @@ -40,7 +40,7 @@ static bool initializeQATContext() { bool initializeContext(const std::string runtime_choice) { #ifdef IPCL_USE_QAT hasQAT = true; - switch (runtimeMap.at(runtime_choice) 1) { + switch (runtimeMap.at(runtime_choice)) { case RuntimeValue::QAT: return initializeQATContext(); case RuntimeValue::CPU: From 05e43fce8f024b2245d0821b482bbe0ae870453a Mon Sep 17 00:00:00 2001 From: Zhao Pengfei Date: Tue, 8 Nov 2022 16:41:43 +0800 Subject: [PATCH 335/364] modexp: Fix setHybridMode cannot set hybrid mode correctly Signed-off-by: Zhao Pengfei --- ipcl/ciphertext.cpp | 2 +- ipcl/include/ipcl/mod_exp.hpp | 3 ++- ipcl/mod_exp.cpp | 10 ++++------ ipcl/pri_key.cpp | 2 +- ipcl/pub_key.cpp | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/ipcl/ciphertext.cpp b/ipcl/ciphertext.cpp index 91c0016..440e1d1 100644 --- a/ipcl/ciphertext.cpp +++ b/ipcl/ciphertext.cpp @@ -155,7 +155,7 @@ std::vector CipherText::raw_mul( float qat_ratio = (v_size <= IPCL_WORKLOAD_SIZE_THRESHOLD) ? IPCL_HYBRID_MODEXP_RATIO_FULL : IPCL_HYBRID_MODEXP_RATIO_MULTIPLY; - setHybridRatio(qat_ratio); + setHybridRatio(qat_ratio, false); } return modExp(a, b, sq); diff --git a/ipcl/include/ipcl/mod_exp.hpp b/ipcl/include/ipcl/mod_exp.hpp index c93700e..2c9fc04 100644 --- a/ipcl/include/ipcl/mod_exp.hpp +++ b/ipcl/include/ipcl/mod_exp.hpp @@ -38,8 +38,9 @@ void setHybridMode(HybridMode mode); /** * Set the number of mod exp operatiions * @param[in] Proportion calculated with QAT + * @param[in] rest_mode Whether reset the mode to UNDIFINED(default is true) */ -void setHybridRatio(float qat_ratio); +void setHybridRatio(float qat_ratio, bool reset_mode = true); /** * Turn off hybrid mod exp. diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index 7de6140..0f82f9c 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -32,28 +32,26 @@ static inline int scale_up(float value, int scale = 100) { return value * scale; } -void setHybridRatio(float ratio) { +void setHybridRatio(float ratio, bool reset_mode) { #ifdef IPCL_USE_QAT ERROR_CHECK((ratio <= 1.0) && (ratio >= 0), "setHybridRatio: Hybrid modexp qat ratio is NOT correct"); g_hybrid_params.ratio = ratio; - g_hybrid_params.mode = HybridMode::UNDEFINED; + if (reset_mode) g_hybrid_params.mode = HybridMode::UNDEFINED; #endif // IPCL_USE_QAT } void setHybridMode(HybridMode mode) { #ifdef IPCL_USE_QAT - g_hybrid_params.mode = mode; int mode_value = static_cast::type>(mode); float ratio = scale_down(mode_value); - setHybridRatio(ratio); + g_hybrid_params = {ratio, mode}; #endif // IPCL_USE_QAT } void setHybridOff() { #ifdef IPCL_USE_QAT - g_hybrid_params.mode = HybridMode::UNDEFINED; - g_hybrid_params.ratio = 0.0; + g_hybrid_params = {0.0, HybridMode::UNDEFINED}; #endif // IPCL_USE_QAT } diff --git a/ipcl/pri_key.cpp b/ipcl/pri_key.cpp index 09b4984..29201f6 100644 --- a/ipcl/pri_key.cpp +++ b/ipcl/pri_key.cpp @@ -67,7 +67,7 @@ PlainText PrivateKey::decrypt(const CipherText& ct) const { float qat_ratio = (ct_size <= IPCL_WORKLOAD_SIZE_THRESHOLD) ? IPCL_HYBRID_MODEXP_RATIO_FULL : IPCL_HYBRID_MODEXP_RATIO_DECRYPT; - setHybridRatio(qat_ratio); + setHybridRatio(qat_ratio, false); } if (m_enable_crt) diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index 581d830..abbbd64 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -126,7 +126,7 @@ CipherText PublicKey::encrypt(const PlainText& pt, bool make_secure) const { float qat_ratio = (pt_size <= IPCL_WORKLOAD_SIZE_THRESHOLD) ? IPCL_HYBRID_MODEXP_RATIO_FULL : IPCL_HYBRID_MODEXP_RATIO_ENCRYPT; - setHybridRatio(qat_ratio); + setHybridRatio(qat_ratio, false); } ct_bn_v = raw_encrypt(pt.getTexts(), make_secure); From de6b1b0f449450a30f7fa0a1fa745e2e30b57ed4 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Tue, 8 Nov 2022 14:49:33 -0800 Subject: [PATCH 336/364] Enable Python shared library build --- CMakeLists.txt | 14 +++++--------- cmake/cpufeatures.cmake | 15 +++++++++++++-- cmake/ippcrypto.cmake | 22 ++++++++++++++++++---- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 78ac4f6..4cf8ce1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,7 +69,7 @@ option(IPCL_THREAD_COUNT "The max number of threads used by OpenMP(If the value option(IPCL_DOCS "Enable document building" OFF) option(IPCL_SHARED "Build shared library" ON) option(IPCL_DETECT_CPU_RUNTIME "Detect CPU supported instructions during runtime" OFF) -option(IPCL_DEBUG_DISABLE_AVX512IFMA "(Debugging) Disable usage of AVX512IFMA instructions" OFF) +option(IPCL_PYTHON_BUILD "Additional steps for IPCL_Python build" OFF) if(IPCL_ENABLE_QAT) ipcl_detect_qat() @@ -102,14 +102,10 @@ if(IPCL_DETECT_CPU_RUNTIME) set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ipcl/cpufeatures") else() # check whether cpu support avx512ifma instructions - if(IPCL_DEBUG_DISABLE_AVX512IFMA) - message(STATUS "Support AVX512IFMA instruction: False") - else() - ipcl_detect_lscpu_flag("avx512ifma" FALSE) - if(IPCL_FOUND_avx512ifma) - add_compile_definitions(IPCL_CRYPTO_MB_MOD_EXP) - message(STATUS "Support AVX512IFMA instruction: True") - endif() + ipcl_detect_lscpu_flag("avx512ifma" FALSE) + if(IPCL_FOUND_avx512ifma) + add_compile_definitions(IPCL_CRYPTO_MB_MOD_EXP) + message(STATUS "Support AVX512IFMA instruction: True") endif() # check whether cpu support rdseed/rdrand instructions diff --git a/cmake/cpufeatures.cmake b/cmake/cpufeatures.cmake index 189dd8e..2e48b62 100644 --- a/cmake/cpufeatures.cmake +++ b/cmake/cpufeatures.cmake @@ -34,8 +34,19 @@ if(IPCL_SHARED) target_include_directories(libcpu_features SYSTEM INTERFACE ${CPUFEATURES_INC_DIR}) - target_link_libraries(libcpu_features - INTERFACE ${CPUFEATURES_LIB_DIR}/libcpu_features.a) + # ipcl python build + if(IPCL_PYTHON_BUILD) + target_link_libraries(libcpu_features INTERFACE + ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/cpufeatures/libcpu_features.a) + + add_custom_command(TARGET ext_cpufeatures + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CPUFEATURES_LIB_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/cpufeatures + ) + else() + target_link_libraries(libcpu_features INTERFACE + ${CPUFEATURES_LIB_DIR}/libcpu_features.a) + endif() install( DIRECTORY ${CPUFEATURES_LIB_DIR}/ diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake index 4f9b743..00ef41e 100644 --- a/cmake/ippcrypto.cmake +++ b/cmake/ippcrypto.cmake @@ -49,12 +49,26 @@ if(IPCL_SHARED) ExternalProject_Get_Property(ext_ipp-crypto SOURCE_DIR BINARY_DIR) - target_link_libraries(IPPCP INTERFACE - ${IPPCRYPTO_LIB_DIR}/libippcp.so - ${IPPCRYPTO_LIB_DIR}/libcrypto_mb.so - ) target_include_directories(IPPCP SYSTEM INTERFACE ${IPPCRYPTO_INC_DIR}) + # if ipcl python build + if(IPCL_PYTHON_BUILD) + target_link_libraries(IPPCP INTERFACE + ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ippcrypto/libippcp.so + ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ippcrypto/libcrypto_mb.so + ) + + add_custom_command(TARGET ext_ipp-crypto + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory ${IPPCRYPTO_LIB_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ippcrypto + ) + else() + target_link_libraries(IPPCP INTERFACE + ${IPPCRYPTO_LIB_DIR}/libippcp.so + ${IPPCRYPTO_LIB_DIR}/libcrypto_mb.so + ) + endif() + install( DIRECTORY ${IPPCRYPTO_LIB_DIR}/ DESTINATION "${IPCL_INSTALL_LIBDIR}/ippcrypto" From 6229ff79fbd4d7e73ffeeb71b8f6bafb3f01607e Mon Sep 17 00:00:00 2001 From: sejunkim Date: Tue, 8 Nov 2022 15:02:51 -0800 Subject: [PATCH 337/364] Improve IPCL Python build parameter check --- CMakeLists.txt | 11 ++++++++++- cmake/cpufeatures.cmake | 2 +- cmake/ippcrypto.cmake | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4cf8ce1..ce07e28 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,7 +69,16 @@ option(IPCL_THREAD_COUNT "The max number of threads used by OpenMP(If the value option(IPCL_DOCS "Enable document building" OFF) option(IPCL_SHARED "Build shared library" ON) option(IPCL_DETECT_CPU_RUNTIME "Detect CPU supported instructions during runtime" OFF) -option(IPCL_PYTHON_BUILD "Additional steps for IPCL_Python build" OFF) +option(IPCL_INTERNAL_PYTHON_BUILD "Additional steps for IPCL_Python build" OFF) + +# Used only for ipcl_python IPCL_INTERNAL_PYTHON_BUILD - additional check if invalid parameters +if(IPCL_INTERNAL_PYTHON_BUILD) + if(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY) + set(IPCL_INTERNAL_PYTHON_BUILD OFF) + elseif(NOT IS_ABSOLUTE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) + set(IPCL_INTERNAL_PYTHON_BUILD OFF) + endif() +endif() if(IPCL_ENABLE_QAT) ipcl_detect_qat() diff --git a/cmake/cpufeatures.cmake b/cmake/cpufeatures.cmake index 2e48b62..1da25f1 100644 --- a/cmake/cpufeatures.cmake +++ b/cmake/cpufeatures.cmake @@ -35,7 +35,7 @@ if(IPCL_SHARED) target_include_directories(libcpu_features SYSTEM INTERFACE ${CPUFEATURES_INC_DIR}) # ipcl python build - if(IPCL_PYTHON_BUILD) + if(IPCL_INTERNAL_PYTHON_BUILD) target_link_libraries(libcpu_features INTERFACE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/cpufeatures/libcpu_features.a) diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake index 00ef41e..d9477f9 100644 --- a/cmake/ippcrypto.cmake +++ b/cmake/ippcrypto.cmake @@ -52,7 +52,7 @@ if(IPCL_SHARED) target_include_directories(IPPCP SYSTEM INTERFACE ${IPPCRYPTO_INC_DIR}) # if ipcl python build - if(IPCL_PYTHON_BUILD) + if(IPCL_INTERNAL_PYTHON_BUILD) target_link_libraries(IPPCP INTERFACE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ippcrypto/libippcp.so ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ippcrypto/libcrypto_mb.so From 59f824568995baf1d9102b07dd20f455ef33c60a Mon Sep 17 00:00:00 2001 From: sejunkim Date: Tue, 8 Nov 2022 15:51:58 -0800 Subject: [PATCH 338/364] Add IPCL_INTERNAL_PYTHON_BUILD message when set --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ce07e28..55c7d14 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,7 +152,9 @@ endif() message(STATUS "IPCL_DOCS: ${IPCL_DOCS}") message(STATUS "IPCL_SHARED: ${IPCL_SHARED}") message(STATUS "IPCL_DETECT_CPU_RUNTIME: ${IPCL_DETECT_CPU_RUNTIME}") - +if(IPCL_INTERNAL_PYTHON_BUILD) + message(STATUS "IPCL_INTERNAL_PYTHON_BUILD: ${IPCL_INTERNAL_PYTHON_BUILD}") +endif() # check whether cpu support rdseed or rdrand instruction set(IPCL_FORWARD_CMAKE_ARGS From 4fc14a53c5718458711a1bb4215d0aa929217c67 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Tue, 8 Nov 2022 17:55:48 -0800 Subject: [PATCH 339/364] Testing rpath setup for ipcl --- ipcl/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 6f15293..bf0276e 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -25,6 +25,9 @@ endif() add_library(IPCL::ipcl ALIAS ipcl) set_target_properties(ipcl PROPERTIES PUBLIC_HEADER ${IPCL_PUBLIC_HEADER}) +set_target_properties(ipcl PROPERTIES + BUILD_WITH_INSTALL_RPATH FALSE + LINK_FLAGS "-Wl,-rpath,'$ORIGIN' -Wl,-rpath,'$ORIGIN'/ippcrypto -Wl,-rpath,'$ORIGIN'/cpufeatures") target_include_directories(ipcl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) @@ -72,7 +75,6 @@ if(IPCL_ENABLE_QAT) PRIVATE "$" ) - target_include_directories(ipcl PRIVATE "$" PRIVATE $ From 0b7257eb396e1c90c80e8e428b7ef8023e8a9fcd Mon Sep 17 00:00:00 2001 From: sejunkim Date: Tue, 8 Nov 2022 19:06:45 -0800 Subject: [PATCH 340/364] Fix ORIGIN rpath to include HEQAT correctly --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 55c7d14..6efdf9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,7 +45,7 @@ endif() set(CMAKE_C_FLAGS "-O2 -Wno-error=deprecated-declarations -Wno-error=deprecated-copy") set(CMAKE_CXX_FLAGS "-O2 -fpermissive -Wno-error=deprecated-declarations -Wno-error=deprecated-copy") -set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ipcl;${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ipcl/ippcrypto") +set(CMAKE_INSTALL_RPATH "$ORIGIN/${CMAKE_INSTALL_LIBDIR};$ORIGIN/ippcrypto") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) @@ -84,7 +84,7 @@ if(IPCL_ENABLE_QAT) ipcl_detect_qat() if(IPCL_FOUND_QAT) add_compile_definitions(IPCL_USE_QAT) - set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/heqat") + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};$ORIGIN/../heqat") if(IPCL_USE_QAT_LITE) add_compile_definitions(IPCL_USE_QAT_LITE) message(STATUS "QAT Lite enabled - IPCL_USE_QAT_LITE set to ON") @@ -108,7 +108,7 @@ endif() if(IPCL_DETECT_CPU_RUNTIME) # add_compile_definitions(IPCL_RUNTIME_MOD_EXP) add_compile_definitions(IPCL_RUNTIME_DETECT_CPU_FEATURES) - set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ipcl/cpufeatures") + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};$ORIGIN/cpufeatures") else() # check whether cpu support avx512ifma instructions ipcl_detect_lscpu_flag("avx512ifma" FALSE) From c8a17a32290c06b102d97685f373b58cceb542de Mon Sep 17 00:00:00 2001 From: sejunkim Date: Tue, 8 Nov 2022 20:32:32 -0800 Subject: [PATCH 341/364] Disable IPCL_ENABLE_QAT if dependencies are not correctly set rather than abort --- CMakeLists.txt | 2 ++ cmake/ipcl/ipcl-util.cmake | 32 ++++++++++++++++++-------------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6efdf9d..ede9409 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,6 +91,8 @@ if(IPCL_ENABLE_QAT) else() message(STATUS "QAT Lite disabled - IPCL_USE_QAT_LITE set to OFF") endif() + else() + set(IPCL_ENABLE_QAT OFF) endif() endif() diff --git a/cmake/ipcl/ipcl-util.cmake b/cmake/ipcl/ipcl-util.cmake index ba42b22..709a18c 100644 --- a/cmake/ipcl/ipcl-util.cmake +++ b/cmake/ipcl/ipcl-util.cmake @@ -52,6 +52,7 @@ function(ipcl_detect_qat) # Detect SPR based QAT message(STATUS "Detecting QAT...... ") if(DEFINED ENV{ICP_ROOT}) + # Validate environment variable ICP_ROOT set(tmp_ICP_ROOT $ENV{ICP_ROOT}) get_filename_component(tmp_ICP_ROOT_fullpath "${tmp_ICP_ROOT}" REALPATH) if(EXISTS "${tmp_ICP_ROOT_fullpath}" AND @@ -61,23 +62,26 @@ function(ipcl_detect_qat) else() message(FATAL_ERROR "Environment variable ICP_ROOT is incorrect. Try \$ export ICP_ROOT=") endif() - else() - message(FATAL_ERROR "Environment variable ICP_ROOT must be defined. Try \$ export ICP_ROOT=") - endif() - execute_process(COMMAND lspci -d 8086:4940 COMMAND wc -l OUTPUT_VARIABLE QAT_PHYSICAL OUTPUT_STRIP_TRAILING_WHITESPACE) - set(IPCL_FOUND_QAT FALSE PARENT_SCOPE) - if(${QAT_PHYSICAL} GREATER_EQUAL "1") - message(STATUS "Detected ${QAT_PHYSICAL} physical QAT processes") - execute_process(COMMAND lspci -d 8086:4941 COMMAND wc -l OUTPUT_VARIABLE QAT_VIRTUAL OUTPUT_STRIP_TRAILING_WHITESPACE) - if(${QAT_VIRTUAL} GREATER_EQUAL "1") - message(STATUS "Detected ${QAT_VIRTUAL} virtual QAT processes") - ipcl_check_qat_service_status() - set(IPCL_FOUND_QAT TRUE PARENT_SCOPE) + + execute_process(COMMAND lspci -d 8086:4940 COMMAND wc -l OUTPUT_VARIABLE QAT_PHYSICAL OUTPUT_STRIP_TRAILING_WHITESPACE) + set(IPCL_FOUND_QAT FALSE PARENT_SCOPE) + if(${QAT_PHYSICAL} GREATER_EQUAL "1") + message(STATUS "Detected ${QAT_PHYSICAL} physical QAT processes") + execute_process(COMMAND lspci -d 8086:4941 COMMAND wc -l OUTPUT_VARIABLE QAT_VIRTUAL OUTPUT_STRIP_TRAILING_WHITESPACE) + if(${QAT_VIRTUAL} GREATER_EQUAL "1") + message(STATUS "Detected ${QAT_VIRTUAL} virtual QAT processes") + ipcl_check_qat_service_status() + set(IPCL_FOUND_QAT TRUE PARENT_SCOPE) + else() + message(WARNING "NO virtual QAT processors - IPCL_ENABLE_QAT set to OFF") + endif() else() - message(STATUS "NO virtual QAT processors - IPCL_ENABLE_QAT set to OFF") + message(WARNING "NO physical QAT processors - IPCL_ENABLE_QAT set to OFF") endif() + else() - message(STATUS "NO physical QAT processors - IPCL_ENABLE_QAT set to OFF") + message(WARNING "Environment variable ICP_ROOT must be defined. Disabling QAT build") + set(IPCL_FOUND_QAT FALSE PARENT_SCOPE) endif() endfunction() From 0be9ece481fa8e843ce070c996449a1d876bbd47 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Tue, 8 Nov 2022 20:35:59 -0800 Subject: [PATCH 342/364] IPCL_FOUND_QAT cases refactoring --- cmake/ipcl/ipcl-util.cmake | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/cmake/ipcl/ipcl-util.cmake b/cmake/ipcl/ipcl-util.cmake index 709a18c..625c150 100644 --- a/cmake/ipcl/ipcl-util.cmake +++ b/cmake/ipcl/ipcl-util.cmake @@ -51,6 +51,8 @@ endfunction() function(ipcl_detect_qat) # Detect SPR based QAT message(STATUS "Detecting QAT...... ") + set(IPCL_FOUND_QAT FALSE PARENT_SCOPE) + if(DEFINED ENV{ICP_ROOT}) # Validate environment variable ICP_ROOT set(tmp_ICP_ROOT $ENV{ICP_ROOT}) @@ -59,29 +61,25 @@ function(ipcl_detect_qat) EXISTS "${tmp_ICP_ROOT_fullpath}/build" AND EXISTS "${tmp_ICP_ROOT_fullpath}/quickassist") message(STATUS "Environment variable ICP_ROOT is defined as ${tmp_ICP_ROOT_fullpath}.") - else() - message(FATAL_ERROR "Environment variable ICP_ROOT is incorrect. Try \$ export ICP_ROOT=") - endif() - - execute_process(COMMAND lspci -d 8086:4940 COMMAND wc -l OUTPUT_VARIABLE QAT_PHYSICAL OUTPUT_STRIP_TRAILING_WHITESPACE) - set(IPCL_FOUND_QAT FALSE PARENT_SCOPE) - if(${QAT_PHYSICAL} GREATER_EQUAL "1") - message(STATUS "Detected ${QAT_PHYSICAL} physical QAT processes") - execute_process(COMMAND lspci -d 8086:4941 COMMAND wc -l OUTPUT_VARIABLE QAT_VIRTUAL OUTPUT_STRIP_TRAILING_WHITESPACE) - if(${QAT_VIRTUAL} GREATER_EQUAL "1") - message(STATUS "Detected ${QAT_VIRTUAL} virtual QAT processes") - ipcl_check_qat_service_status() - set(IPCL_FOUND_QAT TRUE PARENT_SCOPE) + execute_process(COMMAND lspci -d 8086:4940 COMMAND wc -l OUTPUT_VARIABLE QAT_PHYSICAL OUTPUT_STRIP_TRAILING_WHITESPACE) + if(${QAT_PHYSICAL} GREATER_EQUAL "1") + message(STATUS "Detected ${QAT_PHYSICAL} physical QAT processes") + execute_process(COMMAND lspci -d 8086:4941 COMMAND wc -l OUTPUT_VARIABLE QAT_VIRTUAL OUTPUT_STRIP_TRAILING_WHITESPACE) + if(${QAT_VIRTUAL} GREATER_EQUAL "1") + message(STATUS "Detected ${QAT_VIRTUAL} virtual QAT processes") + ipcl_check_qat_service_status() + set(IPCL_FOUND_QAT TRUE PARENT_SCOPE) + else() + message(WARNING "NO virtual QAT processors - IPCL_ENABLE_QAT set to OFF") + endif() else() - message(WARNING "NO virtual QAT processors - IPCL_ENABLE_QAT set to OFF") + message(WARNING "NO physical QAT processors - IPCL_ENABLE_QAT set to OFF") endif() else() - message(WARNING "NO physical QAT processors - IPCL_ENABLE_QAT set to OFF") + message(WARNING "Environment variable ICP_ROOT is incorrect - IPCL_ENABLE_QAT set to OFF") endif() - else() - message(WARNING "Environment variable ICP_ROOT must be defined. Disabling QAT build") - set(IPCL_FOUND_QAT FALSE PARENT_SCOPE) + message(WARNING "Environment variable ICP_ROOT must be defined - IPCL_ENABLE_QAT set to OFF") endif() endfunction() From bc38b24e09724739670e42f9769c83d968efebf1 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Wed, 9 Nov 2022 01:12:10 -0800 Subject: [PATCH 343/364] Fix - use full QAT when OMP is disabled --- ipcl/ciphertext.cpp | 4 ++++ ipcl/pri_key.cpp | 4 ++++ ipcl/pub_key.cpp | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/ipcl/ciphertext.cpp b/ipcl/ciphertext.cpp index 440e1d1..d5638fa 100644 --- a/ipcl/ciphertext.cpp +++ b/ipcl/ciphertext.cpp @@ -152,9 +152,13 @@ std::vector CipherText::raw_mul( // If hybrid OPTIMAL mode is used, use a special ratio if (isHybridOptimal()) { +#ifdef IPCL_USE_OMP float qat_ratio = (v_size <= IPCL_WORKLOAD_SIZE_THRESHOLD) ? IPCL_HYBRID_MODEXP_RATIO_FULL : IPCL_HYBRID_MODEXP_RATIO_MULTIPLY; +#else + float qat_ratio = IPCL_HYBRID_MODEXP_RATIO_FULL; +#endif // IPCL_USE_OMP setHybridRatio(qat_ratio, false); } diff --git a/ipcl/pri_key.cpp b/ipcl/pri_key.cpp index 29201f6..8b18eb5 100644 --- a/ipcl/pri_key.cpp +++ b/ipcl/pri_key.cpp @@ -64,9 +64,13 @@ PlainText PrivateKey::decrypt(const CipherText& ct) const { // If hybrid OPTIMAL mode is used, use a special ratio if (isHybridOptimal()) { +#ifdef IPCL_USE_OMP float qat_ratio = (ct_size <= IPCL_WORKLOAD_SIZE_THRESHOLD) ? IPCL_HYBRID_MODEXP_RATIO_FULL : IPCL_HYBRID_MODEXP_RATIO_DECRYPT; +#else + float qat_ratio = IPCL_HYBRID_MODEXP_RATIO_FULL; +#endif // IPCL_USE_OMP setHybridRatio(qat_ratio, false); } diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index abbbd64..e99a933 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -123,9 +123,13 @@ CipherText PublicKey::encrypt(const PlainText& pt, bool make_secure) const { // If hybrid OPTIMAL mode is used, use a special ratio if (isHybridOptimal()) { +#ifdef IPCL_USE_OMP float qat_ratio = (pt_size <= IPCL_WORKLOAD_SIZE_THRESHOLD) ? IPCL_HYBRID_MODEXP_RATIO_FULL : IPCL_HYBRID_MODEXP_RATIO_ENCRYPT; +#else + float qat_ratio = IPCL_HYBRID_MODEXP_RATIO_FULL; +#endif // IPCL_USE_OMP setHybridRatio(qat_ratio, false); } From 277add2f0289301e556c26f2f44ddac636e11513 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Wed, 9 Nov 2022 01:26:49 -0800 Subject: [PATCH 344/364] Revert "Fix - use full QAT when OMP is disabled" This reverts commit bc38b24e09724739670e42f9769c83d968efebf1. --- ipcl/ciphertext.cpp | 4 ---- ipcl/pri_key.cpp | 4 ---- ipcl/pub_key.cpp | 4 ---- 3 files changed, 12 deletions(-) diff --git a/ipcl/ciphertext.cpp b/ipcl/ciphertext.cpp index d5638fa..440e1d1 100644 --- a/ipcl/ciphertext.cpp +++ b/ipcl/ciphertext.cpp @@ -152,13 +152,9 @@ std::vector CipherText::raw_mul( // If hybrid OPTIMAL mode is used, use a special ratio if (isHybridOptimal()) { -#ifdef IPCL_USE_OMP float qat_ratio = (v_size <= IPCL_WORKLOAD_SIZE_THRESHOLD) ? IPCL_HYBRID_MODEXP_RATIO_FULL : IPCL_HYBRID_MODEXP_RATIO_MULTIPLY; -#else - float qat_ratio = IPCL_HYBRID_MODEXP_RATIO_FULL; -#endif // IPCL_USE_OMP setHybridRatio(qat_ratio, false); } diff --git a/ipcl/pri_key.cpp b/ipcl/pri_key.cpp index 8b18eb5..29201f6 100644 --- a/ipcl/pri_key.cpp +++ b/ipcl/pri_key.cpp @@ -64,13 +64,9 @@ PlainText PrivateKey::decrypt(const CipherText& ct) const { // If hybrid OPTIMAL mode is used, use a special ratio if (isHybridOptimal()) { -#ifdef IPCL_USE_OMP float qat_ratio = (ct_size <= IPCL_WORKLOAD_SIZE_THRESHOLD) ? IPCL_HYBRID_MODEXP_RATIO_FULL : IPCL_HYBRID_MODEXP_RATIO_DECRYPT; -#else - float qat_ratio = IPCL_HYBRID_MODEXP_RATIO_FULL; -#endif // IPCL_USE_OMP setHybridRatio(qat_ratio, false); } diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index e99a933..abbbd64 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -123,13 +123,9 @@ CipherText PublicKey::encrypt(const PlainText& pt, bool make_secure) const { // If hybrid OPTIMAL mode is used, use a special ratio if (isHybridOptimal()) { -#ifdef IPCL_USE_OMP float qat_ratio = (pt_size <= IPCL_WORKLOAD_SIZE_THRESHOLD) ? IPCL_HYBRID_MODEXP_RATIO_FULL : IPCL_HYBRID_MODEXP_RATIO_ENCRYPT; -#else - float qat_ratio = IPCL_HYBRID_MODEXP_RATIO_FULL; -#endif // IPCL_USE_OMP setHybridRatio(qat_ratio, false); } From 839ceddd34b758f49e232a712ab61dc1f2de6529 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Wed, 9 Nov 2022 01:28:39 -0800 Subject: [PATCH 345/364] Remove example files from cpplint excludes --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1605958..a401a02 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -45,7 +45,7 @@ repos: entry: cpplint language: system files: \.(c|cc|cxx|cpp|h|hpp|hxx)$ - exclude: ipcl/bignum.cpp|ipcl/include/ipcl/bignum.h|example/test.cpp + exclude: ipcl/bignum.cpp|ipcl/include/ipcl/bignum.h args: - --recursive - --filter=-runtime/references,-whitespace/comments,-whitespace/indent From 98883f00ead83e5de89af08406bbc7f8037324a9 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Wed, 9 Nov 2022 15:06:35 -0800 Subject: [PATCH 346/364] * pre-commit fixes - Added ```NOLINT``` for certain "C" expressions - Replaced ```expr``` with ```$(( ))``` - Shellcheck fixes and added shellcheck disable statements where needed - Put shebang on top of licenses * Refactor cmake - Added message output on heqat/CMake when standalone build - INSTALL_RPATH to include $ORIGIN (reverted) --- .pre-commit-config.yaml | 2 +- CMakeLists.txt | 2 +- cmake/gbenchmark.cmake | 2 - module/heqat/.gitignore | 2 +- module/heqat/CMakeLists.txt | 20 ++- module/heqat/README.md | 59 ++++---- module/heqat/cmake/qatconfig.cmake | 18 +-- module/heqat/config/4xxx_dev0.conf | 28 ++-- module/heqat/config/4xxxvf_dev0.conf | 27 ++-- module/heqat/doc/CMakeLists.txt | 2 +- module/heqat/doc/Doxyfile.in | 8 +- module/heqat/doc/index.rst | 8 +- module/heqat/example/CMakeLists.txt | 4 +- module/heqat/example/example.cpp | 39 ++--- module/heqat/heqat/cb.c | 12 +- module/heqat/heqat/include/heqat/bnops.h | 53 +++---- .../heqat/heqat/include/heqat/common/types.h | 14 +- .../heqat/heqat/include/heqat/misc/bignum.h | 2 +- module/heqat/heqat/misc/misc.cpp | 2 +- module/heqat/scripts/auto_find_qat_install.sh | 5 +- .../heqat/scripts/reset_asym_buffer_size.sh | 63 ++++---- module/heqat/scripts/restart_devices.sh | 100 ++++++------- module/heqat/scripts/run.sh | 15 +- module/heqat/scripts/setup_devices.sh | 128 ++++++++--------- module/heqat/setup_env.sh | 7 +- module/heqat/test/CMakeLists.txt | 14 +- module/heqat/test/test_BIGNUMModExp.c | 42 +++--- module/heqat/test/test_bnConversion.cpp | 30 ++-- module/heqat/test/test_bnModExp.cpp | 70 ++++----- module/heqat/test/test_bnModExp_MT.cpp | 134 ++++++++++-------- module/heqat/test/test_context.c | 6 +- 31 files changed, 472 insertions(+), 446 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1605958..a0b85da 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -45,7 +45,7 @@ repos: entry: cpplint language: system files: \.(c|cc|cxx|cpp|h|hpp|hxx)$ - exclude: ipcl/bignum.cpp|ipcl/include/ipcl/bignum.h|example/test.cpp + exclude: ipcl/bignum.cpp|ipcl/include/ipcl/bignum.h|module/heqat/heqat/include/heqat/misc/bignum.h args: - --recursive - --filter=-runtime/references,-whitespace/comments,-whitespace/indent diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e57fff..83b11ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,7 +45,7 @@ endif() set(CMAKE_C_FLAGS "-O2 -Wno-error=deprecated-declarations -Wno-error=deprecated-copy") set(CMAKE_CXX_FLAGS "-O2 -fpermissive -Wno-error=deprecated-declarations -Wno-error=deprecated-copy") -set(CMAKE_INSTALL_RPATH "$ORIGIN/${CMAKE_INSTALL_LIBDIR};$ORIGIN/ippcrypto") +set(CMAKE_INSTALL_RPATH "$ORIGIN;$ORIGIN/${CMAKE_INSTALL_LIBDIR};$ORIGIN/ippcrypto") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) diff --git a/cmake/gbenchmark.cmake b/cmake/gbenchmark.cmake index f9907b3..94011be 100644 --- a/cmake/gbenchmark.cmake +++ b/cmake/gbenchmark.cmake @@ -2,10 +2,8 @@ # SPDX-License-Identifier: Apache-2.0 include(ExternalProject) -include(GNUInstallDirs) set(GBENCHMARK_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_gbenchmark) - set(GBENCHMARK_SRC_DIR ${GBENCHMARK_PREFIX}/src/ext_gbenchmark/) set(GBENCHMARK_BUILD_DIR ${GBENCHMARK_PREFIX}/src/ext_gbenchmark-build/) set(GBENCHMARK_REPO_URL https://github.com/google/benchmark.git) diff --git a/module/heqat/.gitignore b/module/heqat/.gitignore index 3b962b7..0e2a8ef 100644 --- a/module/heqat/.gitignore +++ b/module/heqat/.gitignore @@ -9,4 +9,4 @@ cmake/he_qat-*.*.*/HE_QATConfig.cmake *.log Doxyfile -**.swp \ No newline at end of file +**.swp diff --git a/module/heqat/CMakeLists.txt b/module/heqat/CMakeLists.txt index 571bde1..cd0c123 100644 --- a/module/heqat/CMakeLists.txt +++ b/module/heqat/CMakeLists.txt @@ -51,10 +51,7 @@ if(HE_QAT_STANDALONE) endif() endif() -set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/heqat") - -message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") - +set(CMAKE_INSTALL_RPATH "$ORIGIN;$ORIGIN/${CMAKE_INSTALL_LIBDIR}") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) # ------------------------------------------------------------------- @@ -95,6 +92,21 @@ else() set(HE_QAT_DEBUG OFF) endif() +if(HE_QAT_STANDALONE) + message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") + message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}") + message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}") + message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") + message(STATUS "HE_QAT_MISC: ${HE_QAT_MISC}") + message(STATUS "HE_QAT_SYNC: ${HE_QAT_SYNC}") + message(STATUS "HE_QAT_MT: ${HE_QAT_MT}") + message(STATUS "HE_QAT_PERF: ${HE_QAT_PERF}") + message(STATUS "HE_QAT_TEST: ${HE_QAT_TEST}") + message(STATUS "HE_QAT_OMP: ${HE_QAT_OMP}") + message(STATUS "HE_QAT_DOCS: ${HE_QAT_DOCS}") + message(STATUS "HE_QAT_SHARED: ${HE_QAT_SHARED}") +endif() + if(HE_QAT_MISC) add_definitions(-DHE_QAT_MISC) endif() diff --git a/module/heqat/README.md b/module/heqat/README.md index 3b202d9..4f22caa 100644 --- a/module/heqat/README.md +++ b/module/heqat/README.md @@ -1,16 +1,26 @@ # Intel Homomorphic Encryption (HE) Acceleration Library for Quick Assist Technology (QAT) -Intel Homomorphic Encryption Acceleration Library for QAT (HE QAT Lib) is an open-source library which provides accelerated performance for homomorphic encryption (HE) math functions involving multi-precision numbers and modular arithmetic. This library is written in C99. +Intel Homomorphic Encryption Acceleration Library for QAT (HE QAT Lib) is an open-source library which provides accelerated performance for homomorphic encryption (HE) math functions involving multi-precision numbers and modular arithmetic. This library is written in C99. ## Contents -- [Intel Homomorphic Encryption Acceleration Library for QAT](#intel-homomorphic-encryption-library-for-qat) +- [Intel Homomorphic Encryption (HE) Acceleration Library for Quick Assist Technology (QAT)](#intel-homomorphic-encryption-he-acceleration-library-for-quick-assist-technology-qat) - [Contents](#contents) - [Introduction](#introduction) - - [Building the Library](#building-the-library) + - [Building the HE QAT Library](#building-the-he-qat-library) - [Requirements](#requirements) - [Dependencies](#dependencies) - [Instructions](#instructions) + - [Installing Dependencies](#installing-dependencies) + - [Installing OpenSSL](#installing-openssl) + - [Installing QAT Software Stack](#installing-qat-software-stack) + - [Setup Environment](#setup-environment) + - [Building the Library](#building-the-library) + - [Configuring QAT endpoints](#configuring-qat-endpoints) + - [Configuration Options](#configuration-options) + - [Running Samples](#running-samples) + - [Running All Samples](#running-all-samples) - [Troubleshooting](#troubleshooting) - [Testing and Benchmarking](#testing-and-benchmarking) +- [Contributors](#contributors) - [Contributors](#contributors) @@ -19,18 +29,18 @@ Intel Homomorphic Encryption Acceleration Library for QAT (HE QAT Lib) is an ope This library currently only offers acceleration of modular exponentiation of multi-precision numbers, i.e. large numbers whose precision range from 1024 to 8192 bits. Current stage of implementation supports modular exponentiation of big numbers encoded with OpenSSL `BIGNUM` data type, `ippcrypto`'s `BigNumber` class and octet strings encoded with `unsigned char`. More details about the modes of operation and characteristics of the execution flow are described below: - Synchronous: API calls will submit requests that will be executed in the order they are first issued by the host caller, i.e. a series of modular exponentiation operation requests will be offloaded for processing by the accelerator in the order they are issued. - + - Asynchronous: API calls will submit requests that will NOT necessarily be executed in the order they are first issued by the host caller, i.e. a sequence of multiple requests for the modular exponentiation operation could be scheduled out of order and executed concurrently by the accelerator; thus, completed out of order. - Blocking: API calls will be blocked until work request processing completion. Internally, the next buffered work request waits for completion of the processing of the most recently offloaded request to the accelerator. - + - Non-Blocking: API calls will be non-blocking, it does not wait for completion of the work request to return from call. After multiple non-blocking calls to the API, a blocking function to wait for the requests to complete processing must be called. Internally, non-blocking request submissions are scheduled to the accelerator asynchronously. When there are multiple requests from concurrent API callers, the requests are not guaranteed to be processed in order of arrival. - Batch Support: The internal buffers are set accommodate up to 1024 requests at a time so that the maximum number of non-blocking API calls is 1024 for each concurrent thread caller. Therefore, only up to 1024 requests can be exercised asynchronously from the application side, be it from a single `for loop` or static code block. Finally, in order to collect the requests, a call to the `getBnModExpRequest()` function must be performed to wait for completion of all submitted asynchronous requests. On multithreaded mode, the blocking function to be called at the end of the code block shall be `release_bnModExp_buffer()`. - + - Multithreading Support: This feature permits the API to be called by concurrently threads running on the host. Effective multithreading support relies on a separate buffer that admits outstanding work requests. This buffer is acquired before an API call to submit work requests to the accelerator. This is accomplished by first calling `acquire_bnModExp_buffer()` to reserve an internal buffer to store outstanding requests from the host API caller. - - Multiple Instances: The library accesses all logical instances from all visible and configured QAT endpoints at the creation of the QAT runtime context. Therefore, if 8 QAT endpoints are available, it will attempt to use them all, including all the total number of logical instances configured per process. + - Multiple Instances: The library accesses all logical instances from all visible and configured QAT endpoints at the creation of the QAT runtime context. Therefore, if 8 QAT endpoints are available, it will attempt to use them all, including all the total number of logical instances configured per process. >> _**Note**_: Current implementation does not verify if the instance/endpoint has the capabilities needed by the library. For example, the library needs access to the _asym_ capabilities like `CyLnModExp`, therefore if the configuration file of an endpoint happens to be configured to not offer it, the application will exit with an error at some point during execution. @@ -82,8 +92,8 @@ In the example above, the platform is a dual-socket server with Sapphire Rapids #### Installing Dependencies ``` -sudo apt install yasm zlib1g -sudo apt update -y +sudo apt install yasm zlib1g +sudo apt update -y sudo apt install -y libsystemd-dev sudo apt install -y pciutils (tested with version=3.6.4) sudo apt install -y libudev-dev @@ -122,7 +132,7 @@ $ sudo make -j $ sudo make install ``` -Add `$USER` to the `qat` group. Must logout and log back in to take effect. +Add `$USER` to the `qat` group. Must logout and log back in to take effect. ``` $ sudo usermod -aG qat $USER @@ -143,9 +153,9 @@ sudo systemctl status qat_service.service If all checks out, following the instructions below to build the HE QAT library. -#### Setup Environment +#### Setup Environment -This step is required. Note that if the step [Installing QAT Software Stack](#installing-qat-software-stack) has just been performed, then the exact path of the installation is known, i.e. +This step is required. Note that if the step [Installing QAT Software Stack](#installing-qat-software-stack) has just been performed, then the exact path of the installation is known, i.e. ``` export ICP_ROOT=$HOME/QAT @@ -153,18 +163,18 @@ export ICP_ROOT=$HOME/QAT Alternatively, if the system has a pre-built QAT software stack installed, the script `auto_find_qat_install.sh` can used to help automatically find the path where it was installed (see command below). The script `auto_find_qat_install.sh` assumes that the QAT package is installed in a single location, such that if multiple installations are available at different locations, the script may produce undetermined behavior. - - Explicity way: + - Explicit way: ``` export ICP_ROOT=$(./auto_find_qat_install.sh) ``` - - Implicity way: + - Implicit way: ``` source setup_env.sh ``` #### Building the Library -Follow the steps in the sections [Installing QAT Software Stack](#installing-qat-software-stack) and [Setup Environment](#setup-environment) before attempting to build the library. +Follow the steps in the sections [Installing QAT Software Stack](#installing-qat-software-stack) and [Setup Environment](#setup-environment) before attempting to build the library. - How to build without `BigNumber` support @@ -204,9 +214,9 @@ $ sudo cmake --install _build #### Configuring QAT endpoints -Before trying to run any application or example that uses the HE QAT Lib, the QAT endpoints must be configured. +Before trying to run any application or example that uses the HE QAT Lib, the QAT endpoints must be configured. The default configuration provided in this release is the optimal configuration to provide computing acceleration support for [IPCL](https://github.com/intel/pailliercryptolib). -The boilerplate configurations can be found in the `config` directory. +The boilerplate configurations can be found in the `config` directory. ``` ./scripts/setup_devices.sh @@ -237,21 +247,21 @@ Test showing creation and teardown of the QAT runtime environment: ``` ./build/samples/sample_context -``` +``` Test showing functional correctness and performance using BIGNUM data as input: ``` ./build/samples/sample_BIGNUMModExp -``` +``` -If built with `HE_QAT_MISC=ON`, then the following samples below are also available to try. +If built with `HE_QAT_MISC=ON`, then the following samples below are also available to try. Test showing data conversion between `BigNumber` and `CpaFlatBuffer` formats: ``` ./build/samples/sample_bnConversion -``` +``` Test showing functional correctness and performance using `BigNumber` data types: @@ -272,7 +282,7 @@ HEQATLIB_ROOT_DIR=$PWD ./scripts/run.sh ## Troubleshooting -- **Issue #1** +- **Issue #1** ``` xuser@ubuntu-guest:~/heqat$ cmake -S . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHE_QAT_MISC=ON @@ -290,7 +300,7 @@ CMake Error at CMakeLists.txt:93 (find_package): FOUND. ``` -To resolve the error below simply create the symbolic link `/opt/ipp-crypto/lib/intel64/libippcp.a` from the apropriate static ippcp library that was compiled. For example: +To resolve the error below simply create the symbolic link `/opt/ipp-crypto/lib/intel64/libippcp.a` from the appropriate static ippcp library that was compiled. For example: ``` xuser@ubuntu-guest:/opt/ipp-crypto/lib/intel64$ ls -lha @@ -318,6 +328,5 @@ Main contributors to this project, sorted by alphabetical order of last name are - [Fillipe Dias M. de Souza](https://www.linkedin.com/in/fillipe-d-m-de-souza-a8281820) (lead) - [Xiaoran Fang](https://github.com/fangxiaoran) - [Jingyi Jin](https://www.linkedin.com/in/jingyi-jin-655735) - - [Sejun Kim](https://www.linkedin.com/in/sejun-kim-2b1b4866) + - [Sejun Kim](https://www.linkedin.com/in/sejun-kim-2b1b4866) - [Pengfei Zhao](https://github.com/justalittlenoob) - diff --git a/module/heqat/cmake/qatconfig.cmake b/module/heqat/cmake/qatconfig.cmake index bf9dee3..da52322 100644 --- a/module/heqat/cmake/qatconfig.cmake +++ b/module/heqat/cmake/qatconfig.cmake @@ -8,24 +8,24 @@ else() message(FATAL_ERROR "Environment variable ICP_ROOT must be defined. Try export ICP_ROOT=") endif() -set(ICP_ROOT $ENV{ICP_ROOT}) -set(ICP_BUILDOUTPUT_PATH ${ICP_ROOT}/build) -set(ICP_BUILDSYSTEM_PATH ${ICP_ROOT}/quickassist/build_system) +set(ICP_ROOT $ENV{ICP_ROOT}) +set(ICP_BUILDOUTPUT_PATH ${ICP_ROOT}/build) +set(ICP_BUILDSYSTEM_PATH ${ICP_ROOT}/quickassist/build_system) set(ICP_API_DIR ${ICP_ROOT}/quickassist) -set(ICP_LAC_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer) +set(ICP_LAC_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer) set(ICP_OSAL_DIR ${ICP_ROOT}/quickassist/utilities/oasl) -set(ICP_ADF_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/qat_direct) +set(ICP_ADF_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/qat_direct) set(CMN_ROOT ${ICP_ROOT}/quickassist/utilities/libusdm_drv) -set(ICP_INC_DIR ${ICP_API_DIR}/include - ${ICP_LAC_DIR}/include +set(ICP_INC_DIR ${ICP_API_DIR}/include + ${ICP_LAC_DIR}/include ${ICP_ADF_DIR}/include ${CMN_ROOT} ${ICP_API_DIR}/include/dc ${ICP_API_DIR}/include/lac) -#add_definitions(-DDO_CRYPTO) -add_definitions(-DUSER_SPACE) +#add_definitions(-DDO_CRYPTO) +add_definitions(-DUSER_SPACE) add_compile_options(-fPIC) add_library(libadf_static STATIC IMPORTED GLOBAL) diff --git a/module/heqat/config/4xxx_dev0.conf b/module/heqat/config/4xxx_dev0.conf index 870318c..fcaa5f2 100755 --- a/module/heqat/config/4xxx_dev0.conf +++ b/module/heqat/config/4xxx_dev0.conf @@ -1,38 +1,38 @@ ################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. -# +# # GPL LICENSE SUMMARY -# +# # Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# +# # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. -# +# # Contact Information: # Intel Corporation -# +# # BSD LICENSE -# +# # Copyright(c) 2007-2021 Intel Corporation. All rights reserved. # All rights reserved. -# +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: -# +# # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright @@ -42,7 +42,7 @@ # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. -# +# # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -54,8 +54,8 @@ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# +# +# # version: QAT20.L.0.8.0-00071 ################################################################ [GENERAL] @@ -93,7 +93,7 @@ PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 -# Default value for power management idle interrrupt delay +# Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support diff --git a/module/heqat/config/4xxxvf_dev0.conf b/module/heqat/config/4xxxvf_dev0.conf index 3a7fa18..a633579 100755 --- a/module/heqat/config/4xxxvf_dev0.conf +++ b/module/heqat/config/4xxxvf_dev0.conf @@ -1,38 +1,38 @@ ################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. -# +# # GPL LICENSE SUMMARY -# +# # Copyright(c) 2007-2021 Intel Corporation. All rights reserved. -# +# # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. -# +# # Contact Information: # Intel Corporation -# +# # BSD LICENSE -# +# # Copyright(c) 2007-2021 Intel Corporation. All rights reserved. # All rights reserved. -# +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: -# +# # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright @@ -42,7 +42,7 @@ # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. -# +# # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -54,8 +54,8 @@ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# +# +# # version: QAT20.L.0.8.0-00071 ################################################################ [GENERAL] @@ -131,4 +131,3 @@ Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 2 - diff --git a/module/heqat/doc/CMakeLists.txt b/module/heqat/doc/CMakeLists.txt index 8639c0d..822e556 100644 --- a/module/heqat/doc/CMakeLists.txt +++ b/module/heqat/doc/CMakeLists.txt @@ -18,7 +18,7 @@ add_custom_command(OUTPUT ${DOXYGEN_INDEX_FILE} MAIN_DEPENDENCY ${DOXYFILE_OUT} ${DOXYFILE_IN} COMMENT "Generating Doxygen documentation") -add_custom_target(docs ALL DEPENDS ${DOXYGEN_INDEX_FILE}) +add_custom_target(docs ALL DEPENDS ${DOXYGEN_INDEX_FILE}) install(DIRECTORY ${CMAKE_BINARY_DIR}/doc/doxygen diff --git a/module/heqat/doc/Doxyfile.in b/module/heqat/doc/Doxyfile.in index 5c8e2b7..be375b4 100644 --- a/module/heqat/doc/Doxyfile.in +++ b/module/heqat/doc/Doxyfile.in @@ -8,11 +8,11 @@ OUTPUT_DIRECTORY = @CMAKE_BINARY_DIR@/doc/doxygen INPUT = @CMAKE_SOURCE_DIR@/heqat/include/heqat \ @CMAKE_SOURCE_DIR@/heqat/include/heqat/common \ @CMAKE_SOURCE_DIR@/heqat/include/heqat/misc \ - @CMAKE_SOURCE_DIR@/heqat \ - @CMAKE_SOURCE_DIR@/heqat/misc \ - @CMAKE_SOURCE_DIR@/heqat/common \ + @CMAKE_SOURCE_DIR@/heqat \ + @CMAKE_SOURCE_DIR@/heqat/misc \ + @CMAKE_SOURCE_DIR@/heqat/common \ @CMAKE_SOURCE_DIR@/samples \ - @CMAKE_SOURCE_DIR@/README.md + @CMAKE_SOURCE_DIR@/README.md RECURSIVE = YES USE_MDFILE_AS_MAINPAGE = @CMAKE_SOURCE_DIR@/README.md USE_MATHJAX = YES diff --git a/module/heqat/doc/index.rst b/module/heqat/doc/index.rst index db1489b..860a83a 100644 --- a/module/heqat/doc/index.rst +++ b/module/heqat/doc/index.rst @@ -1,5 +1,5 @@ -## Intel HE Acceleration Library for QAT Documentation ## -.. toctree:: - api +## Intel HE Acceleration Library for QAT Documentation ## +.. toctree:: + api -.. mdinclude:: ../README.md +.. mdinclude:: ../README.md diff --git a/module/heqat/example/CMakeLists.txt b/module/heqat/example/CMakeLists.txt index ec84eac..11f2aab 100644 --- a/module/heqat/example/CMakeLists.txt +++ b/module/heqat/example/CMakeLists.txt @@ -10,8 +10,8 @@ set(HE_QAT_HINT_DIR ${CMAKE_PREFIX_PATH}) message(STATUS "CMAKE_PREFIX_PATH ${HE_QAT_HINT_DIR}") # Example using source -find_package(HE_QAT 1.3.2 - HINTS ${HE_QAT_HINT_DIR} +find_package(HE_QAT 1.3.2 + HINTS ${HE_QAT_HINT_DIR} REQUIRED) if(NOT TARGET HE_QAT::he_qat) message(FATAL_ERROR "TARGET HE_QAT::he_qat not found") diff --git a/module/heqat/example/example.cpp b/module/heqat/example/example.cpp index 1a8f9f9..b3460b0 100644 --- a/module/heqat/example/example.cpp +++ b/module/heqat/example/example.cpp @@ -1,12 +1,13 @@ // Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include "heqat/heqat.h" - #include #include #include #include +#include + +#include "heqat/heqat.h" #define LEN_OF_1024_BITS 128 #define LEN_OF_2048_BITS 256 @@ -16,7 +17,6 @@ #define ODD_RND_NUM 1 #define BATCH_SIZE 1 -#include struct timeval start_time, end_time; double time_taken = 0.0; @@ -47,8 +47,8 @@ int main(int argc, const char** argv) { #ifdef HE_QAT_DEBUG char* bn_str = BN_bn2hex(bn_mod); - HE_QAT_PRINT("Generated modulus: %s num_bytes: %d num_bits: %d\n", bn_str, - BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); + HE_QAT_PRINT("Generated modulus: %s num_bytes: %d num_bits: %d\n", + bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); OPENSSL_free(bn_str); #endif // bn_exponent in [0..bn_mod] @@ -62,7 +62,7 @@ int main(int argc, const char** argv) { // Perform OpenSSL ModExp Op BIGNUM* ssl_res = BN_new(); - gettimeofday(&start_time, NULL); + gettimeofday(&start_time, NULL); BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); gettimeofday(&end_time, NULL); time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; @@ -73,24 +73,24 @@ int main(int argc, const char** argv) { if (!ERR_get_error()) { #ifdef HE_QAT_DEBUG bn_str = BN_bn2hex(ssl_res); - HE_QAT_PRINT("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", bn_str, - BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); + HE_QAT_PRINT("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", + bn_str, BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); showHexBN(ssl_res, bit_length); OPENSSL_free(bn_str); #endif } else { HE_QAT_PRINT_ERR("Modular exponentiation failed.\n"); - exit(1); + exit(1); } HE_QAT_PRINT_DBG("\nStarting QAT bnModExp...\n"); // Perform QAT ModExp Op BIGNUM* qat_res = BN_new(); - gettimeofday(&start_time, NULL); + gettimeofday(&start_time, NULL); for (unsigned int j = 0; j < BATCH_SIZE; j++) status = HE_QAT_BIGNUMModExp(qat_res, bn_base, bn_exponent, bn_mod, - bit_length); + bit_length); getBnModExpRequest(BATCH_SIZE); gettimeofday(&end_time, NULL); time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; @@ -102,18 +102,19 @@ int main(int argc, const char** argv) { qat_avg_time = (mod * qat_avg_time + qat_elapsed / BATCH_SIZE) / (mod + 1); avg_speed_up = - (mod * avg_speed_up + - (ssl_elapsed) / (qat_elapsed/BATCH_SIZE)) / (mod + 1); + (mod * avg_speed_up + (ssl_elapsed) / (qat_elapsed / BATCH_SIZE)) / + (mod + 1); - HE_QAT_PRINT("Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", + HE_QAT_PRINT( + "Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", (mod + 1), ssl_avg_time, qat_avg_time, avg_speed_up); - if (HE_QAT_STATUS_SUCCESS != status) { + if (HE_QAT_STATUS_SUCCESS != status) { HE_QAT_PRINT_ERR("\nQAT bnModExpOp failed\n"); - exit(1); + exit(1); } - - if (BN_cmp(qat_res, ssl_res) != 0) + + if (BN_cmp(qat_res, ssl_res) != 0) HE_QAT_PRINT("\t** FAIL **\n"); else HE_QAT_PRINT("\t** PASS **\n"); @@ -134,5 +135,5 @@ int main(int argc, const char** argv) { // Tear down QAT runtime context release_qat_devices(); - return (int)status; + return static_cast(status); } diff --git a/module/heqat/heqat/cb.c b/module/heqat/heqat/cb.c index 90c72a2..998926b 100644 --- a/module/heqat/heqat/cb.c +++ b/module/heqat/heqat/cb.c @@ -18,7 +18,7 @@ static pthread_mutex_t response_mutex; ///< It protects against race condition on response_count ///< due to concurrent callback events. -extern volatile unsigned long +extern volatile unsigned long // NOLINT response_count; ///< It counts the number of requests completed by the ///< accelerator. @@ -39,10 +39,10 @@ void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, // Check if input data for the op is available and do something if (NULL != pCallbackTag) { // Read request data - request = (HE_QAT_TaskRequest*)pCallbackTag; + request = (HE_QAT_TaskRequest*)pCallbackTag; // NOLINT pthread_mutex_lock(&response_mutex); - // Global track of reponses by accelerator + // Global track of responses by accelerator response_count += 1; pthread_mutex_unlock(&response_mutex); @@ -56,7 +56,7 @@ void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, BIGNUM* r = BN_bin2bn(request->op_result.pData, request->op_result.dataLenInBytes, - (BIGNUM*)request->op_output); + (BIGNUM*)request->op_output); // NOLINT if (NULL == r) request->request_status = HE_QAT_STATUS_FAIL; #ifdef HE_QAT_PERF gettimeofday(&request->end, NULL); @@ -93,10 +93,10 @@ void HE_QAT_bnModExpCallback(void* pCallbackTag, CpaStatus status, // Check if input data for the op is available and do something if (NULL != pCallbackTag) { // Read request data - request = (HE_QAT_TaskRequest*)pCallbackTag; + request = (HE_QAT_TaskRequest*)pCallbackTag; // NOLINT pthread_mutex_lock(&response_mutex); - // Global track of reponses by accelerator + // Global track of responses by accelerator response_count += 1; pthread_mutex_unlock(&response_mutex); diff --git a/module/heqat/heqat/include/heqat/bnops.h b/module/heqat/heqat/include/heqat/bnops.h index c773370..346c9a4 100644 --- a/module/heqat/heqat/include/heqat/bnops.h +++ b/module/heqat/heqat/include/heqat/bnops.h @@ -3,32 +3,33 @@ /// @file heqat/bnops.h /// /// @details -/// In this file, functions for Big Number operations accelerated by the -/// QuickAssist (QAT) co-processor are specified. +/// In this file, functions for Big Number operations accelerated by the +/// QuickAssist (QAT) co-processor are specified. /// /// @note -/// Unless otherwise specified, Big numbers are represented by octet strings -/// and stored in memory as pointers of type unsigned char*. On the QAT API -/// the octect string is copied into a data structure of type CpaFlatBuffer. The -/// octet strings representing Big Numbers are encoded with compliance to PKCA#1 -/// v2.1, section 4, which is consistent with ASN.1 syntax. -/// -/// The largest number supported here has 8192 bits, i.e. numbers from 0 to -/// 2^(8192)-1. If the number is N, then the bit length is defined by n = -/// floor(log2(N))+1. The memory buffer b to hold such number N needs to -/// have at least M = ceiling(n/8) bytes allocated. In general, it will be -/// larger and a power of 2, e.g. total bytes allocated is T=128 for -/// numbers having up to n=1024 bits, total bytes allocated is T=256 for -/// numbers having up to n=2048 bits, and so forth. Finally, the big number -/// N is stored in `big endian` format, i.e. the least significant byte -/// (LSB) is located at index [T-1], whereas the most significant byte is -/// stored at [T-M]. -/// -/// The API client is responsible for allocation and release of their memory -/// spaces of the function arguments. Allocated memory spaces must be -/// contiguous. Once a function is called, the ownership of the memory spaces is -/// transfered to the function until their completion such that concurrent usage -/// by the client during excution may result in undefined behavior. +/// Unless otherwise specified, Big numbers are represented by octet strings +/// and stored in memory as pointers of type unsigned char*. On the QAT API +/// the octet string is copied into a data structure of type +/// CpaFlatBuffer. The octet strings representing Big Numbers are encoded +/// with compliance to PKCA#1 v2.1, section 4, which is consistent with +/// ASN.1 syntax. +/// The largest number supported here has 8192 bits, i.e. numbers from 0 to +/// 2^(8192)-1. If the number is N, then the bit length is defined by n = +/// floor(log2(N))+1. The memory buffer b to hold such number N needs to +/// have at least M = ceiling(n/8) bytes allocated. In general, it will be +/// larger and a power of 2, e.g. total bytes allocated is T=128 for +/// numbers having up to n=1024 bits, total bytes allocated is T=256 for +/// numbers having up to n=2048 bits, and so forth. Finally, the big number +/// N is stored in `big endian` format, i.e. the least significant byte +/// (LSB) is located at index [T-1], whereas the most significant byte is +/// stored at [T-M]. +/// +/// The API client is responsible for allocation and release of their memory +/// spaces of the function arguments. Allocated memory spaces must be +/// contiguous. Once a function is called, the ownership of the memory +/// spaces is transferred to the function until their completion such +/// that concurrent usage by the client during execution may result in +/// undefined behavior. // New compilers #pragma once @@ -41,10 +42,10 @@ extern "C" { #endif -#include "heqat/common/types.h" - #include +#include "heqat/common/types.h" + /// @brief Performs modular exponentiation using BIGNUM data structure. /// /// @details diff --git a/module/heqat/heqat/include/heqat/common/types.h b/module/heqat/heqat/include/heqat/common/types.h index aa9dab1..31b1334 100644 --- a/module/heqat/heqat/include/heqat/common/types.h +++ b/module/heqat/heqat/include/heqat/common/types.h @@ -11,11 +11,6 @@ extern "C" { #endif -// QATLib Headers -#include "cpa.h" -#include "cpa_cy_im.h" -#include "cpa_cy_ln.h" - // C Libraries #include #include @@ -23,6 +18,11 @@ extern "C" { #include #endif +// QATLib Headers +#include +#include +#include + #include "heqat/common/consts.h" struct completion_struct { @@ -150,11 +150,11 @@ typedef struct { // One for each consumer typedef struct { - unsigned long long id; ///< Work request ID. + unsigned long long id; ///< Work request ID. NOLINT // sem_t callback; struct completion_struct callback; ///< Synchronization object. HE_QAT_OP - op_type; ///< Work type: type of operation to be offloaded to QAT. + op_type; ///< Work type: type of operation to be offloaded to QAT. CpaStatus op_status; ///< Status of the operation after completion. CpaFlatBuffer op_result; ///< Output of the operation in contiguous memory. // CpaCyLnModExpOpData op_data; diff --git a/module/heqat/heqat/include/heqat/misc/bignum.h b/module/heqat/heqat/include/heqat/misc/bignum.h index 68c3e4d..1e83f01 100644 --- a/module/heqat/heqat/include/heqat/misc/bignum.h +++ b/module/heqat/heqat/include/heqat/misc/bignum.h @@ -43,7 +43,7 @@ class BigNumber { friend IppsBigNumState* BN(const BigNumber& bn) { return bn.m_pBN; } operator IppsBigNumState*() const { return m_pBN; } - // some useful constatns + // some useful constants static const BigNumber& Zero(); static const BigNumber& One(); static const BigNumber& Two(); diff --git a/module/heqat/heqat/misc/misc.cpp b/module/heqat/heqat/misc/misc.cpp index 16b19aa..5116003 100644 --- a/module/heqat/heqat/misc/misc.cpp +++ b/module/heqat/heqat/misc/misc.cpp @@ -12,7 +12,7 @@ HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; int len_ = (nbits + 7) >> 3; // nbits/8; - // Create BigNumber containg input data passed as argument + // Create BigNumber containing input data passed as argument bn = BigNumber(reinterpret_cast(data), BITSIZE_WORD(nbits)); Ipp32u* ref_bn_data_ = NULL; ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); diff --git a/module/heqat/scripts/auto_find_qat_install.sh b/module/heqat/scripts/auto_find_qat_install.sh index 1f90d83..07e5968 100755 --- a/module/heqat/scripts/auto_find_qat_install.sh +++ b/module/heqat/scripts/auto_find_qat_install.sh @@ -1,4 +1,7 @@ +#!/bin/bash + # Copyright (C) 2022 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -for item in $(locate QAT/build); do [ -d $item ] && [ $(echo $item | grep $HOME) ] && echo ${item%/*}; done +# shellcheck disable=SC2143 +for item in $(locate QAT/build); do [ -d "$item" ] && [ "$(echo "$item" | grep "$HOME")" ] && echo "${item%/*}"; done diff --git a/module/heqat/scripts/reset_asym_buffer_size.sh b/module/heqat/scripts/reset_asym_buffer_size.sh index 2d7be43..a4d523d 100755 --- a/module/heqat/scripts/reset_asym_buffer_size.sh +++ b/module/heqat/scripts/reset_asym_buffer_size.sh @@ -1,7 +1,9 @@ +#!/bin/bash + # Copyright (C) 2022 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -#!/bin/bash +# shellcheck disable=SC2199 if [[ -z "${@}" ]]; then echo "Usage: ./reset_asym_buffer_size " exit @@ -12,7 +14,7 @@ OLD_BUFFER_SIZE=$1 if [[ -z ${2} ]]; then echo "Error: second parameter missing" echo "Usage: ./reset_asym_buffer_size " - exit + exit fi NEW_BUFFER_SIZE=$2 @@ -21,35 +23,33 @@ num_phys_dev=$(lspci -d 8086:4940 | wc -l) num_virt_dev=$(lspci -d 8086:4941 | wc -l) # Update physical device configuration files -i=0; -while [ $i -lt $num_phys_dev ]; -do - sudo sed -i /etc/4xxx_dev$i.conf -e "s/CyNumConcurrentAsymRequests = $OLD_BUFFER_SIZE/CyNumConcurrentAsymRequests = $NEW_BUFFER_SIZE/g"; - i=`expr $i + 1`; +i=0 +while [ $i -lt "$num_phys_dev" ]; do + sudo sed -i /etc/4xxx_dev$i.conf -e "s/CyNumConcurrentAsymRequests = $OLD_BUFFER_SIZE/CyNumConcurrentAsymRequests = $NEW_BUFFER_SIZE/g" + i=$((i + 1)) done # Update virtual function configuration files -i=0; -while [ $i -lt $num_virt_dev ]; -do - sudo sed -i /etc/4xxxvf_dev$i.conf -e "s/CyNumConcurrentAsymRequests = $OLD_BUFFER_SIZE/CyNumConcurrentAsymRequests = $NEW_BUFFER_SIZE/g"; - i=`expr $i + 1`; +i=0 +while [ $i -lt "$num_virt_dev" ]; do + sudo sed -i /etc/4xxxvf_dev$i.conf -e "s/CyNumConcurrentAsymRequests = $OLD_BUFFER_SIZE/CyNumConcurrentAsymRequests = $NEW_BUFFER_SIZE/g" + i=$((i + 1)) done ## Power Off PFs -#i=0; -#while [ $i -lt $num_phys_dev ]; -#do -# sudo adf_ctl qat_dev$i down; -# i=`expr $i + 1`; +#i=0; +#while [ $i -lt $num_phys_dev ]; +#do +# sudo adf_ctl qat_dev$i down; +# i=`expr $i + 1`; #done # ## Power On PFs -#i=0; -#while [ $i -lt $num_phys_dev ]; -#do -# sudo adf_ctl qat_dev$i up; -# i=`expr $i + 1`; +#i=0; +#while [ $i -lt $num_phys_dev ]; +#do +# sudo adf_ctl qat_dev$i up; +# i=`expr $i + 1`; #done # ## Restart QAT service (This will bring up PFs and VFs) @@ -61,17 +61,16 @@ done #vf_per_pf=`expr $num_virt_dev / $num_phys_dev` #n=`expr $vf_per_pf \\* $num_phys_dev` #n=`expr $n + $num_phys_dev` -#while [ $i -lt $n ]; -#do -# sudo adf_ctl qat_dev$i down; -# i=`expr $i + 1`; +#while [ $i -lt $n ]; +#do +# sudo adf_ctl qat_dev$i down; +# i=`expr $i + 1`; #done # ## Power On One QAT VF per QAT PF -#i=$num_phys_dev; -#while [ $i -lt $n ]; -#do -# sudo adf_ctl qat_dev$i up; -# i=`expr $i + $vf_per_pf`; +#i=$num_phys_dev; +#while [ $i -lt $n ]; +#do +# sudo adf_ctl qat_dev$i up; +# i=`expr $i + $vf_per_pf`; #done - diff --git a/module/heqat/scripts/restart_devices.sh b/module/heqat/scripts/restart_devices.sh index e9652aa..c563a25 100755 --- a/module/heqat/scripts/restart_devices.sh +++ b/module/heqat/scripts/restart_devices.sh @@ -1,21 +1,22 @@ +#!/bin/bash + # Copyright (C) 2022 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -#!/bin/bash # Refresh echo "sudo service restart qat_service" sudo service qat_service restart -num_phys_dev=$(lspci -d 8086:4940 | wc -l) -if [ $num_phys_dev -eq 0 ]; then +num_phys_dev=$(lspci -d 8086:4940 | wc -l) +if [ "$num_phys_dev" -eq 0 ]; then echo "No QAT Device Found !" exit else - echo "$num_phys_dev QAT Devices Found !" + echo "$num_phys_dev QAT Devices Found !" fi -total_virt_func=$(lspci -d 8086:4941 | wc -l) -num_virt_func=`expr $total_virt_func / $num_phys_dev` +total_virt_func=$(lspci -d 8086:4941 | wc -l) +num_virt_func=$((total_virt_func / num_phys_dev)) dev_step=1 if [ $# -eq 0 ]; then @@ -29,52 +30,50 @@ fi nphysdev=$num_phys_dev if [ -n "$1" ]; then nphysdev=$1 - if [ $nphysdev -gt $num_phys_dev ]; then + if [ "$nphysdev" -gt "$num_phys_dev" ]; then nphysdev=$num_phys_dev fi fi conf_virt_func=0 # Check if virtual function is enabled -if [ $num_virt_func -gt 0 ]; then +if [ "$num_virt_func" -gt 0 ]; then conf_virt_func=1 -fi +fi if [ -n "$2" ]; then conf_virt_func=$2 # if user attempts to request higher than available - if [ $conf_virt_func -gt $num_virt_func ]; then + if [ "$conf_virt_func" -gt "$num_virt_func" ]; then conf_virt_func=$num_virt_func fi fi # Shutdown QAT PFs i=0 -while [ $i -lt $num_phys_dev ]; -do - echo "sudo adf_ctl qat_dev$i down"; - sudo adf_ctl qat_dev$i down; - i=`expr $i + 1`; +while [ $i -lt "$num_phys_dev" ]; do + echo "sudo adf_ctl qat_dev$i down" + sudo adf_ctl qat_dev$i down + i=$((i + 1)) done # Reconfigure Target QAT PFs i=0 n=$nphysdev -while [ $i -lt $n ]; -do - echo "sudo adf_ctl qat_dev$i up"; - sudo adf_ctl qat_dev$i up; - i=`expr $i + 1`; +while [ $i -lt "$n" ]; do + echo "sudo adf_ctl qat_dev$i up" + sudo adf_ctl qat_dev$i up + i=$((i + 1)) done # Refresh echo "sudo service restart qat_service" -sudo service qat_service restart +sudo systemctl restart qat_service # If Virtualization Mode Enabled start=0 -if [ $num_virt_func -gt 0 ]; then - if [ $conf_virt_func -gt 0 ]; then +if [ "$num_virt_func" -gt 0 ]; then + if [ "$conf_virt_func" -gt 0 ]; then start=$num_phys_dev dev_step=$num_virt_func fi @@ -82,53 +81,46 @@ fi # Shutdown QAT VFs i=$start -stop=`expr $num_phys_dev \\* $num_virt_func` -stop=`expr $start + $stop` -step=$dev_step -while [ $i -lt $stop ]; -do - echo "sudo adf_ctl qat_dev$i down"; - sudo adf_ctl qat_dev$i down; - i=`expr $i + 1`; +stop=$((num_phys_dev * num_virt_func)) +stop=$((start + stop)) +while [ "$i" -lt "$stop" ]; do + echo "sudo adf_ctl qat_dev$i down" + sudo adf_ctl qat_dev"$i" down + i=$((i + 1)) done i=0 -while [ $i -lt $nphysdev ]; -do +while [ $i -lt "$nphysdev" ]; do # Start QAT PF - echo "sudo adf_ctl qat_dev$i up"; - sudo adf_ctl qat_dev$i up; - i=`expr $i + 1`; + echo "sudo adf_ctl qat_dev$i up" + sudo adf_ctl qat_dev$i up + i=$((i + 1)) done start=$num_phys_dev i=$start -stop=`expr $nphysdev \\* $num_virt_func` -stop=`expr $start + $stop` -step=$dev_step -while [ $i -lt $stop ]; -do +stop=$((nphysdev * num_virt_func)) +stop=$((start + stop)) +while [ "$i" -lt "$stop" ]; do # Start QAT VF echo "adf_ctl qat_dev$i up" - sudo adf_ctl qat_dev$i up; + sudo adf_ctl qat_dev"$i" up # Start up additional instances mapped to the same physical device - j=1; - while [ $j -lt $conf_virt_func ]; - do - dev_id=`expr $i + $j`; + j=1 + while [ $j -lt "$conf_virt_func" ]; do + dev_id=$((i + j)) # Start QAT VF echo "adf_ctl qat_dev$dev_id up" - sudo adf_ctl qat_dev$dev_id up; - j=`expr $j + 1`; + sudo adf_ctl qat_dev"$dev_id" up + j=$((j + 1)) done - i=`expr $i + $dev_step` + i=$((i + dev_step)) done # Shutdown Unused QAT PFs i=$nphysdev -while [ $i -lt $num_phys_dev ]; -do - echo "sudo adf_ctl qat_dev$i down"; - sudo adf_ctl qat_dev$i down; - i=`expr $i + 1`; +while [ "$i" -lt "$num_phys_dev" ]; do + echo "sudo adf_ctl qat_dev$i down" + sudo adf_ctl qat_dev"$i" down + i=$((i + 1)) done diff --git a/module/heqat/scripts/run.sh b/module/heqat/scripts/run.sh index 88fad28..b4a5090 100755 --- a/module/heqat/scripts/run.sh +++ b/module/heqat/scripts/run.sh @@ -1,22 +1,23 @@ +#!/bin/bash + # Copyright (C) 2022 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -#!/bin/bash export HEQATLIB_INSTALL_DIR=$HEQATLIB_ROOT_DIR/install -export ICP_ROOT=$($HEQATLIB_ROOT_DIR/scripts/auto_find_qat_install.sh) +ICP_ROOT=$("$HEQATLIB_ROOT_DIR"/scripts/auto_find_qat_install.sh) +export ICP_ROOT export LD_LIBRARY_PATH=$HEQATLIB_INSTALL_DIR/lib:$ICP_ROOT/build:$LD_LIBRARY_PATH -pushd $HEQATLIB_INSTALL_DIR/bin +pushd "$HEQATLIB_INSTALL_DIR"/bin || exit -for app in $(ls test_*) -do +for app in test_*; do echo "*****************************************************************" echo "* [START] RUNNING TEST SAMPLE $app *" echo "*****************************************************************" - ./$app + ./"$app" echo "*****************************************************************" echo "* [STOP] RUNNING TEST SAMPLE $app *" echo "*****************************************************************" done -popd +popd || exit diff --git a/module/heqat/scripts/setup_devices.sh b/module/heqat/scripts/setup_devices.sh index 5162daf..57f56ee 100755 --- a/module/heqat/scripts/setup_devices.sh +++ b/module/heqat/scripts/setup_devices.sh @@ -1,22 +1,23 @@ +#!/bin/bash + # Copyright (C) 2022 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -#!/bin/bash # Refresh echo "sudo service restart qat_service" #sudo service qat_service restart sudo systemctl restart qat_service.service -num_phys_dev=$(lspci -d 8086:4940 | wc -l) -if [ $num_phys_dev -eq 0 ]; then +num_phys_dev=$(lspci -d 8086:4940 | wc -l) +if [ "$num_phys_dev" -eq 0 ]; then echo "No QAT Device Found !" exit else - echo "$num_phys_dev QAT Devices Found !" + echo "$num_phys_dev QAT Devices Found !" fi -total_virt_func=$(lspci -d 8086:4941 | wc -l) -num_virt_func=`expr $total_virt_func / $num_phys_dev` +total_virt_func=$(lspci -d 8086:4941 | wc -l) +num_virt_func=$((total_virt_func / num_phys_dev)) dev_step=1 if [ $# -eq 0 ]; then @@ -30,44 +31,42 @@ fi nphysdev=$num_phys_dev if [ -n "$1" ]; then nphysdev=$1 - if [ $nphysdev -gt $num_phys_dev ]; then + if [ "$nphysdev" -gt "$num_phys_dev" ]; then nphysdev=$num_phys_dev fi fi conf_virt_func=0 # Check if virtual function is enabled -if [ $num_virt_func -gt 0 ]; then +if [ "$num_virt_func" -gt 0 ]; then conf_virt_func=1 -fi +fi if [ -n "$2" ]; then conf_virt_func=$2 # if user attempts to request higher than available - if [ $conf_virt_func -gt $num_virt_func ]; then + if [ "$conf_virt_func" -gt "$num_virt_func" ]; then conf_virt_func=$num_virt_func fi fi # Shutdown QAT PFs i=0 -while [ $i -lt $num_phys_dev ]; -do - echo "sudo adf_ctl qat_dev$i down"; - sudo adf_ctl qat_dev$i down; - i=`expr $i + 1`; +while [ $i -lt "$num_phys_dev" ]; do + echo "sudo adf_ctl qat_dev$i down" + sudo adf_ctl qat_dev$i down + i=$((i + 1)) done # Reconfigure Target QAT PFs i=0 n=$nphysdev -while [ $i -lt $n ]; -do - echo "sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf"; - sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf; - echo "sudo adf_ctl qat_dev$i up"; - sudo adf_ctl qat_dev$i up; - i=`expr $i + 1`; +while [ $i -lt "$n" ]; do + echo "sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf" + sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf + echo "sudo adf_ctl qat_dev$i up" + sudo adf_ctl qat_dev$i up + i=$((i + 1)) done # Refresh @@ -77,8 +76,8 @@ sudo systemctl restart qat_service.service # If Virtualization Mode Enabled start=0 -if [ $num_virt_func -gt 0 ]; then - if [ $conf_virt_func -gt 0 ]; then +if [ "$num_virt_func" -gt 0 ]; then + if [ "$conf_virt_func" -gt 0 ]; then start=$num_phys_dev dev_step=$num_virt_func fi @@ -86,72 +85,65 @@ fi # Shutdown QAT VFs i=$start -stop=`expr $num_phys_dev \\* $num_virt_func` -stop=`expr $start + $stop` -step=$dev_step -while [ $i -lt $stop ]; -do - echo "sudo adf_ctl qat_dev$i down"; - sudo adf_ctl qat_dev$i down; - i=`expr $i + 1`; +stop=$((num_phys_dev * num_virt_func)) +stop=$((start + stop)) +while [ "$i" -lt "$stop" ]; do + echo "sudo adf_ctl qat_dev$i down" + sudo adf_ctl qat_dev"$i" down + i=$((i + 1)) done #i=0 -#while [ $i -lt $total_virt_func ]; -#do -# echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$i.conf"; -# sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$i.conf; -# i=`expr $i + 1`; +#while [ $i -lt $total_virt_func ]; +#do +# echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$i.conf"; +# sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$i.conf; +# i=`expr $i + 1`; #done i=0 -while [ $i -lt $nphysdev ]; -do +while [ $i -lt "$nphysdev" ]; do # Reconfigure QAT PF - echo "sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf"; - sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf; + echo "sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf" + sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf # Start QAT PF - echo "sudo adf_ctl qat_dev$i up"; - sudo adf_ctl qat_dev$i up; - i=`expr $i + 1`; + echo "sudo adf_ctl qat_dev$i up" + sudo adf_ctl qat_dev$i up + i=$((i + 1)) done start=$num_phys_dev i=$start -stop=`expr $nphysdev \\* $num_virt_func` -stop=`expr $start + $stop` -step=$dev_step -while [ $i -lt $stop ]; -do - k=`expr $i - $start` +stop=$((nphysdev * num_virt_func)) +stop=$((start + stop)) +while [ "$i" -lt "$stop" ]; do + k=$((i - start)) # Reconfigure QAT VF (must match PF's config) - echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf"; - sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf; + echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf" + sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev"$k".conf # Start QAT VF echo "adf_ctl qat_dev$i up" - sudo adf_ctl qat_dev$i up; + sudo adf_ctl qat_dev"$i" up # Start up additional instances mapped to the same physical device - j=1; - while [ $j -lt $conf_virt_func ]; - do - dev_id=`expr $i + $j`; - k=`expr $dev_id - $start`; + j=1 + while [ $j -lt "$conf_virt_func" ]; do + dev_id=$((i + j)) + k=$((dev_id - start)) # Reconfigure QAT VF (must match PF's config) - echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf"; - sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf; + echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf" + sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev"$k".conf # Start QAT VF echo "adf_ctl qat_dev$dev_id up" - sudo adf_ctl qat_dev$dev_id up; - j=`expr $j + 1`; + sudo adf_ctl qat_dev"$dev_id" up + j=$((j + 1)) done - i=`expr $i + $dev_step` + i=$((i + dev_step)) done # Shutdown Unused QAT PFs i=$nphysdev -while [ $i -lt $num_phys_dev ]; -do - echo "sudo adf_ctl qat_dev$i down"; - sudo adf_ctl qat_dev$i down; - i=`expr $i + 1`; +while [ "$i" -lt "$num_phys_dev" ]; do + echo "sudo adf_ctl qat_dev$i down" + sudo adf_ctl qat_dev"$i" down + i=$((i + 1)) done diff --git a/module/heqat/setup_env.sh b/module/heqat/setup_env.sh index 27dffda..05d4dbc 100755 --- a/module/heqat/setup_env.sh +++ b/module/heqat/setup_env.sh @@ -1,5 +1,6 @@ #!/bin/bash -export HEQATLIB_ROOT_DIR=$(pwd) -export ICP_ROOT=$($PWD/scripts/auto_find_qat_install.sh) - +HEQATLIB_ROOT_DIR=$(pwd) +export HEQATLIB_ROOT_DIR +ICP_ROOT=$("$PWD"/scripts/auto_find_qat_install.sh) +export ICP_ROOT diff --git a/module/heqat/test/CMakeLists.txt b/module/heqat/test/CMakeLists.txt index 1c7f0e5..2bd391f 100644 --- a/module/heqat/test/CMakeLists.txt +++ b/module/heqat/test/CMakeLists.txt @@ -13,11 +13,11 @@ macro(heqat_create_executable test_case language dependencies) set(target test_${test_case}) add_executable(${target} test_${test_case}.${extension}) - + target_include_directories(${target} PUBLIC ${HE_QAT_INC_DIR}) - + target_link_libraries(${target} PUBLIC he_qat) - + if(NOT ${dependencies} STREQUAL "") message(STATUS "Target: ${target} Additional Dependencies: ${${dependencies}}") target_link_libraries(${target} PUBLIC ${${dependencies}}) @@ -40,17 +40,17 @@ if(HE_QAT_MISC) add_compile_options(-fpermissive) list(APPEND EXECUTABLE_DEPENDENCIES IPPCP::ippcp) - + # Sample showing how to convert from/to BigNumber to/from CpaFlatBuffer heqat_create_executable(bnConversion cxx EXECUTABLE_DEPENDENCIES) # Sample showing how to use bnModExp API - heqat_create_executable(bnModExp CXX EXECUTABLE_DEPENDENCIES) + heqat_create_executable(bnModExp CXX EXECUTABLE_DEPENDENCIES) - if(OpenMP_CXX_FOUND) + if(OpenMP_CXX_FOUND) list(APPEND EXECUTABLE_DEPENDENCIES OpenMP::OpenMP_CXX) # Sample showing how to use bnModExp_MT API for multithreaded applications - heqat_create_executable(bnModExp_MT CXX EXECUTABLE_DEPENDENCIES) + heqat_create_executable(bnModExp_MT CXX EXECUTABLE_DEPENDENCIES) endif() endif() diff --git a/module/heqat/test/test_BIGNUMModExp.c b/module/heqat/test/test_BIGNUMModExp.c index c496ea0..b31e936 100644 --- a/module/heqat/test/test_BIGNUMModExp.c +++ b/module/heqat/test/test_BIGNUMModExp.c @@ -1,14 +1,14 @@ // Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include "heqat/heqat.h" - #include #include #include #include - #include + +#include "heqat/heqat.h" + struct timeval start_time, end_time; double time_taken = 0.0; @@ -22,8 +22,8 @@ int main(int argc, const char** argv) { double ssl_avg_time = 0.0; double qat_avg_time = 0.0; - double ssl_elapsed = 0.0 ; - double qat_elapsed = 0.0 ; + double ssl_elapsed = 0.0; + double qat_elapsed = 0.0; HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; @@ -41,7 +41,8 @@ int main(int argc, const char** argv) { #ifdef HE_QAT_DEBUG char* bn_str = BN_bn2hex(bn_mod); - HE_QAT_PRINT("Generated modulus: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); + HE_QAT_PRINT("Generated modulus: %s num_bytes: %d num_bits: %d\n", + bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); OPENSSL_free(bn_str); #endif // bn_exponent in [0..bn_mod] @@ -55,10 +56,10 @@ int main(int argc, const char** argv) { // Perform OpenSSL ModExp Op BIGNUM* ssl_res = BN_new(); - //start = clock(); - gettimeofday(&start_time, NULL); - BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); - //ssl_elapsed = clock() - start; + // start = clock(); + gettimeofday(&start_time, NULL); + BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); + // ssl_elapsed = clock() - start; gettimeofday(&end_time, NULL); time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; time_taken = @@ -68,7 +69,8 @@ int main(int argc, const char** argv) { if (!ERR_get_error()) { #ifdef HE_QAT_DEBUG bn_str = BN_bn2hex(ssl_res); - HE_QAT_PRINT("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); + HE_QAT_PRINT("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", + bn_str, BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); showHexBN(ssl_res, bit_length); OPENSSL_free(bn_str); #endif @@ -79,13 +81,13 @@ int main(int argc, const char** argv) { // Perform QAT ModExp Op BIGNUM* qat_res = BN_new(); - //start = clock(); - gettimeofday(&start_time, NULL); + // start = clock(); + gettimeofday(&start_time, NULL); for (unsigned int j = 0; j < BATCH_SIZE; j++) status = HE_QAT_BIGNUMModExp(qat_res, bn_base, bn_exponent, bn_mod, - bit_length); + bit_length); getBnModExpRequest(BATCH_SIZE); - //qat_elapsed = clock() - start; + // qat_elapsed = clock() - start; gettimeofday(&end_time, NULL); time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; time_taken = @@ -96,10 +98,12 @@ int main(int argc, const char** argv) { qat_avg_time = (mod * qat_avg_time + qat_elapsed / BATCH_SIZE) / (mod + 1); avg_speed_up = - (mod * avg_speed_up + - (ssl_elapsed) / (qat_elapsed/BATCH_SIZE)) / (mod + 1); + (mod * avg_speed_up + (ssl_elapsed) / (qat_elapsed / BATCH_SIZE)) / + (mod + 1); - HE_QAT_PRINT("Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", (mod + 1), ssl_avg_time, qat_avg_time, avg_speed_up); + HE_QAT_PRINT( + "Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", + (mod + 1), ssl_avg_time, qat_avg_time, avg_speed_up); if (HE_QAT_STATUS_SUCCESS != status) { HE_QAT_PRINT_ERR("\nQAT bnModExpOp failed\n"); @@ -126,5 +130,5 @@ int main(int argc, const char** argv) { // Tear down QAT runtime context release_qat_devices(); - return (int)status; + return (int)status; // NOLINT } diff --git a/module/heqat/test/test_bnConversion.cpp b/module/heqat/test/test_bnConversion.cpp index b6cb347..38d0dfa 100644 --- a/module/heqat/test/test_bnConversion.cpp +++ b/module/heqat/test/test_bnConversion.cpp @@ -1,18 +1,18 @@ // Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include "heqat/heqat.h" - #include #include #include #include +#include #include #include -#include +#include "heqat/heqat.h" + struct timeval start_time, end_time; double time_taken = 0.0; @@ -20,8 +20,8 @@ int main(int argc, const char** argv) { const int bit_length = 1024; const size_t num_trials = 4; - double ssl_elapsed = 0.0 ; - double qat_elapsed = 0.0 ; + double ssl_elapsed = 0.0; + double qat_elapsed = 0.0; HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; @@ -35,7 +35,8 @@ int main(int argc, const char** argv) { if (!bn_mod) continue; char* bn_str = BN_bn2hex(bn_mod); - HE_QAT_PRINT("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); + HE_QAT_PRINT("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, + BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); OPENSSL_free(bn_str); int len_ = (bit_length + 7) >> 3; @@ -49,7 +50,7 @@ int main(int argc, const char** argv) { BigNumber big_num((Ipp32u)0); - gettimeofday(&start_time, NULL); + gettimeofday(&start_time, NULL); status = binToBigNumber(big_num, bn_mod_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { HE_QAT_PRINT("Failed at binToBigNumber()\n"); @@ -61,16 +62,16 @@ int main(int argc, const char** argv) { (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; ssl_elapsed = time_taken; HE_QAT_PRINT("Conversion to BigNumber has completed in %.1lfus.\n", - (ssl_elapsed)); + (ssl_elapsed)); int bit_len = 0; ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); std::string str; big_num.num2hex(str); - HE_QAT_PRINT("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, - bit_len); + HE_QAT_PRINT("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), + len_, bit_len); - gettimeofday(&start_time, NULL); + gettimeofday(&start_time, NULL); unsigned char* ref_bn_data_ = (unsigned char*)calloc(len_, sizeof(unsigned char)); if (NULL == ref_bn_data_) exit(1); @@ -85,12 +86,13 @@ int main(int argc, const char** argv) { (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; qat_elapsed = time_taken; HE_QAT_PRINT("Conversion from BigNumber has completed %.1lfus.\n", - (qat_elapsed)); + (qat_elapsed)); BIGNUM* ref_bin_ = BN_new(); BN_bin2bn(ref_bn_data_, len_, ref_bin_); bn_str = BN_bn2hex(ref_bin_); - HE_QAT_PRINT("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, BN_num_bytes(ref_bin_), BN_num_bits(ref_bin_)); + HE_QAT_PRINT("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, + BN_num_bytes(ref_bin_), BN_num_bits(ref_bin_)); HE_QAT_PRINT("-----------------------\n"); OPENSSL_free(bn_str); @@ -102,5 +104,5 @@ int main(int argc, const char** argv) { // Tear down OpenSSL context BN_CTX_end(ctx); - return (int)status; + return static_cast(status); } diff --git a/module/heqat/test/test_bnModExp.cpp b/module/heqat/test/test_bnModExp.cpp index 8428ff7..9aae63e 100644 --- a/module/heqat/test/test_bnModExp.cpp +++ b/module/heqat/test/test_bnModExp.cpp @@ -1,9 +1,6 @@ // Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include "heqat/heqat.h" - -#include #include #include #include @@ -11,10 +8,11 @@ #include #include +#include // NOLINT [build/c++11] -const unsigned int BATCH_SIZE = 48; +#include "heqat/heqat.h" -using namespace std::chrono; +const unsigned int BATCH_SIZE = 48; int main(int argc, const char** argv) { const int bit_length = 4096; @@ -42,7 +40,7 @@ int main(int argc, const char** argv) { char* bn_str = BN_bn2hex(bn_mod); #ifdef HE_QAT_DEBUG HE_QAT_PRINT("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, - BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); + BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); #endif OPENSSL_free(bn_str); @@ -58,15 +56,16 @@ int main(int argc, const char** argv) { // Perform OpenSSL ModExp Op BIGNUM* ssl_res = BN_new(); - auto start = high_resolution_clock::now(); + auto start = std::chrono::high_resolution_clock::now(); BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); - auto stop = high_resolution_clock::now(); - auto ssl_duration = duration_cast(stop - start); + auto stop = std::chrono::high_resolution_clock::now(); + auto ssl_duration = + std::chrono::duration_cast(stop - start); int len_ = (bit_length + 7) >> 3; // Start QAT timer (including data conversion overhead) - start = high_resolution_clock::now(); + start = std::chrono::high_resolution_clock::now(); unsigned char* bn_base_data_ = (unsigned char*)calloc(len_, sizeof(unsigned char)); if (NULL == bn_base_data_) exit(1); @@ -82,8 +81,9 @@ int main(int argc, const char** argv) { unsigned char* bn_remainder_data_ = (unsigned char*)calloc(len_, sizeof(unsigned char)); if (NULL == bn_remainder_data_) exit(1); - stop = high_resolution_clock::now(); - auto cvt_duration = duration_cast(stop - start); + stop = std::chrono::high_resolution_clock::now(); + auto cvt_duration = + std::chrono::duration_cast(stop - start); // Simulate input number in BigNumber representation BigNumber big_num_base((Ipp32u)0); @@ -117,7 +117,7 @@ int main(int argc, const char** argv) { exit(1); } - start = high_resolution_clock::now(); + start = std::chrono::high_resolution_clock::now(); status = bigNumberToBin(bn_base_data_, bit_length, big_num_base); if (HE_QAT_STATUS_SUCCESS != status) { HE_QAT_PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); @@ -134,28 +134,32 @@ int main(int argc, const char** argv) { HE_QAT_PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); exit(1); } - cvt_duration += - duration_cast(high_resolution_clock::now() - start); + cvt_duration += std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() - start); // Perform BigNumber modular exponentiation on QAT - start = high_resolution_clock::now(); + start = std::chrono::high_resolution_clock::now(); for (unsigned int b = 0; b < BATCH_SIZE; b++) status = HE_QAT_bnModExp(bn_remainder_data_, bn_base_data_, bn_exponent_data_, bn_mod_data_, bit_length); getBnModExpRequest(BATCH_SIZE); - stop = high_resolution_clock::now(); - auto qat_duration = duration_cast(stop - start); + stop = std::chrono::high_resolution_clock::now(); + auto qat_duration = + std::chrono::duration_cast(stop - start); ssl_avg_time = - (mod * ssl_avg_time + ((double)(ssl_duration.count()))) / (mod + 1); - qat_avg_time = (mod * qat_avg_time + - ((double)(qat_duration.count())) / BATCH_SIZE) / - (mod + 1); - avg_speed_up = (mod * avg_speed_up + - (ssl_duration.count() / - (double)(qat_duration.count() / BATCH_SIZE))) / - (mod + 1); + (mod * ssl_avg_time + (static_cast(ssl_duration.count()))) / + (mod + 1); + qat_avg_time = + (mod * qat_avg_time + + (static_cast(qat_duration.count())) / BATCH_SIZE) / + (mod + 1); + avg_speed_up = + (mod * avg_speed_up + + (ssl_duration.count() / + static_cast(qat_duration.count() / BATCH_SIZE))) / + (mod + 1); HE_QAT_PRINT("Request #%u\t", mod + 1); HE_QAT_PRINT("Overhead: %.1luus", cvt_duration.count()); HE_QAT_PRINT("\tOpenSSL: %.1lfus", ssl_avg_time); @@ -169,22 +173,22 @@ int main(int argc, const char** argv) { HE_QAT_PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); } #ifdef HE_QAT_DEBUG - else { + else HE_QAT_PRINT("\nQAT bnModExpOp finished\n"); - } #endif BigNumber big_num((Ipp32u)0); status = binToBigNumber(big_num, bn_remainder_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { - HE_QAT_PRINT_ERR("bn_remainder_data_: Failed at bigNumberToBin()\n"); + HE_QAT_PRINT_ERR( + "bn_remainder_data_: Failed at bigNumberToBin()\n"); exit(1); } #ifdef HE_QAT_DEBUG bn_str = BN_bn2hex(qat_res); HE_QAT_PRINT("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, - BN_num_bytes(qat_res), BN_num_bits(qat_res)); + BN_num_bytes(qat_res), BN_num_bits(qat_res)); #endif #ifdef HE_QAT_DEBUG @@ -192,8 +196,8 @@ int main(int argc, const char** argv) { ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); std::string str; big_num.num2hex(str); - HE_QAT_PRINT("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, - bit_len); + HE_QAT_PRINT("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), + len_, bit_len); HE_QAT_PRINT( "---------------------################-----------------------\n"); #endif @@ -221,5 +225,5 @@ int main(int argc, const char** argv) { // Tear down QAT runtime context release_qat_devices(); - return (int)status; + return static_cast(status); } diff --git a/module/heqat/test/test_bnModExp_MT.cpp b/module/heqat/test/test_bnModExp_MT.cpp index d283f7e..b511982 100644 --- a/module/heqat/test/test_bnModExp_MT.cpp +++ b/module/heqat/test/test_bnModExp_MT.cpp @@ -1,21 +1,20 @@ // Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include "heqat/heqat.h" - -#include #include -#include -#include #include #include #include #include -const unsigned int BATCH_SIZE = 4096; +#include +#include +#include // NOLINT [build/c++11] -using namespace std::chrono; +#include "heqat/heqat.h" + +const unsigned int BATCH_SIZE = 4096; int main(int argc, const char** argv) { const int bit_length = 4096; @@ -44,7 +43,7 @@ int main(int argc, const char** argv) { char* bn_str = BN_bn2hex(bn_mod); HE_QAT_PRINT_DBG("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, - BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); + BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); OPENSSL_free(bn_str); @@ -60,15 +59,16 @@ int main(int argc, const char** argv) { // Perform OpenSSL ModExp Op BIGNUM* ssl_res = BN_new(); - auto start = high_resolution_clock::now(); + auto start = std::chrono::high_resolution_clock::now(); BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); - auto stop = high_resolution_clock::now(); - auto ssl_duration = duration_cast(stop - start); + auto stop = std::chrono::high_resolution_clock::now(); + auto ssl_duration = + std::chrono::duration_cast(stop - start); int len_ = (bit_length + 7) >> 3; // Start QAT timer (including data conversion overhead) - start = high_resolution_clock::now(); + start = std::chrono::high_resolution_clock::now(); unsigned char* bn_base_data_ = (unsigned char*)calloc(len_, sizeof(unsigned char)); if (NULL == bn_base_data_) exit(1); @@ -84,8 +84,9 @@ int main(int argc, const char** argv) { unsigned char* bn_remainder_data_ = (unsigned char*)calloc(nthreads * len_, sizeof(unsigned char)); if (NULL == bn_remainder_data_) exit(1); - stop = high_resolution_clock::now(); - auto cvt_duration = duration_cast(stop - start); + stop = std::chrono::high_resolution_clock::now(); + auto cvt_duration = + std::chrono::duration_cast(stop - start); // Simulate input number in BigNumber representation BigNumber big_num_base((Ipp32u)0); @@ -120,7 +121,7 @@ int main(int argc, const char** argv) { } // start = clock(); - start = high_resolution_clock::now(); + start = std::chrono::high_resolution_clock::now(); status = bigNumberToBin(bn_base_data_, bit_length, big_num_base); if (HE_QAT_STATUS_SUCCESS != status) { HE_QAT_PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); @@ -138,62 +139,68 @@ int main(int argc, const char** argv) { exit(1); } // cvt_elapsed += (clock() - start); - cvt_duration += - duration_cast(high_resolution_clock::now() - start); + cvt_duration += std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() - start); - omp_set_num_threads(nthreads); + omp_set_num_threads(nthreads); - // Perform BigNumber modular exponentiation on QAT - start = high_resolution_clock::now(); + // Perform BigNumber modular exponentiation on QAT + start = std::chrono::high_resolution_clock::now(); #pragma omp parallel private(status) -{ - int thread_id = omp_get_thread_num(); - unsigned int buffer_id = thread_id; - - // Secure one of the distributed outstanding buffers - status = acquire_bnModExp_buffer(&buffer_id); - if (HE_QAT_STATUS_SUCCESS != status) { - HE_QAT_PRINT_ERR("Failed to acquire_bnModExp_buffer()\n"); - exit(1); - } + { + int thread_id = omp_get_thread_num(); + unsigned int buffer_id = thread_id; - HE_QAT_PRINT_DBG("Thread #%d HE QAT ACQUIRED BUFFER ID: %u\n",thread_id,buffer_id); + // Secure one of the distributed outstanding buffers + status = acquire_bnModExp_buffer(&buffer_id); + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("Failed to acquire_bnModExp_buffer()\n"); + exit(1); + } - // Divide work among threads - unsigned int worksize = BATCH_SIZE/nthreads; - unsigned int begin = thread_id*worksize; - unsigned int end = begin + worksize; + HE_QAT_PRINT_DBG("Thread #%d HE QAT ACQUIRED BUFFER ID: %u\n", + thread_id, buffer_id); - HE_QAT_PRINT_DBG("Thread #%d Begin: %u End: %u\n",thread_id,begin,end); + // Divide work among threads + unsigned int worksize = BATCH_SIZE / nthreads; + unsigned int begin = thread_id * worksize; + unsigned int end = begin + worksize; - // For local thread, schedule work execution - for (unsigned int b = begin; b < end; b++) - status = HE_QAT_bnModExp_MT(buffer_id, bn_remainder_data_ + thread_id*len_, - bn_base_data_, bn_exponent_data_, bn_mod_data_, bit_length); - - HE_QAT_PRINT_DBG("Thread #%d Waiting\n",thread_id); + HE_QAT_PRINT_DBG("Thread #%d Begin: %u End: %u\n", thread_id, begin, + end); - // Wait for the request to complete - release_bnModExp_buffer(buffer_id, BATCH_SIZE/nthreads); + // For local thread, schedule work execution + for (unsigned int b = begin; b < end; b++) + status = HE_QAT_bnModExp_MT( + buffer_id, bn_remainder_data_ + thread_id * len_, + bn_base_data_, bn_exponent_data_, bn_mod_data_, bit_length); - HE_QAT_PRINT_DBG("Thread #%d Completed\n",thread_id); + HE_QAT_PRINT_DBG("Thread #%d Waiting\n", thread_id); -} // pragma omp parallel + // Wait for the request to complete + release_bnModExp_buffer(buffer_id, BATCH_SIZE / nthreads); - stop = high_resolution_clock::now(); - auto qat_duration = duration_cast(stop - start); + HE_QAT_PRINT_DBG("Thread #%d Completed\n", thread_id); + } // pragma omp parallel + + stop = std::chrono::high_resolution_clock::now(); + auto qat_duration = + std::chrono::duration_cast(stop - start); ssl_avg_time = - (mod * ssl_avg_time + ((double)(ssl_duration.count()))) / (mod + 1); - qat_avg_time = (mod * qat_avg_time + - ((double)(qat_duration.count())) / BATCH_SIZE) / - (mod + 1); - avg_speed_up = (mod * avg_speed_up + - (ssl_duration.count() / - (double)(qat_duration.count() / BATCH_SIZE))) / - (mod + 1); - + (mod * ssl_avg_time + (static_cast(ssl_duration.count()))) / + (mod + 1); + qat_avg_time = + (mod * qat_avg_time + + (static_cast(qat_duration.count())) / BATCH_SIZE) / + (mod + 1); + avg_speed_up = + (mod * avg_speed_up + + (ssl_duration.count() / + static_cast(qat_duration.count() / BATCH_SIZE))) / + (mod + 1); + HE_QAT_PRINT("Request #%u\t", mod + 1); HE_QAT_PRINT("Overhead: %.1luus", cvt_duration.count()); HE_QAT_PRINT("\tOpenSSL: %.1lfus", ssl_avg_time); @@ -205,7 +212,7 @@ int main(int argc, const char** argv) { if (HE_QAT_STATUS_SUCCESS != status) { HE_QAT_PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); - exit(1); + exit(1); } HE_QAT_PRINT_DBG("\nQAT bnModExpOp finished\n"); @@ -214,14 +221,15 @@ int main(int argc, const char** argv) { BigNumber big_num((Ipp32u)0); status = binToBigNumber(big_num, bn_remainder_data_, bit_length); if (HE_QAT_STATUS_SUCCESS != status) { - HE_QAT_PRINT_ERR("bn_remainder_data_: Failed at bigNumberToBin()\n"); + HE_QAT_PRINT_ERR( + "bn_remainder_data_: Failed at bigNumberToBin()\n"); exit(1); } #ifdef HE_QAT_DEBUG bn_str = BN_bn2hex(qat_res); HE_QAT_PRINT_DBG("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, - BN_num_bytes(qat_res), BN_num_bits(qat_res)); + BN_num_bytes(qat_res), BN_num_bits(qat_res)); #endif #ifdef HE_QAT_DEBUG @@ -229,8 +237,8 @@ int main(int argc, const char** argv) { ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); std::string str; big_num.num2hex(str); - HE_QAT_PRINT_DBG("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), len_, - bit_len); + HE_QAT_PRINT_DBG("BigNumber: %s num_bytes: %d num_bits: %d\n", + str.c_str(), len_, bit_len); HE_QAT_PRINT_DBG( "---------------------################-----------------------\n"); #endif @@ -258,5 +266,5 @@ int main(int argc, const char** argv) { // Tear down QAT runtime context release_qat_devices(); - return (int)status; + return static_cast(status); } diff --git a/module/heqat/test/test_context.c b/module/heqat/test/test_context.c index f318f59..2d4846f 100644 --- a/module/heqat/test/test_context.c +++ b/module/heqat/test/test_context.c @@ -5,7 +5,7 @@ int main() { HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; - + status = release_qat_devices(); if (HE_QAT_STATUS_SUCCESS == status) { printf("Nothing to do by release_qat_devices().\n"); @@ -21,7 +21,7 @@ int main() { printf("acquire_qat_devices() failed.\n"); exit(1); } - + status = acquire_qat_devices(); if (HE_QAT_STATUS_SUCCESS == status) { printf("QAT context already exists.\n"); @@ -39,7 +39,7 @@ int main() { printf("release_qat_devices() failed.\n"); exit(1); } - + status = release_qat_devices(); if (HE_QAT_STATUS_SUCCESS == status) { printf("Nothing to do by release_qat_devices().\n"); From bf521eca50790022cb2f6dc097d32e65b0051517 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Wed, 9 Nov 2022 15:39:14 -0800 Subject: [PATCH 347/364] Separated cpplint for C and C++ codes - Added filter C codes: readability/casting and runtime/int --- .pre-commit-config.yaml | 13 +- example/test.cpp | 40 ----- module/heqat/heqat/common/utils.c | 6 +- module/heqat/heqat/context.c | 11 +- module/heqat/heqat/ctrl.c | 148 +++++++++--------- module/heqat/heqat/include/heqat/common.h | 5 + .../heqat/heqat/include/heqat/common/utils.h | 121 +++++++------- module/heqat/heqat/include/heqat/heqat.h | 5 + module/heqat/heqat/include/heqat/misc/utils.h | 6 +- 9 files changed, 175 insertions(+), 180 deletions(-) delete mode 100644 example/test.cpp diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a0b85da..cbbdcc6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -44,11 +44,20 @@ repos: name: cpplint entry: cpplint language: system - files: \.(c|cc|cxx|cpp|h|hpp|hxx)$ - exclude: ipcl/bignum.cpp|ipcl/include/ipcl/bignum.h|module/heqat/heqat/include/heqat/misc/bignum.h + files: \.(cxx|cpp|hpp|hxx)$ + exclude: ipcl/bignum.cpp|module/heqat/heqat/misc/bignum.cpp args: - --recursive - --filter=-runtime/references,-whitespace/comments,-whitespace/indent + - id: cpplint-c + name: cpplint-c + entry: cpplint + language: system + files: \.(c|cc|h)$ + exclude: ipcl/include/ipcl/bignum.h|module/heqat/heqat/include/heqat/misc/bignum.h + args: + - --recursive + - --filter=-runtime/references,-whitespace/comments,-whitespace/indent,-readability/casting,-runtime/int - id: shellcheck name: shellcheck entry: shellcheck diff --git a/example/test.cpp b/example/test.cpp deleted file mode 100644 index 5ac7a31..0000000 --- a/example/test.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include - -int main() { - const uint32_t num_values = 9; - - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector exp_value(num_values); - ipcl::PlainText pt; - ipcl::CipherText ct; - ipcl::PlainText dt; - - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < num_values; i++) { - exp_value[i] = dist(rng); - } - - pt = ipcl::PlainText(exp_value); - ct = key.pub_key->encrypt(pt); - dt = key.priv_key->decrypt(ct); - - for (int i = 0; i < num_values; i++) { - std::vector v = dt.getElementVec(i); - bool chk = v[0] == exp_value[i]; - std::cout << (chk ? "pass" : "fail") << std::endl; - } - - delete key.pub_key; - delete key.priv_key; -} diff --git a/module/heqat/heqat/common/utils.c b/module/heqat/heqat/common/utils.c index 0eea595..81fcb73 100644 --- a/module/heqat/heqat/common/utils.c +++ b/module/heqat/heqat/common/utils.c @@ -1,12 +1,12 @@ // Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include "heqat/common/utils.h" -#include "heqat/common/types.h" - #include #include +#include "heqat/common/utils.h" +#include "heqat/common/types.h" + BIGNUM* generateTestBNData(int nbits) { if (!RAND_status()) return NULL; diff --git a/module/heqat/heqat/context.c b/module/heqat/heqat/context.c index eb0cd9b..a334acd 100644 --- a/module/heqat/heqat/context.c +++ b/module/heqat/heqat/context.c @@ -223,13 +223,15 @@ HE_QAT_STATUS acquire_qat_devices() { he_qat_inst_config[i].attr = &he_qat_inst_attr[i]; } - he_qat_config = (HE_QAT_Config*)malloc(sizeof(HE_QAT_Config)); + he_qat_config = (HE_QAT_Config*)malloc( // NOLINT [readability/casting] + sizeof(HE_QAT_Config)); // NOLINT [readability/casting] he_qat_config->inst_config = he_qat_inst_config; he_qat_config->count = HE_QAT_NUM_ACTIVE_INSTANCES; he_qat_config->running = 0; he_qat_config->active = 0; - pthread_create(&he_qat_runner, NULL, start_instances, (void*)he_qat_config); + pthread_create(&he_qat_runner, NULL, start_instances, + (void*)he_qat_config); // NOLINT [readability/casting] HE_QAT_PRINT_DBG("Created processing threads.\n"); // Dispatch the qat instances to run independently in the background @@ -240,8 +242,9 @@ HE_QAT_STATUS acquire_qat_devices() { context_state = HE_QAT_STATUS_ACTIVE; // Launch buffer manager thread to schedule incoming requests - if (0 != pthread_create(&buffer_manager, NULL, schedule_requests, - (void*)&context_state)) { + if (0 != pthread_create( + &buffer_manager, NULL, schedule_requests, + (void*)&context_state)) { // NOLINT [readability/casting] pthread_mutex_unlock(&context_lock); release_qat_devices(); HE_QAT_PRINT_ERR( diff --git a/module/heqat/heqat/ctrl.c b/module/heqat/heqat/ctrl.c index 597df14..c24e1c8 100644 --- a/module/heqat/heqat/ctrl.c +++ b/module/heqat/heqat/ctrl.c @@ -2,11 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 /// @file heqat/ctrl.c -// QAT-API headers -#include -#include -#include -#include +// C support libraries +#include +#include +#include +#include // Global variables used to hold measured performance numbers. #ifdef HE_QAT_PERF @@ -15,11 +15,11 @@ struct timeval start_time, end_time; double time_taken = 0.0; #endif -// C support libraries -#include -#include -#include -#include +// QAT-API headers +#include +#include +#include +#include // Local headers #include "heqat/common/utils.h" @@ -40,17 +40,17 @@ HE_QAT_RequestBuffer HE_QAT_OutstandingBuffer outstanding; ///< This is the data structure that holds outstanding ///< requests from separate active threads calling the API. -volatile unsigned long response_count = +volatile unsigned long response_count = // NOLINT [runtime/int] 0; ///< Counter of processed requests and it is used to help control ///< throttling. -static volatile unsigned long request_count = +static volatile unsigned long request_count = // NOLINT [runtime/int] 0; ///< Counter of received requests and it is used to help control ///< throttling. -static unsigned long restart_threshold = +static unsigned long restart_threshold = // NOLINT [runtime/int] NUM_PKE_SLICES * HE_QAT_NUM_ACTIVE_INSTANCES; ///< Number of concurrent requests allowed to ///< be sent to accelerator at once. -static unsigned long max_pending = +static unsigned long max_pending = // NOLINT [runtime/int] (2 * NUM_PKE_SLICES * HE_QAT_NUM_ACTIVE_INSTANCES); ///< Number of requests sent to the ///< accelerator that are pending @@ -278,15 +278,15 @@ static void pull_outstanding_requests( /// internal buffer, from which requests are ready to be submitted to the device /// for processing. /// @param[in] context_state A volatile integer variable used to activate -/// (val>0) or -/// disactive (val=0) the scheduler. +/// (val>0) or disactive (val=0) the scheduler. void* schedule_requests(void* context_state) { if (NULL == context_state) { HE_QAT_PRINT_DBG("Failed at buffer_manager: argument is NULL.\n"); pthread_exit(NULL); } - HE_QAT_STATUS* active = (HE_QAT_STATUS*)context_state; + HE_QAT_STATUS* active = + (HE_QAT_STATUS*)context_state; // NOLINT [readability/casting] HE_QAT_TaskRequestList outstanding_requests; for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { @@ -309,8 +309,7 @@ void* schedule_requests(void* context_state) { /// @brief Poll responses from a specific QAT instance. /// @param[in] _inst_config Instance configuration containing the parameter -/// values to start and poll responses from the -/// accelerator. +/// values to start and poll responses from the accelerator. static void* start_inst_polling(void* _inst_config) { if (NULL == _inst_config) { HE_QAT_PRINT_ERR( @@ -318,7 +317,8 @@ static void* start_inst_polling(void* _inst_config) { pthread_exit(NULL); } - HE_QAT_InstConfig* config = (HE_QAT_InstConfig*)_inst_config; + HE_QAT_InstConfig* config = + (HE_QAT_InstConfig*)_inst_config; // NOLINT [readability/casting] if (NULL == config->inst_handle) return NULL; @@ -336,30 +336,25 @@ static void* start_inst_polling(void* _inst_config) { } /// @brief -/// Initialize and start multiple instances, their polling thread, -/// and a single processing thread. +/// Initialize and start multiple instances, their polling thread, +/// and a single processing thread. /// /// @details -/// It initializes multiple QAT instances and launches their respective -/// independent -/// polling threads that will listen to responses to requests sent to the -/// accelerators concurrently. Then, it becomes the thread that collect -/// the incoming requests stored in a shared buffer and send them to the -/// accelerator -/// for processing. This is the only processing thread for requests handled -/// by multiple instances -- unlike when using -/// multiple instances with the `start_perform_op` function, in which case -/// each instance -/// has a separate processing thread. The implementation of the multiple -/// instance support using `start_perform_op` is obsolete and slower. The way -/// is -/// using this function, which delivers better performance. The scheduling of -/// request offloads uses a round-robin approach. It collects multiple -/// requests from the internal buffer and then send them to the multiple -/// accelerator instances to process in a round-robin fashion. It was designed -/// to support -/// processing requests of different operation types but currently only -/// supports Modular Exponentiation. +/// It initializes multiple QAT instances and launches their respective +/// independent polling threads that will listen to responses to requests sent +/// to the accelerators concurrently. Then, it becomes the thread that collect +/// the incoming requests stored in a shared buffer and send them to the +/// accelerator for processing. This is the only processing thread for requests +/// handled by multiple instances -- unlike when using multiple instances with +/// the `start_perform_op` function, in which case each instance has a separate +/// processing thread. The implementation of the multiple instance support using +/// `start_perform_op` is obsolete and slower. The way is using this function, +/// which delivers better performance. The scheduling of request offloads uses a +/// round-robin approach. It collects multiple requests from the internal buffer +/// and then send them to the multiple accelerator instances to process in a +/// round-robin fashion. It was designed to support processing requests of +/// different operation types but currently only supports Modular +/// Exponentiation. /// /// @param[in] _config Data structure containing the configuration of multiple /// instances. @@ -372,12 +367,15 @@ void* start_instances(void* _config) { pthread_exit(NULL); } - HE_QAT_Config* config = (HE_QAT_Config*)_config; + HE_QAT_Config* config = + (HE_QAT_Config*)_config; // NOLINT [readability/casting] instance_count = config->count; HE_QAT_PRINT_DBG("Instance Count: %d\n", instance_count); pthread_t* polling_thread = - (pthread_t*)malloc(sizeof(pthread_t) * instance_count); + (pthread_t*)malloc( // NOLINT [readability/casting] + sizeof(pthread_t) * + instance_count); // NOLINT [readability/casting] if (NULL == polling_thread) { HE_QAT_PRINT_ERR( "Failed in start_instances: polling_thread is NULL.\n"); @@ -385,7 +383,8 @@ void* start_instances(void* _config) { } unsigned* request_count_per_instance = - (unsigned*)malloc(sizeof(unsigned) * instance_count); + (unsigned*)malloc( // NOLINT [readability/casting] + sizeof(unsigned) * instance_count); // NOLINT [readability/casting] if (NULL == request_count_per_instance) { HE_QAT_PRINT_ERR( "Failed in start_instances: polling_thread is NULL.\n"); @@ -424,7 +423,8 @@ void* start_instances(void* _config) { // Start QAT instance and start polling if (pthread_create(&polling_thread[j], config->inst_config[j].attr, start_inst_polling, - (void*)&(config->inst_config[j])) != 0) { + (void*)&(config->inst_config[j])) != // NOLINT + 0) { HE_QAT_PRINT_ERR( "Failed at creating and starting polling thread.\n"); pthread_exit(NULL); @@ -437,7 +437,6 @@ void* start_instances(void* _config) { config->inst_config[j].active = 1; config->inst_config[j].running = 1; - } // for loop HE_QAT_TaskRequestList outstanding_requests; @@ -452,8 +451,9 @@ void* start_instances(void* _config) { HE_QAT_PRINT_DBG("Try reading request from buffer. Inst #%d\n", next_instance); - unsigned long pending = request_count - response_count; - unsigned long available = + unsigned long pending = // NOLINT [runtime/int] + request_count - response_count; + unsigned long available = // NOLINT [runtime/int] max_pending - ((pending < max_pending) ? pending : max_pending); HE_QAT_PRINT_DBG( @@ -509,7 +509,9 @@ void* start_instances(void* _config) { config->inst_config[next_instance].inst_handle, (CpaCyGenFlatBufCbFunc) request->callback_func, // lnModExpCallback, - (void*)request, (CpaCyLnModExpOpData*)request->op_data, + (void*)request, // NOLINT [readability/casting] + (CpaCyLnModExpOpData*) // NOLINT [readability/casting] + request->op_data, &request->op_result); retry++; break; @@ -526,7 +528,6 @@ void* start_instances(void* _config) { HE_QAT_PRINT_DBG("RETRY count = %u\n", retry); pthread_exit(NULL); // halt the whole system } - } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); // Ensure every call to perform operation is blocking for each @@ -566,7 +567,6 @@ void* start_instances(void* _config) { // Reset pointer outstanding_requests.request[i] = NULL; request = NULL; - } // for loop over batch of requests outstanding_requests.count = 0; } @@ -574,27 +574,28 @@ void* start_instances(void* _config) { } /// @brief -/// Start independent processing and polling threads for an instance. +/// Start independent processing and polling threads for an instance. /// /// @details -/// It initializes a QAT instance and launches its polling thread to listen +/// It initializes a QAT instance and launches its polling thread to listen /// to responses (request outputs) from the accelerator. It is also /// reponsible -/// to collect requests from the internal buffer and send them to the -/// accelerator periodiacally. It was designed to extend to receiving -/// and offloading requests of different operation types but currently only -/// supports Modular Exponentiation. +/// to collect requests from the internal buffer and send them to the +/// accelerator periodiacally. It was designed to extend to receiving +/// and offloading requests of different operation types but currently only +/// supports Modular Exponentiation. /// /// @param[in] _inst_config Data structure containing the configuration of a /// single -/// instance. +/// instance. void* start_perform_op(void* _inst_config) { if (NULL == _inst_config) { HE_QAT_PRINT_ERR("Failed in start_perform_op: _inst_config is NULL.\n"); pthread_exit(NULL); } - HE_QAT_InstConfig* config = (HE_QAT_InstConfig*)_inst_config; + HE_QAT_InstConfig* config = + (HE_QAT_InstConfig*)_inst_config; // NOLINT [readability/casting] CpaStatus status = CPA_STATUS_FAIL; @@ -621,7 +622,7 @@ void* start_perform_op(void* _inst_config) { // Start QAT instance and start polling pthread_t polling_thread; if (pthread_create(&polling_thread, config->attr, start_inst_polling, - (void*)config) != 0) { + (void*)config) != 0) { // NOLINT [readability/casting] HE_QAT_PRINT_ERR("Failed at creating and starting polling thread.\n"); pthread_exit(NULL); } @@ -643,8 +644,9 @@ void* start_perform_op(void* _inst_config) { HE_QAT_PRINT_DBG("Try reading request from buffer. Inst #%d\n", config->inst_id); - unsigned long pending = request_count - response_count; - unsigned long available = + unsigned long pending = // NOLINT [runtime/int] + request_count - response_count; + unsigned long available = // NOLINT [runtime/int] max_pending - ((pending < max_pending) ? pending : max_pending); HE_QAT_PRINT_DBG( @@ -672,7 +674,7 @@ void* start_perform_op(void* _inst_config) { // operation read_request_list(&outstanding_requests, &he_qat_buffer, max_requests); - // // Try consume data from butter to perform requested operation + // // Try consume data from butter to perform requested operation // HE_QAT_TaskRequest* request = // (HE_QAT_TaskRequest*)read_request(&he_qat_buffer); // @@ -705,7 +707,9 @@ void* start_perform_op(void* _inst_config) { config->inst_handle, (CpaCyGenFlatBufCbFunc) request->callback_func, // lnModExpCallback, - (void*)request, (CpaCyLnModExpOpData*)request->op_data, + (void*)request, // NOLINT [readability/casting] + (CpaCyLnModExpOpData*) // NOLINT [readability/casting] + request->op_data, &request->op_result); retry++; break; @@ -722,7 +726,6 @@ void* start_perform_op(void* _inst_config) { HE_QAT_PRINT_DBG("RETRY count: %u\n", retry); HE_QAT_SLEEP(600, HE_QAT_MICROSEC); } - } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); // Ensure every call to perform operation is blocking for each @@ -751,7 +754,6 @@ void* start_perform_op(void* _inst_config) { // Reset pointer outstanding_requests.request[i] = NULL; request = NULL; - } // for loop over batch of requests outstanding_requests.count = 0; @@ -768,17 +770,17 @@ void* start_perform_op(void* _inst_config) { } /// @brief -/// Stop specified number of instances from running. +/// Stop specified number of instances from running. /// /// @details -/// Stop first 'num_inst' number of cpaCyInstance(s), including their -/// polling and running threads. Stop runnning and polling instances. +/// Stop first 'num_inst' number of cpaCyInstance(s), including their +/// polling and running threads. Stop runnning and polling instances. /// Release QAT instances handles. /// /// @param[in] config List of all created QAT instances and their /// configurations. /// @param[in] num_inst Unsigned integer number indicating first number of -/// instances to be terminated. +/// instances to be terminated. void stop_perform_op(HE_QAT_InstConfig* config, unsigned num_inst) { if (NULL == config) return; @@ -818,8 +820,8 @@ void stop_perform_op(HE_QAT_InstConfig* config, unsigned num_inst) { /// @brief Stop all running instances. /// @details -/// Stop all running instances after calling `start_instances()`. -/// It will set the states of the instances to terminate gracefully. +/// Stop all running instances after calling `start_instances()`. +/// It will set the states of the instances to terminate gracefully. /// @param[in] _config All QAT instances configurations holding their states. void stop_instances(HE_QAT_Config* _config) { if (NULL == _config) return; diff --git a/module/heqat/heqat/include/heqat/common.h b/module/heqat/heqat/include/heqat/common.h index cfbb717..2c94a58 100644 --- a/module/heqat/heqat/include/heqat/common.h +++ b/module/heqat/heqat/include/heqat/common.h @@ -2,6 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 /// @file heqat/common.h +#ifndef MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_COMMON_H_ +#define MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_COMMON_H_ + #include "heqat/common/consts.h" #include "heqat/common/types.h" #include "heqat/common/utils.h" @@ -11,3 +14,5 @@ #include "heqat/misc.h" #endif #endif + +#endif // MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_COMMON_H_ diff --git a/module/heqat/heqat/include/heqat/common/utils.h b/module/heqat/heqat/include/heqat/common/utils.h index 182e28b..cec2380 100644 --- a/module/heqat/heqat/include/heqat/common/utils.h +++ b/module/heqat/heqat/include/heqat/common/utils.h @@ -4,8 +4,8 @@ #pragma once -#ifndef HE_QAT_UTILS_H_ -#define HE_QAT_UTILS_H_ +#ifndef MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_MISC_UTILS_H_ +#define MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_MISC_UTILS_H_ #ifdef __cplusplus #define HE_QAT_RESTRICT __restrict__ @@ -13,17 +13,17 @@ #define HE_QAT_RESTRICT restrict #endif -#ifdef __cplusplus +#ifdef __cplusplus // NOLINT extern "C" { #endif -#include "heqat/common/types.h" - #include #include #include +#include "heqat/common/types.h" + #ifndef BYTE_ALIGNMENT_8 #define BYTE_ALIGNMENT_8 (8) #endif @@ -41,7 +41,7 @@ extern "C" { #define HE_QAT_PRINT_DBG(args...) \ do { \ printf("%s(): ", __func__); \ - printf(args); \ + printf("%s", args); \ fflush(stdout); \ } while (0) #else @@ -52,7 +52,7 @@ extern "C" { #ifndef HE_QAT_PRINT #define HE_QAT_PRINT(args...) \ do { \ - printf(args); \ + printf("%s", args); \ } while (0) #endif @@ -60,7 +60,7 @@ extern "C" { #define HE_QAT_PRINT_ERR(args...) \ do { \ printf("%s(): ", __func__); \ - printf(args); \ + printf("%s", args); \ } while (0) #endif @@ -96,7 +96,8 @@ static __inline HE_QAT_STATUS HE_QAT_memAllocContig(void** ppMemAddr, return HE_QAT_STATUS_SUCCESS; } #define HE_QAT_MEM_ALLOC_CONTIG(ppMemAddr, sizeBytes, alignment) \ - HE_QAT_memAllocContig((void*)(ppMemAddr), (sizeBytes), (alignment), 0) + HE_QAT_memAllocContig((void*)(ppMemAddr), (sizeBytes), (alignment), \ // NOLINT [readability/casting] + 0) /// @brief /// This function and associated macro frees the memory at the given @@ -106,59 +107,69 @@ static __inline HE_QAT_STATUS HE_QAT_memAllocContig(void** ppMemAddr, /// @param[out] ppMemAddr address of pointer where mem address is stored. /// If pointer is NULL, the function will exit silently static __inline void HE_QAT_memFreeContig(void** ppMemAddr) { - if (NULL != *ppMemAddr) { - qaeMemFreeNUMA(ppMemAddr); - *ppMemAddr = NULL; - } -} -#define HE_QAT_MEM_FREE_CONTIG(pMemAddr) HE_QAT_memFreeContig((void*)&pMemAddr) - -/// @brief Sleep for time unit. -/// @param[in] time Unsigned integer representing amount of time. -/// @param[in] unit Time unit of the amount of time passed in the first -/// parameter. Unit values can be HE_QAT_NANOSEC (nano seconds), HE_QAT_MICROSEC -/// (micro seconds), HE_QAT_MILLISEC (milli seconds), or HE_QAT_SEC (seconds). -static __inline HE_QAT_STATUS HE_QAT_sleep(unsigned int time, - HE_QAT_TIME_UNIT unit) { - int ret = 0; - struct timespec resTime, remTime; - - resTime.tv_sec = time / unit; - resTime.tv_nsec = (time % unit) * (HE_QAT_NANOSEC / unit); - - do { - ret = nanosleep(&resTime, &remTime); - resTime = remTime; - } while ((0 != ret) && (EINTR == errno)); - - if (0 != ret) { - HE_QAT_PRINT_ERR("nano sleep failed with code %d\n", ret); - return HE_QAT_STATUS_FAIL; - } else { - return HE_QAT_STATUS_SUCCESS; - } -} + if (NULL != *ppMemAddr) { + qaeMemFreeNUMA(ppMemAddr); + *ppMemAddr = NULL; + } + } +#define HE_QAT_MEM_FREE_CONTIG(pMemAddr) \ + HE_QAT_memFreeContig((void*)&pMemAddr) // NOLINT [readability/casting] + + /// @brief Sleep for time unit. + /// @param[in] time Unsigned integer representing + /// amount of time. + /// @param[in] unit Time unit of the amount of time + /// passed in the first parameter. Unit values can be + /// HE_QAT_NANOSEC (nano seconds), HE_QAT_MICROSEC + /// (micro seconds), HE_QAT_MILLISEC (milli seconds), + /// or HE_QAT_SEC (seconds). + static __inline HE_QAT_STATUS HE_QAT_sleep( + unsigned int time, HE_QAT_TIME_UNIT unit) { + int ret = 0; + struct timespec resTime, remTime; + + resTime.tv_sec = time / unit; + resTime.tv_nsec = + (time % unit) * (HE_QAT_NANOSEC / unit); + + do { + ret = nanosleep(&resTime, &remTime); + resTime = remTime; + } while ((0 != ret) && (EINTR == errno)); + + if (0 != ret) { + HE_QAT_PRINT_ERR( + "nano sleep failed with code %d\n", ret); + return HE_QAT_STATUS_FAIL; + } else { + return HE_QAT_STATUS_SUCCESS; + } + } #define HE_QAT_SLEEP(time, timeUnit) HE_QAT_sleep((time), (timeUnit)) -/// @brief -/// This function returns the physical address for a given virtual address. -/// In case of error 0 is returned. -/// @param[in] virtAddr Virtual address -/// @retval CpaPhysicalAddr Physical address or 0 in case of error -static __inline CpaPhysicalAddr HE_QAT_virtToPhys(void* virtAddr) { - return (CpaPhysicalAddr)qaeVirtToPhysNUMA(virtAddr); -} + /// @brief + /// This function returns the physical address + /// for a given virtual address. In case of error + /// 0 is returned. + /// @param[in] virtAddr Virtual address + /// @retval CpaPhysicalAddr Physical address or 0 in + /// case of error + static __inline CpaPhysicalAddr HE_QAT_virtToPhys( + void* virtAddr) { + return (CpaPhysicalAddr)qaeVirtToPhysNUMA( + virtAddr); + } -BIGNUM* generateTestBNData(int nbits); + BIGNUM* generateTestBNData(int nbits); -unsigned char* paddingZeros(BIGNUM* bn, int nbits); + unsigned char* paddingZeros(BIGNUM* bn, int nbits); -void showHexBN(BIGNUM* bn, int nbits); + void showHexBN(BIGNUM* bn, int nbits); -void showHexBin(unsigned char* bin, int len); + void showHexBin(unsigned char* bin, int len); #ifdef __cplusplus -} // extern "C" { + } // extern "C" { #endif -#endif // HE_QAT_UTILS_H_ +#endif // MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_MISC_UTILS_H_ diff --git a/module/heqat/heqat/include/heqat/heqat.h b/module/heqat/heqat/include/heqat/heqat.h index c5ab5d7..6c5e4a8 100644 --- a/module/heqat/heqat/include/heqat/heqat.h +++ b/module/heqat/heqat/include/heqat/heqat.h @@ -2,6 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 /// @file heqat/heqat.h +#ifndef MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_HEQAT_H_ +#define MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_HEQAT_H_ + #include "heqat/common.h" #include "heqat/context.h" #include "heqat/bnops.h" + +#endif // MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_HEQAT_H_ diff --git a/module/heqat/heqat/include/heqat/misc/utils.h b/module/heqat/heqat/include/heqat/misc/utils.h index bc06bff..3d0ae49 100644 --- a/module/heqat/heqat/include/heqat/misc/utils.h +++ b/module/heqat/heqat/include/heqat/misc/utils.h @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. *******************************************************************************/ -#ifndef _UTILS_H_ -#define _UTILS_H_ +#ifndef MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_MISC_UTILS_H_ +#define MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_MISC_UTILS_H_ #include @@ -31,4 +31,4 @@ */ size_t strlen_safe(const char* dest, size_t dmax = RSIZE_MAX_STR); -#endif // _UTILS_H_ +#endif // MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_MISC_UTILS_H_ From 5c97c59801d0b03658f9686d309883437fa0154e Mon Sep 17 00:00:00 2001 From: sejunkim Date: Wed, 9 Nov 2022 15:42:57 -0800 Subject: [PATCH 348/364] Removed ```NOLINT``` keywords after added C filters --- module/heqat/heqat/cb.c | 8 +- module/heqat/heqat/context.c | 11 +- module/heqat/heqat/ctrl.c | 50 +++----- .../heqat/heqat/include/heqat/common/types.h | 2 +- .../heqat/heqat/include/heqat/common/utils.h | 110 +++++++++--------- module/heqat/test/test_BIGNUMModExp.c | 2 +- 6 files changed, 80 insertions(+), 103 deletions(-) diff --git a/module/heqat/heqat/cb.c b/module/heqat/heqat/cb.c index 998926b..5151996 100644 --- a/module/heqat/heqat/cb.c +++ b/module/heqat/heqat/cb.c @@ -18,7 +18,7 @@ static pthread_mutex_t response_mutex; ///< It protects against race condition on response_count ///< due to concurrent callback events. -extern volatile unsigned long // NOLINT +extern volatile unsigned long response_count; ///< It counts the number of requests completed by the ///< accelerator. @@ -39,7 +39,7 @@ void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, // Check if input data for the op is available and do something if (NULL != pCallbackTag) { // Read request data - request = (HE_QAT_TaskRequest*)pCallbackTag; // NOLINT + request = (HE_QAT_TaskRequest*)pCallbackTag; pthread_mutex_lock(&response_mutex); // Global track of responses by accelerator @@ -56,7 +56,7 @@ void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, BIGNUM* r = BN_bin2bn(request->op_result.pData, request->op_result.dataLenInBytes, - (BIGNUM*)request->op_output); // NOLINT + (BIGNUM*)request->op_output); if (NULL == r) request->request_status = HE_QAT_STATUS_FAIL; #ifdef HE_QAT_PERF gettimeofday(&request->end, NULL); @@ -93,7 +93,7 @@ void HE_QAT_bnModExpCallback(void* pCallbackTag, CpaStatus status, // Check if input data for the op is available and do something if (NULL != pCallbackTag) { // Read request data - request = (HE_QAT_TaskRequest*)pCallbackTag; // NOLINT + request = (HE_QAT_TaskRequest*)pCallbackTag; pthread_mutex_lock(&response_mutex); // Global track of responses by accelerator diff --git a/module/heqat/heqat/context.c b/module/heqat/heqat/context.c index a334acd..eb0cd9b 100644 --- a/module/heqat/heqat/context.c +++ b/module/heqat/heqat/context.c @@ -223,15 +223,13 @@ HE_QAT_STATUS acquire_qat_devices() { he_qat_inst_config[i].attr = &he_qat_inst_attr[i]; } - he_qat_config = (HE_QAT_Config*)malloc( // NOLINT [readability/casting] - sizeof(HE_QAT_Config)); // NOLINT [readability/casting] + he_qat_config = (HE_QAT_Config*)malloc(sizeof(HE_QAT_Config)); he_qat_config->inst_config = he_qat_inst_config; he_qat_config->count = HE_QAT_NUM_ACTIVE_INSTANCES; he_qat_config->running = 0; he_qat_config->active = 0; - pthread_create(&he_qat_runner, NULL, start_instances, - (void*)he_qat_config); // NOLINT [readability/casting] + pthread_create(&he_qat_runner, NULL, start_instances, (void*)he_qat_config); HE_QAT_PRINT_DBG("Created processing threads.\n"); // Dispatch the qat instances to run independently in the background @@ -242,9 +240,8 @@ HE_QAT_STATUS acquire_qat_devices() { context_state = HE_QAT_STATUS_ACTIVE; // Launch buffer manager thread to schedule incoming requests - if (0 != pthread_create( - &buffer_manager, NULL, schedule_requests, - (void*)&context_state)) { // NOLINT [readability/casting] + if (0 != pthread_create(&buffer_manager, NULL, schedule_requests, + (void*)&context_state)) { pthread_mutex_unlock(&context_lock); release_qat_devices(); HE_QAT_PRINT_ERR( diff --git a/module/heqat/heqat/ctrl.c b/module/heqat/heqat/ctrl.c index c24e1c8..774a700 100644 --- a/module/heqat/heqat/ctrl.c +++ b/module/heqat/heqat/ctrl.c @@ -40,17 +40,17 @@ HE_QAT_RequestBuffer HE_QAT_OutstandingBuffer outstanding; ///< This is the data structure that holds outstanding ///< requests from separate active threads calling the API. -volatile unsigned long response_count = // NOLINT [runtime/int] +volatile unsigned long response_count = 0; ///< Counter of processed requests and it is used to help control ///< throttling. -static volatile unsigned long request_count = // NOLINT [runtime/int] +static volatile unsigned long request_count = 0; ///< Counter of received requests and it is used to help control ///< throttling. -static unsigned long restart_threshold = // NOLINT [runtime/int] +static unsigned long restart_threshold = NUM_PKE_SLICES * HE_QAT_NUM_ACTIVE_INSTANCES; ///< Number of concurrent requests allowed to ///< be sent to accelerator at once. -static unsigned long max_pending = // NOLINT [runtime/int] +static unsigned long max_pending = (2 * NUM_PKE_SLICES * HE_QAT_NUM_ACTIVE_INSTANCES); ///< Number of requests sent to the ///< accelerator that are pending @@ -285,8 +285,7 @@ void* schedule_requests(void* context_state) { pthread_exit(NULL); } - HE_QAT_STATUS* active = - (HE_QAT_STATUS*)context_state; // NOLINT [readability/casting] + HE_QAT_STATUS* active = (HE_QAT_STATUS*)context_state; HE_QAT_TaskRequestList outstanding_requests; for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { @@ -317,8 +316,7 @@ static void* start_inst_polling(void* _inst_config) { pthread_exit(NULL); } - HE_QAT_InstConfig* config = - (HE_QAT_InstConfig*)_inst_config; // NOLINT [readability/casting] + HE_QAT_InstConfig* config = (HE_QAT_InstConfig*)_inst_config; if (NULL == config->inst_handle) return NULL; @@ -367,15 +365,12 @@ void* start_instances(void* _config) { pthread_exit(NULL); } - HE_QAT_Config* config = - (HE_QAT_Config*)_config; // NOLINT [readability/casting] + HE_QAT_Config* config = (HE_QAT_Config*)_config; instance_count = config->count; HE_QAT_PRINT_DBG("Instance Count: %d\n", instance_count); pthread_t* polling_thread = - (pthread_t*)malloc( // NOLINT [readability/casting] - sizeof(pthread_t) * - instance_count); // NOLINT [readability/casting] + (pthread_t*)malloc(sizeof(pthread_t) * instance_count); if (NULL == polling_thread) { HE_QAT_PRINT_ERR( "Failed in start_instances: polling_thread is NULL.\n"); @@ -383,8 +378,7 @@ void* start_instances(void* _config) { } unsigned* request_count_per_instance = - (unsigned*)malloc( // NOLINT [readability/casting] - sizeof(unsigned) * instance_count); // NOLINT [readability/casting] + (unsigned*)malloc(sizeof(unsigned) * instance_count); if (NULL == request_count_per_instance) { HE_QAT_PRINT_ERR( "Failed in start_instances: polling_thread is NULL.\n"); @@ -423,8 +417,7 @@ void* start_instances(void* _config) { // Start QAT instance and start polling if (pthread_create(&polling_thread[j], config->inst_config[j].attr, start_inst_polling, - (void*)&(config->inst_config[j])) != // NOLINT - 0) { + (void*)&(config->inst_config[j])) != 0) { HE_QAT_PRINT_ERR( "Failed at creating and starting polling thread.\n"); pthread_exit(NULL); @@ -451,9 +444,8 @@ void* start_instances(void* _config) { HE_QAT_PRINT_DBG("Try reading request from buffer. Inst #%d\n", next_instance); - unsigned long pending = // NOLINT [runtime/int] - request_count - response_count; - unsigned long available = // NOLINT [runtime/int] + unsigned long pending = request_count - response_count; + unsigned long available = max_pending - ((pending < max_pending) ? pending : max_pending); HE_QAT_PRINT_DBG( @@ -509,9 +501,7 @@ void* start_instances(void* _config) { config->inst_config[next_instance].inst_handle, (CpaCyGenFlatBufCbFunc) request->callback_func, // lnModExpCallback, - (void*)request, // NOLINT [readability/casting] - (CpaCyLnModExpOpData*) // NOLINT [readability/casting] - request->op_data, + (void*)request, (CpaCyLnModExpOpData*)request->op_data, &request->op_result); retry++; break; @@ -594,8 +584,7 @@ void* start_perform_op(void* _inst_config) { pthread_exit(NULL); } - HE_QAT_InstConfig* config = - (HE_QAT_InstConfig*)_inst_config; // NOLINT [readability/casting] + HE_QAT_InstConfig* config = (HE_QAT_InstConfig*)_inst_config; CpaStatus status = CPA_STATUS_FAIL; @@ -622,7 +611,7 @@ void* start_perform_op(void* _inst_config) { // Start QAT instance and start polling pthread_t polling_thread; if (pthread_create(&polling_thread, config->attr, start_inst_polling, - (void*)config) != 0) { // NOLINT [readability/casting] + (void*)config) != 0) { HE_QAT_PRINT_ERR("Failed at creating and starting polling thread.\n"); pthread_exit(NULL); } @@ -644,9 +633,8 @@ void* start_perform_op(void* _inst_config) { HE_QAT_PRINT_DBG("Try reading request from buffer. Inst #%d\n", config->inst_id); - unsigned long pending = // NOLINT [runtime/int] - request_count - response_count; - unsigned long available = // NOLINT [runtime/int] + unsigned long pending = request_count - response_count; + unsigned long available = max_pending - ((pending < max_pending) ? pending : max_pending); HE_QAT_PRINT_DBG( @@ -707,9 +695,7 @@ void* start_perform_op(void* _inst_config) { config->inst_handle, (CpaCyGenFlatBufCbFunc) request->callback_func, // lnModExpCallback, - (void*)request, // NOLINT [readability/casting] - (CpaCyLnModExpOpData*) // NOLINT [readability/casting] - request->op_data, + (void*)request, (CpaCyLnModExpOpData*)request->op_data, &request->op_result); retry++; break; diff --git a/module/heqat/heqat/include/heqat/common/types.h b/module/heqat/heqat/include/heqat/common/types.h index 31b1334..e3790f8 100644 --- a/module/heqat/heqat/include/heqat/common/types.h +++ b/module/heqat/heqat/include/heqat/common/types.h @@ -150,7 +150,7 @@ typedef struct { // One for each consumer typedef struct { - unsigned long long id; ///< Work request ID. NOLINT + unsigned long long id; ///< Work request ID. // sem_t callback; struct completion_struct callback; ///< Synchronization object. HE_QAT_OP diff --git a/module/heqat/heqat/include/heqat/common/utils.h b/module/heqat/heqat/include/heqat/common/utils.h index cec2380..21d19e2 100644 --- a/module/heqat/heqat/include/heqat/common/utils.h +++ b/module/heqat/heqat/include/heqat/common/utils.h @@ -13,7 +13,7 @@ #define HE_QAT_RESTRICT restrict #endif -#ifdef __cplusplus // NOLINT +#ifdef __cplusplus extern "C" { #endif @@ -96,8 +96,7 @@ static __inline HE_QAT_STATUS HE_QAT_memAllocContig(void** ppMemAddr, return HE_QAT_STATUS_SUCCESS; } #define HE_QAT_MEM_ALLOC_CONTIG(ppMemAddr, sizeBytes, alignment) \ - HE_QAT_memAllocContig((void*)(ppMemAddr), (sizeBytes), (alignment), \ // NOLINT [readability/casting] - 0) + HE_QAT_memAllocContig((void*)(ppMemAddr), (sizeBytes), (alignment), 0) /// @brief /// This function and associated macro frees the memory at the given @@ -107,69 +106,64 @@ static __inline HE_QAT_STATUS HE_QAT_memAllocContig(void** ppMemAddr, /// @param[out] ppMemAddr address of pointer where mem address is stored. /// If pointer is NULL, the function will exit silently static __inline void HE_QAT_memFreeContig(void** ppMemAddr) { - if (NULL != *ppMemAddr) { - qaeMemFreeNUMA(ppMemAddr); - *ppMemAddr = NULL; - } - } -#define HE_QAT_MEM_FREE_CONTIG(pMemAddr) \ - HE_QAT_memFreeContig((void*)&pMemAddr) // NOLINT [readability/casting] - - /// @brief Sleep for time unit. - /// @param[in] time Unsigned integer representing - /// amount of time. - /// @param[in] unit Time unit of the amount of time - /// passed in the first parameter. Unit values can be - /// HE_QAT_NANOSEC (nano seconds), HE_QAT_MICROSEC - /// (micro seconds), HE_QAT_MILLISEC (milli seconds), - /// or HE_QAT_SEC (seconds). - static __inline HE_QAT_STATUS HE_QAT_sleep( - unsigned int time, HE_QAT_TIME_UNIT unit) { - int ret = 0; - struct timespec resTime, remTime; - - resTime.tv_sec = time / unit; - resTime.tv_nsec = - (time % unit) * (HE_QAT_NANOSEC / unit); - - do { - ret = nanosleep(&resTime, &remTime); - resTime = remTime; - } while ((0 != ret) && (EINTR == errno)); - - if (0 != ret) { - HE_QAT_PRINT_ERR( - "nano sleep failed with code %d\n", ret); - return HE_QAT_STATUS_FAIL; - } else { - return HE_QAT_STATUS_SUCCESS; - } - } + if (NULL != *ppMemAddr) { + qaeMemFreeNUMA(ppMemAddr); + *ppMemAddr = NULL; + } +} +#define HE_QAT_MEM_FREE_CONTIG(pMemAddr) HE_QAT_memFreeContig((void*)&pMemAddr) + +/// @brief Sleep for time unit. +/// @param[in] time Unsigned integer representing +/// amount of time. +/// @param[in] unit Time unit of the amount of time +/// passed in the first parameter. Unit values can be +/// HE_QAT_NANOSEC (nano seconds), HE_QAT_MICROSEC +/// (micro seconds), HE_QAT_MILLISEC (milli seconds), +/// or HE_QAT_SEC (seconds). +static __inline HE_QAT_STATUS HE_QAT_sleep(unsigned int time, + HE_QAT_TIME_UNIT unit) { + int ret = 0; + struct timespec resTime, remTime; + + resTime.tv_sec = time / unit; + resTime.tv_nsec = (time % unit) * (HE_QAT_NANOSEC / unit); + + do { + ret = nanosleep(&resTime, &remTime); + resTime = remTime; + } while ((0 != ret) && (EINTR == errno)); + + if (0 != ret) { + HE_QAT_PRINT_ERR("nano sleep failed with code %d\n", ret); + return HE_QAT_STATUS_FAIL; + } else { + return HE_QAT_STATUS_SUCCESS; + } +} #define HE_QAT_SLEEP(time, timeUnit) HE_QAT_sleep((time), (timeUnit)) - /// @brief - /// This function returns the physical address - /// for a given virtual address. In case of error - /// 0 is returned. - /// @param[in] virtAddr Virtual address - /// @retval CpaPhysicalAddr Physical address or 0 in - /// case of error - static __inline CpaPhysicalAddr HE_QAT_virtToPhys( - void* virtAddr) { - return (CpaPhysicalAddr)qaeVirtToPhysNUMA( - virtAddr); - } +/// @brief +/// This function returns the physical address +/// for a given virtual address. In case of error +/// 0 is returned. +/// @param[in] virtAddr Virtual address +/// @retval CpaPhysicalAddr Physical address or 0 in +/// case of error +static __inline CpaPhysicalAddr HE_QAT_virtToPhys(void* virtAddr) { + return (CpaPhysicalAddr)qaeVirtToPhysNUMA(virtAddr); +} - BIGNUM* generateTestBNData(int nbits); +BIGNUM* generateTestBNData(int nbits); - unsigned char* paddingZeros(BIGNUM* bn, int nbits); +unsigned char* paddingZeros(BIGNUM* bn, int nbits); - void showHexBN(BIGNUM* bn, int nbits); +void showHexBN(BIGNUM* bn, int nbits); - void showHexBin(unsigned char* bin, int len); +void showHexBin(unsigned char* bin, int len); #ifdef __cplusplus - } // extern "C" { +} // extern "C" { #endif #endif // MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_MISC_UTILS_H_ diff --git a/module/heqat/test/test_BIGNUMModExp.c b/module/heqat/test/test_BIGNUMModExp.c index b31e936..612bfb3 100644 --- a/module/heqat/test/test_BIGNUMModExp.c +++ b/module/heqat/test/test_BIGNUMModExp.c @@ -130,5 +130,5 @@ int main(int argc, const char** argv) { // Tear down QAT runtime context release_qat_devices(); - return (int)status; // NOLINT + return (int)status; } From 1bb0ae8135cc60e6ecf568a82373c2cb7237336b Mon Sep 17 00:00:00 2001 From: sejunkim Date: Wed, 9 Nov 2022 15:44:07 -0800 Subject: [PATCH 349/364] Add ```IPCL_ENABLE_QAT=ON``` option in CI/CD build command --- .github/workflows/github-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-ci.yml b/.github/workflows/github-ci.yml index 6c29546..b84b3be 100644 --- a/.github/workflows/github-ci.yml +++ b/.github/workflows/github-ci.yml @@ -60,7 +60,7 @@ jobs: # Build library - name: Build the repository run: | - cmake -S . -B build -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=Release + cmake -S . -B build -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=Release -DIPCL_ENABLE_QAT=ON cmake --build build --target all -j # Unit tests and examples @@ -94,7 +94,7 @@ jobs: # Build library - name: Build the repository run: | - cmake -S . -B build -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=Release -DIPCL_SHARED=OFF + cmake -S . -B build -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=Release -DIPCL_ENABLE_QAT=ON -DIPCL_SHARED=OFF cmake --build build --target all -j # Unit tests and examples From c64bd33906edaad7983316dfd60ca19894bf131e Mon Sep 17 00:00:00 2001 From: Fillipe Souza Date: Wed, 9 Nov 2022 16:29:52 -0800 Subject: [PATCH 350/364] QAT Integration for IPCL 2.0 Release (#130) Merge QAT integration to upstream development branch Signed-off-by: Fillipe Souza Signed-off-by: Souza, Fillipe Signed-off-by: Zhao Pengfei Co-authored-by: Pengfei Zhao Co-authored-by: Sejun Kim Co-authored-by: Fillipe Souza --- .github/workflows/github-ci.yml | 4 +- .pre-commit-config.yaml | 15 +- CMakeLists.txt | 172 ++-- README.md | 48 +- benchmark/CMakeLists.txt | 14 +- benchmark/bench_cryptography.cpp | 4 +- benchmark/bench_hybrid.cpp | 234 +++++ benchmark/bench_ops.cpp | 4 +- benchmark/main.cpp | 11 +- cmake/cpufeatures.cmake | 22 +- cmake/gbenchmark.cmake | 5 +- cmake/gtest.cmake | 9 +- cmake/ipcl/ipcl-util.cmake | 89 ++ cmake/ippcrypto.cmake | 48 +- cmake/patch/ippcrypto_patch.patch | 125 +++ example/CMakeLists.txt | 9 +- example/README.md | 43 +- example/example_add_mul.cpp | 100 +++ example/example_encrypt_decrypt.cpp | 55 ++ example/example_hybridmode.cpp | 96 ++ example/test.cpp | 40 - ipcl/CMakeLists.txt | 107 ++- ipcl/bignum.cpp | 57 ++ ipcl/ciphertext.cpp | 13 +- ipcl/common.cpp | 18 + ipcl/context.cpp | 88 ++ ipcl/include/ipcl/bignum.h | 11 +- ipcl/include/ipcl/common.hpp | 8 + ipcl/include/ipcl/context.hpp | 47 + ipcl/include/ipcl/ipcl.hpp | 2 + ipcl/include/ipcl/mod_exp.hpp | 88 +- ipcl/include/ipcl/util.hpp | 16 +- ipcl/keygen.cpp | 2 +- ipcl/mod_exp.cpp | 481 ++++++++-- ipcl/pri_key.cpp | 19 +- ipcl/pub_key.cpp | 14 +- module/heqat.cmake | 71 ++ module/heqat/.clang-format | 9 + module/heqat/.gitignore | 12 + module/heqat/CMakeLists.txt | 209 +++++ module/heqat/LICENSE | 201 +++++ module/heqat/README.md | 332 +++++++ .../heqat/cmake/he_qat/HE_QATConfig.cmake.in | 22 + module/heqat/cmake/he_qat/heqat-util.cmake | 31 + module/heqat/cmake/qatconfig.cmake | 50 ++ module/heqat/config/4xxx_dev0.conf | 182 ++++ module/heqat/config/4xxxvf_dev0.conf | 133 +++ module/heqat/doc/CMakeLists.txt | 25 + module/heqat/doc/Doxyfile.in | 36 + module/heqat/doc/index.html | 2 + module/heqat/doc/index.rst | 5 + module/heqat/example/CMakeLists.txt | 32 + module/heqat/example/README.md | 7 + module/heqat/example/example.cpp | 139 +++ module/heqat/heqat/CMakeLists.txt | 117 +++ module/heqat/heqat/bnops.c | 540 ++++++++++++ module/heqat/heqat/cb.c | 129 +++ module/heqat/heqat/common/utils.c | 69 ++ module/heqat/heqat/context.c | 302 +++++++ module/heqat/heqat/ctrl.c | 818 ++++++++++++++++++ module/heqat/heqat/include/heqat/bnops.h | 154 ++++ module/heqat/heqat/include/heqat/common.h | 18 + .../heqat/heqat/include/heqat/common/consts.h | 18 + .../heqat/heqat/include/heqat/common/types.h | 186 ++++ .../heqat/heqat/include/heqat/common/utils.h | 169 ++++ module/heqat/heqat/include/heqat/context.h | 32 + module/heqat/heqat/include/heqat/heqat.h | 12 + module/heqat/heqat/include/heqat/misc.h | 38 + .../heqat/heqat/include/heqat/misc/bignum.h | 112 +++ module/heqat/heqat/include/heqat/misc/utils.h | 34 + module/heqat/heqat/misc/bignum.cpp | 395 +++++++++ module/heqat/heqat/misc/misc.cpp | 41 + module/heqat/heqat/misc/utils.cpp | 45 + module/heqat/scripts/auto_find_qat_install.sh | 7 + .../heqat/scripts/reset_asym_buffer_size.sh | 76 ++ module/heqat/scripts/restart_devices.sh | 126 +++ module/heqat/scripts/run.sh | 23 + module/heqat/scripts/setup_devices.sh | 149 ++++ module/heqat/setup_env.sh | 6 + module/heqat/test/CMakeLists.txt | 57 ++ module/heqat/test/test_BIGNUMModExp.c | 134 +++ module/heqat/test/test_bnConversion.cpp | 108 +++ module/heqat/test/test_bnModExp.cpp | 229 +++++ module/heqat/test/test_bnModExp_MT.cpp | 270 ++++++ module/heqat/test/test_context.c | 52 ++ test/CMakeLists.txt | 8 +- test/main.cpp | 38 +- test/test_cryptography.cpp | 10 +- test/test_ops.cpp | 40 +- 89 files changed, 7873 insertions(+), 305 deletions(-) create mode 100644 benchmark/bench_hybrid.cpp create mode 100644 cmake/patch/ippcrypto_patch.patch create mode 100644 example/example_add_mul.cpp create mode 100644 example/example_encrypt_decrypt.cpp create mode 100644 example/example_hybridmode.cpp delete mode 100644 example/test.cpp create mode 100644 ipcl/context.cpp create mode 100644 ipcl/include/ipcl/context.hpp create mode 100644 module/heqat.cmake create mode 100644 module/heqat/.clang-format create mode 100644 module/heqat/.gitignore create mode 100644 module/heqat/CMakeLists.txt create mode 100644 module/heqat/LICENSE create mode 100644 module/heqat/README.md create mode 100644 module/heqat/cmake/he_qat/HE_QATConfig.cmake.in create mode 100644 module/heqat/cmake/he_qat/heqat-util.cmake create mode 100644 module/heqat/cmake/qatconfig.cmake create mode 100755 module/heqat/config/4xxx_dev0.conf create mode 100755 module/heqat/config/4xxxvf_dev0.conf create mode 100644 module/heqat/doc/CMakeLists.txt create mode 100644 module/heqat/doc/Doxyfile.in create mode 100644 module/heqat/doc/index.html create mode 100644 module/heqat/doc/index.rst create mode 100644 module/heqat/example/CMakeLists.txt create mode 100644 module/heqat/example/README.md create mode 100644 module/heqat/example/example.cpp create mode 100644 module/heqat/heqat/CMakeLists.txt create mode 100644 module/heqat/heqat/bnops.c create mode 100644 module/heqat/heqat/cb.c create mode 100644 module/heqat/heqat/common/utils.c create mode 100644 module/heqat/heqat/context.c create mode 100644 module/heqat/heqat/ctrl.c create mode 100644 module/heqat/heqat/include/heqat/bnops.h create mode 100644 module/heqat/heqat/include/heqat/common.h create mode 100644 module/heqat/heqat/include/heqat/common/consts.h create mode 100644 module/heqat/heqat/include/heqat/common/types.h create mode 100644 module/heqat/heqat/include/heqat/common/utils.h create mode 100644 module/heqat/heqat/include/heqat/context.h create mode 100644 module/heqat/heqat/include/heqat/heqat.h create mode 100644 module/heqat/heqat/include/heqat/misc.h create mode 100644 module/heqat/heqat/include/heqat/misc/bignum.h create mode 100644 module/heqat/heqat/include/heqat/misc/utils.h create mode 100644 module/heqat/heqat/misc/bignum.cpp create mode 100644 module/heqat/heqat/misc/misc.cpp create mode 100644 module/heqat/heqat/misc/utils.cpp create mode 100755 module/heqat/scripts/auto_find_qat_install.sh create mode 100755 module/heqat/scripts/reset_asym_buffer_size.sh create mode 100755 module/heqat/scripts/restart_devices.sh create mode 100755 module/heqat/scripts/run.sh create mode 100755 module/heqat/scripts/setup_devices.sh create mode 100755 module/heqat/setup_env.sh create mode 100644 module/heqat/test/CMakeLists.txt create mode 100644 module/heqat/test/test_BIGNUMModExp.c create mode 100644 module/heqat/test/test_bnConversion.cpp create mode 100644 module/heqat/test/test_bnModExp.cpp create mode 100644 module/heqat/test/test_bnModExp_MT.cpp create mode 100644 module/heqat/test/test_context.c diff --git a/.github/workflows/github-ci.yml b/.github/workflows/github-ci.yml index 6c29546..b84b3be 100644 --- a/.github/workflows/github-ci.yml +++ b/.github/workflows/github-ci.yml @@ -60,7 +60,7 @@ jobs: # Build library - name: Build the repository run: | - cmake -S . -B build -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=Release + cmake -S . -B build -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=Release -DIPCL_ENABLE_QAT=ON cmake --build build --target all -j # Unit tests and examples @@ -94,7 +94,7 @@ jobs: # Build library - name: Build the repository run: | - cmake -S . -B build -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=Release -DIPCL_SHARED=OFF + cmake -S . -B build -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=Release -DIPCL_ENABLE_QAT=ON -DIPCL_SHARED=OFF cmake --build build --target all -j # Unit tests and examples diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2f41239..cbbdcc6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,9 @@ repos: rev: v4.0.1 hooks: - id: trailing-whitespace + exclude: cmake/patch/ippcrypto_patch.patch - id: end-of-file-fixer + exclude: cmake/patch/ippcrypto_patch.patch - id: check-merge-conflict - id: mixed-line-ending - id: check-byte-order-marker @@ -42,11 +44,20 @@ repos: name: cpplint entry: cpplint language: system - files: \.(c|cc|cxx|cpp|h|hpp|hxx)$ - exclude: ipcl/bignum.cpp|ipcl/include/ipcl/bignum.h|example/test.cpp + files: \.(cxx|cpp|hpp|hxx)$ + exclude: ipcl/bignum.cpp|module/heqat/heqat/misc/bignum.cpp args: - --recursive - --filter=-runtime/references,-whitespace/comments,-whitespace/indent + - id: cpplint-c + name: cpplint-c + entry: cpplint + language: system + files: \.(c|cc|h)$ + exclude: ipcl/include/ipcl/bignum.h|module/heqat/heqat/include/heqat/misc/bignum.h + args: + - --recursive + - --filter=-runtime/references,-whitespace/comments,-whitespace/indent,-readability/casting,-runtime/int - id: shellcheck name: shellcheck entry: shellcheck diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d26427..83b11ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,13 +3,15 @@ cmake_minimum_required(VERSION 3.15.1) -project(IPCL VERSION 1.1.3 LANGUAGES C CXX) -project(IPCL VERSION 1.1.4 LANGUAGES C CXX) +project(IPCL VERSION 2.0.0 LANGUAGES C CXX) +# includes include(CMakePackageConfigHelpers) include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) include(GNUInstallDirs) +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ipcl) +include(ipcl-util) if(CMAKE_BUILD_TYPE) set(RELEASE_TYPES @@ -41,21 +43,63 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "/opt/intel/ipcl") endif() -set(CMAKE_C_FLAGS "-O2 -Wno-error=deprecated-declarations") -set(CMAKE_CXX_FLAGS "-O2 -fpermissive -Wno-error=deprecated-declarations") -set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR};${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ippcrypto") +set(CMAKE_C_FLAGS "-O2 -Wno-error=deprecated-declarations -Wno-error=deprecated-copy") +set(CMAKE_CXX_FLAGS "-O2 -fpermissive -Wno-error=deprecated-declarations -Wno-error=deprecated-copy") +set(CMAKE_INSTALL_RPATH "$ORIGIN;$ORIGIN/${CMAKE_INSTALL_LIBDIR};$ORIGIN/ippcrypto") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) +# Compiler version check - icx/icpx-2021.3.0 is supported +if(CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM") + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 2021.3.0) + message(FATAL_ERROR + " ${CMAKE_CXX_COMPILER_ID}-${CMAKE_CXX_COMPILER_VERSION} is not supported." + " Please refer to Intel IPP-Crypto (https://github.com/intel/ipp-crypto" + " for more information.") + endif() +endif() + #--------------------------------------------------- option(IPCL_TEST "Enable testing" ON) option(IPCL_BENCHMARK "Enable benchmark" ON) +option(IPCL_ENABLE_QAT "Enable QAT" OFF) +option(IPCL_USE_QAT_LITE "Enable uses QAT for base and exponent length different than modulus" OFF) option(IPCL_ENABLE_OMP "Enable OpenMP testing/benchmarking" ON) option(IPCL_THREAD_COUNT "The max number of threads used by OpenMP(If the value is OFF/0, it is determined at runtime)" OFF) option(IPCL_DOCS "Enable document building" OFF) option(IPCL_SHARED "Build shared library" ON) -option(IPCL_DETECT_IFMA_RUNTIME "Detect AVX512/IFMA instructions during runtime" OFF) -option(IPCL_DEBUG_DISABLE_AVX512IFMA "(Debugging) Disable usage of AVX512IFMA instructions" OFF) +option(IPCL_DETECT_CPU_RUNTIME "Detect CPU supported instructions during runtime" OFF) +option(IPCL_INTERNAL_PYTHON_BUILD "Additional steps for IPCL_Python build" OFF) + +# Used only for ipcl_python IPCL_INTERNAL_PYTHON_BUILD - additional check if invalid parameters +if(IPCL_INTERNAL_PYTHON_BUILD) + if(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY) + set(IPCL_INTERNAL_PYTHON_BUILD OFF) + elseif(NOT IS_ABSOLUTE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) + set(IPCL_INTERNAL_PYTHON_BUILD OFF) + endif() +endif() + +if(IPCL_ENABLE_QAT) + ipcl_detect_qat() + if(IPCL_FOUND_QAT) + add_compile_definitions(IPCL_USE_QAT) + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};$ORIGIN/../heqat") + if(IPCL_USE_QAT_LITE) + add_compile_definitions(IPCL_USE_QAT_LITE) + message(STATUS "QAT Lite enabled - IPCL_USE_QAT_LITE set to ON") + else() + message(STATUS "QAT Lite disabled - IPCL_USE_QAT_LITE set to OFF") + endif() + else() + set(IPCL_ENABLE_QAT OFF) + endif() +endif() + +if(IPCL_THREAD_COUNT LESS_EQUAL 1) + set(IPCL_ENABLE_OMP OFF) +endif() + if(IPCL_ENABLE_OMP) add_compile_definitions(IPCL_USE_OMP) if(IPCL_THREAD_COUNT) @@ -63,13 +107,36 @@ if(IPCL_ENABLE_OMP) endif() endif() -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(IPCL_DEBUG ON) +if(IPCL_DETECT_CPU_RUNTIME) + # add_compile_definitions(IPCL_RUNTIME_MOD_EXP) + add_compile_definitions(IPCL_RUNTIME_DETECT_CPU_FEATURES) + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};$ORIGIN/cpufeatures") else() - set(IPCL_DEBUG OFF) -endif() + # check whether cpu support avx512ifma instructions + ipcl_detect_lscpu_flag("avx512ifma" FALSE) + if(IPCL_FOUND_avx512ifma) + add_compile_definitions(IPCL_CRYPTO_MB_MOD_EXP) + message(STATUS "Support AVX512IFMA instruction: True") + endif() -set(IPCL_CMAKE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/ipcl") + # check whether cpu support rdseed/rdrand instructions + ipcl_detect_lscpu_flag("rdseed" FALSE) + if(IPCL_FOUND_rdseed) + message(STATUS "Support RDSEED instruction: True") + add_compile_definitions(IPCL_RNG_INSTR_RDSEED) + else() + ipcl_detect_lscpu_flag("rdrand" FALSE) + if(IPCL_FOUND_rdrand) + message(STATUS "Support RDRAND instruction: True") + add_compile_definitions(IPCL_RNG_INSTR_RDRAND) + else() + message(WARNING + "CPU doesn't support RDSEED and RDRAND instruction, using IPP-Crypto" + " S/W pseudo random number generator" + ) + endif() + endif() +endif() message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}") @@ -78,6 +145,7 @@ message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") message(STATUS "IPCL_TEST: ${IPCL_TEST}") message(STATUS "IPCL_BENCHMARK: ${IPCL_BENCHMARK}") message(STATUS "IPCL_ENABLE_OMP: ${IPCL_ENABLE_OMP}") +message(STATUS "IPCL_ENABLE_QAT: ${IPCL_ENABLE_QAT}") if (IPCL_ENABLE_OMP) message(STATUS "IPCL_THREAD_COUNT: ${IPCL_THREAD_COUNT}") else() @@ -85,11 +153,10 @@ else() endif() message(STATUS "IPCL_DOCS: ${IPCL_DOCS}") message(STATUS "IPCL_SHARED: ${IPCL_SHARED}") -message(STATUS "IPCL_DETECT_IFMA_RUNTIME: ${IPCL_DETECT_IFMA_RUNTIME}") - -set(IPCL_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) -set(IPCL_SRC_DIR ${IPCL_ROOT_DIR}/ipcl) -set(IPCL_INC_DIR ${IPCL_SRC_DIR}/include) +message(STATUS "IPCL_DETECT_CPU_RUNTIME: ${IPCL_DETECT_CPU_RUNTIME}") +if(IPCL_INTERNAL_PYTHON_BUILD) + message(STATUS "IPCL_INTERNAL_PYTHON_BUILD: ${IPCL_INTERNAL_PYTHON_BUILD}") +endif() set(IPCL_FORWARD_CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} @@ -103,59 +170,42 @@ set(IPCL_FORWARD_CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ) -if(IPCL_DETECT_IFMA_RUNTIME) - add_compile_definitions(IPCL_RUNTIME_MOD_EXP) - set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cpufeatures") -else() - # check whether cpu support avx512 flag - if(IPCL_DEBUG_DISABLE_AVX512IFMA) - message(STATUS "Support AVX512IFMA: False") - else() - set(CPU_AVX512_FLAG "avx512ifma") - execute_process(COMMAND lscpu COMMAND grep ${CPU_AVX512_FLAG} OUTPUT_VARIABLE CPU_ENABLE_AVX512) - if("${CPU_ENABLE_AVX512}" STREQUAL "") - message(STATUS "Support AVX512IFMA: False") - else() - message(STATUS "Support AVX512IFMA: True") - add_compile_definitions(IPCL_CRYPTO_MB_MOD_EXP) - endif() - endif() -endif() - -# check whether cpu support rdseed or rdrand instruction -set(CPU_RDSEED_FLAG "rdseed") -execute_process(COMMAND lscpu COMMAND grep ${CPU_RDSEED_FLAG} OUTPUT_VARIABLE CPU_ENABLE_RDSEED) -if("${CPU_ENABLE_RDSEED}" STREQUAL "") - set(CPU_RDRAND_FLAG "rdrand") - execute_process(COMMAND lscpu COMMAND grep ${CPU_RDRAND_FLAG} OUTPUT_VARIABLE CPU_ENABLE_RDRAND) - if("${CPU_ENABLE_RDRAND}" STREQUAL "") - message(WARNING "CPU doesn't support RDSEED and RDRAND instruction, using random generator will cause errors.") - else () - message(STATUS "Support RDRAND instruction: True") - add_compile_definitions(IPCL_RNG_INSTR_RDRAND) - endif() +# global IPCL folders +set(IPCL_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(IPCL_SRC_DIR ${IPCL_ROOT_DIR}/ipcl) +set(IPCL_INC_DIR ${IPCL_SRC_DIR}/include) +set(IPCL_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ipcl) +set(IPCL_INSTALL_LIBDIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ipcl) +set(IPCL_CMAKE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/ipcl") +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(IPCL_DEBUG ON) else() - message(STATUS "Support RDSEED instruction: True") - add_compile_definitions(IPCL_RNG_INSTR_RDSEED) + set(IPCL_DEBUG OFF) endif() -# find package for OpenSSL and Threads -# set(OPENSSL_USE_STATIC_LIBS TRUE) +# find package: Threads config +set(CMAKE_THREAD_PREFER_PTHREAD ON) find_package(Threads REQUIRED) + +# find package: OpenSSL config find_package(OpenSSL REQUIRED) # External dependencies -set(CMAKE_THREAD_PREFER_PTHREAD ON) -set(THREADS_PREFER_PTHREAD_FLAG ON) - -set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ipcl) -include(ipcl-util) - include(cmake/ippcrypto.cmake) -if(IPCL_DETECT_IFMA_RUNTIME) + +if(IPCL_DETECT_CPU_RUNTIME) include(cmake/cpufeatures.cmake) endif() +if(IPCL_ENABLE_QAT) + # preset values for including HE_QAT + set(HE_QAT_MISC OFF) # revisit later on + set(HE_QAT_DOCS ${IPCL_DOCS}) + set(HE_QAT_SHARED ${IPCL_SHARED}) + set(HE_QAT_TEST OFF) + add_subdirectory(module/heqat) +endif() + if(IPCL_TEST) include(cmake/gtest.cmake) endif() @@ -163,8 +213,7 @@ if(IPCL_BENCHMARK) include(cmake/gbenchmark.cmake) endif() - - +# IPCL main directory add_subdirectory(ipcl) # unit-test and benchmarks @@ -179,6 +228,7 @@ if(IPCL_BENCHMARK) add_custom_target(benchmark COMMAND $ DEPENDS bench_ipcl) endif() +# doxygen generation if(IPCL_DOCS) add_subdirectory(docs) endif() diff --git a/README.md b/README.md index e90903f..932bf11 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Intel Paillier Cryptosystem Library -Intel Paillier Cryptosystem Library is an open-source library which provides accelerated performance of a partial homomorphic encryption (HE), named Paillier cryptosystem, by utilizing IntelĀ® [Integrated Performance Primitives Cryptography](https://github.com/intel/ipp-crypto) technologies on Intel CPUs supporting the AVX512IFMA instructions. The library is written in modern standard C++ and provides the essential API for the Paillier cryptosystem scheme. Intel Paillier Cryptosystem Library is certified for ISO compliance. +Intel Paillier Cryptosystem Library is an open-source library which provides accelerated performance of a partial homomorphic encryption (HE), named Paillier cryptosystem, by utilizing IntelĀ® [Integrated Performance Primitives Cryptography](https://github.com/intel/ipp-crypto) technologies on Intel CPUs supporting the AVX512IFMA instructions and IntelĀ® [Quickassist Technology](https://01.org/intel-quickassist-technology). The library is written in modern standard C++ and provides the essential API for the Paillier cryptosystem scheme. Intel Paillier Cryptosystem Library is certified for ISO compliance. ## Contents - [Intel Paillier Cryptosystem Library](#intel-paillier-cryptosystem-library) @@ -10,6 +10,7 @@ Intel Paillier Cryptosystem Library is an open-source library which provides acc - [Dependencies](#dependencies) - [Instructions](#instructions) - [Installing and Using Example](#installing-and-using-example) + - [Compiling for QAT](#compiling-for-qat) - [Testing and Benchmarking](#testing-and-benchmarking) - [Python Extension](#python-extension) - [Standardization](#standardization) @@ -26,19 +27,21 @@ As a public key encryption scheme, Paillier cryptosystem has three stages: - Encryption with public key - Decryption with private key -For increased security, typically the key length is at least 1024 bits, but recommendation is 2048 bits or larger. To handle such large size integers, conventional implementations of the Paillier cryptosystem utilizes the GNU Multiple Precision Arithmetic Library (GMP). The essential computation of the scheme relies on the modular exponentiation, and our library takes advantage of the multi-buffer modular exponentiation function (```mbx_exp_mb8```) of IPP-Crypto library, which is enabled in AVX512IFMA instruction sets supporting SKUs, such as Intel Icelake Xeon CPUs. +For increased security, typically the key length is at least 1024 bits, but recommendation is 2048 bits or larger. To handle such large size integers, conventional implementations of the Paillier cryptosystem utilizes the GNU Multiple Precision Arithmetic Library (GMP). The essential computation of the scheme relies on the modular exponentiation, and our library takes advantage of two Intel features - the multi-buffer modular exponentiation function (```mbx_exp_mb8```) of IPP-Crypto library, which is enabled in AVX512IFMA instruction sets supporting SKUs, such as Intel Icelake/Sapphire Rapid XeonĀ® scalable processors and the modular exponentiation operation (```cpaCyLnModExp```) of Quickassist Technology library for QAT devices. ## Building the Library ### Prerequisites For best performance, especially due to the multi-buffer modular exponentiation function, the library is to be used on AVX512IFMA enabled systems, as listed below in Intel CPU codenames: - Intel Cannon Lake - Intel Ice Lake + - Intel Sapphire Rapids -The library can be built and used without AVX512IFMA, as if the instruction set is not detected on the system, it will automatically switch to non multi-buffer modular exponentiation. +The library can be built and used without AVX512IFMA and/or QAT, if the features are not supported. But for better performance, it is recommended to use the library on Intel XeonĀ® scalable processors - Ice Lake-SP or Sapphire Rapids-SP Xeon CPUs while fully utilizing the features. The following operating systems have been tested and deemed to be fully functional. - Ubuntu 18.04 and higher - Red Hat Enterprise Linux 8.1 and higher + - CentOS Stream We will keep working on adding more supported operating systems. ### Dependencies @@ -47,7 +50,10 @@ Must have dependencies include: cmake >= 3.15.1 git pthread -g++ >= 7.0 or clang >= 10.0 +Intel C++ Compiler Classic 2021.3 for Linux* OS +Intel oneAPI DPC++/C++ Compiler for Linux* OS >= 2021.3 +g++ >= 8.0 +clang >= 10.0 ``` The following libraries and tools are also required, @@ -57,17 +63,17 @@ OpenSSL >= 1.1.0 numa >= 2.0.12 ``` -For ```nasm```, please refer to the [Netwide Assembler](https://nasm.us/) for installation details. - On Ubuntu, ```OpenSSL``` and ```numa``` can be installed with: ```bash sudo apt update -sudo apt install libssl-dev -sudo apt install libnuma-dev +sudo apt install nasm # for Ubuntu 20.04 or higher +sudo apt install libssl-dev libnuma-dev ``` -For RHEL, ```OpenSSL``` needs to be built and installed from source as the static libraries are missing when installed through the package managers. Please refer to [OpenSSL Project](https://github.com/openssl/openssl) for installation details for static libraries. ```numa``` can be installed with: +For Ubuntu 18.04, RHEL and CentOS, please refer to the [Netwide Assembler webpage](https://nasm.us/) for installation details. + +For RHEL and CentOS, the required libraries can be installed via: ``` -sudo yum install numactl-devel +sudo yum install numactl-devel openssl-devel ``` ### Instructions @@ -84,19 +90,32 @@ It is possible to pass additional options to enable more features. The following |--------------------------|-----------|---------|-------------------------------------| |`IPCL_TEST` | ON/OFF | ON | unit-test | |`IPCL_BENCHMARK` | ON/OFF | ON | benchmark | +|`IPCL_ENABLE_QAT` | ON/OFF | OFF | enables QAT functionalities | |`IPCL_ENABLE_OMP` | ON/OFF | ON | enables OpenMP functionalities | |`IPCL_THREAD_COUNT` | Integer | OFF | explicitly set max number of threads| |`IPCL_DOCS` | ON/OFF | OFF | build doxygen documentation | |`IPCL_SHARED` | ON/OFF | ON | build shared library | -|`IPCL_DETECT_IFMA_RUNTIME`| ON/OFF | OFF | detects AVX512IFMA during runtime | +|`IPCL_DETECT_CPU_RUNTIME` | ON/OFF | OFF | detects CPU supported instructions (AVX512IFMA, rdseed, rdrand) during runtime | -If ```IPCL_DETECT_IFMA_RUNTIME``` flag is set to ```ON```, it will determine whether the system supports the AVX512IFMA instructions on runtime. It is still possible to disable IFMA exclusive feature (multi-buffer modular exponentiation) during runtime by setting up the environment variable ```IPCL_DISABLE_AVX512IFMA=1```. +If ```IPCL_DETECT_CPU_RUNTIME``` flag is ```ON```, it will determine whether the system supports the AVX512IFMA instructions on runtime. It is still possible to disable IFMA exclusive feature (multi-buffer modular exponentiation) during runtime by setting up the environment variable ```IPCL_DISABLE_AVX512IFMA=1```. ### Installing and Using Example For installing and using the library externally, see [example/README.md](./example/README.md). +## Compiling for QAT + +Install QAT software stack following the [Building the HE QAT Library](./module/heqat/README.md#building-the-library). + +```bash +export IPCL_DIR=$(pwd) +export ICP_ROOT=$HOME/QAT +cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DIPCL_ENABLE_QAT=ON +cmake --build build -j +``` +For more details, please refer to the [HEQAT Readme](./module/heqat/README.md). + ## Testing and Benchmarking -To run a set of unit tests via [Googletest](https://github.com/google/googletest), configure and build library with `-DIPCL_TEST=ON` (see [Instructions](#instructions)). +To run a set of unit tests via [GoogleTest](https://github.com/google/googletest), configure and build library with `-DIPCL_TEST=ON` (see [Instructions](#instructions)). Then, run ```bash cmake --build build --target unittest @@ -115,8 +134,7 @@ The executables are located at `${IPCL_ROOT}/build/test/unittest_ipcl` and `${IP Alongside the Intel Paillier Cryptosystem Library, we provide a Python extension package utilizing this library as a backend. For installation and usage detail, refer to [Intel Paillier Cryptosystem Library - Python](https://github.com/intel/pailliercryptolib_python). # Standardization -This library is certified for ISO compliance with the homomorphic encryption standards [ISO/IEC 18033-6](https://www.iso.org/standard/67740.html) by Dekra. - +This library is certified for ISO compliance with the homomorphic encryption standards [ISO/IEC 18033-6](https://www.iso.org/standard/67740.html) by [Dekra](https://www.dekra.com). # Contributors Main contributors to this project, sorted by alphabetical order of last name are: - [Flavio Bergamaschi](https://www.linkedin.com/in/flavio-bergamaschi) diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 00662dc..cadb1f6 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -1,14 +1,20 @@ # Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -set(IPCL_BENCH_SRC main.cpp +set(IPCL_BENCH_SRC + main.cpp bench_cryptography.cpp - bench_ops.cpp) + bench_ops.cpp +) + +if(IPCL_ENABLE_QAT) + list(APPEND IPCL_BENCH_SRC bench_hybrid.cpp) +endif() add_executable(bench_ipcl ${IPCL_BENCH_SRC}) target_include_directories(bench_ipcl PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${IPCL_INC_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${IPCL_INC_DIR} ) target_link_libraries(bench_ipcl PRIVATE diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index 9f30a53..49d983b 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -15,7 +15,8 @@ ->Args({256}) \ ->Args({512}) \ ->Args({1024}) \ - ->Args({2048}) + ->Args({2048}) \ + ->Args({2100}) constexpr bool Enable_DJN = true; @@ -93,6 +94,7 @@ static void BM_Encrypt(benchmark::State& state) { delete pub_key; delete priv_key; } + BENCHMARK(BM_Encrypt) ->Unit(benchmark::kMicrosecond) ->ADD_SAMPLE_VECTOR_SIZE_ARGS; diff --git a/benchmark/bench_hybrid.cpp b/benchmark/bench_hybrid.cpp new file mode 100644 index 0000000..d911301 --- /dev/null +++ b/benchmark/bench_hybrid.cpp @@ -0,0 +1,234 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include + +#include + +#include "ipcl/ipcl.hpp" + +#define BENCH_HYBRID_DETAIL 1 + +#define INPUT_BN_NUM_MAX 256 +#define INPUT_BN_NUM_MIN 16 +#define INPUT_BN_NUM_GROWTH_RATE 2 + +// scale it from [0, 1] to [0, 100] +#define HYBRID_QAT_RATIO_MAX 100 +#define HYBRID_QAT_RATIO_MIN 0 +#define HYBRID_QAT_RATIO_STEP 10 + +constexpr bool Enable_DJN = true; + +// P_BN comes from ISO_IEC_18033_6_Compliance +const BigNumber P_BN = + "0xff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c" + "8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b4" + "0a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff76" + "4dd8b091f11a0943a2dd2b983b0df02f4c4d00b413"; + +// Q_BN comes from ISO_IEC_18033_6_Compliance +const BigNumber Q_BN = + "0xdacaabc1dc57faa9fd6a4274c4d588765a1d3311c22e57d8101431b07eb3ddcb05d77d" + "9a742ac2322fe6a063bd1e05acb13b0fe91c70115c2b1eee1155e072527011a5f849de70" + "72a1ce8e6b71db525fbcda7a89aaed46d27aca5eaeaf35a26270a4a833c5cda681ffd49b" + "aa0f610bad100cdf47cc86e5034e2a0b2179e04ec7"; + +// R_BN comes from ISO_IEC_18033_6_Compliance +const BigNumber R_BN = + "0x57fb19590c31dc7c034b2a889cf4037ce3db799909c1eb0adb6199d8e96791daca9018" + "891f34309daff32dced4af7d793d16734d055e28023acab7295956bfbfdf62bf0ccb2ed3" + "1d5d176ca8b404e93007565fb6b72c33a512b4dc4f719231d62e27e34c3733929af32247" + "f88c20d1ee77096cc80d3d642464054c815b35878ba812349c8bdc3c6b645daf1a0de609" + "65f44dcf705681032480f1eeba82243196b96903becdc0df0801d4120cbd6db1c4b2841a" + "27991c44a43750c24ed0825718ad14cfb9c6b40b78ff3d25f71741f2def1c9d420d4b0fa" + "1e0a02e7851b5ec6a81133a368b80d1500b0f28fc653d2e6ff4366236dbf80ae3b4beae3" + "5e04579f2c"; + +const BigNumber HS_BN = + "0x7788f6e8f57d3488cf9e0c7f4c19521de9aa172bf35924c7827a1189d6c688ac078f77" + "7efcfc230e34f1fa5ae8d9d2ed5b062257618e0a0a485b0084b3fd39080031ea739bb48c" + "dcce4ad41704ed930d40f53a1cc5d7f70bcb379f17a912b0ad14fabe8fc10213dcd1eabd" + "9175ee9bf66c31e9af9703c9d92fa5c8d36279459631ba7e9d4571a10960f8e8d031b267" + "22f6ae6f618895b9ce4fce926c8f54169168f6bb3e033861e08c2eca2161198481bc7c52" + "3a38310be22f4dd7d028dc6b774e5cb8e6f33b24168697743b7deff411510e27694bf2e8" + "0258b325fd97370f5110f54d8d7580b45ae3db26da4e3b0409f0cfbc56d9d9856b66d8bf" + "46e727dc3148f70362d05faea743621e3841c94c78d53ee7e7fdef61022dd56922368991" + "f843ca0aebf8436e5ec7e737c7ce72ac58f138bb11a3035fe96cc5a7b1aa9d565cb8a317" + "f42564482dd3c842c5ee9fb523c165a8507ecee1ac4f185bdbcb7a51095c4c46bfe15aec" + "3dfd77e1fd2b0003596df83bbb0d5521f16e2301ec2d4aafe25e4479ee965d8bb30a689a" + "6f38ba710222fff7cf359d0f317b8e268f40f576c04262a595cdfc9a07b72978b9564ace" + "699208291da7024e86b6eeb1458658852f10794c677b53db8577af272233722ad4579d7a" + "074e57217e1c57d11862f74486c7f2987e4d09cd6fb2923569b577de50e89e6965a27e18" + "7a8a341a7282b385ef"; + +// (data_size, qat_ratio) +static void customArgs(benchmark::internal::Benchmark* b) { + for (int i = INPUT_BN_NUM_MIN; i <= INPUT_BN_NUM_MAX; + i *= INPUT_BN_NUM_GROWTH_RATE) { +#if BENCH_HYBRID_DETAIL + for (int j = HYBRID_QAT_RATIO_MIN; j <= HYBRID_QAT_RATIO_MAX; + j += HYBRID_QAT_RATIO_STEP) { + b->Args({i, j}); + } +#else + b->Args({i}); +#endif + } +} + +static void BM_Hybrid_ModExp(benchmark::State& state) { + ipcl::setHybridOff(); + + int64_t dsize = state.range(0); + float qat_ratio = state.range(1) * 0.01; // scale it back + + BigNumber n = P_BN * Q_BN; + int n_length = n.BitSize(); + ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); + ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + + std::vector r_bn_v(dsize, R_BN); + pub_key->setRandom(r_bn_v); + pub_key->setHS(HS_BN); + + std::vector exp_bn_v(dsize); + for (size_t i = 0; i < dsize; i++) + exp_bn_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); + + ipcl::PlainText pt(exp_bn_v); + + BigNumber lambda = priv_key->getLambda(); + std::vector pow(dsize, lambda); + std::vector m(dsize, n * n); + + ipcl::CipherText ct = pub_key->encrypt(pt); + std::vector res(dsize); + +#if BENCH_HYBRID_DETAIL + ipcl::setHybridRatio(qat_ratio); +#else + ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); +#endif + + for (auto _ : state) res = ipcl::modExp(ct.getTexts(), pow, m); // decryptRAW + + delete pub_key; + delete priv_key; +} +BENCHMARK(BM_Hybrid_ModExp)->Unit(benchmark::kMicrosecond)->Apply(customArgs); + +static void BM_Hybrid_Encrypt(benchmark::State& state) { + // need to reset, otherwise will be affected by the previous benchmark + // (i.e. BM_Hybrid_ModExp) + ipcl::setHybridOff(); + + int64_t dsize = state.range(0); + float qat_ratio = state.range(1) * 0.01; // scale it back + + BigNumber n = P_BN * Q_BN; + int n_length = n.BitSize(); + ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); + ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + + std::vector r_bn_v(dsize, R_BN); + pub_key->setRandom(r_bn_v); + pub_key->setHS(HS_BN); + + std::vector exp_bn_v(dsize); + for (size_t i = 0; i < dsize; i++) + exp_bn_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); + ipcl::PlainText pt(exp_bn_v); + ipcl::CipherText ct; + +#if BENCH_HYBRID_DETAIL + ipcl::setHybridRatio(qat_ratio); +#else + ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); +#endif + + for (auto _ : state) ct = pub_key->encrypt(pt); + + delete pub_key; + delete priv_key; +} +BENCHMARK(BM_Hybrid_Encrypt)->Unit(benchmark::kMicrosecond)->Apply(customArgs); + +static void BM_Hybrid_Decrypt(benchmark::State& state) { + // need to reset, otherwise will be affected by the previous benchmark + // (i.e. BM_Hybrid_Encrypt) + ipcl::setHybridOff(); + + int64_t dsize = state.range(0); + float qat_ratio = state.range(1) * 0.01; // scale it back + + BigNumber n = P_BN * Q_BN; + int n_length = n.BitSize(); + ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); + ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + + std::vector r_bn_v(dsize, R_BN); + pub_key->setRandom(r_bn_v); + pub_key->setHS(HS_BN); + + std::vector exp_bn_v(dsize); + for (size_t i = 0; i < dsize; i++) + exp_bn_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); + + ipcl::PlainText pt(exp_bn_v), dt; + ipcl::CipherText ct = pub_key->encrypt(pt); + +#if BENCH_HYBRID_DETAIL + ipcl::setHybridRatio(qat_ratio); +#else + ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); +#endif + + for (auto _ : state) dt = priv_key->decrypt(ct); + + delete pub_key; + delete priv_key; +} +BENCHMARK(BM_Hybrid_Decrypt)->Unit(benchmark::kMicrosecond)->Apply(customArgs); + +static void BM_Hybrid_MulCTPT(benchmark::State& state) { + // need to reset, otherwise will be affected by the previous benchmark + // (i.e. BM_Hybrid_Decrypt) + ipcl::setHybridOff(); + + int64_t dsize = state.range(0); + float qat_ratio = state.range(1) * 0.01; // scale it back + + BigNumber n = P_BN * Q_BN; + int n_length = n.BitSize(); + ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); + ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + + std::vector r_bn_v(dsize, R_BN); + pub_key->setRandom(r_bn_v); + pub_key->setHS(HS_BN); + + std::vector exp_bn1_v(dsize), exp_bn2_v(dsize); + for (int i = 0; i < dsize; i++) { + exp_bn1_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); + exp_bn2_v[i] = Q_BN + BigNumber((unsigned int)(i * 1024)); + } + + ipcl::PlainText pt1(exp_bn1_v); + ipcl::PlainText pt2(exp_bn2_v); + + ipcl::CipherText ct1 = pub_key->encrypt(pt1); + ipcl::CipherText product; + +#if BENCH_HYBRID_DETAIL + ipcl::setHybridRatio(qat_ratio); +#else + ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); +#endif + + for (auto _ : state) product = ct1 * pt2; + + delete pub_key; + delete priv_key; +} +BENCHMARK(BM_Hybrid_MulCTPT)->Unit(benchmark::kMicrosecond)->Apply(customArgs); diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index 48fe76c..cb0acfd 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -3,7 +3,6 @@ #include -#include #include #include "ipcl/ipcl.hpp" @@ -16,7 +15,8 @@ ->Args({256}) \ ->Args({512}) \ ->Args({1024}) \ - ->Args({2048}) + ->Args({2048}) \ + ->Args({2100}) constexpr bool Enable_DJN = true; diff --git a/benchmark/main.cpp b/benchmark/main.cpp index da89895..915ed5b 100644 --- a/benchmark/main.cpp +++ b/benchmark/main.cpp @@ -1,11 +1,20 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include +#include "benchmark/benchmark.h" +#include "ipcl/context.hpp" int main(int argc, char** argv) { +#ifdef IPCL_USE_QAT + ipcl::initializeContext("QAT"); +#else + ipcl::initializeContext("default"); +#endif // IPCL_USE_QAT + benchmark::Initialize(&argc, argv); benchmark::RunSpecifiedBenchmarks(); + ipcl::terminateContext(); + return 0; } diff --git a/cmake/cpufeatures.cmake b/cmake/cpufeatures.cmake index 6df3c12..1da25f1 100644 --- a/cmake/cpufeatures.cmake +++ b/cmake/cpufeatures.cmake @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 include(ExternalProject) -include(GNUInstallDirs) message(STATUS "configuring cpu_features") set(CPUFEATURES_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_cpufeatures) @@ -20,14 +19,14 @@ ExternalProject_Add( -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + -DCMAKE_INSTALL_LIBDIR=lib UPDATE_COMMAND "" EXCLUDE_FROM_ALL TRUE INSTALL_COMMAND make DESTDIR=${CPUFEATURES_DESTDIR} install ) - set(CPUFEATURES_INC_DIR ${CPUFEATURES_DESTDIR}/${CMAKE_INSTALL_PREFIX}/include) -set(CPUFEATURES_LIB_DIR ${CPUFEATURES_DESTDIR}/${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) +set(CPUFEATURES_LIB_DIR ${CPUFEATURES_DESTDIR}/${CMAKE_INSTALL_PREFIX}/lib) if(IPCL_SHARED) add_library(libcpu_features INTERFACE) @@ -35,12 +34,23 @@ if(IPCL_SHARED) target_include_directories(libcpu_features SYSTEM INTERFACE ${CPUFEATURES_INC_DIR}) - target_link_libraries(libcpu_features - INTERFACE ${CPUFEATURES_LIB_DIR}/libcpu_features.a) + # ipcl python build + if(IPCL_INTERNAL_PYTHON_BUILD) + target_link_libraries(libcpu_features INTERFACE + ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/cpufeatures/libcpu_features.a) + + add_custom_command(TARGET ext_cpufeatures + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CPUFEATURES_LIB_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/cpufeatures + ) + else() + target_link_libraries(libcpu_features INTERFACE + ${CPUFEATURES_LIB_DIR}/libcpu_features.a) + endif() install( DIRECTORY ${CPUFEATURES_LIB_DIR}/ - DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cpufeatures" + DESTINATION "${IPCL_INSTALL_LIBDIR}/cpufeatures" USE_SOURCE_PERMISSIONS ) else() diff --git a/cmake/gbenchmark.cmake b/cmake/gbenchmark.cmake index 8c3e8c6..94011be 100644 --- a/cmake/gbenchmark.cmake +++ b/cmake/gbenchmark.cmake @@ -2,10 +2,8 @@ # SPDX-License-Identifier: Apache-2.0 include(ExternalProject) -include(GNUInstallDirs) set(GBENCHMARK_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_gbenchmark) - set(GBENCHMARK_SRC_DIR ${GBENCHMARK_PREFIX}/src/ext_gbenchmark/) set(GBENCHMARK_BUILD_DIR ${GBENCHMARK_PREFIX}/src/ext_gbenchmark-build/) set(GBENCHMARK_REPO_URL https://github.com/google/benchmark.git) @@ -24,6 +22,7 @@ ExternalProject_Add( -DBENCHMARK_ENABLE_GTEST_TESTS=OFF -DBENCHMARK_ENABLE_TESTING=OFF -DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_LIBDIR=lib BUILD_BYPRODUCTS ${GBENCHMARK_PATHS} # Skip updates UPDATE_COMMAND "" @@ -33,7 +32,7 @@ ExternalProject_Add( add_library(libgbenchmark INTERFACE) add_dependencies(libgbenchmark ext_gbenchmark) -target_link_libraries(libgbenchmark INTERFACE ${GBENCHMARK_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libbenchmark.a) +target_link_libraries(libgbenchmark INTERFACE ${GBENCHMARK_PREFIX}/lib/libbenchmark.a) target_include_directories(libgbenchmark SYSTEM INTERFACE ${GBENCHMARK_PREFIX}/include) diff --git a/cmake/gtest.cmake b/cmake/gtest.cmake index 24b80a7..09ad1d1 100644 --- a/cmake/gtest.cmake +++ b/cmake/gtest.cmake @@ -6,7 +6,7 @@ include(GNUInstallDirs) set(GTEST_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_gtest) set(GTEST_GIT_REPO_URL https://github.com/google/googletest.git) -set(GTEST_GIT_LABEL release-1.10.0) +set(GTEST_GIT_LABEL release-1.12.1) set(GTEST_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS} -fPIC") ExternalProject_Add( @@ -16,17 +16,12 @@ ExternalProject_Add( GIT_TAG ${GTEST_GIT_LABEL} CMAKE_ARGS ${GTEST_CXX_FLAGS} -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + -DCMAKE_INSTALL_LIBDIR=lib UPDATE_COMMAND "" EXCLUDE_FROM_ALL TRUE INSTALL_COMMAND "" ) -# install( -# DIRECTORY ${GTEST_DESTDIR}/${CMAKE_INSTALL_PREFIX}/ -# DESTINATION "." -# USE_SOURCE_PERMISSIONS -# ) - ExternalProject_Get_Property(ext_gtest SOURCE_DIR BINARY_DIR) add_library(libgtest INTERFACE) diff --git a/cmake/ipcl/ipcl-util.cmake b/cmake/ipcl/ipcl-util.cmake index e9d2cfe..625c150 100644 --- a/cmake/ipcl/ipcl-util.cmake +++ b/cmake/ipcl/ipcl-util.cmake @@ -29,3 +29,92 @@ function(ipcl_create_archive target dependency) message(WARNING "Unsupported compiler ${CMAKE_CXX_COMPILER_ID}") endif() endfunction() + + +function(ipcl_detect_lscpu_flag flag verbose) + # Detect IFMA by parsing lscpu + set(LSCPU_FLAG ${flag}) + execute_process(COMMAND lscpu COMMAND grep ${LSCPU_FLAG} OUTPUT_VARIABLE LSCPU_FLAG) + if("${LSCPU_FLAG}" STREQUAL "") + if(verbose) + message(STATUS "Support ${flag}: False") + endif() + set(IPCL_FOUND_${flag} FALSE PARENT_SCOPE) + else() + if(verbose) + message(STATUS "Support ${flag}: True") + endif() + set(IPCL_FOUND_${flag} TRUE PARENT_SCOPE) + endif() +endfunction() + +function(ipcl_detect_qat) + # Detect SPR based QAT + message(STATUS "Detecting QAT...... ") + set(IPCL_FOUND_QAT FALSE PARENT_SCOPE) + + if(DEFINED ENV{ICP_ROOT}) + # Validate environment variable ICP_ROOT + set(tmp_ICP_ROOT $ENV{ICP_ROOT}) + get_filename_component(tmp_ICP_ROOT_fullpath "${tmp_ICP_ROOT}" REALPATH) + if(EXISTS "${tmp_ICP_ROOT_fullpath}" AND + EXISTS "${tmp_ICP_ROOT_fullpath}/build" AND + EXISTS "${tmp_ICP_ROOT_fullpath}/quickassist") + message(STATUS "Environment variable ICP_ROOT is defined as ${tmp_ICP_ROOT_fullpath}.") + execute_process(COMMAND lspci -d 8086:4940 COMMAND wc -l OUTPUT_VARIABLE QAT_PHYSICAL OUTPUT_STRIP_TRAILING_WHITESPACE) + if(${QAT_PHYSICAL} GREATER_EQUAL "1") + message(STATUS "Detected ${QAT_PHYSICAL} physical QAT processes") + execute_process(COMMAND lspci -d 8086:4941 COMMAND wc -l OUTPUT_VARIABLE QAT_VIRTUAL OUTPUT_STRIP_TRAILING_WHITESPACE) + if(${QAT_VIRTUAL} GREATER_EQUAL "1") + message(STATUS "Detected ${QAT_VIRTUAL} virtual QAT processes") + ipcl_check_qat_service_status() + set(IPCL_FOUND_QAT TRUE PARENT_SCOPE) + else() + message(WARNING "NO virtual QAT processors - IPCL_ENABLE_QAT set to OFF") + endif() + else() + message(WARNING "NO physical QAT processors - IPCL_ENABLE_QAT set to OFF") + endif() + else() + message(WARNING "Environment variable ICP_ROOT is incorrect - IPCL_ENABLE_QAT set to OFF") + endif() + else() + message(WARNING "Environment variable ICP_ROOT must be defined - IPCL_ENABLE_QAT set to OFF") + endif() +endfunction() + + +function(ipcl_check_qat_service_status) + # Detect qat_service service status + execute_process(COMMAND systemctl status qat_service.service COMMAND grep "Active: active" COMMAND wc -l OUTPUT_VARIABLE QAT_SERVICE_STATUS OUTPUT_STRIP_TRAILING_WHITESPACE) + if(${QAT_SERVICE_STATUS} EQUAL "1") + message(STATUS "qat_service is ACTIVE") + else() + message(WARNING + " qat_service is NOT ACTIVE!\n" + " Since QAT is detected, compilation will continue however the" + " qat_service need to be active to use the library.\n" + " To start the service, issue the following command --" + " \$ sudo systemctl start qat_service.service" + ) + endif() +endfunction() + +function(ipcl_define_icp_variables OutVariable) + set(ICP_ROOT $ENV{ICP_ROOT}) + set(ICP_BUILDOUTPUT_PATH ${ICP_ROOT}/build) + set(ICP_BUILDSYSTEM_PATH ${ICP_ROOT}/quickassist/build_system) + set(ICP_API_DIR ${ICP_ROOT}/quickassist) + set(ICP_LAC_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer) + set(ICP_OSAL_DIR ${ICP_ROOT}/quickassist/utilities/oasl) + set(ICP_ADF_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/qat_direct) + set(CMN_ROOT ${ICP_ROOT}/quickassist/utilities/libusdm_drv) + + set(${OutVariable} ${ICP_API_DIR}/include + ${ICP_LAC_DIR}/include + ${ICP_ADF_DIR}/include + ${CMN_ROOT} + ${ICP_API_DIR}/include/dc + ${ICP_API_DIR}/include/lac + PARENT_SCOPE) +endfunction() diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake index 3650b9a..d9477f9 100644 --- a/cmake/ippcrypto.cmake +++ b/cmake/ippcrypto.cmake @@ -6,6 +6,7 @@ message(STATUS "Configuring ipp-crypto") set(IPPCRYPTO_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_ipp-crypto) set(IPPCRYPTO_DESTDIR ${IPPCRYPTO_PREFIX}/ippcrypto_install) +set(IPPCRYPTO_DEST_INCLUDE_DIR include/ippcrypto) set(IPPCRYPTO_GIT_REPO_URL https://github.com/intel/ipp-crypto.git) set(IPPCRYPTO_GIT_LABEL ippcp_2021.6) set(IPPCRYPTO_SRC_DIR ${IPPCRYPTO_PREFIX}/src/ext_ipp-crypto/) @@ -32,44 +33,63 @@ ExternalProject_Add( -DCMAKE_ASM_NASM_COMPILER=nasm -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + -DCMAKE_INSTALL_INCLUDEDIR=${IPPCRYPTO_DEST_INCLUDE_DIR} UPDATE_COMMAND "" + PATCH_COMMAND git apply ${CMAKE_CURRENT_LIST_DIR}/patch/ippcrypto_patch.patch INSTALL_COMMAND make DESTDIR=${IPPCRYPTO_DESTDIR} install ) set(IPPCRYPTO_INC_DIR ${IPPCRYPTO_DESTDIR}/${CMAKE_INSTALL_PREFIX}/include) -set(IPPCRYPTO_LIB_DIR ${IPPCRYPTO_DESTDIR}/${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${IPPCRYPTO_ARCH}) +set(IPPCRYPTO_LIB_DIR ${IPPCRYPTO_DESTDIR}/${CMAKE_INSTALL_PREFIX}/lib/${IPPCRYPTO_ARCH}) if(IPCL_SHARED) - add_library(libippcrypto INTERFACE) - add_dependencies(libippcrypto ext_ipp-crypto) + add_library(IPPCP INTERFACE) + add_library(IPPCP::ippcp ALIAS IPPCP) + + add_dependencies(IPPCP ext_ipp-crypto) ExternalProject_Get_Property(ext_ipp-crypto SOURCE_DIR BINARY_DIR) - target_link_libraries(libippcrypto INTERFACE - ${IPPCRYPTO_LIB_DIR}/libippcp.so - ${IPPCRYPTO_LIB_DIR}/libcrypto_mb.so) - target_include_directories(libippcrypto SYSTEM INTERFACE ${IPPCRYPTO_INC_DIR}) + target_include_directories(IPPCP SYSTEM INTERFACE ${IPPCRYPTO_INC_DIR}) + + # if ipcl python build + if(IPCL_INTERNAL_PYTHON_BUILD) + target_link_libraries(IPPCP INTERFACE + ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ippcrypto/libippcp.so + ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ippcrypto/libcrypto_mb.so + ) + + add_custom_command(TARGET ext_ipp-crypto + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory ${IPPCRYPTO_LIB_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ippcrypto + ) + else() + target_link_libraries(IPPCP INTERFACE + ${IPPCRYPTO_LIB_DIR}/libippcp.so + ${IPPCRYPTO_LIB_DIR}/libcrypto_mb.so + ) + endif() install( DIRECTORY ${IPPCRYPTO_LIB_DIR}/ - DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/ippcrypto" + DESTINATION "${IPCL_INSTALL_LIBDIR}/ippcrypto" USE_SOURCE_PERMISSIONS ) else() - add_library(libippcrypto::ippcp STATIC IMPORTED GLOBAL) - add_library(libippcrypto::crypto_mb STATIC IMPORTED GLOBAL) + add_library(IPPCP::ippcp STATIC IMPORTED GLOBAL) + add_library(IPPCP::crypto_mb STATIC IMPORTED GLOBAL) - add_dependencies(libippcrypto::ippcp ext_ipp-crypto) - add_dependencies(libippcrypto::crypto_mb ext_ipp-crypto) + add_dependencies(IPPCP::ippcp ext_ipp-crypto) + add_dependencies(IPPCP::crypto_mb ext_ipp-crypto) find_package(OpenSSL REQUIRED) - set_target_properties(libippcrypto::ippcp PROPERTIES + set_target_properties(IPPCP::ippcp PROPERTIES IMPORTED_LOCATION ${IPPCRYPTO_LIB_DIR}/libippcp.a INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} ) - set_target_properties(libippcrypto::crypto_mb PROPERTIES + set_target_properties(IPPCP::crypto_mb PROPERTIES IMPORTED_LOCATION ${IPPCRYPTO_LIB_DIR}/libcrypto_mb.a INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} ) diff --git a/cmake/patch/ippcrypto_patch.patch b/cmake/patch/ippcrypto_patch.patch new file mode 100644 index 0000000..6dfff68 --- /dev/null +++ b/cmake/patch/ippcrypto_patch.patch @@ -0,0 +1,125 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index ddb61db..302ca95 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -54,6 +54,7 @@ endif() + project(${PROJECT_NAME} + VERSION ${PROJECT_VERSION} + LANGUAGES C CXX) ++include(GNUInstallDirs) + + if("${CMAKE_BUILD_TYPE}" STREQUAL "") + message(STATUS "CMAKE_BUILD_TYPE is unset, defaulting to Release") +diff --git a/sources/cmake/linux/GNU8.2.0.cmake b/sources/cmake/linux/GNU8.2.0.cmake +index 9c848d5..30ad189 100644 +--- a/sources/cmake/linux/GNU8.2.0.cmake ++++ b/sources/cmake/linux/GNU8.2.0.cmake +@@ -96,7 +96,7 @@ if(${ARCH} MATCHES "ia32") + endif(${ARCH} MATCHES "ia32") + + # Optimization level = 3, no-debug definition (turns off asserts), warnings=errors +-set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -Werror") ++set (CMAKE_C_FLAGS_RELEASE " -O3 -DNDEBUG -Wno-stringop-overflow -Werror") + + set(w7_opt "${w7_opt} -march=pentium4 -msse2") + set(s8_opt "${s8_opt} -march=core2 -mssse3") +diff --git a/sources/ippcp/CMakeLists.txt b/sources/ippcp/CMakeLists.txt +index dd5ef41..b60357e 100644 +--- a/sources/ippcp/CMakeLists.txt ++++ b/sources/ippcp/CMakeLists.txt +@@ -378,7 +378,7 @@ foreach(opt ${PLATFORM_LIST}) + install(TARGETS ${IPPCP_DYN_ITER} + LIBRARY DESTINATION "lib/${ARCH}/$<$:nonpic>" + RUNTIME DESTINATION "lib/${ARCH}/$<$:nonpic>" +- PUBLIC_HEADER DESTINATION "include") ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + list(APPEND IPPCP_LIB_DYNAMIC ${IPPCP_DYN_ITER}) + endif(DYNAMIC_LIB AND NOT MERGED_BLD) + +@@ -407,7 +407,7 @@ foreach(opt ${PLATFORM_LIST}) + set_target_properties(${IPPCP_ST_ITER} PROPERTIES PUBLIC_HEADER "${IPPCP_PUBLIC_HEADERS}") + install(TARGETS ${IPPCP_ST_ITER} + ARCHIVE DESTINATION "lib/${ARCH}/$<$:nonpic>" +- PUBLIC_HEADER DESTINATION "include") ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + endif() + + list(APPEND IPPCP_LIB_STATIC ${IPPCP_ST_ITER}) +@@ -482,7 +482,7 @@ if(MERGED_BLD) + + install(TARGETS ${IPPCP_LIB_MERGED} + ARCHIVE DESTINATION "lib/${ARCH}/$<$:nonpic>" +- PUBLIC_HEADER DESTINATION "include" ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + PRIVATE_HEADER DESTINATION "tools/${ARCH}/staticlib") + + set_source_files_properties(${DISPATCHER_C_SOURCES} pcpver.rc PROPERTIES INCLUDE_DIRECTORIES "${C_INCLUDE_DIRECTORIES}") +@@ -521,7 +521,7 @@ if(MERGED_BLD) + install(TARGETS ${IPPCP_LIB_PCS} + LIBRARY DESTINATION "lib/${ARCH}/$<$:nonpic>" + RUNTIME DESTINATION "lib/${ARCH}/$<$:nonpic>" +- PUBLIC_HEADER DESTINATION "include" ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + PRIVATE_HEADER DESTINATION "tools/${ARCH}/staticlib") + + if(WIN32) +diff --git a/sources/ippcp/crypto_mb/src/CMakeLists.txt b/sources/ippcp/crypto_mb/src/CMakeLists.txt +index f75f448..2f43255 100644 +--- a/sources/ippcp/crypto_mb/src/CMakeLists.txt ++++ b/sources/ippcp/crypto_mb/src/CMakeLists.txt +@@ -117,12 +117,12 @@ if (MB_STANDALONE) # standalone crypto_mb's cmake run + install(TARGETS ${MB_DYN_LIB_TARGET} + LIBRARY DESTINATION "lib" + RUNTIME DESTINATION "lib" +- PUBLIC_HEADER DESTINATION "include/crypto_mb") ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/crypto_mb) + elseif (DYNAMIC_LIB) # build from ippcp's cmake + install(TARGETS ${MB_DYN_LIB_TARGET} + LIBRARY DESTINATION "lib/intel64" + RUNTIME DESTINATION "lib/intel64" +- PUBLIC_HEADER DESTINATION "include/crypto_mb") ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/crypto_mb) + endif() + + # Static library +@@ -147,9 +147,9 @@ endif() + if(MB_STANDALONE) + install(TARGETS ${MB_STATIC_LIB_TARGET} + ARCHIVE DESTINATION "lib" +- PUBLIC_HEADER DESTINATION "include/crypto_mb") ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/crypto_mb) + else() + install(TARGETS ${MB_STATIC_LIB_TARGET} + ARCHIVE DESTINATION "lib/intel64" +- PUBLIC_HEADER DESTINATION "include/crypto_mb") ++ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/crypto_mb) + endif() +diff --git a/sources/ippcp/crypto_mb/src/cmake/linux/GNU.cmake b/sources/ippcp/crypto_mb/src/cmake/linux/GNU.cmake +index b95f703..1be6ca7 100644 +--- a/sources/ippcp/crypto_mb/src/cmake/linux/GNU.cmake ++++ b/sources/ippcp/crypto_mb/src/cmake/linux/GNU.cmake +@@ -46,7 +46,7 @@ set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -fcf-protection=full") + # Enables important warning and error messages relevant to security during compilation + set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wall") + # Warnings=errors +-set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Werror") ++set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wno-stringop-overflow -Werror") + + # Linker flags + +diff --git a/sources/ippcp/crypto_mb/src/cmake/linux/Intel.cmake b/sources/ippcp/crypto_mb/src/cmake/linux/Intel.cmake +index 39862aa..35d49c1 100644 +--- a/sources/ippcp/crypto_mb/src/cmake/linux/Intel.cmake ++++ b/sources/ippcp/crypto_mb/src/cmake/linux/Intel.cmake +@@ -40,7 +40,7 @@ set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -fcf-protection=full") + # Enables important warning and error messages relevant to security during compilation + set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wall") + # Warnings=errors +-set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Werror") ++set(CMAKE_C_FLAGS_SECURITY "${CMAKE_C_FLAGS_SECURITY} -Wno-stringop-overflow -Werror") + + # Linker flags + diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index cb66be8..9e2de3a 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -9,7 +9,10 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) -find_package(IPCL 1.1.4 REQUIRED HINTS ${IPCL_HINT_DIR}) +find_package(IPCL 2.0.0 REQUIRED HINTS ${IPCL_HINT_DIR}) -add_executable(test test.cpp) -target_link_libraries(test PRIVATE IPCL::ipcl) +set(examples encrypt_decrypt add_mul hybridmode) +foreach(ex IN LISTS examples) + add_executable(example_${ex} example_${ex}.cpp) + target_link_libraries(example_${ex} PRIVATE IPCL::ipcl) +endforeach() diff --git a/example/README.md b/example/README.md index 0bfe98c..b117c41 100644 --- a/example/README.md +++ b/example/README.md @@ -7,8 +7,9 @@ This document provides an example program for using the Intel Paillier Cryptosys - [Installation](#installation) - [Linking and Running Applications](#linking-and-running-applications) - [Building with CMake](#building-with-cmake) - - [Manually Compiling](#manually-compiling) - [Using Intel Paillier Cryptosystem Library](#using-intel-paillier-cryptosystem-library) + - [Enabling QAT usage](#enabling-qat-usage) + - [Hybrid mode configuration](#hybrid-mode-configuration) - [Data handling](#data-handling) - [```ipcl::PlainText``` Constructor](#ipclplaintext-constructor) - [Accessing data](#accessing-data) @@ -34,7 +35,7 @@ For more details about the build configuration options, please refer to the buil Before proceeding after the library is installed, it is useful to setup an environment variable to point to the installation location. ```bash -export IPCL_DIR=/path/to/install/ +export IPCL_DIR=/path/to/ipcl/install/ ``` ### Building with CMake @@ -42,26 +43,44 @@ A more convenient way to use the library is via the `find_package` functionality In your external applications, add the following lines to your `CMakeLists.txt`. ```bash -find_package(IPCL 1.1.4 +find_package(IPCL 2.0.0 HINTS ${IPCL_HINT_DIR} REQUIRED) target_link_libraries(${TARGET} IPCL::ipcl) ``` -If the library is installed globally, `IPCL_DIR` or `IPCL_HINT_DIR` flag is not needed. If `IPCL_DIR` is properly set, `IPCL_HINT_DIR` is not needed as well. Otherwise `IPCL_HINT_DIR` should be the directory containing `IPCLCOnfig.cmake`, under `${CMAKE_INSTALL_PREFIX}/lib/cmake/ipcl-1.1.4/` +If the library is installed globally, `IPCL_DIR` or `IPCL_HINT_DIR` flag is not needed. If environment variable `IPCL_DIR` is set, `IPCL_HINT_DIR` is not needed as well. Otherwise `IPCL_HINT_DIR` should be the directory containing `IPCLCOnfig.cmake`, under `${CMAKE_INSTALL_PREFIX}/lib/cmake/ipcl-2.0.0/` -### Manually Compiling -In order to directly use `g++` or `clang++` to compile an example code, it can be done by: -```bash -# gcc -g++ test.cpp -o test -L${IPCL_DIR}/lib -I${IPCL_DIR}/include -lipcl -fopenmp -lnuma -lcrypto +## Using Intel Paillier Cryptosystem Library + +### Enabling QAT usage +When QAT is enabled while building the library with the flag ```IPCL_ENABLE_QAT=ON```, it is essential to initialize and release the HE QAT context. +```C++ +// Initialize HE QAT context +ipcl::initializeContext("QAT"); + +// perform IPCL operations +auto ct = key.pub_key->encrypt(pt); +auto dec_pt = key.priv_key->decrypt(ct); -# clang -clang++ test.cpp -o test -L${IPCL_DIR}/lib -I${IPCL_DIR}/include -lipcl -fopenmp -lnuma -lcrypto +// Release HE QAT context +ipcl::terminateContext(); ``` +If QAT is disabled, ```ipcl::initializeContext("QAT")``` statement will not do anything, thus safe to include in any codes using the library. +### Hybrid mode configuration +The main accelerated operation - modular exponentiation - can be performed by either IPP-Crypto or the HE QAT. Our library provides a configurable method to distribute the workload between these two methods. +```C++ +// Use optimal mode +ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); -## Using Intel Paillier Cryptosystem Library +// Use IPP-Crypto modexp only +ipcl::setHybridMode(ipcl::HybridMode::IPP); + +// Use QAT modexp only +ipcl::setHybridMode(ipcl::HybridMode::QAT); +``` +By default, the hybrid mode is set to ```ipcl::HybridMode::OPTIMAL```. For more details about the modes, please refer to [```mod_exp.hpp```](../ipcl/include/ipcl/mod_exp.hpp#L16). ### Data handling The library uses a container - ```ipcl::PlainText``` for encryption inputs and decryption outputs as well as plaintext HE operations. diff --git a/example/example_add_mul.cpp b/example/example_add_mul.cpp new file mode 100644 index 0000000..6d9ec22 --- /dev/null +++ b/example/example_add_mul.cpp @@ -0,0 +1,100 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +/* + Example of encryption and decryption +*/ +#include +#include +#include +#include + +#include "ipcl/ipcl.hpp" + +int main() { + ipcl::initializeContext("QAT"); + + const uint32_t num_total = 20; + + ipcl::keyPair key = ipcl::generateKeypair(2048, true); + + std::vector x(num_total); + std::vector y(num_total); + + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, + UINT_MAX >> 16); + + for (int i = 0; i < num_total; i++) { + x[i] = dist(rng); + y[i] = dist(rng); + } + + ipcl::PlainText pt_x = ipcl::PlainText(x); + ipcl::PlainText pt_y = ipcl::PlainText(y); + + ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); + + ipcl::CipherText ct_x = key.pub_key->encrypt(pt_x); + ipcl::CipherText ct_y = key.pub_key->encrypt(pt_y); + + // Perform enc(x) + enc(y) + std::cout << "--- IPCL CipherText + CipherText ---" << std::endl; + ipcl::CipherText ct_add_ctx_cty = ct_x + ct_y; + ipcl::PlainText dt_add_ctx_cty = key.priv_key->decrypt(ct_add_ctx_cty); + + // verify result + bool verify = true; + for (int i = 0; i < num_total; i++) { + std::vector v = dt_add_ctx_cty.getElementVec(i); + if (v[0] != (x[i] + y[i])) { + verify = false; + break; + } + } + std::cout << "Test (x + y) == dec(enc(x) + enc(y)) -- " + << (verify ? "pass" : "fail") << std::endl + << std::endl; + + // Perform enc(x) + y + std::cout << "--- IPCL CipherText + PlainText ---" << std::endl; + ipcl::CipherText ct_add_ctx_pty = ct_x + pt_y; + ipcl::PlainText dt_add_ctx_pty = key.priv_key->decrypt(ct_add_ctx_pty); + + // verify result + verify = true; + for (int i = 0; i < num_total; i++) { + std::vector v = dt_add_ctx_pty.getElementVec(i); + if (v[0] != (x[i] + y[i])) { + verify = false; + break; + } + } + std::cout << "Test (x + y) == dec(enc(x) + y) -- " + << (verify ? "pass" : "fail") << std::endl + << std::endl; + + // Perform enc(x) * y + std::cout << "--- IPCL CipherText * PlainText ---" << std::endl; + ipcl::CipherText ct_mul_ctx_pty = ct_x * pt_y; + ipcl::PlainText dt_mul_ctx_pty = key.priv_key->decrypt(ct_mul_ctx_pty); + + // verify result + verify = true; + for (int i = 0; i < num_total; i++) { + std::vector v = dt_mul_ctx_pty.getElementVec(i); + if (v[0] != (x[i] * y[i])) { + verify = false; + break; + } + } + std::cout << "Test (x * y) == dec(enc(x) * y) -- " + << (verify ? "pass" : "fail") << std::endl; + + ipcl::setHybridOff(); + + delete key.pub_key; + delete key.priv_key; + ipcl::terminateContext(); +} diff --git a/example/example_encrypt_decrypt.cpp b/example/example_encrypt_decrypt.cpp new file mode 100644 index 0000000..e8c0c7e --- /dev/null +++ b/example/example_encrypt_decrypt.cpp @@ -0,0 +1,55 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +/* + Example of encryption and decryption +*/ +#include +#include +#include +#include + +#include "ipcl/ipcl.hpp" + +int main() { + ipcl::initializeContext("QAT"); + + const uint32_t num_total = 20; + + ipcl::keyPair key = ipcl::generateKeypair(2048, true); + + std::vector exp_value(num_total); + + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + + for (int i = 0; i < num_total; i++) { + exp_value[i] = dist(rng); + } + + ipcl::PlainText pt = ipcl::PlainText(exp_value); + + ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); + + ipcl::CipherText ct = key.pub_key->encrypt(pt); + ipcl::PlainText dt = key.priv_key->decrypt(ct); + + ipcl::setHybridOff(); + + // verify result + bool verify = true; + for (int i = 0; i < num_total; i++) { + std::vector v = dt.getElementVec(i); + if (v[0] != exp_value[i]) { + verify = false; + break; + } + } + std::cout << "Test pt == dec(enc(pt)) -- " << (verify ? "pass" : "fail") + << std::endl; + + delete key.pub_key; + delete key.priv_key; + ipcl::terminateContext(); +} diff --git a/example/example_hybridmode.cpp b/example/example_hybridmode.cpp new file mode 100644 index 0000000..4feaa1e --- /dev/null +++ b/example/example_hybridmode.cpp @@ -0,0 +1,96 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +/* + Example of encryption and decryption +*/ +#include // NOLINT [build/c++11] +#include +#include +#include +#include + +#include "ipcl/ipcl.hpp" + +typedef std::chrono::high_resolution_clock::time_point tVar; +#define tNow() std::chrono::high_resolution_clock::now() +#define tStart(t) t = tNow() +#define tEnd(t) \ + std::chrono::duration_cast(tNow() - t).count() + +int main() { + ipcl::initializeContext("QAT"); + tVar t; + double elapsed(0.); + + const uint32_t num_total = 64; + + ipcl::keyPair key = ipcl::generateKeypair(2048, true); + + std::vector exp_value(num_total); + + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(0, UINT_MAX); + BigNumber bigNum = + "0xff03b1a74827c746db83d2eaff00067622f545b62584321256e62b01509f10962f9c5c" + "8fd0b7f5184a9ce8e81f439df47dda14563dd55a221799d2aa57ed2713271678a5a0b8b4" + "0a84ad13d5b6e6599e6467c670109cf1f45ccfed8f75ea3b814548ab294626fe4d14ff76" + "4dd8b091f11a0943a2dd2b983b0df02f4c4d00b413acaabc1dc57faa9fd6a4274c4d5887" + "65a1d3311c22e57d8101431b07eb3ddcb05d77d9a742ac2322fe6a063bd1e05acb13b0fe" + "91c70115c2b1eee1155e072527011a5f849de7072a1ce8e6b71db525fbcda7a89aaed46d" + "27aca5eaeaf35a26270a4a833c5cda681ffd49baa0f610bad100cdf47cc86e5034e2a0b2" + "179e04ec7"; + + for (int i = 0; i < num_total; i++) { + exp_value[i] = bigNum - dist(rng); + } + + ipcl::PlainText pt = ipcl::PlainText(exp_value); + + // Encrypt/Decrypt - IPP-Crypto only mode + ipcl::setHybridMode(ipcl::HybridMode::IPP); + tStart(t); + ipcl::CipherText ct = key.pub_key->encrypt(pt); + elapsed = tEnd(t); + std::cout << " Encrypt - HybridMode::IPP = " << elapsed << "ms" + << std::endl; + tStart(t); + ipcl::PlainText dt = key.priv_key->decrypt(ct); + elapsed = tEnd(t); + std::cout << " Decrypt - HybridMode::IPP = " << elapsed << "ms" + << std::endl + << std::endl; + + // Encrypt/Decrypt - QAT only mode + ipcl::setHybridMode(ipcl::HybridMode::QAT); + tStart(t); + ct = key.pub_key->encrypt(pt); + elapsed = tEnd(t); + std::cout << " Encrypt - HybridMode::QAT = " << elapsed << "ms" + << std::endl; + tStart(t); + dt = key.priv_key->decrypt(ct); + elapsed = tEnd(t); + std::cout << " Decrypt - HybridMode::QAT = " << elapsed << "ms" + << std::endl + << std::endl; + + // Encrypt/Decrypt - OPTIMAL mode + ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); + tStart(t); + ct = key.pub_key->encrypt(pt); + elapsed = tEnd(t); + std::cout << " Encrypt - HybridMode::OPTIMAL = " << elapsed << "ms" + << std::endl; + tStart(t); + dt = key.priv_key->decrypt(ct); + elapsed = tEnd(t); + std::cout << " Decrypt - HybridMode::OPTIMAL = " << elapsed << "ms" + << std::endl + << std::endl; + + delete key.pub_key; + delete key.priv_key; + ipcl::terminateContext(); +} diff --git a/example/test.cpp b/example/test.cpp deleted file mode 100644 index 5ac7a31..0000000 --- a/example/test.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include - -int main() { - const uint32_t num_values = 9; - - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector exp_value(num_values); - ipcl::PlainText pt; - ipcl::CipherText ct; - ipcl::PlainText dt; - - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < num_values; i++) { - exp_value[i] = dist(rng); - } - - pt = ipcl::PlainText(exp_value); - ct = key.pub_key->encrypt(pt); - dt = key.priv_key->decrypt(ct); - - for (int i = 0; i < num_values; i++) { - std::vector v = dt.getElementVec(i); - bool chk = v[0] == exp_value[i]; - std::cout << (chk ? "pass" : "fail") << std::endl; - } - - delete key.pub_key; - delete key.priv_key; -} diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index e645d38..44005bb 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -2,17 +2,19 @@ # SPDX-License-Identifier: Apache-2.0 set(IPCL_SRCS pri_key.cpp - pub_key.cpp - keygen.cpp - bignum.cpp - mod_exp.cpp - base_text.cpp - plaintext.cpp - ciphertext.cpp - util.cpp - common.cpp + pub_key.cpp + keygen.cpp + bignum.cpp + mod_exp.cpp + context.cpp + base_text.cpp + plaintext.cpp + ciphertext.cpp + util.cpp + common.cpp ) +set(IPCL_PUBLIC_HEADER ${IPCL_INC_DIR}/ipcl/ipcl.hpp) if(IPCL_SHARED) add_library(ipcl SHARED ${IPCL_SRCS}) @@ -22,17 +24,17 @@ endif() add_library(IPCL::ipcl ALIAS ipcl) -target_include_directories(ipcl - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PUBLIC $ - PUBLIC $ -) +set_target_properties(ipcl PROPERTIES PUBLIC_HEADER ${IPCL_PUBLIC_HEADER}) +set_target_properties(ipcl PROPERTIES + BUILD_WITH_INSTALL_RPATH FALSE + LINK_FLAGS "-Wl,-rpath,'$ORIGIN' -Wl,-rpath,'$ORIGIN'/ippcrypto -Wl,-rpath,'$ORIGIN'/cpufeatures") +target_include_directories(ipcl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +# include and install definition of IPCL target_include_directories(ipcl - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PUBLIC $ - PUBLIC $ + PUBLIC $ + PUBLIC $ ) if(IPCL_DETECT_IFMA_RUNTIME) @@ -50,17 +52,49 @@ if(IPCL_DETECT_IFMA_RUNTIME) endif() install(DIRECTORY ${IPCL_INC_DIR}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} + DESTINATION ${IPCL_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h") +# include and install definition of IPP-Crypto +target_include_directories(ipcl + PUBLIC $ + PUBLIC $ +) + install(DIRECTORY ${IPPCRYPTO_INC_DIR}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} + DESTINATION ${IPCL_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h") +# include and install definition of cpu_features +if(IPCL_DETECT_CPU_RUNTIME) + target_include_directories(ipcl + PUBLIC $ + PRIVATE $ + ) + install(DIRECTORY ${CPUFEATURES_INC_DIR}/ + DESTINATION ${IPCL_INSTALL_INCLUDEDIR} + FILES_MATCHING + PATTERN "*.hpp" + PATTERN "*.h") + +endif() + +if(IPCL_ENABLE_QAT) + ipcl_define_icp_variables(icp_inc_dir) + target_include_directories(ipcl + PRIVATE "$" + ) + + target_include_directories(ipcl + PRIVATE "$" + PRIVATE $ + ) +endif() + find_package(OpenSSL REQUIRED) find_package(Threads REQUIRED) target_link_libraries(ipcl PUBLIC OpenSSL::SSL OpenSSL::Crypto Threads::Threads -lnuma) @@ -71,20 +105,24 @@ if(IPCL_ENABLE_OMP) endif() if(IPCL_SHARED) - target_link_libraries(ipcl PRIVATE libippcrypto) - if(IPCL_DETECT_IFMA_RUNTIME) - target_link_libraries(ipcl PRIVATE libcpu_features) - target_include_directories(ipcl PRIVATE ${CPUFEATURES_INC_DIR}) + target_link_libraries(ipcl PRIVATE IPPCP::ippcp) + if(IPCL_DETECT_CPU_RUNTIME) + target_link_libraries(ipcl PRIVATE libcpu_features) + endif() + if(IPCL_ENABLE_QAT) + target_link_libraries(ipcl PRIVATE he_qat udev z) endif() - target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) else() - ipcl_create_archive(ipcl libippcrypto::ippcp) - ipcl_create_archive(ipcl libippcrypto::crypto_mb) - if(IPCL_DETECT_IFMA_RUNTIME) - ipcl_create_archive(ipcl libcpu_features) - target_include_directories(ipcl PRIVATE ${CPUFEATURES_INC_DIR}) + ipcl_create_archive(ipcl IPPCP::crypto_mb) + ipcl_create_archive(ipcl IPPCP::ippcp) + if(IPCL_ENABLE_QAT) + ipcl_create_archive(ipcl he_qat) + target_link_libraries(ipcl PRIVATE udev z) + endif() + + if(IPCL_DETECT_CPU_RUNTIME) + ipcl_create_archive(ipcl libcpu_features) endif() - target_include_directories(ipcl PRIVATE ${IPPCRYPTO_INC_DIR}) endif() set_target_properties(ipcl PROPERTIES POSITION_INDEPENDENT_CODE ON) @@ -95,8 +133,6 @@ else() set_target_properties(ipcl PROPERTIES OUTPUT_NAME "ipcl") endif() -install(TARGETS ipcl DESTINATION ${CMAKE_INSTALL_LIBDIR}) - # config cmake config and target file set(IPCL_TARGET_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/cmake/ipcl-${IPCL_VERSION}/IPCLTargets.cmake) set(IPCL_CONFIG_IN_FILENAME ${IPCL_CMAKE_PATH}/IPCLConfig.cmake.in) @@ -124,9 +160,10 @@ configure_package_config_file( install( TARGETS ipcl EXPORT IPCLTargets - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + PUBLIC_HEADER DESTINATION ${IPCL_INSTALL_INCLUDEDIR} + ARCHIVE DESTINATION ${IPCL_INSTALL_LIBDIR} + LIBRARY DESTINATION ${IPCL_INSTALL_LIBDIR} + RUNTIME DESTINATION ${IPCL_INSTALL_LIBDIR} ) install(FILES ${IPCL_CONFIG_FILENAME} diff --git a/ipcl/bignum.cpp b/ipcl/bignum.cpp index 7a685db..03045e6 100644 --- a/ipcl/bignum.cpp +++ b/ipcl/bignum.cpp @@ -18,6 +18,7 @@ #include #include +#include ////////////////////////////////////////////////////////////////////// // @@ -506,3 +507,59 @@ void BigNumber::num2char(std::vector& dest) const { int len = (bnBitLen + 7) >> 3; dest.assign(bnData, bnData + len); } + +bool BigNumber::fromBin(BigNumber& bn, const unsigned char* data, int len) { + if (len <= 0) return false; + + // Create BigNumber containg input data passed as argument + bn = BigNumber(reinterpret_cast(data), (len / 4)); + Ipp32u* ref_bn_data_ = NULL; + ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); + + // Convert it to little endian format + unsigned char* data_ = reinterpret_cast(ref_bn_data_); + for (int i = 0; i < len; i++) data_[i] = data[len - 1 - i]; + + return true; +} + +bool BigNumber::toBin(unsigned char* data, int len, const BigNumber& bn) { + if (len <= 0) return false; + + // Extract raw vector of data in little endian format + int bitSize = 0; + Ipp32u* ref_bn_data_ = NULL; + ippsRef_BN(NULL, &bitSize, &ref_bn_data_, BN(bn)); + + // Revert it to big endian format + int bitSizeLen = BITSIZE_WORD(bitSize) * 4; + unsigned char* data_ = reinterpret_cast(ref_bn_data_); + for (int i = 0; i < bitSizeLen; i++) data[len - 1 - i] = data_[i]; + + return true; +} + +bool BigNumber::toBin(unsigned char** bin, int* len, const BigNumber& bn) { + if (NULL == bin) return false; + if (NULL == len) return false; + + // Extract raw vector of data in little endian format + int bitSize = 0; + Ipp32u* ref_bn_data_ = NULL; + ippsRef_BN(NULL, &bitSize, &ref_bn_data_, BN(bn)); + + // Revert it to big endian format + int bitSizeLen = BITSIZE_WORD(bitSize) * 4; + *len = bitSizeLen; + bin[0] = reinterpret_cast( + malloc(bitSizeLen * sizeof(unsigned char))); + memset(bin[0], 0, *len); + if (NULL == bin[0]) return false; + + unsigned char* data_out = bin[0]; + unsigned char* bn_data_ = reinterpret_cast(ref_bn_data_); + for (int i = 0; i < bitSizeLen; i++) + data_out[bitSizeLen - 1 - i] = bn_data_[i]; + + return true; +} diff --git a/ipcl/ciphertext.cpp b/ipcl/ciphertext.cpp index 685b264..440e1d1 100644 --- a/ipcl/ciphertext.cpp +++ b/ipcl/ciphertext.cpp @@ -142,14 +142,23 @@ BigNumber CipherText::raw_add(const BigNumber& a, const BigNumber& b) const { BigNumber CipherText::raw_mul(const BigNumber& a, const BigNumber& b) const { const BigNumber& sq = m_pubkey->getNSQ(); - return ipcl::ippModExp(a, b, sq); + return modExp(a, b, sq); } std::vector CipherText::raw_mul( const std::vector& a, const std::vector& b) const { std::size_t v_size = a.size(); std::vector sq(v_size, m_pubkey->getNSQ()); - return ipcl::ippModExp(a, b, sq); + + // If hybrid OPTIMAL mode is used, use a special ratio + if (isHybridOptimal()) { + float qat_ratio = (v_size <= IPCL_WORKLOAD_SIZE_THRESHOLD) + ? IPCL_HYBRID_MODEXP_RATIO_FULL + : IPCL_HYBRID_MODEXP_RATIO_MULTIPLY; + setHybridRatio(qat_ratio, false); + } + + return modExp(a, b, sq); } } // namespace ipcl diff --git a/ipcl/common.cpp b/ipcl/common.cpp index 90209eb..67e7e1a 100644 --- a/ipcl/common.cpp +++ b/ipcl/common.cpp @@ -10,6 +10,14 @@ namespace ipcl { IppStatus ippGenRandom(Ipp32u* rand, int bits, void* ctx) { +#ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES + if (has_rdseed) + return ippsTRNGenRDSEED(rand, bits, ctx); + else if (has_rdrand) + return ippsPRNGenRDRAND(rand, bits, ctx); + else + return ippsPRNGen(rand, bits, ctx); +#else #ifdef IPCL_RNG_INSTR_RDSEED return ippsTRNGenRDSEED(rand, bits, ctx); #elif defined(IPCL_RNG_INSTR_RDRAND) @@ -17,9 +25,18 @@ IppStatus ippGenRandom(Ipp32u* rand, int bits, void* ctx) { #else return ippsPRNGen(rand, bits, ctx); #endif +#endif // IPCL_RUNTIME_IPP_RNG } IppStatus ippGenRandomBN(IppsBigNumState* rand, int bits, void* ctx) { +#ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES + if (has_rdseed) + return ippsTRNGenRDSEED_BN(rand, bits, ctx); + else if (has_rdrand) + return ippsPRNGenRDRAND_BN(rand, bits, ctx); + else + return ippsPRNGen_BN(rand, bits, ctx); +#else #ifdef IPCL_RNG_INSTR_RDSEED return ippsTRNGenRDSEED_BN(rand, bits, ctx); #elif defined(IPCL_RNG_INSTR_RDRAND) @@ -27,6 +44,7 @@ IppStatus ippGenRandomBN(IppsBigNumState* rand, int bits, void* ctx) { #else return ippsPRNGen_BN(rand, bits, ctx); #endif +#endif // IPCL_RUNTIME_IPP_RNG } BigNumber getRandomBN(int bits) { diff --git a/ipcl/context.cpp b/ipcl/context.cpp new file mode 100644 index 0000000..d64f581 --- /dev/null +++ b/ipcl/context.cpp @@ -0,0 +1,88 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/context.hpp" + +#include +#include + +#ifdef IPCL_USE_QAT +#include +#endif + +namespace ipcl { + +///> Default behavior is selected at runtime and implementation dependent +enum class RuntimeValue { DEFAULT, CPU, QAT, HYBRID }; +const std::map runtimeMap = { + {"DEFAULT", RuntimeValue::DEFAULT}, {"default", RuntimeValue::DEFAULT}, + {"CPU", RuntimeValue::CPU}, {"cpu", RuntimeValue::CPU}, + {"QAT", RuntimeValue::QAT}, {"qat", RuntimeValue::QAT}, + {"HYBRID", RuntimeValue::HYBRID}, {"hybrid", RuntimeValue::HYBRID}}; + +enum class FeatureValue { AVX512IFMA, QAT4XXX }; +const std::map hasFeatureMap = { + {"avx512", FeatureValue::AVX512IFMA}, + {"avx512ifma", FeatureValue::AVX512IFMA}, + {"4xxx", FeatureValue::QAT4XXX}, + {"qat_4xxx", FeatureValue::QAT4XXX}}; + +#ifdef IPCL_USE_QAT +bool hasQAT = false; +static bool isUsingQAT = false; +static bool initializeQATContext() { + if (!isUsingQAT && HE_QAT_STATUS_SUCCESS == acquire_qat_devices()) + return (isUsingQAT = true); + return false; +} +#endif + +bool initializeContext(const std::string runtime_choice) { +#ifdef IPCL_USE_QAT + hasQAT = true; + switch (runtimeMap.at(runtime_choice)) { + case RuntimeValue::QAT: + return initializeQATContext(); + case RuntimeValue::CPU: + case RuntimeValue::HYBRID: + case RuntimeValue::DEFAULT: + default: + return true; + } +#else // Default behavior: CPU choice + return true; +#endif // IPCL_USE_QAT +} + +bool terminateContext() { +#ifdef IPCL_USE_QAT + if (isUsingQAT) { + if (HE_QAT_STATUS_SUCCESS == release_qat_devices()) { + isUsingQAT = false; + return true; + } + return false; + } + return true; +#else // Default behavior: CPU choice + return true; +#endif // IPCL_USE_QAT +} + +bool isQATRunning() { +#ifdef IPCL_USE_QAT + return (HE_QAT_STATUS_RUNNING == get_qat_context_state()); +#else + return false; +#endif +} + +bool isQATActive() { +#ifdef IPCL_USE_QAT + return (HE_QAT_STATUS_ACTIVE == get_qat_context_state()); +#else + return false; +#endif +} + +} // namespace ipcl diff --git a/ipcl/include/ipcl/bignum.h b/ipcl/include/ipcl/bignum.h index b97c0c2..c6531a1 100644 --- a/ipcl/include/ipcl/bignum.h +++ b/ipcl/include/ipcl/bignum.h @@ -14,8 +14,10 @@ * limitations under the License. *******************************************************************************/ -#ifndef _BIGNUM_H_ -#define _BIGNUM_H_ +//#ifndef _BIGNUM_H_ +//#define _BIGNUM_H_ +#if !defined _BIGNUMBER_H_ +#define _BIGNUMBER_H_ #include @@ -120,6 +122,11 @@ class BigNumber { friend std::ostream& operator<<(std::ostream& os, const BigNumber& a); void num2char(std::vector& dest) const; + // Support QAT data format + static bool fromBin(BigNumber& bn, const unsigned char* data, int len); + static bool toBin(unsigned char* data, int len, const BigNumber& bn); + static bool toBin(unsigned char** data, int* len, const BigNumber& bn); + protected: bool create(const Ipp32u* pData, int length, IppsBigNumSGN sgn = IppsBigNumPOS); diff --git a/ipcl/include/ipcl/common.hpp b/ipcl/include/ipcl/common.hpp index e15d44e..674d944 100644 --- a/ipcl/include/ipcl/common.hpp +++ b/ipcl/include/ipcl/common.hpp @@ -9,6 +9,14 @@ namespace ipcl { constexpr int IPCL_CRYPTO_MB_SIZE = 8; +constexpr int IPCL_QAT_MODEXP_BATCH_SIZE = 1024; + +constexpr int IPCL_WORKLOAD_SIZE_THRESHOLD = 128; + +constexpr float IPCL_HYBRID_MODEXP_RATIO_FULL = 1.0; +constexpr float IPCL_HYBRID_MODEXP_RATIO_ENCRYPT = 0.25; +constexpr float IPCL_HYBRID_MODEXP_RATIO_DECRYPT = 0.12; +constexpr float IPCL_HYBRID_MODEXP_RATIO_MULTIPLY = 0.18; /** * Random generator wrapper.Generates a random unsigned Big Number of the diff --git a/ipcl/include/ipcl/context.hpp b/ipcl/include/ipcl/context.hpp new file mode 100644 index 0000000..c528a0a --- /dev/null +++ b/ipcl/include/ipcl/context.hpp @@ -0,0 +1,47 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#ifndef IPCL_INCLUDE_IPCL_CONTEXT_HPP_ +#define IPCL_INCLUDE_IPCL_CONTEXT_HPP_ + +#include + +namespace ipcl { + +/** + * Initialize device (CPU, QAT, or both) runtime context for the Paillier crypto + * services. + * @details It must be called if there is intent of using QAT devices for + * compute acceleration. + * @param[in] runtime_choice Acceptable values are "CPU", "cpu", "QAT", "qat", + * "HYBRID", "hybrid", "DEFAULT", "default". Anything other than the accepted + * values, including typos and absence thereof, will default to the "DEFAULT" + * runtime choice. + * @return true if runtime context has been properly initialized, false + * otherwise. + */ +bool initializeContext(const std::string runtime_choice); + +/** + * Terminate runtime context. + * @return true if runtime context has been properly terminated, false + * otherwise. + */ +bool terminateContext(void); + +/** + * Determine if QAT instances are running for IPCL. + * @return true if QAT instances are active and running, false otherwise. + */ +bool isQATRunning(void); + +/** + * Determine if QAT instances are active for IPCL. + * @return true if QAT instances are active, false otherwise. + */ +bool isQATActive(void); + +} // namespace ipcl +#endif // IPCL_INCLUDE_IPCL_CONTEXT_HPP_ diff --git a/ipcl/include/ipcl/ipcl.hpp b/ipcl/include/ipcl/ipcl.hpp index f82ad31..2117c70 100644 --- a/ipcl/include/ipcl/ipcl.hpp +++ b/ipcl/include/ipcl/ipcl.hpp @@ -4,6 +4,8 @@ #ifndef IPCL_INCLUDE_IPCL_IPCL_HPP_ #define IPCL_INCLUDE_IPCL_IPCL_HPP_ +#include "ipcl/context.hpp" +#include "ipcl/mod_exp.hpp" #include "ipcl/pri_key.hpp" namespace ipcl { diff --git a/ipcl/include/ipcl/mod_exp.hpp b/ipcl/include/ipcl/mod_exp.hpp index 0419e60..2c9fc04 100644 --- a/ipcl/include/ipcl/mod_exp.hpp +++ b/ipcl/include/ipcl/mod_exp.hpp @@ -9,8 +9,81 @@ #include "ipcl/bignum.h" namespace ipcl { + +/** + * Hybrid mode type + */ +enum class HybridMode { + OPTIMAL = 95, + QAT = 100, + PREF_QAT90 = 90, + PREF_QAT80 = 80, + PREF_QAT70 = 70, + PREF_QAT60 = 60, + HALF = 50, + PREF_IPP60 = 40, + PREF_IPP70 = 30, + PREF_IPP80 = 20, + PREF_IPP90 = 10, + IPP = 0, + UNDEFINED = -1 +}; + +/** + * Set hybrid mode + * @param[in] mode The type of hybrid mode + */ +void setHybridMode(HybridMode mode); + +/** + * Set the number of mod exp operatiions + * @param[in] Proportion calculated with QAT + * @param[in] rest_mode Whether reset the mode to UNDIFINED(default is true) + */ +void setHybridRatio(float qat_ratio, bool reset_mode = true); + +/** + * Turn off hybrid mod exp. + */ +void setHybridOff(); + +/** + * Get current hybrid qat ratio + */ +float getHybridRatio(); + +/** + * Get current hybrid mode + */ +HybridMode getHybridMode(); + +/** + * Check current hybrid mode is OPTIMAL + */ +bool isHybridOptimal(); + /** - * Modular exponentiation for multi buffer + * Modular exponentiation for multi BigNumber + * @param[in] base base of the exponentiation + * @param[in] exp pow of the exponentiation + * @param[in] mod modular + * @return the modular exponentiation result of type BigNumber + */ +std::vector modExp(const std::vector& base, + const std::vector& exp, + const std::vector& mod); +/** + * Modular exponentiation for single BigNumber + * @param[in] base base of the exponentiation + * @param[in] exp pow of the exponentiation + * @param[in] mod modular + * @return the modular exponentiation result of type BigNumber + */ +BigNumber modExp(const BigNumber& base, const BigNumber& exp, + const BigNumber& mod); + +/** + * IPP modular exponentiation for multi buffer * @param[in] base base of the exponentiation * @param[in] exp pow of the exponentiation * @param[in] mod modular @@ -21,7 +94,7 @@ std::vector ippModExp(const std::vector& base, const std::vector& mod); /** - * Modular exponentiation for single buffer + * IPP modular exponentiation for single buffer * @param[in] base base of the exponentiation * @param[in] exp pow of the exponentiation * @param[in] mod modular @@ -30,5 +103,16 @@ std::vector ippModExp(const std::vector& base, BigNumber ippModExp(const BigNumber& base, const BigNumber& exp, const BigNumber& mod); +/** + * QAT modular exponentiation for multi BigNumber + * @param[in] base base of the exponentiation + * @param[in] exp pow of the exponentiation + * @param[in] mod modular + * @return the modular exponentiation result of type BigNumber + */ +std::vector qatModExp(const std::vector& base, + const std::vector& exp, + const std::vector& mod); + } // namespace ipcl #endif // IPCL_INCLUDE_IPCL_MOD_EXP_HPP_ diff --git a/ipcl/include/ipcl/util.hpp b/ipcl/include/ipcl/util.hpp index 202e277..c2ea76a 100644 --- a/ipcl/include/ipcl/util.hpp +++ b/ipcl/include/ipcl/util.hpp @@ -4,9 +4,9 @@ #ifndef IPCL_INCLUDE_IPCL_UTIL_HPP_ #define IPCL_INCLUDE_IPCL_UTIL_HPP_ -#ifdef IPCL_RUNTIME_MOD_EXP +#ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES #include -#endif // IPCL_RUNTIME_MOD_EXP +#endif // IPCL_RUNTIME_DETECT_CPU_FEATURES #include #include @@ -71,13 +71,21 @@ class OMPUtilities { #endif // IPCL_USE_OMP -#ifdef IPCL_RUNTIME_MOD_EXP +#ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES static const bool disable_avx512ifma = (std::getenv("IPCL_DISABLE_AVX512IFMA") != nullptr); +static const bool prefer_rdrand = + (std::getenv("IPCL_PREFER_RDRAND") != nullptr); +static const bool prefer_ipp_prng = + (std::getenv("IPCL_PREFER_IPP_PRNG") != nullptr); static const cpu_features::X86Features features = cpu_features::GetX86Info().features; static const bool has_avx512ifma = features.avx512ifma && !disable_avx512ifma; -#endif // IPCL_RUNTIME_MOD_EXP +static const bool has_rdseed = + features.rdseed && !prefer_rdrand && !prefer_ipp_prng; +static const bool has_rdrand = features.rdrnd && prefer_rdrand; + +#endif // IPCL_RUNTIME_DETECT_CPU_FEATURES } // namespace ipcl diff --git a/ipcl/keygen.cpp b/ipcl/keygen.cpp index f2d712e..41301d0 100644 --- a/ipcl/keygen.cpp +++ b/ipcl/keygen.cpp @@ -17,7 +17,7 @@ BigNumber getPrimeBN(int max_bits) { ippsPrimeInit(max_bits, reinterpret_cast(prime_ctx.data())); #if defined(IPCL_RNG_INSTR_RDSEED) || defined(IPCL_RNG_INSTR_RDRAND) - bool rand_param = NULL; + Ipp8u* rand_param = NULL; #else auto buff = std::vector(prime_size); auto rand_param = buff.data(); diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index 1f885a4..0f82f9c 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -8,11 +8,318 @@ #include #include #include +#include //NOLINT + +#ifdef IPCL_USE_QAT +#include +#include +#endif #include "ipcl/util.hpp" namespace ipcl { +static thread_local struct { + float ratio; + HybridMode mode; +} g_hybrid_params = {0.0, HybridMode::OPTIMAL}; + +static inline float scale_down(int value, float scale = 100.0) { + return value / scale; +} + +static inline int scale_up(float value, int scale = 100) { + return value * scale; +} + +void setHybridRatio(float ratio, bool reset_mode) { +#ifdef IPCL_USE_QAT + ERROR_CHECK((ratio <= 1.0) && (ratio >= 0), + "setHybridRatio: Hybrid modexp qat ratio is NOT correct"); + g_hybrid_params.ratio = ratio; + if (reset_mode) g_hybrid_params.mode = HybridMode::UNDEFINED; +#endif // IPCL_USE_QAT +} + +void setHybridMode(HybridMode mode) { +#ifdef IPCL_USE_QAT + int mode_value = static_cast::type>(mode); + float ratio = scale_down(mode_value); + g_hybrid_params = {ratio, mode}; +#endif // IPCL_USE_QAT +} + +void setHybridOff() { +#ifdef IPCL_USE_QAT + g_hybrid_params = {0.0, HybridMode::UNDEFINED}; +#endif // IPCL_USE_QAT +} + +float getHybridRatio() { return g_hybrid_params.ratio; } + +HybridMode getHybridMode() { return g_hybrid_params.mode; } + +bool isHybridOptimal() { + return (g_hybrid_params.mode == HybridMode::OPTIMAL) ? true : false; +} + +#ifdef IPCL_USE_QAT +// Multiple input QAT ModExp interface to offload computation to QAT +static std::vector heQatBnModExp( + const std::vector& base, const std::vector& exponent, + const std::vector& modulus, unsigned int batch_size) { + static unsigned int counter = 0; + int nbits = modulus.front().BitSize(); + int length = BITSIZE_WORD(nbits) * 4; + nbits = 8 * length; + + // Check if QAT Exec Env supports requested batch size + unsigned int worksize = base.size(); + unsigned int nslices = worksize / batch_size; + unsigned int residue = worksize % batch_size; + + if (0 == nslices) { + nslices = 1; + residue = 0; + batch_size = worksize; + } + + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + // TODO(fdiasmor): Try replace calloc by alloca to see impact on performance. + unsigned char* bn_base_data_[batch_size]; + unsigned char* bn_exponent_data_[batch_size]; + unsigned char* bn_modulus_data_[batch_size]; + unsigned char* bn_remainder_data_[batch_size]; + +#if defined(IPCL_USE_QAT_LITE) + // int base_len_[batch_size]; + std::vector base_len_(batch_size, 0); + // int exp_len_[batch_size]; + std::vector exp_len_(batch_size, 0); +#endif + + // Pre-allocate memory used to batch input data + for (int i = 0; i < batch_size; i++) { +#if !defined(IPCL_USE_QAT_LITE) + bn_base_data_[i] = reinterpret_cast( + malloc(length * sizeof(unsigned char))); + bn_exponent_data_[i] = reinterpret_cast( + malloc(length * sizeof(unsigned char))); +#endif + + bn_modulus_data_[i] = reinterpret_cast( + malloc(length * sizeof(unsigned char))); + bn_remainder_data_[i] = reinterpret_cast( + malloc(length * sizeof(unsigned char))); + +#if !defined(IPCL_USE_QAT_LITE) + ERROR_CHECK( + bn_base_data_[i] != nullptr && bn_exponent_data_[i] != nullptr && + bn_modulus_data_[i] != nullptr && bn_remainder_data_[i] != nullptr, + "qatMultiBuffExp: alloc memory for error"); +#else + ERROR_CHECK( + bn_modulus_data_[i] != nullptr && bn_remainder_data_[i] != nullptr, + "qatMultiBuffExp: alloc memory for error"); +#endif + } // End preparing input containers + + // Container to hold total number of outputs to be returned + std::vector remainder(worksize, 0); + + for (unsigned int j = 0; j < nslices; j++) { + // Prepare batch of input data + for (unsigned int i = 0; i < batch_size; i++) { + bool ret = false; + +#if !defined(IPCL_USE_QAT_LITE) + memset(bn_base_data_[i], 0, length); + memset(bn_exponent_data_[i], 0, length); + memset(bn_modulus_data_[i], 0, length); + memset(bn_remainder_data_[i], 0, length); + + ret = + BigNumber::toBin(bn_base_data_[i], length, base[j * batch_size + i]); + if (!ret) { + printf("bn_base_data_: failed at bigNumberToBin()\n"); + exit(1); + } + + ret = BigNumber::toBin(bn_exponent_data_[i], length, + exponent[j * batch_size + i]); + if (!ret) { + printf("bn_exponent_data_: failed at bigNumberToBin()\n"); + exit(1); + } +#else + base_len_[i] = 0; + ret = BigNumber::toBin(&bn_base_data_[i], &base_len_[i], + base[j * batch_size + i]); + if (!ret) { + printf("bn_base_data_: failed at bigNumberToBin()\n"); + exit(1); + } + exp_len_[i] = 0; + ret = BigNumber::toBin(&bn_exponent_data_[i], &exp_len_[i], + exponent[j * batch_size + i]); + if (!ret) { + printf("bn_exponent_data_: failed at bigNumberToBin()\n"); + exit(1); + } +#endif + + ret = BigNumber::toBin(bn_modulus_data_[i], length, + modulus[j * batch_size + i]); + if (!ret) { + printf("bn_modulus_data_: failed at bigNumberToBin()\n"); + exit(1); + } + } // End input setup + + // Process batch of input + for (unsigned int i = 0; i < batch_size; i++) { +#if !defined(IPCL_USE_QAT_LITE) + // Assumes all inputs and the output have the same length + status = + HE_QAT_bnModExp(bn_remainder_data_[i], bn_base_data_[i], + bn_exponent_data_[i], bn_modulus_data_[i], nbits); +#else + // Base and exponent can be of variable length (for more or less) + status = HE_QAT_bnModExp_lite(bn_remainder_data_[i], bn_base_data_[i], + base_len_[i], bn_exponent_data_[i], + exp_len_[i], bn_modulus_data_[i], nbits); +#endif + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); + } + } + getBnModExpRequest(batch_size); + + // Collect results and pack them into BigNumber + for (unsigned int i = 0; i < batch_size; i++) { + bool ret = BigNumber::fromBin(remainder[j * batch_size + i], + bn_remainder_data_[i], length); + if (!ret) { + printf("bn_remainder_data_: failed at bignumbertobin()\n"); + exit(1); + } +#if defined(IPCL_USE_QAT_LITE) + free(bn_base_data_[i]); + bn_base_data_[i] = NULL; + free(bn_exponent_data_[i]); + bn_exponent_data_[i] = NULL; +#endif + } + } // Batch Process + + // Takes care of remaining + if (residue) { + for (unsigned int i = 0; i < residue; i++) { +#if !defined(IPCL_USE_QAT_LITE) + memset(bn_base_data_[i], 0, length); + memset(bn_exponent_data_[i], 0, length); +#endif + memset(bn_modulus_data_[i], 0, length); + memset(bn_remainder_data_[i], 0, length); + } + + for (unsigned int i = 0; i < residue; i++) { + bool ret = false; +#if !defined(IPCL_USE_QAT_LITE) + ret = BigNumber::toBin(bn_base_data_[i], length, + base[nslices * batch_size + i]); + if (!ret) { + printf("bn_base_data_: failed at bigNumberToBin()\n"); + exit(1); + } + ret = BigNumber::toBin(bn_exponent_data_[i], length, + exponent[nslices * batch_size + i]); + if (!ret) { + printf("bn_exponent_data_: failed at bigNumberToBin()\n"); + exit(1); + } +#else + base_len_[i] = 0; + ret = BigNumber::toBin(&bn_base_data_[i], &base_len_[i], + base[nslices * batch_size + i]); + if (!ret) { + printf("bn_base_data_: failed at bigNumberToBin()\n"); + exit(1); + } + exp_len_[i] = 0; + ret = BigNumber::toBin(&bn_exponent_data_[i], &exp_len_[i], + exponent[nslices * batch_size + i]); + if (!ret) { + printf("bn_exponent_data_: failed at bigNumberToBin()\n"); + exit(1); + } +#endif + + ret = BigNumber::toBin(bn_modulus_data_[i], length, + modulus[nslices * batch_size + i]); + if (!ret) { + printf("bn_modulus_data_: failed at bigNumberToBin()\n"); + exit(1); + } + } // + + for (unsigned int i = 0; i < residue; i++) { +#if !defined(IPCL_USE_QAT_LITE) + // Assumes all inputs and the output have the same length + status = + HE_QAT_bnModExp(bn_remainder_data_[i], bn_base_data_[i], + bn_exponent_data_[i], bn_modulus_data_[i], nbits); +#else + // Base and exponent can be of variable length (for more or less) + status = HE_QAT_bnModExp_lite(bn_remainder_data_[i], bn_base_data_[i], + base_len_[i], bn_exponent_data_[i], + exp_len_[i], bn_modulus_data_[i], nbits); +#endif + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); + } + } + getBnModExpRequest(residue); + + // Collect results and pack them into BigNumber + for (unsigned int i = 0; i < residue; i++) { + unsigned char* bn_remainder_ = bn_remainder_data_[i]; + bool ret = BigNumber::fromBin(remainder[nslices * batch_size + i], + bn_remainder_, length); + if (!ret) { + printf("residue bn_remainder_data_: failed at BigNumber::fromBin()\n"); + exit(1); + } +#if defined(IPCL_USE_QAT_LITE) + free(bn_base_data_[i]); + bn_base_data_[i] = NULL; + free(bn_exponent_data_[i]); + bn_exponent_data_[i] = NULL; +#endif + } + } + + for (unsigned int i = 0; i < batch_size; i++) { +#if !defined(IPCL_USE_QAT_LITE) + free(bn_base_data_[i]); + bn_base_data_[i] = NULL; + free(bn_exponent_data_[i]); + bn_exponent_data_[i] = NULL; +#endif + free(bn_modulus_data_[i]); + bn_modulus_data_[i] = NULL; + } + + for (unsigned int i = 0; i < batch_size; i++) { + free(bn_remainder_data_[i]); + bn_remainder_data_[i] = NULL; + } + + return remainder; +} +#endif // IPCL_USE_QAT + static std::vector ippMBModExp(const std::vector& base, const std::vector& exp, const std::vector& mod) { @@ -154,74 +461,21 @@ static BigNumber ippSBModExp(const BigNumber& base, const BigNumber& exp, return res; } -std::vector ippModExp(const std::vector& base, +std::vector qatModExp(const std::vector& base, const std::vector& exp, const std::vector& mod) { - std::size_t v_size = base.size(); - std::vector res(v_size); - -#ifdef IPCL_RUNTIME_MOD_EXP - - // If there is only 1 big number, we don't need to use MBModExp - if (v_size == 1) { - res[0] = ippSBModExp(base[0], exp[0], mod[0]); - return res; - } - - if (has_avx512ifma) { - std::size_t remainder = v_size % IPCL_CRYPTO_MB_SIZE; - std::size_t num_chunk = - (v_size + IPCL_CRYPTO_MB_SIZE - 1) / IPCL_CRYPTO_MB_SIZE; -#ifdef IPCL_USE_OMP - int omp_remaining_threads = OMPUtilities::MaxThreads; -#pragma omp parallel for num_threads( \ - OMPUtilities::assignOMPThreads(omp_remaining_threads, num_chunk)) -#endif // IPCL_USE_OMP - for (std::size_t i = 0; i < num_chunk; i++) { - std::size_t chunk_size = IPCL_CRYPTO_MB_SIZE; - if ((i == (num_chunk - 1)) && (remainder > 0)) chunk_size = remainder; - - std::size_t chunk_offset = i * IPCL_CRYPTO_MB_SIZE; - - auto base_start = base.begin() + chunk_offset; - auto base_end = base_start + chunk_size; - - auto exp_start = exp.begin() + chunk_offset; - auto exp_end = exp_start + chunk_size; - - auto mod_start = mod.begin() + chunk_offset; - auto mod_end = mod_start + chunk_size; - - auto base_chunk = std::vector(base_start, base_end); - auto exp_chunk = std::vector(exp_start, exp_end); - auto mod_chunk = std::vector(mod_start, mod_end); - - auto tmp = ippMBModExp(base_chunk, exp_chunk, mod_chunk); - std::copy(tmp.begin(), tmp.end(), res.begin() + chunk_offset); - } - - return res; - - } else { -#ifdef IPCL_USE_OMP - int omp_remaining_threads = OMPUtilities::MaxThreads; -#pragma omp parallel for num_threads( \ - OMPUtilities::assignOMPThreads(omp_remaining_threads, v_size)) -#endif // IPCL_USE_OMP - for (int i = 0; i < v_size; i++) - res[i] = ippSBModExp(base[i], exp[i], mod[i]); - return res; - } - +#ifdef IPCL_USE_QAT + return heQatBnModExp(base, exp, mod, IPCL_QAT_MODEXP_BATCH_SIZE); #else + ERROR_CHECK(false, "qatModExp: Need to turn on IPCL_ENABLE_QAT"); +#endif // IPCL_USE_QAT +} -#ifdef IPCL_CRYPTO_MB_MOD_EXP - - // If there is only 1 big number, we don't need to use MBModExp - if (v_size == 1) { - res[0] = ippSBModExp(base[0], exp[0], mod[0]); - return res; - } +static std::vector ippMBModExpWrapper( + const std::vector& base, const std::vector& exp, + const std::vector& mod) { + std::size_t v_size = base.size(); + std::vector res(v_size); std::size_t remainder = v_size % IPCL_CRYPTO_MB_SIZE; std::size_t num_chunk = @@ -256,8 +510,13 @@ std::vector ippModExp(const std::vector& base, } return res; +} -#else +static std::vector ippSBModExpWrapper( + const std::vector& base, const std::vector& exp, + const std::vector& mod) { + std::size_t v_size = base.size(); + std::vector res(v_size); #ifdef IPCL_USE_OMP int omp_remaining_threads = OMPUtilities::MaxThreads; @@ -266,15 +525,103 @@ std::vector ippModExp(const std::vector& base, #endif // IPCL_USE_OMP for (int i = 0; i < v_size; i++) res[i] = ippSBModExp(base[i], exp[i], mod[i]); + return res; +} + +std::vector ippModExp(const std::vector& base, + const std::vector& exp, + const std::vector& mod) { + std::size_t v_size = base.size(); + std::vector res(v_size); + + // If there is only 1 big number, we don't need to use MBModExp + if (v_size == 1) { + res[0] = ippSBModExp(base[0], exp[0], mod[0]); + return res; + } + +#ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES + if (has_avx512ifma) { + return ippMBModExpWrapper(base, exp, mod); + } else { + return ippSBModExpWrapper(base, exp, mod); + } +#elif IPCL_CRYPTO_MB_MOD_EXP + return ippMBModExpWrapper(base, exp, mod); +#else + return ippSBModExpWrapper(base, exp, mod); +#endif // IPCL_RUNTIME_DETECT_CPU_FEATURES +} + +std::vector modExp(const std::vector& base, + const std::vector& exp, + const std::vector& mod) { +#ifdef IPCL_USE_QAT +// if QAT is ON, OMP is OFF --> use QAT only +#if !defined(IPCL_USE_OMP) + return qatModExp(base, exp, mod); +#else + ERROR_CHECK(g_hybrid_params.ratio >= 0.0 && g_hybrid_params.ratio <= 1.0, + "modExp: hybrid modexp qat ratio is incorrect"); + std::size_t v_size = base.size(); + std::size_t hybrid_qat_size = + static_cast(g_hybrid_params.ratio * v_size); + + if (hybrid_qat_size == v_size) { + // use QAT only + return qatModExp(base, exp, mod); + } else if (hybrid_qat_size == 0) { + // use IPP only + return ippModExp(base, exp, mod); + } else { + // use QAT & IPP together + std::vector res(v_size); + + auto qat_base_start = base.begin(); + auto qat_base_end = qat_base_start + hybrid_qat_size; + + auto qat_exp_start = exp.begin(); + auto qat_exp_end = qat_exp_start + hybrid_qat_size; + + auto qat_mod_start = mod.begin(); + auto qat_mod_end = qat_mod_start + hybrid_qat_size; + + auto qat_base = std::vector(qat_base_start, qat_base_end); + auto qat_exp = std::vector(qat_exp_start, qat_exp_end); + auto qat_mod = std::vector(qat_mod_start, qat_mod_end); + + auto ipp_base = std::vector(qat_base_end, base.end()); + auto ipp_exp = std::vector(qat_exp_end, exp.end()); + auto ipp_mod = std::vector(qat_mod_end, mod.end()); -#endif // IPCL_CRYPTO_MB_MOD_EXP + std::vector qat_res, ipp_res; + std::thread qat_thread([&] { + qat_res = qatModExp(qat_base, qat_exp, qat_mod); + std::copy(qat_res.begin(), qat_res.end(), res.begin()); + }); + + ipp_res = ippModExp(ipp_base, ipp_exp, ipp_mod); + std::copy(ipp_res.begin(), ipp_res.end(), res.begin() + hybrid_qat_size); + + qat_thread.join(); + return res; + } +#endif // IPCL_USE_OMP +#else + return ippModExp(base, exp, mod); +#endif // IPCL_USE_QAT +} -#endif // IPCL_RUNTIME_MOD_EXP +BigNumber modExp(const BigNumber& base, const BigNumber& exp, + const BigNumber& mod) { + // QAT mod exp is NOT needed, when there is only 1 BigNumber. + return ippModExp(base, exp, mod); } BigNumber ippModExp(const BigNumber& base, const BigNumber& exp, const BigNumber& mod) { + // IPP multi buffer mod exp is NOT needed, when there is only 1 BigNumber. return ippSBModExp(base, exp, mod); } diff --git a/ipcl/pri_key.cpp b/ipcl/pri_key.cpp index 060e858..29201f6 100644 --- a/ipcl/pri_key.cpp +++ b/ipcl/pri_key.cpp @@ -43,8 +43,7 @@ PrivateKey::PrivateKey(const PublicKey* public_key, const BigNumber& p, m_lambda(lcm(m_pminusone, m_qminusone)), // TODO(bwang30): check if ippsModInv_BN does the same thing with // mpz_invert - m_x(m_n.InverseMul((ipcl::ippModExp(m_g, m_lambda, m_nsquare) - 1) / - m_n)), + m_x(m_n.InverseMul((modExp(m_g, m_lambda, m_nsquare) - 1) / m_n)), m_bits(m_pubkey->getBits()), m_dwords(m_pubkey->getDwords()), m_enable_crt(true) { @@ -63,6 +62,14 @@ PlainText PrivateKey::decrypt(const CipherText& ct) const { std::vector pt_bn(ct_size); std::vector ct_bn = ct.getTexts(); + // If hybrid OPTIMAL mode is used, use a special ratio + if (isHybridOptimal()) { + float qat_ratio = (ct_size <= IPCL_WORKLOAD_SIZE_THRESHOLD) + ? IPCL_HYBRID_MODEXP_RATIO_FULL + : IPCL_HYBRID_MODEXP_RATIO_DECRYPT; + setHybridRatio(qat_ratio, false); + } + if (m_enable_crt) decryptCRT(pt_bn, ct_bn); else @@ -77,7 +84,7 @@ void PrivateKey::decryptRAW(std::vector& plaintext, std::vector pow_lambda(v_size, m_lambda); std::vector modulo(v_size, m_nsquare); - std::vector res = ipcl::ippModExp(ciphertext, pow_lambda, modulo); + std::vector res = modExp(ciphertext, pow_lambda, modulo); #ifdef IPCL_USE_OMP int omp_remaining_threads = OMPUtilities::MaxThreads; @@ -112,8 +119,8 @@ void PrivateKey::decryptCRT(std::vector& plaintext, } // Based on the fact a^b mod n = (a mod n)^b mod n - std::vector resp = ipcl::ippModExp(basep, pm1, psq); - std::vector resq = ipcl::ippModExp(baseq, qm1, qsq); + std::vector resp = modExp(basep, pm1, psq); + std::vector resq = modExp(baseq, qm1, qsq); #ifdef IPCL_USE_OMP omp_remaining_threads = OMPUtilities::MaxThreads; @@ -143,7 +150,7 @@ BigNumber PrivateKey::computeHfun(const BigNumber& a, // Based on the fact a^b mod n = (a mod n)^b mod n BigNumber xm = a - 1; BigNumber base = m_g % b; - BigNumber pm = ipcl::ippModExp(base, xm, b); + BigNumber pm = modExp(base, xm, b); BigNumber lcrt = computeLfun(pm, a); return a.InverseMul(lcrt); } diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index 01f8124..abbbd64 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -48,7 +48,7 @@ void PublicKey::enableDJN() { BigNumber rmod_sq = rmod * rmod; BigNumber rmod_neg = rmod_sq * -1; BigNumber h = rmod_neg % m_n; - m_hs = ipcl::ippModExp(h, m_n, m_nsquare); + m_hs = modExp(h, m_n, m_nsquare); m_randbits = m_bits >> 1; // bits/2 m_enable_DJN = true; @@ -66,7 +66,7 @@ std::vector PublicKey::getDJNObfuscator(std::size_t sz) const { r_ = getRandomBN(m_randbits); } } - return ipcl::ippModExp(base, r, sq); + return modExp(base, r, sq); } std::vector PublicKey::getNormalObfuscator(std::size_t sz) const { @@ -82,7 +82,7 @@ std::vector PublicKey::getNormalObfuscator(std::size_t sz) const { r[i] = r[i] % (m_n - 1) + 1; } } - return ipcl::ippModExp(r, pown, sq); + return modExp(r, pown, sq); } void PublicKey::applyObfuscator(std::vector& ciphertext) const { @@ -121,6 +121,14 @@ CipherText PublicKey::encrypt(const PlainText& pt, bool make_secure) const { ERROR_CHECK(pt_size > 0, "encrypt: Cannot encrypt empty PlainText"); std::vector ct_bn_v(pt_size); + // If hybrid OPTIMAL mode is used, use a special ratio + if (isHybridOptimal()) { + float qat_ratio = (pt_size <= IPCL_WORKLOAD_SIZE_THRESHOLD) + ? IPCL_HYBRID_MODEXP_RATIO_FULL + : IPCL_HYBRID_MODEXP_RATIO_ENCRYPT; + setHybridRatio(qat_ratio, false); + } + ct_bn_v = raw_encrypt(pt.getTexts(), make_secure); return CipherText(this, ct_bn_v); } diff --git a/module/heqat.cmake b/module/heqat.cmake new file mode 100644 index 0000000..a26a272 --- /dev/null +++ b/module/heqat.cmake @@ -0,0 +1,71 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +include(ExternalProject) +MESSAGE(STATUS "Configuring HE QAT") +set(HEQAT_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_he_qat) +set(HEQAT_DESTDIR ${HEQAT_PREFIX}/heqat_install) +set(HEQAT_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/module/heqat) +set(HEQAT_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS}") + +set(HEQAT_BUILD_TYPE Release) +if (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") + set(HEQAT_BUILD_TYPE Debug) +endif() + +ExternalProject_Add( + ext_he_qat + SOURCE_DIR ${HEQAT_SRC_DIR} + PREFIX ${HEQAT_PREFIX} + CMAKE_ARGS ${HEQAT_CXX_FLAGS} + -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + -DHE_QAT_MISC=OFF + -DHE_QAT_DOCS=${IPCL_DOCS} + -DHE_QAT_SHARED=${IPCL_SHARED} + -DHE_QAT_TEST=OFF + -DCMAKE_BUILD_TYPE=${HEQAT_BUILD_TYPE} + UPDATE_COMMAND "" + EXCLUDE_FROM_ALL TRUE + INSTALL_COMMAND make DESTDIR=${HEQAT_DESTDIR} install +) +add_dependencies(ext_he_qat ext_ipp-crypto) + +set(HEQAT_INC_DIR ${HEQAT_DESTDIR}/${CMAKE_INSTALL_PREFIX}/include) +set(HEQAT_LIB_DIR ${HEQAT_DESTDIR}/${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) + +# Create heqat library interface +if(IPCL_SHARED) + add_library(he_qat INTERFACE) + add_dependencies(he_qat ext_he_qat) + + ExternalProject_Get_Property(ext_he_qat SOURCE_DIR BINARY_DIR) + + if(CMAKE_BUILD_TYPE STREQUAL "Debug") + target_link_libraries(he_qat INTERFACE ${HEQAT_LIB_DIR}/libhe_qat_debug.so) + else() + target_link_libraries(he_qat INTERFACE ${HEQAT_LIB_DIR}/libhe_qat.so) + endif() + target_include_directories(he_qat SYSTEM INTERFACE ${HEQAT_INC_DIR}) + + install( + DIRECTORY ${HEQAT_LIB_DIR}/ + DESTINATION "${IPCL_INSTALL_LIBDIR}/heqat" + USE_SOURCE_PERMISSIONS + PATTERN "cmake" EXCLUDE + ) +else() + add_library(he_qat STATIC IMPORTED GLOBAL) + add_dependencies(he_qat ext_he_qat) + + ExternalProject_Get_Property(ext_he_qat SOURCE_DIR BINARY_DIR) + + if (CMAKE_BUILD_TYPE STREQUAL "Debug") + set_target_properties(he_qat PROPERTIES + IMPORTED_LOCATION ${HEQAT_LIB_DIR}/libhe_qat_debug.a + INCLUDE_DIRECTORIES ${HEQAT_INC_DIR}) + else() + set_target_properties(he_qat PROPERTIES + IMPORTED_LOCATION ${HEQAT_LIB_DIR}/libhe_qat.a + INCLUDE_DIRECTORIES ${HEQAT_INC_DIR}) + endif() +endif() diff --git a/module/heqat/.clang-format b/module/heqat/.clang-format new file mode 100644 index 0000000..c16dae7 --- /dev/null +++ b/module/heqat/.clang-format @@ -0,0 +1,9 @@ +BasedOnStyle: Google +Language: Cpp +DerivePointerAlignment: false +PointerAlignment: Left +IndentWidth: 4 +AccessModifierOffset: -4 +IndentCaseLabels: false +SortIncludes: false +ColumnLimit: 80 diff --git a/module/heqat/.gitignore b/module/heqat/.gitignore new file mode 100644 index 0000000..0e2a8ef --- /dev/null +++ b/module/heqat/.gitignore @@ -0,0 +1,12 @@ +.vscode/ +.vs/ + + +build*/ +install + +cmake/he_qat-*.*.*/HE_QATConfig.cmake +*.log +Doxyfile + +**.swp diff --git a/module/heqat/CMakeLists.txt b/module/heqat/CMakeLists.txt new file mode 100644 index 0000000..cd0c123 --- /dev/null +++ b/module/heqat/CMakeLists.txt @@ -0,0 +1,209 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.13) + +# The hekat or heqat (transcribed HqA.t) was an ancient Egyptian volume unit +# used to measure grain, bread, and beer. +project(HE_QAT VERSION 1.3.2 LANGUAGES C CXX) + +include(CheckCCompilerFlag) +include(CheckCXXCompilerFlag) +include(CMakePackageConfigHelpers) +include(GNUInstallDirs) + +set(HE_QAT_STANDALONE ON) +if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) # built under IPCL + set(HE_QAT_STANDALONE OFF) +endif() + +if(HE_QAT_STANDALONE) + if(CMAKE_BUILD_TYPE) + set(RELEASE_TYPES + Debug + Release + RelWithDebInfo + MinSizeRel) + list(FIND RELEASE_TYPES ${CMAKE_BUILD_TYPE} INDEX_FOUND) + if(${INDEX_FOUND} EQUAL -1) + message( + FATAL_ERROR + "CMAKE_BUILD_TYPE must be one of Debug, Release, RelWithDebInfo, or MinSizeRel" + ) + endif() + else() + set(CMAKE_BUILD_TYPE Release) + endif() + + set(CMAKE_C_STANDARD 99) + set(CMAKE_C_STANDARD_REQUIRED ON) + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + + set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) + set(CMAKE_INSTALL_MESSAGE LAZY) + + set(CMAKE_C_FLAGS "-O2 -Wunused-variable -Wunused-function") + set(CMAKE_CXX_FLAGS "-O2 -Wunused-variable -Wunused-function -fpermissive") + if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_LIST_DIR}/install) + endif() +endif() + +set(CMAKE_INSTALL_RPATH "$ORIGIN;$ORIGIN/${CMAKE_INSTALL_LIBDIR}") +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) + +# ------------------------------------------------------------------- +if(HE_QAT_STANDALONE) # standalone + option(HE_QAT_MISC "Enable miscellaneous features" ON) + option(HE_QAT_SYNC "Enable synchronous mode execution" OFF) + option(HE_QAT_MT "Enable interfaces for multithreaded programs" ON) + option(HE_QAT_PERF "Show request performance" OFF) + option(HE_QAT_TEST "Enable testing" ON) + option(HE_QAT_OMP "Enable tests using OpenMP" ON) + option(HE_QAT_DOCS "Enable document building" ON) + option(HE_QAT_SHARED "Build shared library" ON) + + set(HE_QAT_FORWARD_CMAKE_ARGS + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -DCMAKE_C_STANDARD=${CMAKE_C_STANDARD} + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} + -DCMAKE_CXX_STANDARD_REQUIRED=${CMAKE_CXX_STANDARD_REQUIRED} + -DCMAKE_CXX_EXTENSIONS=${CMAKE_CXX_EXTENSIONS} + -DCMAKE_EXPORT_COMPILE_COMMANDS=${CMAKE_EXPORT_COMPILE_COMMANDS} + -DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE} + -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + ) +else() + option(HE_QAT_SYNC "Enable synchronous mode execution" OFF) + option(HE_QAT_MT "Enable interfaces for multithreaded programs" ON) + option(HE_QAT_PERF "Show request performance" OFF) + option(HE_QAT_OMP "Enable tests using OpenMP" ON) + set(HE_QAT_FORWARD_CMAKE_ARGS ${IPCL_FORWARD_CMAKE_ARGS}) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(HE_QAT_DEBUG ON) + add_definitions(-DHE_QAT_DEBUG) +else() + set(HE_QAT_DEBUG OFF) +endif() + +if(HE_QAT_STANDALONE) + message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") + message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}") + message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}") + message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") + message(STATUS "HE_QAT_MISC: ${HE_QAT_MISC}") + message(STATUS "HE_QAT_SYNC: ${HE_QAT_SYNC}") + message(STATUS "HE_QAT_MT: ${HE_QAT_MT}") + message(STATUS "HE_QAT_PERF: ${HE_QAT_PERF}") + message(STATUS "HE_QAT_TEST: ${HE_QAT_TEST}") + message(STATUS "HE_QAT_OMP: ${HE_QAT_OMP}") + message(STATUS "HE_QAT_DOCS: ${HE_QAT_DOCS}") + message(STATUS "HE_QAT_SHARED: ${HE_QAT_SHARED}") +endif() + +if(HE_QAT_MISC) + add_definitions(-DHE_QAT_MISC) +endif() + +# Why? +set(HE_QAT_CMAKE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/he_qat") +set(HE_QAT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(HE_QAT_SRC_DIR ${HE_QAT_ROOT_DIR}/heqat) +set(HE_QAT_INC_DIR ${HE_QAT_ROOT_DIR}/heqat/include) +if(NOT HE_QAT_STANDALONE) + set(HE_QAT_INC_DIR ${HE_QAT_INC_DIR} PARENT_SCOPE) +endif() +set(HE_QAT_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}) +set(HE_QAT_INSTALL_LIBDIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/heqat) + +if(HE_QAT_OMP) + find_package(OpenMP REQUIRED) + if(NOT TARGET OpenMP::OpenMP_CXX) + message(FATAL_ERROR "Missing OpenMP::OpenMP_CXX.") + endif() + if(NOT TARGET OpenMP::OpenMP_C) + message(FATAL_ERROR "Missing OpenMP::OpenMP_C.") + endif() +endif() + +if(HE_QAT_MT) + add_definitions(-DHE_QAT_MT) + message(STATUS "Compile with multithreaded interfaces.") +endif() + +if(HE_QAT_MISC) + if(HE_QAT_STANDALONE) + # IPP Crypto installation + if(IPPCP_PREFIX_PATH) + list(APPEND CMAKE_PREFIX_PATH "${IPPCP_PREFIX_PATH}") + set(IPPCP_DIR "${IPPCP_PREFIX_PATH}/../../../") + message(STATUS "IPPCP_DIR=${IPPCP_DIR}") + else() + # Default to this + set(IPPCP_DIR "/opt/ipp-crypto") + set(IPPCP_PREFIX_PATH "${IPPCP_DIR}/lib/cmake") + list(APPEND CMAKE_PREFIX_PATH "${IPPCP_PREFIX_PATH}") + message(STATUS "Else IPPCP_DIR=${IPPCP_DIR}") + endif() + find_package(IPPCP REQUIRED) + message(STATUS "IPPCP_LIBRARIES ${IPPCP_LIBRARIES}") + set(IPPCP_INC_DIR ${IPPCP_DIR}/../../../include) + set(IPPCP_LIB_DIR ${IPPCP_DIR}/lib/intel64) + else() + set(IPPCP_INC_DIR ${IPPCRYPTO_INC_DIR}/ippcrypto) + set(IPPCP_LIB_DIR ${IPPCRYPTO_LIB_DIR}) + endif() +endif() + +if(HE_QAT_SYNC) + add_definitions(-DHE_QAT_SYNC_MODE) +endif() + +if(HE_QAT_PERF) + add_definitions(-DHE_QAT_PERF) +endif() + +# OpenSSL installation +find_package(OpenSSL REQUIRED) + +# External dependencies +find_package(Threads REQUIRED) +set(CMAKE_THREAD_PREFER_PTHREAD ON) +set(THREADS_PREFER_PTHREAD_FLAG ON) + +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/he_qat) +include(heqat-util) + +if(NOT CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_LIST_DIR}/install) +endif() + +# Include QAT lib API support +include(cmake/qatconfig.cmake) + +# HE_QAT Library +add_subdirectory(heqat) + +#Validation test examples +if(HE_QAT_TEST) + add_subdirectory(test) +endif() + +if(HE_QAT_DOCS) + # sudo apt-get install doxygen + find_package(Doxygen) + option(BUILD_DOCS "Create and install the HTML based API docs (requires Doxygen)" ${DOXYGEN_FOUND}) + if(BUILD_DOCS) + if(NOT DOXYGEN_FOUND) + message(FATAL_ERROR "Doxygen was not found (Required)") + else() + add_subdirectory(doc) + endif() + endif() +endif() diff --git a/module/heqat/LICENSE b/module/heqat/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/module/heqat/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/module/heqat/README.md b/module/heqat/README.md new file mode 100644 index 0000000..4f22caa --- /dev/null +++ b/module/heqat/README.md @@ -0,0 +1,332 @@ +# Intel Homomorphic Encryption (HE) Acceleration Library for Quick Assist Technology (QAT) +Intel Homomorphic Encryption Acceleration Library for QAT (HE QAT Lib) is an open-source library which provides accelerated performance for homomorphic encryption (HE) math functions involving multi-precision numbers and modular arithmetic. This library is written in C99. + +## Contents +- [Intel Homomorphic Encryption (HE) Acceleration Library for Quick Assist Technology (QAT)](#intel-homomorphic-encryption-he-acceleration-library-for-quick-assist-technology-qat) + - [Contents](#contents) + - [Introduction](#introduction) + - [Building the HE QAT Library](#building-the-he-qat-library) + - [Requirements](#requirements) + - [Dependencies](#dependencies) + - [Instructions](#instructions) + - [Installing Dependencies](#installing-dependencies) + - [Installing OpenSSL](#installing-openssl) + - [Installing QAT Software Stack](#installing-qat-software-stack) + - [Setup Environment](#setup-environment) + - [Building the Library](#building-the-library) + - [Configuring QAT endpoints](#configuring-qat-endpoints) + - [Configuration Options](#configuration-options) + - [Running Samples](#running-samples) + - [Running All Samples](#running-all-samples) + - [Troubleshooting](#troubleshooting) + - [Testing and Benchmarking](#testing-and-benchmarking) +- [Contributors](#contributors) + +- [Contributors](#contributors) + +## Introduction + +This library currently only offers acceleration of modular exponentiation of multi-precision numbers, i.e. large numbers whose precision range from 1024 to 8192 bits. Current stage of implementation supports modular exponentiation of big numbers encoded with OpenSSL `BIGNUM` data type, `ippcrypto`'s `BigNumber` class and octet strings encoded with `unsigned char`. More details about the modes of operation and characteristics of the execution flow are described below: + + - Synchronous: API calls will submit requests that will be executed in the order they are first issued by the host caller, i.e. a series of modular exponentiation operation requests will be offloaded for processing by the accelerator in the order they are issued. + + - Asynchronous: API calls will submit requests that will NOT necessarily be executed in the order they are first issued by the host caller, i.e. a sequence of multiple requests for the modular exponentiation operation could be scheduled out of order and executed concurrently by the accelerator; thus, completed out of order. + + - Blocking: API calls will be blocked until work request processing completion. Internally, the next buffered work request waits for completion of the processing of the most recently offloaded request to the accelerator. + + - Non-Blocking: API calls will be non-blocking, it does not wait for completion of the work request to return from call. After multiple non-blocking calls to the API, a blocking function to wait for the requests to complete processing must be called. Internally, non-blocking request submissions are scheduled to the accelerator asynchronously. When there are multiple requests from concurrent API callers, the requests are not guaranteed to be processed in order of arrival. + + - Batch Support: The internal buffers are set accommodate up to 1024 requests at a time so that the maximum number of non-blocking API calls is 1024 for each concurrent thread caller. Therefore, only up to 1024 requests can be exercised asynchronously from the application side, be it from a single `for loop` or static code block. Finally, in order to collect the requests, a call to the `getBnModExpRequest()` function must be performed to wait for completion of all submitted asynchronous requests. On multithreaded mode, the blocking function to be called at the end of the code block shall be `release_bnModExp_buffer()`. + + - Multithreading Support: This feature permits the API to be called by concurrently threads running on the host. Effective multithreading support relies on a separate buffer that admits outstanding work requests. This buffer is acquired before an API call to submit work requests to the accelerator. This is accomplished by first calling `acquire_bnModExp_buffer()` to reserve an internal buffer to store outstanding requests from the host API caller. + + - Multiple Instances: The library accesses all logical instances from all visible and configured QAT endpoints at the creation of the QAT runtime context. Therefore, if 8 QAT endpoints are available, it will attempt to use them all, including all the total number of logical instances configured per process. + +>> _**Note**_: Current implementation does not verify if the instance/endpoint has the capabilities needed by the library. For example, the library needs access to the _asym_ capabilities like `CyLnModExp`, therefore if the configuration file of an endpoint happens to be configured to not offer it, the application will exit with an error at some point during execution. + +## Building the HE QAT Library + +### Requirements +The hardware requirement to use the library is the following: + - Intel 4xxx co-processor + + +As for the operating systems, the library has been tested and confirmed to work on Ubuntu 20.04 and CentOS 7.9. + +### Dependencies + +Required dependencies include: + +``` +cmake >=3.15.1 +git +yasm +libboost >= 1.14 +libudev >= 1.47 +pthread +OpenSSL >=1.1.0 +gcc >= 9.1 +QAT20.L.0.8.0-00071.tar.gz (qatlib and QAT drivers) +nasm >= 2.15 +ipp-crypto +``` + +### Instructions + +Before attempting to build the library, please check if the platform has the QAT hardware. + +``` +$ sudo lspci -d 8086:4940 +6b:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) +70:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) +75:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) +7a:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) +e8:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) +ed:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) +f2:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) +f7:00.0 Co-processor: Intel Corporation Device 4940 (rev 30) +``` + +In the example above, the platform is a dual-socket server with Sapphire Rapids (SPR) CPU and it shows 8 QAT endpoints, 4 on each socket. + +#### Installing Dependencies + +``` +sudo apt install yasm zlib1g +sudo apt update -y +sudo apt install -y libsystemd-dev +sudo apt install -y pciutils (tested with version=3.6.4) +sudo apt install -y libudev-dev +sudo apt install -y libreadline-dev +sudo apt install -y libxml2-dev +sudo apt install -y libboost-dev +sudo apt install -y elfutils libelf-dev +sudo apt install -y libnl-3-dev +sudo apt install -y linux-headers-$(uname -r) +sudo apt install -y build-essential +sudo apt install -y libboost-regex-dev +sudo apt install -y pkg-config +``` + +#### Installing OpenSSL + +``` +$ git clone https://github.com/openssl/openssl.git +$ cd openssl/ +$ git checkout OpenSSL_1_1_1-stable +$ ./Configure --prefix=/opt/openssl +$ make +$ sudo make install +``` + +#### Installing QAT Software Stack + +``` +$ cd $HOME +$ mkdir QAT +$ mv QAT20.L.0.8.0-00071.tar.gz QAT/ +$ cd QAT +$ tar zxvf QAT20.L.0.8.0-00071.tar.gz +$ ./configure +$ sudo make -j +$ sudo make install +``` + +Add `$USER` to the `qat` group. Must logout and log back in to take effect. + +``` +$ sudo usermod -aG qat $USER +``` + +> _**Note**_: Please contact the QAT team listed at [https://01.org/intel-quickassist-technology](https://01.org/intel-quickassist-technology) to obtain the latest `QAT20.L.0.8.0-00071.tar.gz` package. + +Verify the QAT installation by checking the QAT service status: + + - Ubuntu +``` +sudo service qat_service status +``` + - CentOS +``` +sudo systemctl status qat_service.service +``` + +If all checks out, following the instructions below to build the HE QAT library. + +#### Setup Environment + +This step is required. Note that if the step [Installing QAT Software Stack](#installing-qat-software-stack) has just been performed, then the exact path of the installation is known, i.e. + +``` +export ICP_ROOT=$HOME/QAT +``` + +Alternatively, if the system has a pre-built QAT software stack installed, the script `auto_find_qat_install.sh` can used to help automatically find the path where it was installed (see command below). The script `auto_find_qat_install.sh` assumes that the QAT package is installed in a single location, such that if multiple installations are available at different locations, the script may produce undetermined behavior. + + - Explicit way: +``` +export ICP_ROOT=$(./auto_find_qat_install.sh) +``` + - Implicit way: +``` +source setup_env.sh +``` + +#### Building the Library + +Follow the steps in the sections [Installing QAT Software Stack](#installing-qat-software-stack) and [Setup Environment](#setup-environment) before attempting to build the library. + +- How to build without `BigNumber` support + +``` +$ git clone https://github.com/intel-sandbox/libraries.security.cryptography.homomorphic-encryption.glade.project-destiny.git +$ git checkout development +$ cmake -S . -B build -DHE_QAT_MISC=OFF +$ cmake --build build +$ cmake --install build +``` + +- How to build with `BigNumber` support + +The `cmake` configuration variable `HE_QAT_MISC=ON` enables `BigNumber` resources and samples, requiring IPP Crypto installation as a dependency. If usage of the utility functions that support `BigNumber` data type is needed, follow the building instructions below to install IPP Crypto and then rebuild the library with the cmake flag `HE_QAT_MISC=ON`: + +- Installing `nasm-2.15` + +``` +$ wget -c https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.xz +$ tar -xf nasm-2.15.05.tar.xz +$ cd nasm-2.15.05/ +$ ./configure --prefix=/opt/nasm-2.15 +$ make -j +$ sudo make install +``` + +- Installing `ippcrypto` + +``` +$ cd ~ +$ git clone https://github.com/intel/ipp-crypto.git +$ cd ipp-crypto +$ CC=gcc CXX=g++ cmake CMakeLists.txt -B_build -DARCH=intel64 -DMERGED_BLD:BOOL=ON -DCMAKE_INSTALL_PREFIX=/opt/ipp-crypto -DOPENSSL_INCLUDE_DIR=/opt/openssl/include -DOPENSSL_LIBRARIES=/opt/openssl/lib -DOPENSSL_ROOT_DIR=/opt/openssl -DCMAKE_ASM_NASM_COMPILER=/opt/nasm-2.15/bin/nasm +$ cmake --build _build -j +$ sudo cmake --install _build +``` + +#### Configuring QAT endpoints + +Before trying to run any application or example that uses the HE QAT Lib, the QAT endpoints must be configured. +The default configuration provided in this release is the optimal configuration to provide computing acceleration support for [IPCL](https://github.com/intel/pailliercryptolib). +The boilerplate configurations can be found in the `config` directory. + +``` +./scripts/setup_devices.sh +``` + +The script above will configure the QAT devices to perform asymmetric functions only. + +#### Configuration Options + +In addition to the standard CMake configuration options, Intel HE Acceleration Library for QAT supports several cmake options to configure the build. For convenience, they are listed below: + +| CMake option | Values | Description | +| ------------------------------| ---------------------- | ------------------------------------------------------- | +| HE_QAT_MISC | ON / OFF (default OFF) | Enable/Disable BigNumber conversion functions. | +| HE_QAT_DEBUG | ON / OFF (default OFF) | Enable/Disable debug log at large runtime penalty. | +| HE_QAT_SAMPLES | ON / OFF (default ON) | Enable/Disable building of samples. | +| HE_QAT_DOCS | ON / OFF (default ON) | Enable/Disable building of documentation. | +| HE_QAT_SYNC | ON / OFF (default OFF) | Enable/Disable synchronous mode execution. | +| HE_QAT_MT | ON / OFF (default ON) | Enable/Disable interfaces for multithreaded programs. | +| HE_QAT_PERF | ON / OFF (default OFF) | Enable/Disable display of measured request performance. | +| HE_QAT_TEST | ON / OFF (default OFF) | Enable/Disable testing. | +| HE_QAT_OMP | ON / OFF (default ON) | Enable/Disable tests using OpenMP. | +| HE_QAT_SHARED | ON / OFF (default ON) | Enable/Disable building shared library. | + +#### Running Samples + +Test showing creation and teardown of the QAT runtime environment: + +``` +./build/samples/sample_context +``` + +Test showing functional correctness and performance using BIGNUM data as input: + +``` +./build/samples/sample_BIGNUMModExp +``` + +If built with `HE_QAT_MISC=ON`, then the following samples below are also available to try. + +Test showing data conversion between `BigNumber` and `CpaFlatBuffer` formats: + +``` +./build/samples/sample_bnConversion +``` + +Test showing functional correctness and performance using `BigNumber` data types: + +``` +./build/samples/sample_bnModExp +``` + +Test showing functional correctness and performance of multithreading support: + +``` +./build/samples/sample_bnModExp_MT +``` +#### Running All Samples + +``` +HEQATLIB_ROOT_DIR=$PWD ./scripts/run.sh +``` + +## Troubleshooting + +- **Issue #1** + +``` +xuser@ubuntu-guest:~/heqat$ cmake -S . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHE_QAT_MISC=ON +-- CMAKE_INSTALL_PREFIX: /usr/local +-- CMAKE_PREFIX_PATH /home/xuser/ipp-crypto/_build/ +-- Missed required Intel IPP Cryptography component: ippcp +-- library not found: + /opt/ipp-crypto/lib/intel64/libippcp.a +CMake Error at CMakeLists.txt:93 (find_package): + Found package configuration file: + + /opt/ipp-crypto/lib/cmake/ippcp/ippcp-config.cmake + + but it set IPPCP_FOUND to FALSE so package "IPPCP" is considered to be NOT + FOUND. +``` + +To resolve the error below simply create the symbolic link `/opt/ipp-crypto/lib/intel64/libippcp.a` from the appropriate static ippcp library that was compiled. For example: + +``` +xuser@ubuntu-guest:/opt/ipp-crypto/lib/intel64$ ls -lha +total 7.3M +drwxr-xr-x 2 root root 4.0K Jun 3 16:29 . +drwxr-xr-x 5 root root 4.0K Jun 3 16:29 .. +-rw-r--r-- 1 root root 1.6M Jun 3 16:28 libcrypto_mb.a +lrwxrwxrwx 1 root root 18 Jun 3 16:29 libcrypto_mb.so -> libcrypto_mb.so.11 +lrwxrwxrwx 1 root root 20 Jun 3 16:29 libcrypto_mb.so.11 -> libcrypto_mb.so.11.5 +-rw-r--r-- 1 root root 1.3M Jun 3 16:28 libcrypto_mb.so.11.5 +lrwxrwxrwx 1 root root 16 Jun 3 16:29 libippcpmx.so -> libippcpmx.so.11 +lrwxrwxrwx 1 root root 18 Jun 3 16:29 libippcpmx.so.11 -> libippcpmx.so.11.5 +-rw-r--r-- 1 root root 1.7M Jun 3 16:28 libippcpmx.so.11.5 +-rw-r--r-- 1 root root 2.9M Jun 3 16:28 libippcp_s_mx.a +xuser@ubuntu-guest:/opt/ipp-crypto/lib/intel64$ sudo ln -s libippcp_s_mx.a libippcp.a +``` + +## Testing and Benchmarking + +TODO + +# Contributors + +Main contributors to this project, sorted by alphabetical order of last name are: + - [Fillipe Dias M. de Souza](https://www.linkedin.com/in/fillipe-d-m-de-souza-a8281820) (lead) + - [Xiaoran Fang](https://github.com/fangxiaoran) + - [Jingyi Jin](https://www.linkedin.com/in/jingyi-jin-655735) + - [Sejun Kim](https://www.linkedin.com/in/sejun-kim-2b1b4866) + - [Pengfei Zhao](https://github.com/justalittlenoob) diff --git a/module/heqat/cmake/he_qat/HE_QATConfig.cmake.in b/module/heqat/cmake/he_qat/HE_QATConfig.cmake.in new file mode 100644 index 0000000..5267fd1 --- /dev/null +++ b/module/heqat/cmake/he_qat/HE_QATConfig.cmake.in @@ -0,0 +1,22 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) + +include(${CMAKE_CURRENT_LIST_DIR}/he_qatTargets.cmake) + +if(TARGET HE_QAT::he_qat) + set(HE_QAT_FOUND TRUE) + message(STATUS "Intel Homomorphic Encryption Acceleration Library for QAT found") +else() + message(STATUS "Intel Homomorphic Encryption Acceleraiton Library for QAT not found") +endif() + +set(HE_QAT_VERSION "@HE_QAT_VERSION") +set(HE_QAT_VERSION_MAJOR "@HE_QAT_VERSION_MAJOR") +set(HE_QAT_VERSION_MINOR "@HE_QAT_VERSION") +set(HE_QAT_VERSION_PATCH "@HE_QAT_VERSION") + +set(HE_QAT_DEBUG "@HE_QAT_DEBUG") diff --git a/module/heqat/cmake/he_qat/heqat-util.cmake b/module/heqat/cmake/he_qat/heqat-util.cmake new file mode 100644 index 0000000..8034239 --- /dev/null +++ b/module/heqat/cmake/he_qat/heqat-util.cmake @@ -0,0 +1,31 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Add dependency to the target archive +function(heqat_create_archive target dependency) + # For proper export of IPCLConfig.cmake / IPCLTargets.cmake, + # we avoid explicitly linking dependencies via target_link_libraries, since + # this would add dependencies to the exported ipcl target. + add_dependencies(${target} ${dependency}) + + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + add_custom_command(TARGET ${target} POST_BUILD + COMMAND ar -x $ + COMMAND ar -x $ + COMMAND ar -qcs $ *.o + COMMAND rm -f *.o + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${target} ${dependency} + ) + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + add_custom_command(TARGET ${target} POST_BUILD + COMMAND lib.exe /OUT:$ + $ + $ + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${target} ${dependency} + ) + else() + message(WARNING "Unsupported compiler ${CMAKE_CXX_COMPILER_ID}") + endif() +endfunction() diff --git a/module/heqat/cmake/qatconfig.cmake b/module/heqat/cmake/qatconfig.cmake new file mode 100644 index 0000000..da52322 --- /dev/null +++ b/module/heqat/cmake/qatconfig.cmake @@ -0,0 +1,50 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Setup ICP variables +if(DEFINED ENV{ICP_ROOT}) + message(STATUS "Environment variable ICP_ROOT is defined as $ENV{ICP_ROOT}.") +else() + message(FATAL_ERROR "Environment variable ICP_ROOT must be defined. Try export ICP_ROOT=") +endif() + +set(ICP_ROOT $ENV{ICP_ROOT}) +set(ICP_BUILDOUTPUT_PATH ${ICP_ROOT}/build) +set(ICP_BUILDSYSTEM_PATH ${ICP_ROOT}/quickassist/build_system) +set(ICP_API_DIR ${ICP_ROOT}/quickassist) +set(ICP_LAC_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer) +set(ICP_OSAL_DIR ${ICP_ROOT}/quickassist/utilities/oasl) +set(ICP_ADF_DIR ${ICP_ROOT}/quickassist/lookaside/access_layer/src/qat_direct) +set(CMN_ROOT ${ICP_ROOT}/quickassist/utilities/libusdm_drv) + +set(ICP_INC_DIR ${ICP_API_DIR}/include + ${ICP_LAC_DIR}/include + ${ICP_ADF_DIR}/include + ${CMN_ROOT} + ${ICP_API_DIR}/include/dc + ${ICP_API_DIR}/include/lac) + +#add_definitions(-DDO_CRYPTO) +add_definitions(-DUSER_SPACE) +add_compile_options(-fPIC) + +add_library(libadf_static STATIC IMPORTED GLOBAL) +add_library(libosal_static STATIC IMPORTED GLOBAL) +add_library(libqat_static STATIC IMPORTED GLOBAL) +add_library(libusdm_drv_static STATIC IMPORTED GLOBAL) + +set_target_properties(libadf_static PROPERTIES + IMPORTED_LOCATION ${ICP_BUILDOUTPUT_PATH}/libadf.a +) + +set_target_properties(libosal_static PROPERTIES + IMPORTED_LOCATION ${ICP_BUILDOUTPUT_PATH}/libosal.a +) + +set_target_properties(libqat_static PROPERTIES + IMPORTED_LOCATION ${ICP_BUILDOUTPUT_PATH}/libqat.a +) + +set_target_properties(libusdm_drv_static PROPERTIES + IMPORTED_LOCATION ${ICP_BUILDOUTPUT_PATH}/libusdm_drv.a +) diff --git a/module/heqat/config/4xxx_dev0.conf b/module/heqat/config/4xxx_dev0.conf new file mode 100755 index 0000000..fcaa5f2 --- /dev/null +++ b/module/heqat/config/4xxx_dev0.conf @@ -0,0 +1,182 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default value for FW Auth loading +FirmwareAuthEnabled = 1 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 64 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Default value for power management idle interrupt delay +PmIdleInterruptDelay = 0 + +# This flag is to enable power management idle support +PmIdleSupport = 1 + +# This flag is to enable key protection technology +KptEnabled = 1 + +# Define the maximum SWK count per function can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerFn = 1 + +# Define the maximum SWK count per pasid can have +# Default value is 1, the maximum value is 128 +KptMaxSWKPerPASID = 1 + +# Define the maximum SWK lifetime in second +# Default value is 0 (eternal of life) +# The maximum value is 31536000 (one year) +KptMaxSWKLifetime = 31536000 + +# Flag to define whether to allow SWK to be shared among processes +# Default value is 0 (shared mode is off) +KptSWKShared = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 1 +NumberDcInstances = 0 + +# Crypto - Kernel instance #0 +Cy0Name = "IPSec0" +Cy0IsPolled = 0 +Cy0CoreAffinity = 0 + +# Data Compression - Kernel instance #0 +Dc0Name = "IPComp0" +Dc0IsPolled = 0 +Dc0CoreAffinity = 0 + +############################################## +# ADI Section for Scalable IOV +############################################## +[SIOV] +NumberAdis = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 1 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 1 + +## Crypto - User instance #1 +#Cy1Name = "SSL1" +#Cy1IsPolled = 1 +## List of core affinities +#Cy1CoreAffinity = 2 +# +## Crypto - User instance #2 +#Cy2Name = "SSL2" +#Cy2IsPolled = 1 +## List of core affinities +#Cy2CoreAffinity = 3 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/module/heqat/config/4xxxvf_dev0.conf b/module/heqat/config/4xxxvf_dev0.conf new file mode 100755 index 0000000..a633579 --- /dev/null +++ b/module/heqat/config/4xxxvf_dev0.conf @@ -0,0 +1,133 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2021 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT20.L.0.8.0-00071 +################################################################ +[GENERAL] +ServicesEnabled = asym;dc + +ConfigVersion = 2 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 64 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable SSF features (CNV and BnP) +StorageEnabled = 0 + +# Disable public key crypto and prime number +# services by specifying a value of 1 (default is 0) +PkeServiceDisabled = 0 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +# Disable Address translation services +ATEnabled = 0 +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 0 +NumberDcInstances = 0 + +############################################## +# User Process Instance Section +############################################## +[SSL] +NumberCyInstances = 1 +NumberDcInstances = 2 +NumProcesses = 1 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "SSL0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 1 + +## Crypto - User instance #1 +#Cy1Name = "SSL1" +#Cy1IsPolled = 1 +## List of core affinities +#Cy1CoreAffinity = 2 + +# Data Compression - User instance #0 +Dc0Name = "Dc0" +Dc0IsPolled = 1 +# List of core affinities +Dc0CoreAffinity = 1 + +# Data Compression - User instance #1 +Dc1Name = "Dc1" +Dc1IsPolled = 1 +# List of core affinities +Dc1CoreAffinity = 2 diff --git a/module/heqat/doc/CMakeLists.txt b/module/heqat/doc/CMakeLists.txt new file mode 100644 index 0000000..822e556 --- /dev/null +++ b/module/heqat/doc/CMakeLists.txt @@ -0,0 +1,25 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Build Doxygen documentation +SET(DOXYGEN_MIN_VERSION "1.8.5") +find_package(Doxygen ${DOXYGEN_MIN_VERSION} REQUIRED) + +set(DOXYGEN_OUTPUT_DIR ${CMAKE_BINARY_DIR}/doxygen) +set(DOXYGEN_INDEX_FILE ${DOXYGEN_OUTPUT_DIR}/xml/indexl.html) +set(DOXYFILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in) +set(DOXYFILE_OUT ${CMAKE_BINARY_DIR}/Doxyfile) + +# Create Doxyfile +configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY) + +add_custom_command(OUTPUT ${DOXYGEN_INDEX_FILE} + COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE_OUT} + MAIN_DEPENDENCY ${DOXYFILE_OUT} ${DOXYFILE_IN} + COMMENT "Generating Doxygen documentation") + +add_custom_target(docs ALL DEPENDS ${DOXYGEN_INDEX_FILE}) + +install(DIRECTORY + ${CMAKE_BINARY_DIR}/doc/doxygen + DESTINATION doc) diff --git a/module/heqat/doc/Doxyfile.in b/module/heqat/doc/Doxyfile.in new file mode 100644 index 0000000..be375b4 --- /dev/null +++ b/module/heqat/doc/Doxyfile.in @@ -0,0 +1,36 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +PROJECT_NAME = "Intel HE Acceleration Library for QAT" +PROJECT_BRIEF = "Intel Homomorphic Encryption Acceleration Library for QAT, accelerating the modular arithmetic operations used in partial homomorphic encryption on Intel QAT." + +OUTPUT_DIRECTORY = @CMAKE_BINARY_DIR@/doc/doxygen +INPUT = @CMAKE_SOURCE_DIR@/heqat/include/heqat \ + @CMAKE_SOURCE_DIR@/heqat/include/heqat/common \ + @CMAKE_SOURCE_DIR@/heqat/include/heqat/misc \ + @CMAKE_SOURCE_DIR@/heqat \ + @CMAKE_SOURCE_DIR@/heqat/misc \ + @CMAKE_SOURCE_DIR@/heqat/common \ + @CMAKE_SOURCE_DIR@/samples \ + @CMAKE_SOURCE_DIR@/README.md +RECURSIVE = YES +USE_MDFILE_AS_MAINPAGE = @CMAKE_SOURCE_DIR@/README.md +USE_MATHJAX = YES +FULL_PATH_NAMES = NO + +GENERATE_XML = YES +EXTRACT_ALL = YES +EXTRACT_PRIVATE = NO +SHOW_NAMESPACES = YES +GENERATE_LATEX = YES + +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = YES +WARN_AS_ERROR = YES + +QUIET = NO + +SEARCHENGINE = YES +SERVER_BASED_SEARCH = NO diff --git a/module/heqat/doc/index.html b/module/heqat/doc/index.html new file mode 100644 index 0000000..c344624 --- /dev/null +++ b/module/heqat/doc/index.html @@ -0,0 +1,2 @@ + + diff --git a/module/heqat/doc/index.rst b/module/heqat/doc/index.rst new file mode 100644 index 0000000..860a83a --- /dev/null +++ b/module/heqat/doc/index.rst @@ -0,0 +1,5 @@ +## Intel HE Acceleration Library for QAT Documentation ## +.. toctree:: + api + +.. mdinclude:: ../README.md diff --git a/module/heqat/example/CMakeLists.txt b/module/heqat/example/CMakeLists.txt new file mode 100644 index 0000000..11f2aab --- /dev/null +++ b/module/heqat/example/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +project(he_qat_example LANGUAGES C CXX) + +cmake_minimum_required(VERSION 3.13) + +set(CMAKE_CXX_STANDARD 11) +set(HE_QAT_HINT_DIR ${CMAKE_PREFIX_PATH}) +message(STATUS "CMAKE_PREFIX_PATH ${HE_QAT_HINT_DIR}") + +# Example using source +find_package(HE_QAT 1.3.2 + HINTS ${HE_QAT_HINT_DIR} + REQUIRED) +if(NOT TARGET HE_QAT::he_qat) + message(FATAL_ERROR "TARGET HE_QAT::he_qat not found") +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + add_definitions(-DHE_QAT_DEBUG) +endif() + +find_package(OpenSSL REQUIRED) +find_package(Threads REQUIRED) +set(CMAKE_THREAD_PREFER_PTHREAD ON) +set(THREADS_PREFER_PTHREAD_FLAG ON) + +add_definitions(-fpermissive) +add_executable(example example.cpp) +target_link_libraries(example PRIVATE HE_QAT::he_qat) +target_link_libraries(example PRIVATE OpenSSL::SSL) diff --git a/module/heqat/example/README.md b/module/heqat/example/README.md new file mode 100644 index 0000000..9bd68d2 --- /dev/null +++ b/module/heqat/example/README.md @@ -0,0 +1,7 @@ +# Building and running + +``` +cmake -S . -B build -DCMAKE_PREFIX_PATH=../install/lib/cmake +cmake --build build +./build/example +``` diff --git a/module/heqat/example/example.cpp b/module/heqat/example/example.cpp new file mode 100644 index 0000000..b3460b0 --- /dev/null +++ b/module/heqat/example/example.cpp @@ -0,0 +1,139 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include + +#include "heqat/heqat.h" + +#define LEN_OF_1024_BITS 128 +#define LEN_OF_2048_BITS 256 +#define msb_CAN_BE_ZERO -1 +#define msb_IS_ONE 0 +#define EVEN_RND_NUM 0 +#define ODD_RND_NUM 1 +#define BATCH_SIZE 1 + +struct timeval start_time, end_time; +double time_taken = 0.0; + +int main(int argc, const char** argv) { + const int bit_length = 4096; // 1024; + const size_t num_trials = 100; + + double avg_speed_up = 0.0; + double ssl_avg_time = 0.0; + double qat_avg_time = 0.0; + + double ssl_elapsed = 0.0; + double qat_elapsed = 0.0; + + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + // Set up QAT runtime context + acquire_qat_devices(); + + // Set up OpenSSL context (as baseline) + BN_CTX* ctx = BN_CTX_new(); + BN_CTX_start(ctx); + + for (size_t mod = 0; mod < num_trials; mod++) { + BIGNUM* bn_mod = generateTestBNData(bit_length); + + if (!bn_mod) continue; + +#ifdef HE_QAT_DEBUG + char* bn_str = BN_bn2hex(bn_mod); + HE_QAT_PRINT("Generated modulus: %s num_bytes: %d num_bits: %d\n", + bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); + OPENSSL_free(bn_str); +#endif + // bn_exponent in [0..bn_mod] + BIGNUM* bn_exponent = BN_new(); + if (!BN_rand_range(bn_exponent, bn_mod)) { + BN_free(bn_mod); + continue; + } + + BIGNUM* bn_base = generateTestBNData(bit_length); + + // Perform OpenSSL ModExp Op + BIGNUM* ssl_res = BN_new(); + gettimeofday(&start_time, NULL); + BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); + gettimeofday(&end_time, NULL); + time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; + time_taken = + (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; + ssl_elapsed = time_taken; + + if (!ERR_get_error()) { +#ifdef HE_QAT_DEBUG + bn_str = BN_bn2hex(ssl_res); + HE_QAT_PRINT("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", + bn_str, BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); + showHexBN(ssl_res, bit_length); + OPENSSL_free(bn_str); +#endif + } else { + HE_QAT_PRINT_ERR("Modular exponentiation failed.\n"); + exit(1); + } + + HE_QAT_PRINT_DBG("\nStarting QAT bnModExp...\n"); + + // Perform QAT ModExp Op + BIGNUM* qat_res = BN_new(); + gettimeofday(&start_time, NULL); + for (unsigned int j = 0; j < BATCH_SIZE; j++) + status = HE_QAT_BIGNUMModExp(qat_res, bn_base, bn_exponent, bn_mod, + bit_length); + getBnModExpRequest(BATCH_SIZE); + gettimeofday(&end_time, NULL); + time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; + time_taken = + (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; + qat_elapsed = time_taken; + + ssl_avg_time = (mod * ssl_avg_time + ssl_elapsed) / (mod + 1); + qat_avg_time = + (mod * qat_avg_time + qat_elapsed / BATCH_SIZE) / (mod + 1); + avg_speed_up = + (mod * avg_speed_up + (ssl_elapsed) / (qat_elapsed / BATCH_SIZE)) / + (mod + 1); + + HE_QAT_PRINT( + "Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", + (mod + 1), ssl_avg_time, qat_avg_time, avg_speed_up); + + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("\nQAT bnModExpOp failed\n"); + exit(1); + } + + if (BN_cmp(qat_res, ssl_res) != 0) + HE_QAT_PRINT("\t** FAIL **\n"); + else + HE_QAT_PRINT("\t** PASS **\n"); + + HE_QAT_PRINT_DBG("\nQAT bnModExpOp finished\n"); + + BN_free(ssl_res); + BN_free(qat_res); + + BN_free(bn_mod); + BN_free(bn_base); + BN_free(bn_exponent); + } + + // Tear down OpenSSL context + BN_CTX_end(ctx); + + // Tear down QAT runtime context + release_qat_devices(); + + return static_cast(status); +} diff --git a/module/heqat/heqat/CMakeLists.txt b/module/heqat/heqat/CMakeLists.txt new file mode 100644 index 0000000..d05886a --- /dev/null +++ b/module/heqat/heqat/CMakeLists.txt @@ -0,0 +1,117 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# HE QAT Lib source code +set(HE_QAT_SRC ${HE_QAT_SRC_DIR}/cb.c + ${HE_QAT_SRC_DIR}/context.c + ${HE_QAT_SRC_DIR}/ctrl.c + ${HE_QAT_SRC_DIR}/bnops.c + ${HE_QAT_SRC_DIR}/common/utils.c +) + +# Helper functions for ippcrypto's BigNumber class +if(HE_QAT_MISC) + list(APPEND HE_QAT_SRC ${HE_QAT_SRC_DIR}/misc/misc.cpp + ${HE_QAT_SRC_DIR}/misc/utils.cpp + ${HE_QAT_SRC_DIR}/misc/bignum.cpp +) +endif() + +if(HE_QAT_SHARED) + add_library(he_qat SHARED ${HE_QAT_SRC}) +else() + add_library(he_qat STATIC ${HE_QAT_SRC}) +endif() + +add_library(HE_QAT::he_qat ALIAS he_qat) + +target_include_directories(he_qat + PUBLIC $ #Public headers + PUBLIC $ #Public headers + PUBLIC ${ICP_INC_DIR} +) + +install(DIRECTORY ${HE_QAT_INC_DIR}/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING + PATTERN "*.hpp" + PATTERN "*.h") + +target_link_directories(he_qat PUBLIC ${ICP_BUILDOUTPUT_PATH}) + +target_link_libraries(he_qat PRIVATE udev z) +target_link_libraries(he_qat PRIVATE OpenSSL::SSL) +target_link_libraries(he_qat PRIVATE Threads::Threads) +if(HE_QAT_SHARED) + target_link_libraries(he_qat PRIVATE qat_s) + target_link_libraries(he_qat PRIVATE usdm_drv_s) +else() + heqat_create_archive(he_qat libadf_static) + heqat_create_archive(he_qat libosal_static) + heqat_create_archive(he_qat libqat_static) + heqat_create_archive(he_qat libusdm_drv_static) +endif() + +if(NOT HE_QAT_STANDALONE) + add_dependencies(he_qat IPPCP::ippcp) +endif() + +if(HE_QAT_MISC) + target_include_directories(he_qat PRIVATE ${IPPCP_INC_DIR}) + target_link_directories(he_qat PRIVATE ${IPPCP_LIB_DIR}) + if(HE_QAT_SHARED) + target_link_libraries(he_qat PRIVATE IPPCP::ippcp) + else() + heqat_create_archive(he_qat IPPCP::ippcp) + endif() +endif() + +set_target_properties(he_qat PROPERTIES POSITION_INDEPENDENT_CODE ON) +set_target_properties(he_qat PROPERTIES VERSION ${HE_QAT_VERSION}) + +if(HE_QAT_DEBUG) + set_target_properties(he_qat PROPERTIES OUTPUT_NAME "he_qat_debug") +else() + set_target_properties(he_qat PROPERTIES OUTPUT_NAME "he_qat") +endif() + +include(CMakePackageConfigHelpers) + +# config cmake config and target file +set(HE_QAT_TARGET_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/cmake/he_qat-${HE_QAT_VERSION}/he_qatTargets.cmake) +set(HE_QAT_CONFIG_IN_FILENAME ${HE_QAT_CMAKE_PATH}/HE_QATConfig.cmake.in) +set(HE_QAT_CONFIG_FILENAME ${HE_QAT_ROOT_DIR}/cmake/he_qat-${HE_QAT_VERSION}/HE_QATConfig.cmake) +set(HE_QAT_CONFIG_VERSION_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/cmake/he_qat-${HE_QAT_VERSION}/HE_QATConfigVersion.cmake) +set(HE_QAT_CONFIG_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/he_qat-${HE_QAT_VERSION}/) + +install( + EXPORT he_qatTargets + NAMESPACE HE_QAT:: + DESTINATION ${HE_QAT_CONFIG_INSTALL_DIR} +) + +write_basic_package_version_file( + ${HE_QAT_CONFIG_VERSION_FILENAME} + VERSION ${HE_QAT_VERSION} + COMPATIBILITY ExactVersion +) + +configure_package_config_file( + ${HE_QAT_CONFIG_IN_FILENAME} ${HE_QAT_CONFIG_FILENAME} + INSTALL_DESTINATION ${HE_QAT_CONFIG_INSTALL_DIR} +) + +install( + TARGETS he_qat + EXPORT he_qatTargets + ARCHIVE DESTINATION ${HE_QAT_INSTALL_LIBDIR} + LIBRARY DESTINATION ${HE_QAT_INSTALL_LIBDIR} + RUNTIME DESTINATION ${HE_QAT_INSTALL_LIBDIR} + ) + +install(FILES ${HE_QAT_CONFIG_FILENAME} + ${HE_QAT_CONFIG_VERSION_FILENAME} + DESTINATION ${HE_QAT_CONFIG_INSTALL_DIR}) + +export(EXPORT he_qatTargets + FILE ${HE_QAT_TARGET_FILENAME}) diff --git a/module/heqat/heqat/bnops.c b/module/heqat/heqat/bnops.c new file mode 100644 index 0000000..43b6673 --- /dev/null +++ b/module/heqat/heqat/bnops.c @@ -0,0 +1,540 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +/// @file heqat/bnops.c + +#include +#include +#include +#include + +#include "heqat/bnops.h" +#include "heqat/common/consts.h" +#include "heqat/common/types.h" +#include "heqat/common/utils.h" + +#ifdef HE_QAT_PERF +#include +#endif + +#include +#include +#include +#include +#include + +#ifdef HE_QAT_SYNC_MODE +#pragma message "Synchronous execution mode." +#else +#pragma message "Asynchronous execution mode." +#endif + +// Global buffer for the runtime environment +extern HE_QAT_RequestBuffer he_qat_buffer; +extern HE_QAT_OutstandingBuffer outstanding; + +// Callback functions +extern void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, + void* pOpData, CpaFlatBuffer* pOut); +extern void HE_QAT_bnModExpCallback(void* pCallbackTag, CpaStatus status, + void* pOpData, CpaFlatBuffer* pOut); + +/// @brief Thread-safe producer implementation for the shared request buffer. +/// @details Fill internal or outstanding buffer with incoming work requests. +/// This function is implemented in he_qat_ctrl.c. +extern void submit_request(HE_QAT_RequestBuffer* _buffer, void* args); + +/* + * ************************************************************************** + * Implementation of Functions for the Single Interface Support + * ************************************************************************** + */ + +HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, + unsigned char* e, unsigned char* m, int nbits) { + static unsigned long long req_count = 0; + + // Unpack data and copy to QAT friendly memory space + int len = (nbits + 7) >> 3; + + if (NULL == r) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == b) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == e) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == m) return HE_QAT_STATUS_INVALID_PARAM; + + Cpa8U* pBase = NULL; + Cpa8U* pModulus = NULL; + Cpa8U* pExponent = NULL; + + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + status = HE_QAT_MEM_ALLOC_CONTIG(&pBase, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != pBase) { + memcpy(pBase, b, len); + } else { + HE_QAT_PRINT_ERR("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + status = HE_QAT_MEM_ALLOC_CONTIG(&pExponent, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != pExponent) { + memcpy(pExponent, e, len); + } else { + printf("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + status = HE_QAT_MEM_ALLOC_CONTIG(&pModulus, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != pModulus) { + memcpy(pModulus, m, len); + } else { + HE_QAT_PRINT_ERR("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + // Pack it as a QAT Task Request + HE_QAT_TaskRequest* request = + (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); + if (NULL == request) { + HE_QAT_PRINT_ERR( + "HE_QAT_TaskRequest memory allocation failed in " + "bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + + CpaCyLnModExpOpData* op_data = + (CpaCyLnModExpOpData*)calloc(1, sizeof(CpaCyLnModExpOpData)); + if (NULL == op_data) { + HE_QAT_PRINT_ERR( + "Cpa memory allocation failed in bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + op_data->base.pData = pBase; + op_data->base.dataLenInBytes = len; + op_data->exponent.pData = pExponent; + op_data->exponent.dataLenInBytes = len; + op_data->modulus.pData = pModulus; + op_data->modulus.dataLenInBytes = len; + request->op_data = (void*)op_data; + + status = HE_QAT_MEM_ALLOC_CONTIG(&request->op_result.pData, len, + BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != request->op_result.pData) { + request->op_result.dataLenInBytes = len; + } else { + HE_QAT_PRINT_ERR( + "CpaFlatBuffer.pData memory allocation failed in " + "bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + + request->op_type = HE_QAT_OP_MODEXP; + request->callback_func = (void*)HE_QAT_bnModExpCallback; + request->op_status = status; + request->op_output = (void*)r; + + request->id = req_count++; + + // Ensure calls are synchronized at exit (blocking) + pthread_mutex_init(&request->mutex, NULL); + pthread_cond_init(&request->ready, NULL); + + HE_QAT_PRINT_DBG("BN ModExp interface call for request #%llu\n", req_count); + + // Submit request using producer function + submit_request(&he_qat_buffer, (void*)request); + + return HE_QAT_STATUS_SUCCESS; +} + +HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, + int nbits) { + static unsigned long long req_count = 0; + + // Unpack data and copy to QAT friendly memory space + int len = (nbits + 7) >> 3; + + Cpa8U* pBase = NULL; + Cpa8U* pModulus = NULL; + Cpa8U* pExponent = NULL; + + HE_QAT_TaskRequest* request = + (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); + if (NULL == request) { + HE_QAT_PRINT_ERR( + "HE_QAT_TaskRequest memory allocation failed in " + "bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + status = HE_QAT_MEM_ALLOC_CONTIG(&pBase, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != pBase) { + if (!BN_bn2binpad(b, pBase, len)) { + HE_QAT_PRINT_ERR( + "BN_bn2binpad (base) failed in bnModExpPerformOp.\n"); + HE_QAT_MEM_FREE_CONTIG(pBase); + return HE_QAT_STATUS_FAIL; + } + } else { + HE_QAT_PRINT_ERR("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + status = HE_QAT_MEM_ALLOC_CONTIG(&pExponent, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != pExponent) { + if (!BN_bn2binpad(e, pExponent, len)) { + HE_QAT_PRINT_ERR( + "BN_bn2binpad (exponent) failed in bnModExpPerformOp.\n"); + HE_QAT_MEM_FREE_CONTIG(pExponent); + return HE_QAT_STATUS_FAIL; + } + } else { + HE_QAT_PRINT_ERR("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + status = HE_QAT_MEM_ALLOC_CONTIG(&pModulus, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != pModulus) { + if (!BN_bn2binpad(m, pModulus, len)) { + HE_QAT_PRINT_ERR("BN_bn2binpad failed in bnModExpPerformOp.\n"); + HE_QAT_MEM_FREE_CONTIG(pModulus); + return HE_QAT_STATUS_FAIL; + } + } else { + HE_QAT_PRINT_ERR("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + // Pack it as a QAT Task Request + CpaCyLnModExpOpData* op_data = + (CpaCyLnModExpOpData*)calloc(1, sizeof(CpaCyLnModExpOpData)); + if (NULL == op_data) { + printf("Cpa memory allocation failed in bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + op_data->base.pData = pBase; + op_data->base.dataLenInBytes = len; + op_data->exponent.pData = pExponent; + op_data->exponent.dataLenInBytes = len; + op_data->modulus.pData = pModulus; + op_data->modulus.dataLenInBytes = len; + request->op_data = (void*)op_data; + + status = HE_QAT_MEM_ALLOC_CONTIG(&request->op_result.pData, len, + BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != request->op_result.pData) { + request->op_result.dataLenInBytes = len; + } else { + HE_QAT_PRINT_ERR( + "CpaFlatBuffer.pData memory allocation failed in " + "bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + + request->op_type = HE_QAT_OP_MODEXP; + request->callback_func = (void*)HE_QAT_BIGNUMModExpCallback; + request->op_status = status; + request->op_output = (void*)r; + + request->id = req_count++; + + // Ensure calls are synchronized at exit (blocking) + pthread_mutex_init(&request->mutex, NULL); + pthread_cond_init(&request->ready, NULL); + + // Submit request using producer function + submit_request(&he_qat_buffer, (void*)request); + + return HE_QAT_STATUS_SUCCESS; +} + +void getBnModExpRequest(unsigned int batch_size) { + static unsigned long block_at_index = 0; + unsigned int j = 0; + +#ifdef HE_QAT_PERF + struct timeval start_time, end_time; + double time_taken = 0.0; + gettimeofday(&start_time, NULL); +#endif + do { + // Buffer read may be safe for single-threaded blocking calls only. + // Note: Not tested on multithreaded environment. + HE_QAT_TaskRequest* task = + (HE_QAT_TaskRequest*)he_qat_buffer.data[block_at_index]; + + if (NULL == task) continue; + + // Block and synchronize: Wait for the most recently offloaded request + // to complete processing + pthread_mutex_lock( + &task->mutex); // mutex only needed for the conditional variable + while (HE_QAT_STATUS_READY != task->request_status) + pthread_cond_wait(&task->ready, &task->mutex); + +#ifdef HE_QAT_PERF + time_taken = (task->end.tv_sec - task->start.tv_sec) * 1e6; + time_taken = + (time_taken + (task->end.tv_usec - task->start.tv_usec)); //*1e-6; + HE_QAT_PRINT("%u time: %.1lfus\n", j, time_taken); +#endif + + // Free up QAT temporary memory + CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; + if (op_data) { + HE_QAT_MEM_FREE_CONTIG(op_data->base.pData); + HE_QAT_MEM_FREE_CONTIG(op_data->exponent.pData); + HE_QAT_MEM_FREE_CONTIG(op_data->modulus.pData); + } + free(task->op_data); + task->op_data = NULL; + if (task->op_result.pData) { + HE_QAT_MEM_FREE_CONTIG(task->op_result.pData); + } + + // Move forward to wait for the next request that will be offloaded + pthread_mutex_unlock(&task->mutex); + + free(he_qat_buffer.data[block_at_index]); + he_qat_buffer.data[block_at_index] = NULL; + + block_at_index = (block_at_index + 1) % HE_QAT_BUFFER_SIZE; + } while (++j < batch_size); + +#ifdef HE_QAT_PERF + gettimeofday(&end_time, NULL); + time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; + time_taken = (time_taken + (end_time.tv_usec - start_time.tv_usec)); + HE_QAT_PRINT("Batch Wall Time: %.1lfus\n", time_taken); +#endif + + return; +} + +/* + * ************************************************************************** + * Implementation of Functions for the Multithreading Interface Support + * ************************************************************************** + */ + +HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, + unsigned char* b, unsigned char* e, + unsigned char* m, int nbits) { + static unsigned long long req_count = 0; + + // Unpack data and copy to QAT friendly memory space + int len = (nbits + 7) >> 3; + + if (NULL == r) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == b) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == e) return HE_QAT_STATUS_INVALID_PARAM; + if (NULL == m) return HE_QAT_STATUS_INVALID_PARAM; + + Cpa8U* pBase = NULL; + Cpa8U* pModulus = NULL; + Cpa8U* pExponent = NULL; + + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + status = HE_QAT_MEM_ALLOC_CONTIG(&pBase, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != pBase) { + memcpy(pBase, b, len); + } else { + HE_QAT_PRINT("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + status = HE_QAT_MEM_ALLOC_CONTIG(&pExponent, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != pExponent) { + memcpy(pExponent, e, len); + } else { + HE_QAT_PRINT_ERR("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + status = HE_QAT_MEM_ALLOC_CONTIG(&pModulus, len, BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != pModulus) { + memcpy(pModulus, m, len); + } else { + HE_QAT_PRINT_ERR("Contiguous memory allocation failed for pBase.\n"); + return HE_QAT_STATUS_FAIL; + } + + // Pack it as a QAT Task Request + HE_QAT_TaskRequest* request = + (HE_QAT_TaskRequest*)calloc(1, sizeof(HE_QAT_TaskRequest)); + if (NULL == request) { + HE_QAT_PRINT_ERR( + "HE_QAT_TaskRequest memory allocation failed in " + "bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + + CpaCyLnModExpOpData* op_data = + (CpaCyLnModExpOpData*)calloc(1, sizeof(CpaCyLnModExpOpData)); + if (NULL == op_data) { + printf("Cpa memory allocation failed in bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + op_data->base.pData = pBase; + op_data->base.dataLenInBytes = len; + op_data->exponent.pData = pExponent; + op_data->exponent.dataLenInBytes = len; + op_data->modulus.pData = pModulus; + op_data->modulus.dataLenInBytes = len; + request->op_data = (void*)op_data; + + status = HE_QAT_MEM_ALLOC_CONTIG(&request->op_result.pData, len, + BYTE_ALIGNMENT_8); + if (HE_QAT_STATUS_SUCCESS == status && NULL != request->op_result.pData) { + request->op_result.dataLenInBytes = len; + } else { + HE_QAT_PRINT_ERR( + "CpaFlatBuffer.pData memory allocation failed in " + "bnModExpPerformOp.\n"); + return HE_QAT_STATUS_FAIL; + } + + request->op_type = HE_QAT_OP_MODEXP; + request->callback_func = (void*)HE_QAT_bnModExpCallback; + request->op_status = status; + request->op_output = (void*)r; + + request->id = req_count++; + + // Ensure calls are synchronized at exit (blocking) + pthread_mutex_init(&request->mutex, NULL); + pthread_cond_init(&request->ready, NULL); + + HE_QAT_PRINT_DBG("BN ModExp interface call for request #%llu\n", req_count); + + // Submit request using producer function + submit_request(&outstanding.buffer[_buffer_id], (void*)request); + + return HE_QAT_STATUS_SUCCESS; +} + +HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id) { + if (NULL == _buffer_id) return HE_QAT_STATUS_INVALID_PARAM; + + HE_QAT_PRINT_DBG("acquire_bnModExp_buffer #%u\n", _buffer_id); + + pthread_mutex_lock(&outstanding.mutex); + + // Wait until next outstanding buffer becomes available for use + while (outstanding.busy_count >= HE_QAT_BUFFER_COUNT) + pthread_cond_wait(&outstanding.any_free_buffer, &outstanding.mutex); + + assert(outstanding.busy_count < HE_QAT_BUFFER_COUNT); + + // Find next outstanding buffer available + unsigned int next_free_buffer = outstanding.next_free_buffer; + for (unsigned int i = 0; i < HE_QAT_BUFFER_COUNT; i++) { + if (outstanding.free_buffer[next_free_buffer]) { + outstanding.free_buffer[next_free_buffer] = 0; + *_buffer_id = next_free_buffer; + break; + } + next_free_buffer = (next_free_buffer + 1) % HE_QAT_BUFFER_COUNT; + } + + outstanding.next_free_buffer = (*_buffer_id + 1) % HE_QAT_BUFFER_COUNT; + outstanding.next_ready_buffer = *_buffer_id; + outstanding.ready_buffer[*_buffer_id] = 1; + outstanding.busy_count++; + // busy meaning: + // taken by a thread, enqueued requests, in processing, waiting results + + pthread_cond_signal(&outstanding.any_ready_buffer); + pthread_mutex_unlock(&outstanding.mutex); + + return HE_QAT_STATUS_SUCCESS; +} + +void release_bnModExp_buffer(unsigned int _buffer_id, + unsigned int _batch_size) { + unsigned int next_data_out = outstanding.buffer[_buffer_id].next_data_out; + unsigned int j = 0; + + HE_QAT_PRINT_DBG("release_bnModExp_buffer #%u\n", _buffer_id); + +#ifdef HE_QAT_PERF + struct timeval start_time, end_time; + double time_taken = 0.0; + gettimeofday(&start_time, NULL); +#endif + + while (j < _batch_size) { + HE_QAT_TaskRequest* task = + (HE_QAT_TaskRequest*)outstanding.buffer[_buffer_id] + .data[next_data_out]; + + if (NULL == task) continue; + + HE_QAT_PRINT_DBG("BatchSize %u Buffer #%u Request #%u Waiting\n", + _batch_size, _buffer_id, j); + + // Block and synchronize: Wait for the most recently offloaded request + // to complete processing. Mutex only needed for the conditional + // variable. + pthread_mutex_lock(&task->mutex); + while (HE_QAT_STATUS_READY != task->request_status) + pthread_cond_wait(&task->ready, &task->mutex); + +#ifdef HE_QAT_PERF + time_taken = (task->end.tv_sec - task->start.tv_sec) * 1e6; + time_taken = + (time_taken + (task->end.tv_usec - task->start.tv_usec)); //*1e-6; + HE_QAT_PRINT("%u time: %.1lfus\n", j, time_taken); +#endif + + // Free up QAT temporary memory + CpaCyLnModExpOpData* op_data = (CpaCyLnModExpOpData*)task->op_data; + if (op_data) { + HE_QAT_MEM_FREE_CONTIG(op_data->base.pData); + HE_QAT_MEM_FREE_CONTIG(op_data->exponent.pData); + HE_QAT_MEM_FREE_CONTIG(op_data->modulus.pData); + } + free(task->op_data); + task->op_data = NULL; + if (task->op_result.pData) { + HE_QAT_MEM_FREE_CONTIG(task->op_result.pData); + } + + // Move forward to wait for the next request that will be offloaded + pthread_mutex_unlock(&task->mutex); + + HE_QAT_PRINT_DBG("Buffer #%u Request #%u Completed\n", _buffer_id, j); + + // outstanding.buffer[_buffer_id].count--; + + free(outstanding.buffer[_buffer_id].data[next_data_out]); + outstanding.buffer[_buffer_id].data[next_data_out] = NULL; + + // Update for next thread on the next external iteration + next_data_out = (next_data_out + 1) % HE_QAT_BUFFER_SIZE; + + j++; + } + +#ifdef HE_QAT_PERF + gettimeofday(&end_time, NULL); + time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; + time_taken = + (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; + HE_QAT_PRINT("Batch Wall Time: %.1lfus\n", time_taken); +#endif + + outstanding.buffer[_buffer_id].next_data_out = next_data_out; + + // Release outstanding buffer for usage by another thread + pthread_mutex_lock(&outstanding.mutex); + + outstanding.next_free_buffer = _buffer_id; + outstanding.ready_buffer[_buffer_id] = 0; + outstanding.free_buffer[_buffer_id] = 1; + outstanding.busy_count--; + + pthread_cond_signal(&outstanding.any_free_buffer); + pthread_mutex_unlock(&outstanding.mutex); + + return; +} diff --git a/module/heqat/heqat/cb.c b/module/heqat/heqat/cb.c new file mode 100644 index 0000000..5151996 --- /dev/null +++ b/module/heqat/heqat/cb.c @@ -0,0 +1,129 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +/// @file heqat/cb.c + +// QAT-API headers +#include + +// C support libraries +#include +#include +#include + +// Local headers +#include "heqat/common/types.h" +#include "heqat/common/utils.h" + +// Global variables +static pthread_mutex_t + response_mutex; ///< It protects against race condition on response_count + ///< due to concurrent callback events. +extern volatile unsigned long + response_count; ///< It counts the number of requests completed by the + ///< accelerator. + +/// @brief Callback implementation for the API HE_QAT_BIGNUMModExp(...) +/// Callback function for the interface HE_QAT_BIGNUMModExp(). It performs +/// any data post-processing required after the modular exponentiation. +/// @param[in] pCallbackTag work request package containing the original input +/// data and other resources for post-processing. +/// @param[in] status CPA_STATUS of the performed operation, e.g. CyLnModExp(). +/// @param[in] pOpData original input data passed to accelerator to perform the +/// target operation (cannot be NULL). +/// @param[out] pOut output returned by the accelerator after executing the +/// target operation. +void HE_QAT_BIGNUMModExpCallback(void* pCallbackTag, CpaStatus status, + void* pOpData, CpaFlatBuffer* pOut) { + HE_QAT_TaskRequest* request = NULL; + + // Check if input data for the op is available and do something + if (NULL != pCallbackTag) { + // Read request data + request = (HE_QAT_TaskRequest*)pCallbackTag; + + pthread_mutex_lock(&response_mutex); + // Global track of responses by accelerator + response_count += 1; + pthread_mutex_unlock(&response_mutex); + + pthread_mutex_lock(&request->mutex); + // Collect the device output in pOut + request->op_status = status; + if (CPA_STATUS_SUCCESS == status) { + if (pOpData == request->op_data) { + // Mark request as complete or ready to be used + request->request_status = HE_QAT_STATUS_READY; + + BIGNUM* r = BN_bin2bn(request->op_result.pData, + request->op_result.dataLenInBytes, + (BIGNUM*)request->op_output); + if (NULL == r) request->request_status = HE_QAT_STATUS_FAIL; +#ifdef HE_QAT_PERF + gettimeofday(&request->end, NULL); +#endif + } else { + request->request_status = HE_QAT_STATUS_FAIL; + } + } + // Make it synchronous and blocking + pthread_cond_signal(&request->ready); + pthread_mutex_unlock(&request->mutex); +#ifdef HE_QAT_SYNC_MODE + COMPLETE((struct COMPLETION_STRUCT*)&request->callback); +#endif + } + + return; +} + +/// @brief Callback implementation for the API HE_QAT_bnModExp(...) +/// Callback function for the interface HE_QAT_bnModExp(). It performs +/// any data post-processing required after the modular exponentiation. +/// @param[in] pCallbackTag work request package containing the original input +/// data and other resources for post-processing. +/// @param[in] status CPA_STATUS of the performed operation, e.g. CyLnModExp(). +/// @param[in] pOpData original input data passed to accelerator to perform the +/// target operation (cannot be NULL). +/// @param[out] pOut output returned by the accelerator after executing the +/// target operation. +void HE_QAT_bnModExpCallback(void* pCallbackTag, CpaStatus status, + void* pOpData, CpaFlatBuffer* pOut) { + HE_QAT_TaskRequest* request = NULL; + + // Check if input data for the op is available and do something + if (NULL != pCallbackTag) { + // Read request data + request = (HE_QAT_TaskRequest*)pCallbackTag; + + pthread_mutex_lock(&response_mutex); + // Global track of responses by accelerator + response_count += 1; + pthread_mutex_unlock(&response_mutex); + + pthread_mutex_lock(&request->mutex); + // Collect the device output in pOut + request->op_status = status; + if (CPA_STATUS_SUCCESS == status) { + if (pOpData == request->op_data) { + // Mark request as complete or ready to be used + request->request_status = HE_QAT_STATUS_READY; + // Copy compute results to output destination + memcpy(request->op_output, request->op_result.pData, + request->op_result.dataLenInBytes); +#ifdef HE_QAT_PERF + gettimeofday(&request->end, NULL); +#endif + } else { + request->request_status = HE_QAT_STATUS_FAIL; + } + } + // Make it synchronous and blocking + pthread_cond_signal(&request->ready); + pthread_mutex_unlock(&request->mutex); +#ifdef HE_QAT_SYNC_MODE + COMPLETE((struct COMPLETION_STRUCT*)&request->callback); +#endif + } + + return; +} diff --git a/module/heqat/heqat/common/utils.c b/module/heqat/heqat/common/utils.c new file mode 100644 index 0000000..81fcb73 --- /dev/null +++ b/module/heqat/heqat/common/utils.c @@ -0,0 +1,69 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include +#include + +#include "heqat/common/utils.h" +#include "heqat/common/types.h" + +BIGNUM* generateTestBNData(int nbits) { + if (!RAND_status()) return NULL; + + HE_QAT_PRINT_DBG("PRNG properly seeded.\n"); + + BIGNUM* bn = BN_new(); + + if (!BN_rand(bn, nbits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { + BN_free(bn); + HE_QAT_PRINT_ERR("Error while generating BN random number: %lu\n", + ERR_get_error()); + return NULL; + } + + return bn; +} + +unsigned char* paddingZeros(BIGNUM* bn, int nbits) { + if (!bn) return NULL; + + // Returns same address if it fails + int num_bytes = BN_num_bytes(bn); + int bytes_left = nbits / 8 - num_bytes; + if (bytes_left <= 0) return NULL; + + // Returns same address if it fails + unsigned char* bin = NULL; + int len = bytes_left + num_bytes; + if (!(bin = (unsigned char*)OPENSSL_zalloc(len))) return NULL; + + HE_QAT_PRINT_DBG("Padding bn with %d bytes to total %d bytes\n", bytes_left, + len); + + BN_bn2binpad(bn, bin, len); + if (ERR_get_error()) { + OPENSSL_free(bin); + return NULL; + } + + return bin; +} + +void showHexBN(BIGNUM* bn, int nbits) { + int len = nbits / 8; + unsigned char* bin = (unsigned char*)OPENSSL_zalloc(len); + if (!bin) return; + if (BN_bn2binpad(bn, bin, len)) { + for (size_t i = 0; i < len; i++) HE_QAT_PRINT("%2.2x", bin[i]); + HE_QAT_PRINT("\n"); + } + OPENSSL_free(bin); + return; +} + +void showHexBin(unsigned char* bin, int len) { + if (!bin) return; + for (size_t i = 0; i < len; i++) HE_QAT_PRINT("%2.2x", bin[i]); + HE_QAT_PRINT("\n"); + return; +} diff --git a/module/heqat/heqat/context.c b/module/heqat/heqat/context.c new file mode 100644 index 0000000..eb0cd9b --- /dev/null +++ b/module/heqat/heqat/context.c @@ -0,0 +1,302 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +/// @file heqat/context.c + +#define _GNU_SOURCE + +#include +#include +#include + +#include +#include +#include + +#include "heqat/common/types.h" +#include "heqat/common/utils.h" +#include "heqat/context.h" + +#ifdef USER_SPACE +#define MAX_INSTANCES 1024 +#else +#define MAX_INSTANCES 1 +#endif + +// Utilities functions from qae_mem.h header +extern CpaStatus qaeMemInit(void); +extern void qaeMemDestroy(void); + +static volatile HE_QAT_STATUS context_state = HE_QAT_STATUS_INACTIVE; +static pthread_mutex_t context_lock; + +// Global variable declarations +static pthread_t buffer_manager; +static pthread_t he_qat_runner; +static pthread_attr_t he_qat_inst_attr[HE_QAT_NUM_ACTIVE_INSTANCES]; +static HE_QAT_InstConfig he_qat_inst_config[HE_QAT_NUM_ACTIVE_INSTANCES]; +static HE_QAT_Config* he_qat_config = NULL; + +// External global variables +extern HE_QAT_RequestBuffer he_qat_buffer; +extern HE_QAT_OutstandingBuffer outstanding; + +/*********** Internal Services ***********/ +// Start scheduler of work requests (consumer) +extern void* schedule_requests(void* state); +// Activate cpaCyInstances to run on background and poll responses from QAT +// accelerator +extern void* start_instances(void* _inst_config); +// Stop a running group of cpaCyInstances started with the "start_instances" +// service +extern void stop_instances(HE_QAT_Config* _config); +// Stop running individual QAT instances from a list of cpaCyInstances (called +// by "stop_instances") +extern void stop_perform_op(void* _inst_config, unsigned num_inst); +// Activate a cpaCyInstance to run on background and poll responses from QAT +// accelerator WARNING: Deprecated when "start_instances" becomes default. +extern void* start_perform_op(void* _inst_config); + +static Cpa16U numInstances = 0; +static Cpa16U nextInstance = 0; + +static CpaInstanceHandle get_qat_instance() { + static CpaInstanceHandle cyInstHandles[MAX_INSTANCES]; + CpaStatus status = CPA_STATUS_SUCCESS; + CpaInstanceInfo2 info = {0}; + + if (0 == numInstances) { + status = cpaCyGetNumInstances(&numInstances); + if (numInstances >= MAX_INSTANCES) { + numInstances = MAX_INSTANCES; + } + if (numInstances >= HE_QAT_NUM_ACTIVE_INSTANCES) { + numInstances = HE_QAT_NUM_ACTIVE_INSTANCES; + } + + if (CPA_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("No CyInstances Found (%d).\n", numInstances); + return NULL; + } + + HE_QAT_PRINT_DBG("Found %d CyInstances.\n", numInstances); + + if ((status == CPA_STATUS_SUCCESS) && (numInstances > 0)) { + status = cpaCyGetInstances(numInstances, cyInstHandles); + + // List instances and their characteristics + for (unsigned int i = 0; i < numInstances; i++) { + status = cpaCyInstanceGetInfo2(cyInstHandles[i], &info); + if (CPA_STATUS_SUCCESS != status) return NULL; +#ifdef HE_QAT_DEBUG + HE_QAT_PRINT("Vendor Name: %s\n", info.vendorName); + HE_QAT_PRINT("Part Name: %s\n", info.partName); + HE_QAT_PRINT("Inst Name: %s\n", info.instName); + HE_QAT_PRINT("Inst ID: %s\n", info.instID); + HE_QAT_PRINT("Node Affinity: %u\n", info.nodeAffinity); + HE_QAT_PRINT("Physical Instance:\n"); + HE_QAT_PRINT("\tpackageId: %d\n", info.physInstId.packageId); + HE_QAT_PRINT("\tacceleratorId: %d\n", + info.physInstId.acceleratorId); + HE_QAT_PRINT("\texecutionEngineId: %d\n", + info.physInstId.executionEngineId); + HE_QAT_PRINT("\tbusAddress: %d\n", info.physInstId.busAddress); + HE_QAT_PRINT("\tkptAcHandle: %d\n", + info.physInstId.kptAcHandle); +#endif + } + HE_QAT_PRINT_DBG("Next Instance: %d.\n", nextInstance); + + if (status == CPA_STATUS_SUCCESS) + return cyInstHandles[nextInstance]; + } + + if (0 == numInstances) { + HE_QAT_PRINT_ERR("No instances found for 'SSL'\n"); + HE_QAT_PRINT_ERR("Please check your section names"); + HE_QAT_PRINT_ERR(" in the config file.\n"); + HE_QAT_PRINT_ERR("Also make sure to use config file version 2.\n"); + } + + return NULL; + } + + nextInstance = ((nextInstance + 1) % numInstances); + HE_QAT_PRINT_DBG("Next Instance: %d.\n", nextInstance); + + return cyInstHandles[nextInstance]; +} + +/// @brief +/// Acquire QAT instances and set up QAT execution environment. +HE_QAT_STATUS acquire_qat_devices() { + CpaStatus status = CPA_STATUS_FAIL; + + pthread_mutex_lock(&context_lock); + + // Handle cases where acquire_qat_devices() is called when already active + // and running + if (HE_QAT_STATUS_ACTIVE == context_state) { + pthread_mutex_unlock(&context_lock); + return HE_QAT_STATUS_SUCCESS; + } + + // Initialize QAT memory pool allocator + status = qaeMemInit(); + if (CPA_STATUS_SUCCESS != status) { + pthread_mutex_unlock(&context_lock); + HE_QAT_PRINT_ERR("Failed to initialized memory driver.\n"); + return HE_QAT_STATUS_FAIL; + } + HE_QAT_PRINT_DBG("QAT memory successfully initialized.\n"); + + status = icp_sal_userStartMultiProcess("SSL", CPA_FALSE); + if (CPA_STATUS_SUCCESS != status) { + pthread_mutex_unlock(&context_lock); + HE_QAT_PRINT_ERR("Failed to start SAL user process SSL\n"); + qaeMemDestroy(); + return HE_QAT_STATUS_FAIL; + } + HE_QAT_PRINT_DBG("SAL user process successfully started.\n"); + + CpaInstanceHandle _inst_handle[HE_QAT_NUM_ACTIVE_INSTANCES]; + for (unsigned int i = 0; i < HE_QAT_NUM_ACTIVE_INSTANCES; i++) { + _inst_handle[i] = get_qat_instance(); + if (_inst_handle[i] == NULL) { + pthread_mutex_unlock(&context_lock); + HE_QAT_PRINT_ERR("Failed to find QAT endpoints.\n"); + return HE_QAT_STATUS_FAIL; + } + } + + HE_QAT_PRINT_DBG("Found QAT endpoints.\n"); + + // Initialize QAT buffer synchronization attributes + he_qat_buffer.count = 0; + he_qat_buffer.next_free_slot = 0; + he_qat_buffer.next_data_slot = 0; + + // Initialize QAT memory buffer + for (int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { + he_qat_buffer.data[i] = NULL; + } + + // Initialize QAT outstanding buffers + outstanding.busy_count = 0; + outstanding.next_free_buffer = 0; + outstanding.next_ready_buffer = 0; + for (int i = 0; i < HE_QAT_BUFFER_COUNT; i++) { + outstanding.free_buffer[i] = 1; + outstanding.ready_buffer[i] = 0; + outstanding.buffer[i].count = 0; + outstanding.buffer[i].next_free_slot = 0; + outstanding.buffer[i].next_data_slot = 0; + outstanding.buffer[i].next_data_out = 0; + for (int j = 0; j < HE_QAT_BUFFER_SIZE; j++) { + outstanding.buffer[i].data[j] = NULL; + } + pthread_mutex_init(&outstanding.buffer[i].mutex, NULL); + pthread_cond_init(&outstanding.buffer[i].any_more_data, NULL); + pthread_cond_init(&outstanding.buffer[i].any_free_slot, NULL); + } + pthread_mutex_init(&outstanding.mutex, NULL); + pthread_cond_init(&outstanding.any_free_buffer, NULL); + pthread_cond_init(&outstanding.any_ready_buffer, NULL); + + // Creating QAT instances (consumer threads) to process op requests + cpu_set_t cpus; + for (int i = 0; i < HE_QAT_NUM_ACTIVE_INSTANCES; i++) { + CPU_ZERO(&cpus); + CPU_SET(i, &cpus); + pthread_attr_init(&he_qat_inst_attr[i]); + pthread_attr_setaffinity_np(&he_qat_inst_attr[i], sizeof(cpu_set_t), + &cpus); + + // configure thread + he_qat_inst_config[i].active = 0; // HE_QAT_STATUS_INACTIVE + he_qat_inst_config[i].polling = 0; // HE_QAT_STATUS_INACTIVE + he_qat_inst_config[i].running = 0; + he_qat_inst_config[i].status = CPA_STATUS_FAIL; + pthread_mutex_init(&he_qat_inst_config[i].mutex, NULL); + pthread_cond_init(&he_qat_inst_config[i].ready, NULL); + he_qat_inst_config[i].inst_handle = _inst_handle[i]; + he_qat_inst_config[i].inst_id = i; + he_qat_inst_config[i].attr = &he_qat_inst_attr[i]; + } + + he_qat_config = (HE_QAT_Config*)malloc(sizeof(HE_QAT_Config)); + he_qat_config->inst_config = he_qat_inst_config; + he_qat_config->count = HE_QAT_NUM_ACTIVE_INSTANCES; + he_qat_config->running = 0; + he_qat_config->active = 0; + + pthread_create(&he_qat_runner, NULL, start_instances, (void*)he_qat_config); + HE_QAT_PRINT_DBG("Created processing threads.\n"); + + // Dispatch the qat instances to run independently in the background + pthread_detach(he_qat_runner); + HE_QAT_PRINT_DBG("Detached processing threads.\n"); + + // Set context state to active + context_state = HE_QAT_STATUS_ACTIVE; + + // Launch buffer manager thread to schedule incoming requests + if (0 != pthread_create(&buffer_manager, NULL, schedule_requests, + (void*)&context_state)) { + pthread_mutex_unlock(&context_lock); + release_qat_devices(); + HE_QAT_PRINT_ERR( + "Failed to complete QAT initialization while creating buffer " + "manager thread.\n"); + return HE_QAT_STATUS_FAIL; + } + + if (0 != pthread_detach(buffer_manager)) { + pthread_mutex_unlock(&context_lock); + release_qat_devices(); + HE_QAT_PRINT_ERR( + "Failed to complete QAT initialization while launching buffer " + "manager thread.\n"); + return HE_QAT_STATUS_FAIL; + } + + pthread_mutex_unlock(&context_lock); + + return HE_QAT_STATUS_SUCCESS; +} + +/// @brief +/// Release QAT instances and tear down QAT execution environment. +HE_QAT_STATUS release_qat_devices() { + pthread_mutex_lock(&context_lock); + + if (HE_QAT_STATUS_INACTIVE == context_state) { + pthread_mutex_unlock(&context_lock); + return HE_QAT_STATUS_SUCCESS; + } + + stop_instances(he_qat_config); + HE_QAT_PRINT_DBG("Stopped polling and processing threads.\n"); + + // Deactivate context (this will terminate buffer manager thread + context_state = HE_QAT_STATUS_INACTIVE; + + // Stop QAT SSL service + icp_sal_userStop(); + HE_QAT_PRINT_DBG("Stopped SAL user process.\n"); + + // Release QAT allocated memory + qaeMemDestroy(); + HE_QAT_PRINT_DBG("Release QAT memory.\n"); + + numInstances = 0; + nextInstance = 0; + + pthread_mutex_unlock(&context_lock); + + return HE_QAT_STATUS_SUCCESS; +} + +/// @brief Retrieve and read context state. +/// @return Possible return values are HE_QAT_STATUS_ACTIVE, +/// HE_QAT_STATUS_RUNNING, and HE_QAT_STATUS_INACTIVE. +HE_QAT_STATUS get_qat_context_state() { return context_state; } diff --git a/module/heqat/heqat/ctrl.c b/module/heqat/heqat/ctrl.c new file mode 100644 index 0000000..774a700 --- /dev/null +++ b/module/heqat/heqat/ctrl.c @@ -0,0 +1,818 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +/// @file heqat/ctrl.c + +// C support libraries +#include +#include +#include +#include + +// Global variables used to hold measured performance numbers. +#ifdef HE_QAT_PERF +#include +struct timeval start_time, end_time; +double time_taken = 0.0; +#endif + +// QAT-API headers +#include +#include +#include +#include + +// Local headers +#include "heqat/common/utils.h" +#include "heqat/common/consts.h" +#include "heqat/common/types.h" + +// Warn user on selected execution mode +#ifdef HE_QAT_SYNC_MODE +#pragma message "Synchronous execution mode." +#else +#pragma message "Asynchronous execution mode." +#endif + +// Global buffer for the runtime environment +HE_QAT_RequestBuffer + he_qat_buffer; ///< This the internal buffer that holds and serializes the + ///< requests to the accelerator. +HE_QAT_OutstandingBuffer + outstanding; ///< This is the data structure that holds outstanding + ///< requests from separate active threads calling the API. +volatile unsigned long response_count = + 0; ///< Counter of processed requests and it is used to help control + ///< throttling. +static volatile unsigned long request_count = + 0; ///< Counter of received requests and it is used to help control + ///< throttling. +static unsigned long restart_threshold = + NUM_PKE_SLICES * + HE_QAT_NUM_ACTIVE_INSTANCES; ///< Number of concurrent requests allowed to + ///< be sent to accelerator at once. +static unsigned long max_pending = + (2 * NUM_PKE_SLICES * + HE_QAT_NUM_ACTIVE_INSTANCES); ///< Number of requests sent to the + ///< accelerator that are pending + ///< completion. + +/// @brief Populate internal buffer with incoming requests from API calls. +/// @details This function is called from the main APIs to submit requests to +/// a shared internal buffer for processing on QAT. It is a thread-safe +/// implementation of the producer for the either the internal buffer or the +/// outstanding buffer to host incoming requests. Depending on the buffer type, +/// the submitted request is either ready to be scheduled or to be processed by +/// the accelerator. +/// @param[out] _buffer Either `he_qat_buffer` or `outstanding` buffer. +/// @param[in] args Work request packaged in a custom data structure. +void submit_request(HE_QAT_RequestBuffer* _buffer, void* args) { + HE_QAT_PRINT_DBG("Lock write request\n"); + + pthread_mutex_lock(&_buffer->mutex); + + HE_QAT_PRINT_DBG("Wait lock write request. [buffer size: %d]\n", + _buffer->count); + + while (_buffer->count >= HE_QAT_BUFFER_SIZE) + pthread_cond_wait(&_buffer->any_free_slot, &_buffer->mutex); + + assert(_buffer->count < HE_QAT_BUFFER_SIZE); + + _buffer->data[_buffer->next_free_slot++] = args; + + _buffer->next_free_slot %= HE_QAT_BUFFER_SIZE; + _buffer->count++; + + pthread_cond_signal(&_buffer->any_more_data); + pthread_mutex_unlock(&_buffer->mutex); + + HE_QAT_PRINT_DBG("Unlocked write request. [buffer size: %d]\n", + _buffer->count); +} + +/// @brief Populates internal buffer with a list of work request. +/// @details This function is called by the request scheduler thread. It is a +/// thread-safe implementation of the producer for the shared internal request +/// buffer. This buffer stores and serializes the offloading of requests that +/// are ready to be processed by the accelerator. +/// @param[out] _buffer reference pointer to the internal buffer +/// `he_qat_buffer`. +/// @param[in] _requests list of requests retrieved from the buffer +/// (`outstanding`) holding outstanding requests. +static void submit_request_list(HE_QAT_RequestBuffer* _buffer, + HE_QAT_TaskRequestList* _requests) { + HE_QAT_PRINT_DBG("Lock submit request list\n"); + + if (0 == _requests->count) return; + + pthread_mutex_lock(&_buffer->mutex); + + HE_QAT_PRINT_DBG( + "Wait lock submit request list. [internal buffer size: %d] [num " + "requests: %u]\n", + _buffer->count, _requests->count); + + // Wait until buffer can accomodate the number of input requests + while (_buffer->count >= HE_QAT_BUFFER_SIZE || + (HE_QAT_BUFFER_SIZE - _buffer->count) < _requests->count) + pthread_cond_wait(&_buffer->any_free_slot, &_buffer->mutex); + + assert(_buffer->count < HE_QAT_BUFFER_SIZE); + // assert(_requests->count <= (HE_QAT_BUFFER_SIZE - _buffer->count)); + + for (unsigned int i = 0; i < _requests->count; i++) { + _buffer->data[_buffer->next_free_slot++] = _requests->request[i]; + _buffer->next_free_slot %= HE_QAT_BUFFER_SIZE; + _requests->request[i] = NULL; + } + _buffer->count += _requests->count; + _requests->count = 0; + + pthread_cond_signal(&_buffer->any_more_data); + pthread_mutex_unlock(&_buffer->mutex); + + HE_QAT_PRINT_DBG( + "Unlocked submit request list. [internal buffer size: %d]\n", + _buffer->count); +} + +/// @brief Retrieve multiple requests from the outstanding buffer. +/// @details Thread-safe consumer implementation for the outstanding request +/// buffer. Read requests from outstanding buffer (requests ready to be +/// scheduled) to later pass them to the internal buffer `he_qat_buffer`. As +/// those requests move from the outstanding buffer into the internal buffer, +/// their state changes from ready-to-be-scheduled to ready-to-be-processed. +/// This function is supported both in single-threaded or multi-threaded mode. +/// @param[out] _requests list of requests retrieved from internal buffer. +/// @param[in] _buffer buffer of type HE_QAT_RequestBuffer, typically the +/// internal buffer in current implementation. +/// @param[in] max_requests maximum number of requests to retrieve from internal +/// buffer, if available. +static void read_request_list(HE_QAT_TaskRequestList* _requests, + HE_QAT_RequestBuffer* _buffer, + unsigned int max_requests) { + if (NULL == _requests) return; + + pthread_mutex_lock(&_buffer->mutex); + + // Wait while buffer is empty + while (_buffer->count <= 0) + pthread_cond_wait(&_buffer->any_more_data, &_buffer->mutex); + + assert(_buffer->count > 0); + assert(_buffer->count <= HE_QAT_BUFFER_SIZE); + + unsigned int count = + (_buffer->count < max_requests) ? _buffer->count : max_requests; + + for (unsigned int i = 0; i < count; i++) { + _requests->request[i] = _buffer->data[_buffer->next_data_slot++]; + _buffer->next_data_slot %= HE_QAT_BUFFER_SIZE; + } + _requests->count = count; + _buffer->count -= count; + + pthread_cond_signal(&_buffer->any_free_slot); + pthread_mutex_unlock(&_buffer->mutex); + + return; +} + +/// @brief Read requests from the outstanding buffer. +/// @details Thread-safe consumer implementation for the outstanding request +/// buffer. Retrieve work requests from outstanding buffer (requests ready to be +/// scheduled) to later on pass them to the internal buffer `he_qat_buffer`. As +/// those requests move from the outstanding buffer into the internal buffer, +/// their state changes from ready-to-be-scheduled to ready-to-be-processed. +/// This function is supported in single-threaded or multi-threaded mode. +/// @param[out] _requests list of work requests retrieved from outstanding +/// buffer. +/// @param[in] _outstanding_buffer outstanding buffer holding requests in +/// ready-to-be-scheduled state. +/// @param[in] max_num_requests maximum number of requests to retrieve from +/// outstanding buffer if available. +static void pull_outstanding_requests( + HE_QAT_TaskRequestList* _requests, + HE_QAT_OutstandingBuffer* _outstanding_buffer, + unsigned int max_num_requests) { + if (NULL == _requests) return; + _requests->count = 0; + + // For now, only one thread can change next_ready_buffer + // so no need for synchronization objects + + // Select an outstanding buffer to pull requests and add them into the + // processing queue (internal buffer) + pthread_mutex_lock(&_outstanding_buffer->mutex); + // Wait until next outstanding buffer becomes available for use + while (outstanding.busy_count <= 0) + pthread_cond_wait(&_outstanding_buffer->any_ready_buffer, + &_outstanding_buffer->mutex); + + int any_ready = 0; + unsigned int index = _outstanding_buffer->next_ready_buffer; // no fairness + for (unsigned int i = 0; i < HE_QAT_BUFFER_COUNT; i++) { + index = i; // ensure fairness + if (_outstanding_buffer->ready_buffer[index] && + _outstanding_buffer->buffer[index] + .count) { // sync with mutex at interface + any_ready = 1; + break; + } + // index = (index + 1) % HE_QAT_BUFFER_COUNT; + } + // Ensures it gets picked once only + pthread_mutex_unlock(&_outstanding_buffer->mutex); + + if (!any_ready) return; + + // Extract outstanding requests from outstanding buffer + // (this is the only function that reads from outstanding buffer, + // from a single thread) + pthread_mutex_lock(&_outstanding_buffer->buffer[index].mutex); + + // This conditional waiting may not be required + // Wait while buffer is empty + while (_outstanding_buffer->buffer[index].count <= 0) { + pthread_cond_wait(&_outstanding_buffer->buffer[index].any_more_data, + &_outstanding_buffer->buffer[index].mutex); + } + assert(_outstanding_buffer->buffer[index].count > 0); + + unsigned int num_requests = + (_outstanding_buffer->buffer[index].count < max_num_requests) + ? _outstanding_buffer->buffer[index].count + : max_num_requests; + + assert(num_requests <= HE_QAT_BUFFER_SIZE); + + for (unsigned int i = 0; i < num_requests; i++) { + _requests->request[i] = + _outstanding_buffer->buffer[index] + .data[_outstanding_buffer->buffer[index].next_data_slot]; + _outstanding_buffer->buffer[index].count--; + _outstanding_buffer->buffer[index].next_data_slot++; + _outstanding_buffer->buffer[index].next_data_slot %= HE_QAT_BUFFER_SIZE; + } + _requests->count = num_requests; + + pthread_cond_signal(&_outstanding_buffer->buffer[index].any_free_slot); + pthread_mutex_unlock(&_outstanding_buffer->buffer[index].mutex); + + // --------------------------------------------------------------------------- + // Notify there is an outstanding buffer in ready for the processing queue + // pthread_mutex_lock(&_outstanding_buffer->mutex); + // + // _outstanding_buffer->ready_count--; + // _outstanding_buffer->ready_buffer[index] = 0; + // + // pthread_cond_signal(&_outstanding_buffer->any_free_buffer); + // pthread_mutex_unlock(&_outstanding_buffer->mutex); + + return; +} + +/// @brief Schedule outstanding requests to the internal buffer and be ready for +/// processing. +/// @details Schedule outstanding requests from outstanding buffers to the +/// internal buffer, from which requests are ready to be submitted to the device +/// for processing. +/// @param[in] context_state A volatile integer variable used to activate +/// (val>0) or disactive (val=0) the scheduler. +void* schedule_requests(void* context_state) { + if (NULL == context_state) { + HE_QAT_PRINT_DBG("Failed at buffer_manager: argument is NULL.\n"); + pthread_exit(NULL); + } + + HE_QAT_STATUS* active = (HE_QAT_STATUS*)context_state; + + HE_QAT_TaskRequestList outstanding_requests; + for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { + outstanding_requests.request[i] = NULL; + } + outstanding_requests.count = 0; + + // This thread should receive signal from context to exit + *active = HE_QAT_STATUS_RUNNING; + while (HE_QAT_STATUS_INACTIVE != *active) { + // Collect a set of requests from the outstanding buffer + pull_outstanding_requests(&outstanding_requests, &outstanding, + HE_QAT_BUFFER_SIZE); + // Submit them to the HE QAT buffer for offloading + submit_request_list(&he_qat_buffer, &outstanding_requests); + } + + pthread_exit(NULL); +} + +/// @brief Poll responses from a specific QAT instance. +/// @param[in] _inst_config Instance configuration containing the parameter +/// values to start and poll responses from the accelerator. +static void* start_inst_polling(void* _inst_config) { + if (NULL == _inst_config) { + HE_QAT_PRINT_ERR( + "Failed at start_inst_polling: argument is NULL.\n"); //,__FUNC__); + pthread_exit(NULL); + } + + HE_QAT_InstConfig* config = (HE_QAT_InstConfig*)_inst_config; + + if (NULL == config->inst_handle) return NULL; + + HE_QAT_PRINT_DBG("Instance ID %d Polling\n", config->inst_id); + + // What is harmful for polling without performing any operation? + config->polling = 1; + while (config->polling) { + icp_sal_CyPollInstance(config->inst_handle, 0); + // OS_SLEEP(50); + HE_QAT_SLEEP(50, HE_QAT_MICROSEC); + } + + pthread_exit(NULL); +} + +/// @brief +/// Initialize and start multiple instances, their polling thread, +/// and a single processing thread. +/// +/// @details +/// It initializes multiple QAT instances and launches their respective +/// independent polling threads that will listen to responses to requests sent +/// to the accelerators concurrently. Then, it becomes the thread that collect +/// the incoming requests stored in a shared buffer and send them to the +/// accelerator for processing. This is the only processing thread for requests +/// handled by multiple instances -- unlike when using multiple instances with +/// the `start_perform_op` function, in which case each instance has a separate +/// processing thread. The implementation of the multiple instance support using +/// `start_perform_op` is obsolete and slower. The way is using this function, +/// which delivers better performance. The scheduling of request offloads uses a +/// round-robin approach. It collects multiple requests from the internal buffer +/// and then send them to the multiple accelerator instances to process in a +/// round-robin fashion. It was designed to support processing requests of +/// different operation types but currently only supports Modular +/// Exponentiation. +/// +/// @param[in] _config Data structure containing the configuration of multiple +/// instances. +void* start_instances(void* _config) { + static unsigned int instance_count = 0; + static unsigned int next_instance = 0; + + if (NULL == _config) { + HE_QAT_PRINT_ERR("Failed in start_instances: _config is NULL.\n"); + pthread_exit(NULL); + } + + HE_QAT_Config* config = (HE_QAT_Config*)_config; + instance_count = config->count; + + HE_QAT_PRINT_DBG("Instance Count: %d\n", instance_count); + pthread_t* polling_thread = + (pthread_t*)malloc(sizeof(pthread_t) * instance_count); + if (NULL == polling_thread) { + HE_QAT_PRINT_ERR( + "Failed in start_instances: polling_thread is NULL.\n"); + pthread_exit(NULL); + } + + unsigned* request_count_per_instance = + (unsigned*)malloc(sizeof(unsigned) * instance_count); + if (NULL == request_count_per_instance) { + HE_QAT_PRINT_ERR( + "Failed in start_instances: polling_thread is NULL.\n"); + pthread_exit(NULL); + } + for (unsigned i = 0; i < instance_count; i++) { + request_count_per_instance[i] = 0; + } + + CpaStatus status = CPA_STATUS_FAIL; + for (unsigned int j = 0; j < config->count; j++) { + // Start from zero or restart after stop_perform_op + pthread_mutex_lock(&config->inst_config[j].mutex); + while (config->inst_config[j].active) + pthread_cond_wait(&config->inst_config[j].ready, + &config->inst_config[j].mutex); + + // assert(0 == config->active); + // assert(NULL == config->inst_handle); + + status = cpaCyStartInstance(config->inst_config[j].inst_handle); + config->inst_config[j].status = status; + if (CPA_STATUS_SUCCESS == status) { + HE_QAT_PRINT_DBG("Cpa CyInstance has successfully started.\n"); + status = cpaCySetAddressTranslation( + config->inst_config[j].inst_handle, HE_QAT_virtToPhys); + } + + pthread_cond_signal(&config->inst_config[j].ready); + pthread_mutex_unlock(&config->inst_config[j].mutex); + + if (CPA_STATUS_SUCCESS != status) pthread_exit(NULL); + + HE_QAT_PRINT_DBG("Instance ID: %d\n", config->inst_config[j].inst_id); + + // Start QAT instance and start polling + if (pthread_create(&polling_thread[j], config->inst_config[j].attr, + start_inst_polling, + (void*)&(config->inst_config[j])) != 0) { + HE_QAT_PRINT_ERR( + "Failed at creating and starting polling thread.\n"); + pthread_exit(NULL); + } + + if (pthread_detach(polling_thread[j]) != 0) { + HE_QAT_PRINT_ERR("Failed at detaching polling thread.\n"); + pthread_exit(NULL); + } + + config->inst_config[j].active = 1; + config->inst_config[j].running = 1; + } // for loop + + HE_QAT_TaskRequestList outstanding_requests; + for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { + outstanding_requests.request[i] = NULL; + } + outstanding_requests.count = 0; + + config->running = 1; + config->active = 1; + while (config->running) { + HE_QAT_PRINT_DBG("Try reading request from buffer. Inst #%d\n", + next_instance); + + unsigned long pending = request_count - response_count; + unsigned long available = + max_pending - ((pending < max_pending) ? pending : max_pending); + + HE_QAT_PRINT_DBG( + "[CHECK] request_count: %lu response_count: %lu pending: %lu " + "available: %lu\n", + request_count, response_count, pending, available); + + while (available < restart_threshold) { + HE_QAT_PRINT_DBG("[WAIT]\n"); + + // argument passed in microseconds + HE_QAT_SLEEP(RESTART_LATENCY_MICROSEC, HE_QAT_MICROSEC); + pending = request_count - response_count; + available = + max_pending - ((pending < max_pending) ? pending : max_pending); + HE_QAT_PRINT_DBG( + "[CHECK] request_count: %lu response_count: %lu pending: %lu " + "available: %lu\n", + request_count, response_count, pending, available); + } + HE_QAT_PRINT_DBG( + "[SUBMIT] request_count: %lu response_count: %lu pending: %lu " + "available: %lu\n", + request_count, response_count, pending, available); + + unsigned int max_requests = available; + + // Try consume maximum amount of data from butter to perform requested + // operation + read_request_list(&outstanding_requests, &he_qat_buffer, max_requests); + + HE_QAT_PRINT_DBG("Offloading %u requests to the accelerator.\n", + outstanding_requests.count); + + for (unsigned int i = 0; i < outstanding_requests.count; i++) { + HE_QAT_TaskRequest* request = outstanding_requests.request[i]; +#ifdef HE_QAT_SYNC_MODE + COMPLETION_INIT(&request->callback); +#endif + + unsigned retry = 0; + do { + // Realize the type of operation from data + switch (request->op_type) { + // Select appropriate action + case HE_QAT_OP_MODEXP: + HE_QAT_PRINT_DBG("Offload request using instance #%d\n", + next_instance); +#ifdef HE_QAT_PERF + gettimeofday(&request->start, NULL); +#endif + status = cpaCyLnModExp( + config->inst_config[next_instance].inst_handle, + (CpaCyGenFlatBufCbFunc) + request->callback_func, // lnModExpCallback, + (void*)request, (CpaCyLnModExpOpData*)request->op_data, + &request->op_result); + retry++; + break; + case HE_QAT_OP_NONE: + default: + HE_QAT_PRINT_DBG("HE_QAT_OP_NONE to instance #%d\n", + next_instance); + retry = HE_QAT_MAX_RETRY; + break; + } + + if (CPA_STATUS_RETRY == status) { + HE_QAT_PRINT_DBG("CPA requested RETRY\n"); + HE_QAT_PRINT_DBG("RETRY count = %u\n", retry); + pthread_exit(NULL); // halt the whole system + } + } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); + + // Ensure every call to perform operation is blocking for each + // endpoint + if (CPA_STATUS_SUCCESS == status) { + // Global tracking of number of requests + request_count += 1; + request_count_per_instance[next_instance] += 1; + next_instance = (next_instance + 1) % instance_count; + + // Wake up any blocked call to stop_perform_op, signaling that + // now it is safe to terminate running instances. Check if this + // detereorate performance. + // TODO(fdiasmor): Check if prone to the lost wake-up problem. + pthread_cond_signal(&config->inst_config[next_instance].ready); + +#ifdef HE_QAT_SYNC_MODE + // Wait until the callback function has been called + if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { + request->op_status = CPA_STATUS_FAIL; + request->request_status = HE_QAT_STATUS_FAIL; // Review it + HE_QAT_PRINT_ERR("Failed in COMPLETION WAIT\n"); + } + + // Destroy synchronization object + COMPLETION_DESTROY(&request->callback); +#endif + } else { + request->op_status = CPA_STATUS_FAIL; + request->request_status = HE_QAT_STATUS_FAIL; // Review it + HE_QAT_PRINT_ERR("Request Submission FAILED\n"); + } + + HE_QAT_PRINT_DBG("Offloading completed by instance #%d\n", + next_instance - 1); + + // Reset pointer + outstanding_requests.request[i] = NULL; + request = NULL; + } // for loop over batch of requests + outstanding_requests.count = 0; + } + pthread_exit(NULL); +} + +/// @brief +/// Start independent processing and polling threads for an instance. +/// +/// @details +/// It initializes a QAT instance and launches its polling thread to listen +/// to responses (request outputs) from the accelerator. It is also +/// reponsible +/// to collect requests from the internal buffer and send them to the +/// accelerator periodiacally. It was designed to extend to receiving +/// and offloading requests of different operation types but currently only +/// supports Modular Exponentiation. +/// +/// @param[in] _inst_config Data structure containing the configuration of a +/// single +/// instance. +void* start_perform_op(void* _inst_config) { + if (NULL == _inst_config) { + HE_QAT_PRINT_ERR("Failed in start_perform_op: _inst_config is NULL.\n"); + pthread_exit(NULL); + } + + HE_QAT_InstConfig* config = (HE_QAT_InstConfig*)_inst_config; + + CpaStatus status = CPA_STATUS_FAIL; + + // Start from zero or restart after stop_perform_op + pthread_mutex_lock(&config->mutex); + while (config->active) pthread_cond_wait(&config->ready, &config->mutex); + + // assert(0 == config->active); + // assert(NULL == config->inst_handle); + + status = cpaCyStartInstance(config->inst_handle); + config->status = status; + if (CPA_STATUS_SUCCESS == status) { + HE_QAT_PRINT_DBG("Cpa CyInstance has successfully started.\n"); + status = + cpaCySetAddressTranslation(config->inst_handle, HE_QAT_virtToPhys); + } + + pthread_cond_signal(&config->ready); + pthread_mutex_unlock(&config->mutex); + + if (CPA_STATUS_SUCCESS != status) pthread_exit(NULL); + + // Start QAT instance and start polling + pthread_t polling_thread; + if (pthread_create(&polling_thread, config->attr, start_inst_polling, + (void*)config) != 0) { + HE_QAT_PRINT_ERR("Failed at creating and starting polling thread.\n"); + pthread_exit(NULL); + } + + if (pthread_detach(polling_thread) != 0) { + HE_QAT_PRINT_ERR("Failed at detaching polling thread.\n"); + pthread_exit(NULL); + } + + HE_QAT_TaskRequestList outstanding_requests; + for (unsigned int i = 0; i < HE_QAT_BUFFER_SIZE; i++) { + outstanding_requests.request[i] = NULL; + } + outstanding_requests.count = 0; + + config->running = 1; + config->active = 1; + while (config->running) { + HE_QAT_PRINT_DBG("Try reading request from buffer. Inst #%d\n", + config->inst_id); + + unsigned long pending = request_count - response_count; + unsigned long available = + max_pending - ((pending < max_pending) ? pending : max_pending); + + HE_QAT_PRINT_DBG( + "[CHECK] request_count: %lu response_count: %lu pending: %lu " + "available: %lu\n", + request_count, response_count, pending, available); + + while (available < restart_threshold) { + HE_QAT_PRINT_DBG("[WAIT]\n"); + + HE_QAT_SLEEP(650, HE_QAT_MICROSEC); + + pending = request_count - response_count; + available = + max_pending - ((pending < max_pending) ? pending : max_pending); + } + HE_QAT_PRINT_DBG( + "[SUBMIT] request_count: %lu response_count: %lu pending: %lu " + "available: %lu\n", + request_count, response_count, pending, available); + + unsigned int max_requests = available; + + // Try consume maximum amount of data from butter to perform requested + // operation + read_request_list(&outstanding_requests, &he_qat_buffer, max_requests); + + // // Try consume data from butter to perform requested operation + // HE_QAT_TaskRequest* request = + // (HE_QAT_TaskRequest*)read_request(&he_qat_buffer); + // + // if (NULL == request) { + // pthread_cond_signal(&config->ready); + // continue; + // } + HE_QAT_PRINT_DBG("Offloading %u requests to the accelerator.\n", + outstanding_requests.count); + + for (unsigned int i = 0; i < outstanding_requests.count; i++) { + HE_QAT_TaskRequest* request = outstanding_requests.request[i]; +#ifdef HE_QAT_SYNC_MODE + COMPLETION_INIT(&request->callback); +#endif + unsigned retry = 0; + do { + // Realize the type of operation from data + switch (request->op_type) { + // Select appropriate action + case HE_QAT_OP_MODEXP: + // if (retry > 0) HE_QAT_PRINT_DBG("Try offloading again + // last request\n"); + HE_QAT_PRINT_DBG("Offload request using instance #%d\n", + config->inst_id); +#ifdef HE_QAT_PERF + gettimeofday(&request->start, NULL); +#endif + status = cpaCyLnModExp( + config->inst_handle, + (CpaCyGenFlatBufCbFunc) + request->callback_func, // lnModExpCallback, + (void*)request, (CpaCyLnModExpOpData*)request->op_data, + &request->op_result); + retry++; + break; + case HE_QAT_OP_NONE: + default: + HE_QAT_PRINT_DBG("HE_QAT_OP_NONE to instance #%d\n", + config->inst_id); + retry = HE_QAT_MAX_RETRY; + break; + } + + if (CPA_STATUS_RETRY == status) { + HE_QAT_PRINT_DBG("CPA requested RETRY\n"); + HE_QAT_PRINT_DBG("RETRY count: %u\n", retry); + HE_QAT_SLEEP(600, HE_QAT_MICROSEC); + } + } while (CPA_STATUS_RETRY == status && retry < HE_QAT_MAX_RETRY); + + // Ensure every call to perform operation is blocking for each + // endpoint + if (CPA_STATUS_SUCCESS == status) { + // Global tracking of number of requests + request_count += 1; + + HE_QAT_PRINT_DBG("retry_count = %d\n", retry_count); +#ifdef HE_QAT_SYNC_MODE + // Wait until the callback function has been called + if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { + request->op_status = CPA_STATUS_FAIL; + request->request_status = HE_QAT_STATUS_FAIL; // Review it + HE_QAT_PRINT_ERR("Failed in COMPLETION WAIT\n"); + } + + // Destroy synchronization object + COMPLETION_DESTROY(&request->callback); +#endif + } else { + request->op_status = CPA_STATUS_FAIL; + request->request_status = HE_QAT_STATUS_FAIL; // Review it + } + + // Reset pointer + outstanding_requests.request[i] = NULL; + request = NULL; + } // for loop over batch of requests + outstanding_requests.count = 0; + + // Wake up any blocked call to stop_perform_op, signaling that now it is + // safe to terminate running instances. Check if this detereorate + // performance. + // TODO(fdiasmor): Check if prone to the lost wake-up problem. + pthread_cond_signal(&config->ready); + + HE_QAT_PRINT_DBG("Offloading completed by instance #%d\n", + config->inst_id); + } + pthread_exit(NULL); +} + +/// @brief +/// Stop specified number of instances from running. +/// +/// @details +/// Stop first 'num_inst' number of cpaCyInstance(s), including their +/// polling and running threads. Stop runnning and polling instances. +/// Release QAT instances handles. +/// +/// @param[in] config List of all created QAT instances and their +/// configurations. +/// @param[in] num_inst Unsigned integer number indicating first number of +/// instances to be terminated. +void stop_perform_op(HE_QAT_InstConfig* config, unsigned num_inst) { + if (NULL == config) return; + + CpaStatus status = CPA_STATUS_FAIL; + for (unsigned i = 0; i < num_inst; i++) { + pthread_mutex_lock(&config[i].mutex); + + HE_QAT_PRINT_DBG("Try teardown HE QAT instance #%d.\n", i); + + while (0 == config[i].active) { + pthread_cond_wait(&config[i].ready, &config[i].mutex); + } + + if (CPA_STATUS_SUCCESS == config[i].status && config[i].active) { + HE_QAT_PRINT_DBG("Stop polling and running threads #%d\n", i); + + config[i].polling = 0; + config[i].running = 0; + + HE_QAT_SLEEP(10, HE_QAT_MICROSEC); + + HE_QAT_PRINT_DBG("Stop cpaCyInstance #%d\n", i); + if (config[i].inst_handle == NULL) continue; + + HE_QAT_PRINT_DBG("cpaCyStopInstance\n"); + status = cpaCyStopInstance(config[i].inst_handle); + if (CPA_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("Failed to stop QAT instance #%d\n", i); + } + } + pthread_cond_signal(&config[i].ready); + pthread_mutex_unlock(&config[i].mutex); + } + + return; +} + +/// @brief Stop all running instances. +/// @details +/// Stop all running instances after calling `start_instances()`. +/// It will set the states of the instances to terminate gracefully. +/// @param[in] _config All QAT instances configurations holding their states. +void stop_instances(HE_QAT_Config* _config) { + if (NULL == _config) return; + if (_config->active) _config->active = 0; + if (_config->running) _config->running = 0; + stop_perform_op(_config->inst_config, _config->count); + return; +} diff --git a/module/heqat/heqat/include/heqat/bnops.h b/module/heqat/heqat/include/heqat/bnops.h new file mode 100644 index 0000000..346c9a4 --- /dev/null +++ b/module/heqat/heqat/include/heqat/bnops.h @@ -0,0 +1,154 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +/// @file heqat/bnops.h +/// +/// @details +/// In this file, functions for Big Number operations accelerated by the +/// QuickAssist (QAT) co-processor are specified. +/// +/// @note +/// Unless otherwise specified, Big numbers are represented by octet strings +/// and stored in memory as pointers of type unsigned char*. On the QAT API +/// the octet string is copied into a data structure of type +/// CpaFlatBuffer. The octet strings representing Big Numbers are encoded +/// with compliance to PKCA#1 v2.1, section 4, which is consistent with +/// ASN.1 syntax. +/// The largest number supported here has 8192 bits, i.e. numbers from 0 to +/// 2^(8192)-1. If the number is N, then the bit length is defined by n = +/// floor(log2(N))+1. The memory buffer b to hold such number N needs to +/// have at least M = ceiling(n/8) bytes allocated. In general, it will be +/// larger and a power of 2, e.g. total bytes allocated is T=128 for +/// numbers having up to n=1024 bits, total bytes allocated is T=256 for +/// numbers having up to n=2048 bits, and so forth. Finally, the big number +/// N is stored in `big endian` format, i.e. the least significant byte +/// (LSB) is located at index [T-1], whereas the most significant byte is +/// stored at [T-M]. +/// +/// The API client is responsible for allocation and release of their memory +/// spaces of the function arguments. Allocated memory spaces must be +/// contiguous. Once a function is called, the ownership of the memory +/// spaces is transferred to the function until their completion such +/// that concurrent usage by the client during execution may result in +/// undefined behavior. + +// New compilers +#pragma once + +// Legacy compilers +#ifndef _HE_QAT_BN_OPS_H_ +#define _HE_QAT_BN_OPS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "heqat/common/types.h" + +/// @brief Performs modular exponentiation using BIGNUM data structure. +/// +/// @details +/// Perform big number modular exponentiation operation accelerated with QAT for +/// input data using OpenSSL BIGNUM data structure. Create QAT contiguous memory +/// space. Copy BIGNUM binary data and package it into a request (HE_QAT_Request +/// data structure) and call producer function to submit request to the internal +/// buffer. +/// +/// @param[out] r Remainder number of the modular exponentiation operation. +/// @param[in] b Base number of the modular exponentiation operation. +/// @param[in] e Exponent number of the modular exponentiation operation. +/// @param[in] m Modulus number of the modular exponentiation operation. +/// @param[in] nbits Number of bits (bit precision) of input/output big numbers. +HE_QAT_STATUS HE_QAT_BIGNUMModExp(BIGNUM* r, BIGNUM* b, BIGNUM* e, BIGNUM* m, + int nbits); + +/// @brief Performs big number modular exponentiation for input data (an octet +/// string) in primitive type format (unsigned char *). +/// +/// @details +/// Perform big number modular exponentiation operation accelerated with QAT for +/// input data as an octet string of unsigned chars. Create QAT contiguous +/// memory space. Upon call it copies input data and package it into a request, +/// then calls producer function to submit request to internal buffer. +/// +/// @param[out] r Remainder number of the modular exponentiation operation. +/// @param[in] b Base number of the modular exponentiation operation. +/// @param[in] e Exponent number of the modular exponentiation operation. +/// @param[in] m Modulus number of the modular exponentiation operation. +/// @param[in] nbits Number of bits (bit precision) of input/output big numbers. +HE_QAT_STATUS HE_QAT_bnModExp(unsigned char* r, unsigned char* b, + unsigned char* e, unsigned char* m, int nbits); + +/// @brief +/// It waits for number of requests sent by HE_QAT_bnModExp or +/// HE_QAT_BIGNUMModExp to complete. +/// +/// @details +/// This function is blocking and works as a barrier. The purpose of this +/// function is to wait for all outstanding requests to complete processing. It +/// will also release all temporary memory allocated used to support the +/// submission and processing of the requests. It monitors outstanding requests +/// to be completed and then it deallocates buffer holding outstanding request. +/// +/// @param[in] num_requests Number of requests to wait for processing +/// completion. +void getBnModExpRequest(unsigned int num_requests); + +/** + * + * Interfaces for the Multithreading Support + * + **/ + +/// @brief Performs big number modular exponentiation for input data (an octet +/// string) in primitive type format (unsigned char *). Same as HE_QAT_bnModExp +/// with multithreading support. +/// +/// @details +/// Perform big number modular exponentiation operation accelerated with QAT for +/// input data as an octet string of unsigned chars. Create QAT contiguous +/// memory space. Upon call it copies input data and package it into a request, +/// then calls producer function to submit request to internal buffer. +/// +/// @param[in] _buffer_id Buffer ID of the reserved buffer for the caller's +/// thread. +/// @param[out] r Remainder number of the modular exponentiation operation. +/// @param[in] b Base number of the modular exponentiation operation. +/// @param[in] e Exponent number of the modular exponentiation operation. +/// @param[in] m Modulus number of the modular exponentiation operation. +/// @param[in] nbits Number of bits (bit precision) of input/output big numbers. +HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, + unsigned char* b, unsigned char* e, + unsigned char* m, int nbits); + +/// @brief Reserve/acquire buffer for multithreading support. +/// +/// @details Try to acquire an available buffer to store outstanding work +/// requests sent by caller. +/// If none is available, it blocks further processing and waits until +/// another caller's concurrent thread releases one. This function must +/// be called before calling HE_QAT_bnModExp_MT(.). +/// +/// @param[out] _buffer_id Memory space address allocated by caller to hold the +/// buffer ID of the buffer used to store caller's outstanding requests. +HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id); + +/// @brief Wait for request processing to complete and release previously +/// acquired buffer. +/// +/// @details Caution: It assumes acquire_bnModExp_buffer(&_buffer_id) to be +/// called first to secure and be assigned an outstanding buffer for the target +/// thread. Equivalent to getBnModExpRequests() for the multithreading support +/// interfaces. +/// +/// param[in] _buffer_id Buffer ID of the buffer to be released/unlock for reuse +/// by the next concurrent thread. param[in] _batch_size Total number of +/// requests to wait for completion before releasing the buffer. +void release_bnModExp_buffer(unsigned int _buffer_id, unsigned int _batch_size); + +#ifdef __cplusplus +} // extern "C" { +#endif + +#endif diff --git a/module/heqat/heqat/include/heqat/common.h b/module/heqat/heqat/include/heqat/common.h new file mode 100644 index 0000000..2c94a58 --- /dev/null +++ b/module/heqat/heqat/include/heqat/common.h @@ -0,0 +1,18 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +/// @file heqat/common.h + +#ifndef MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_COMMON_H_ +#define MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_COMMON_H_ + +#include "heqat/common/consts.h" +#include "heqat/common/types.h" +#include "heqat/common/utils.h" + +#ifdef __cplusplus +#ifdef HE_QAT_MISC +#include "heqat/misc.h" +#endif +#endif + +#endif // MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_COMMON_H_ diff --git a/module/heqat/heqat/include/heqat/common/consts.h b/module/heqat/heqat/include/heqat/common/consts.h new file mode 100644 index 0000000..4b7c63d --- /dev/null +++ b/module/heqat/heqat/include/heqat/common/consts.h @@ -0,0 +1,18 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +/// @file heqat/common/consts.h + +#pragma once + +#ifndef _HE_QAT_CONST_H_ +#define _HE_QAT_CONST_H_ + +// Local Constants +#define HE_QAT_NUM_ACTIVE_INSTANCES 8 +#define HE_QAT_BUFFER_SIZE 1024 +#define HE_QAT_BUFFER_COUNT HE_QAT_NUM_ACTIVE_INSTANCES +#define HE_QAT_MAX_RETRY 100 +#define RESTART_LATENCY_MICROSEC 600 +#define NUM_PKE_SLICES 6 + +#endif // _HE_QAT_CONST_H_ diff --git a/module/heqat/heqat/include/heqat/common/types.h b/module/heqat/heqat/include/heqat/common/types.h new file mode 100644 index 0000000..e3790f8 --- /dev/null +++ b/module/heqat/heqat/include/heqat/common/types.h @@ -0,0 +1,186 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +/// @file heqat/common/types.h + +#pragma once + +#ifndef _HE_QAT_TYPES_H_ +#define _HE_QAT_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// C Libraries +#include +#include +#ifdef HE_QAT_PERF +#include +#endif + +// QATLib Headers +#include +#include +#include + +#include "heqat/common/consts.h" + +struct completion_struct { + sem_t semaphore; +}; + +// Type definitions +typedef enum { HE_QAT_SYNC = 1, HE_QAT_ASYNC = 2 } HE_QAT_EXEC_MODE; + +typedef enum { + HE_QAT_STATUS_ACTIVE = 3, + HE_QAT_STATUS_RUNNING = 4, + HE_QAT_STATUS_INVALID_PARAM = 2, + HE_QAT_STATUS_READY = 1, + HE_QAT_STATUS_SUCCESS = 0, + HE_QAT_STATUS_FAIL = -1, + HE_QAT_STATUS_INACTIVE = -2 +} HE_QAT_STATUS; + +typedef enum { + HE_QAT_OP_NONE = 0, ///< No Operation (NO OP) + HE_QAT_OP_MODEXP = 1 ///< QAT Modular Exponentiation +} HE_QAT_OP; + +typedef enum { + HE_QAT_NANOSEC = 1000000000, + HE_QAT_MICROSEC = 1000000, + HE_QAT_MILLISEC = 1000, + HE_QAT_SEC = 1 +} HE_QAT_TIME_UNIT; + +typedef pthread_t HE_QAT_Inst; + +typedef struct { + void* data[HE_QAT_BUFFER_SIZE]; ///< Stores work requests ready to be sent + ///< to the accelerator. + volatile unsigned int count; ///< Tracks the number of occupied + ///< entries/slots in the data[] buffer. + // nextin index of the next free slot for a request + unsigned int next_free_slot; ///< Index of the next slot available to store + ///< a new request. + // nextout index of next request to be processed + unsigned int next_data_slot; ///< Index of the next slot containing request + ///< ready to be consumed for processing. + // index of next output data to be read by a thread waiting + // for all the request to complete processing + unsigned int + next_data_out; ///< Index of the next slot containing request whose + ///< processing has been completed and its output is + ///< ready to be consumed by the caller. + pthread_mutex_t mutex; ///< Synchronization object used to control access + ///< to the buffer. + pthread_cond_t + any_more_data; ///< Conditional variable used to synchronize the + ///< consumption of data in buffer (wait until more data + ///< is available to be consumed). + pthread_cond_t any_free_slot; ///< Conditional variable used to synchronize + ///< the provision of free slots in buffer + ///< (wait until enough slots are available + ///< to add more data in buffer). +} HE_QAT_RequestBuffer; + +typedef struct { + HE_QAT_RequestBuffer + buffer[HE_QAT_BUFFER_COUNT]; ///< Buffers to support concurrent threads + ///< with less sync overhead. Stores + ///< incoming request from different + ///< threads. + unsigned int busy_count; ///< Counts number of currently occupied buffers. + unsigned int next_free_buffer; ///< Next in: index of the next free slot + ///< for a request. + int free_buffer + [HE_QAT_BUFFER_COUNT]; ///< Keeps track of buffers that are available + ///< (any value > 0 means the buffer at index i + ///< is available). The next_free_buffer does + ///< not necessarily mean that the buffer is + ///< already released from usage. + unsigned int next_ready_buffer; ///< Next out: index of next request to be + ///< processed. + int ready_buffer + [HE_QAT_BUFFER_COUNT]; ///< Keeps track of buffers that are ready (any + ///< value > 0 means the buffer at index i is + ///< ready). The next_ready_buffer does not + ///< necessarily mean that the buffer is not + ///< busy at any time instance. + pthread_mutex_t mutex; ///< Used for synchronization of concurrent access + ///< of an object of the type + pthread_cond_t + any_ready_buffer; ///< Conditional variable used to synchronize the + ///< consumption of the contents in the buffers + ///< storing outstanding requests and ready to be + ///< scheduled to move to the internal buffer. + pthread_cond_t + any_free_buffer; ///< Conditional variable used to synchronize the + ///< provisioning of buffers to store incoming + ///< requests from concurrent threads. +} HE_QAT_OutstandingBuffer; + +typedef struct { + int inst_id; ///< QAT instance ID. + CpaInstanceHandle inst_handle; ///< Handle of this QAT instance. + pthread_attr_t* attr; ///< Unused member. + HE_QAT_RequestBuffer* he_qat_buffer; ///< Unused member. + pthread_mutex_t mutex; + pthread_cond_t ready; + volatile int active; ///< State of this QAT instance. + volatile int + polling; ///< State of this QAT instance's polling thread (any value + ///< different from 0 indicates that it is running). + volatile int + running; ///< State of this QAT instance's processing thread (any value + ///< different from 0 indicates that it is running). + CpaStatus status; ///< Status of the latest activity by this QAT instance. +} HE_QAT_InstConfig; + +typedef struct { + HE_QAT_InstConfig* + inst_config; ///< List of the QAT instance's configurations. + volatile int active; ///< Value different from 0 indicates all QAT + ///< instances are created and active. + volatile int running; ///< Value different from 0 indicates all created QAT + ///< instances are running. + unsigned int count; ///< Total number of created QAT instances. +} HE_QAT_Config; + +// One for each consumer +typedef struct { + unsigned long long id; ///< Work request ID. + // sem_t callback; + struct completion_struct callback; ///< Synchronization object. + HE_QAT_OP + op_type; ///< Work type: type of operation to be offloaded to QAT. + CpaStatus op_status; ///< Status of the operation after completion. + CpaFlatBuffer op_result; ///< Output of the operation in contiguous memory. + // CpaCyLnModExpOpData op_data; + void* op_data; ///< Input data packaged in QAT's data structure for the + ///< target type of operation. + void* op_output; ///< Pointer to the memory space where to store the output + ///< for the caller. + void* callback_func; ///< Pointer to the callback function. + volatile HE_QAT_STATUS request_status; + pthread_mutex_t mutex; + pthread_cond_t ready; +#ifdef HE_QAT_PERF + struct timeval + start; ///< Time when the request was first received from the caller. + struct timeval end; ///< Time when the request completed processing and + ///< callback function was triggered. +#endif +} HE_QAT_TaskRequest; + +typedef struct { + HE_QAT_TaskRequest* request[HE_QAT_BUFFER_SIZE]; + unsigned int count; +} HE_QAT_TaskRequestList; + +#ifdef __cplusplus +} // close the extern "C" { +#endif + +#endif // _HE_QAT_TYPES_H_ diff --git a/module/heqat/heqat/include/heqat/common/utils.h b/module/heqat/heqat/include/heqat/common/utils.h new file mode 100644 index 0000000..21d19e2 --- /dev/null +++ b/module/heqat/heqat/include/heqat/common/utils.h @@ -0,0 +1,169 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +/// @file heqat/common/utils.h + +#pragma once + +#ifndef MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_MISC_UTILS_H_ +#define MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_MISC_UTILS_H_ + +#ifdef __cplusplus +#define HE_QAT_RESTRICT __restrict__ +#else +#define HE_QAT_RESTRICT restrict +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include + +#include "heqat/common/types.h" + +#ifndef BYTE_ALIGNMENT_8 +#define BYTE_ALIGNMENT_8 (8) +#endif +#ifndef BYTE_ALIGNMENT_64 +#define BYTE_ALIGNMENT_64 (64) +#endif + +// 5 seconds +#ifndef TIMEOUT_MS +#define TIMEOUT_MS 5000 +#endif + +// Printing Functions +#ifdef HE_QAT_DEBUG +#define HE_QAT_PRINT_DBG(args...) \ + do { \ + printf("%s(): ", __func__); \ + printf("%s", args); \ + fflush(stdout); \ + } while (0) +#else +#define HE_QAT_PRINT_DBG(args...) \ + {} +#endif + +#ifndef HE_QAT_PRINT +#define HE_QAT_PRINT(args...) \ + do { \ + printf("%s", args); \ + } while (0) +#endif + +#ifndef HE_QAT_PRINT_ERR +#define HE_QAT_PRINT_ERR(args...) \ + do { \ + printf("%s(): ", __func__); \ + printf("%s", args); \ + } while (0) +#endif + +// Use semaphores to signal completion of events +#define COMPLETION_STRUCT completion_struct +#define COMPLETION_INIT(s) sem_init(&((s)->semaphore), 0, 0); +#define COMPLETION_WAIT(s, timeout) (sem_wait(&((s)->semaphore)) == 0) +#define COMPLETE(s) sem_post(&((s)->semaphore)) +#define COMPLETION_DESTROY(s) sem_destroy(&((s)->semaphore)) + +/// @brief +/// This function and associated macro allocates the memory for the given +/// size for the given alignment and stores the address of the memory +/// allocated in the pointer. Memory allocated by this function is +/// guaranteed to be physically contiguous. +/// +/// @param[out] ppMemAddr address of pointer where address will be stored +/// @param[in] sizeBytes the size of the memory to be allocated +/// @param[in] alignment the alignment of the memory to be allocated +/// (non-zero) +/// @param[in] node the allocate memory that is local to cpu(node) +/// +/// @retval HE_QAT_STATUS_FAIL Failed to allocate memory. +/// @retval HE_QAT_STATUS_SUCCESS Memory successfully allocated. +static __inline HE_QAT_STATUS HE_QAT_memAllocContig(void** ppMemAddr, + Cpa32U sizeBytes, + Cpa32U alignment, + Cpa32U node) { + *ppMemAddr = qaeMemAllocNUMA(sizeBytes, node, alignment); + if (NULL == *ppMemAddr) { + return HE_QAT_STATUS_FAIL; + } + return HE_QAT_STATUS_SUCCESS; +} +#define HE_QAT_MEM_ALLOC_CONTIG(ppMemAddr, sizeBytes, alignment) \ + HE_QAT_memAllocContig((void*)(ppMemAddr), (sizeBytes), (alignment), 0) + +/// @brief +/// This function and associated macro frees the memory at the given +/// address and resets the pointer to NULL. The memory must have been +/// allocated by the function Mem_Alloc_Contig(). +/// +/// @param[out] ppMemAddr address of pointer where mem address is stored. +/// If pointer is NULL, the function will exit silently +static __inline void HE_QAT_memFreeContig(void** ppMemAddr) { + if (NULL != *ppMemAddr) { + qaeMemFreeNUMA(ppMemAddr); + *ppMemAddr = NULL; + } +} +#define HE_QAT_MEM_FREE_CONTIG(pMemAddr) HE_QAT_memFreeContig((void*)&pMemAddr) + +/// @brief Sleep for time unit. +/// @param[in] time Unsigned integer representing +/// amount of time. +/// @param[in] unit Time unit of the amount of time +/// passed in the first parameter. Unit values can be +/// HE_QAT_NANOSEC (nano seconds), HE_QAT_MICROSEC +/// (micro seconds), HE_QAT_MILLISEC (milli seconds), +/// or HE_QAT_SEC (seconds). +static __inline HE_QAT_STATUS HE_QAT_sleep(unsigned int time, + HE_QAT_TIME_UNIT unit) { + int ret = 0; + struct timespec resTime, remTime; + + resTime.tv_sec = time / unit; + resTime.tv_nsec = (time % unit) * (HE_QAT_NANOSEC / unit); + + do { + ret = nanosleep(&resTime, &remTime); + resTime = remTime; + } while ((0 != ret) && (EINTR == errno)); + + if (0 != ret) { + HE_QAT_PRINT_ERR("nano sleep failed with code %d\n", ret); + return HE_QAT_STATUS_FAIL; + } else { + return HE_QAT_STATUS_SUCCESS; + } +} +#define HE_QAT_SLEEP(time, timeUnit) HE_QAT_sleep((time), (timeUnit)) + +/// @brief +/// This function returns the physical address +/// for a given virtual address. In case of error +/// 0 is returned. +/// @param[in] virtAddr Virtual address +/// @retval CpaPhysicalAddr Physical address or 0 in +/// case of error +static __inline CpaPhysicalAddr HE_QAT_virtToPhys(void* virtAddr) { + return (CpaPhysicalAddr)qaeVirtToPhysNUMA(virtAddr); +} + +BIGNUM* generateTestBNData(int nbits); + +unsigned char* paddingZeros(BIGNUM* bn, int nbits); + +void showHexBN(BIGNUM* bn, int nbits); + +void showHexBin(unsigned char* bin, int len); + +#ifdef __cplusplus +} // extern "C" { +#endif + +#endif // MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_MISC_UTILS_H_ diff --git a/module/heqat/heqat/include/heqat/context.h b/module/heqat/heqat/include/heqat/context.h new file mode 100644 index 0000000..abe9be5 --- /dev/null +++ b/module/heqat/heqat/include/heqat/context.h @@ -0,0 +1,32 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +/// @file heqat/context.h + +#pragma once + +#ifndef _HE_QAT_CONTEXT_H_ +#define _HE_QAT_CONTEXT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "heqat/common/types.h" + +/// @brief +/// Configure and initialize QAT runtime environment. +HE_QAT_STATUS acquire_qat_devices(); + +/// @brief +/// Release and free resources of the QAT runtime environment. +HE_QAT_STATUS release_qat_devices(); + +/// @brief +/// Probe context status of the QAT runtime environment. +HE_QAT_STATUS get_qat_context_state(); + +#ifdef __cplusplus +} // extern "C" { +#endif + +#endif diff --git a/module/heqat/heqat/include/heqat/heqat.h b/module/heqat/heqat/include/heqat/heqat.h new file mode 100644 index 0000000..6c5e4a8 --- /dev/null +++ b/module/heqat/heqat/include/heqat/heqat.h @@ -0,0 +1,12 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +/// @file heqat/heqat.h + +#ifndef MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_HEQAT_H_ +#define MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_HEQAT_H_ + +#include "heqat/common.h" +#include "heqat/context.h" +#include "heqat/bnops.h" + +#endif // MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_HEQAT_H_ diff --git a/module/heqat/heqat/include/heqat/misc.h b/module/heqat/heqat/include/heqat/misc.h new file mode 100644 index 0000000..9a396bc --- /dev/null +++ b/module/heqat/heqat/include/heqat/misc.h @@ -0,0 +1,38 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +/// @file heqat/misc.h + +#pragma once + +#ifndef HE_QAT_MISC_H_ +#define HE_QAT_MISC_H_ + +#include "heqat/common/consts.h" +#include "heqat/common/types.h" + +#ifdef __cplusplus + +#include "heqat/misc/bignum.h" + +/// @brief +/// Convert QAT large number into little endian format and encapsulate it into a +/// BigNumber object. +/// @param[out] bn BigNumber object representing multi-precision number in +/// little endian format. +/// @param[in] data Large number of nbits precision in big endian format. +/// @param[in] nbits Number of bits. Has to be power of 2, e.g. 1024, 2048, +/// 4096, etc. +HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, + int nbits); +/// @brief +/// Convert BigNumber object into raw data compatible with QAT. +/// @param[out] data BigNumber object's raw data in big endian format. +/// @param[in] nbits Number of bits. Has to be power of 2, e.g. 1024, 2048, +/// 4096, etc. +/// @param[in] bn BigNumber object holding a multi-precision that can be +/// represented in nbits. +HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, + const BigNumber& bn); +#endif // __cpluscplus + +#endif // HE_QAT_MISC_H_ diff --git a/module/heqat/heqat/include/heqat/misc/bignum.h b/module/heqat/heqat/include/heqat/misc/bignum.h new file mode 100644 index 0000000..1e83f01 --- /dev/null +++ b/module/heqat/heqat/include/heqat/misc/bignum.h @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright 2019-2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + +#if !defined _BIGNUMBER_H_ +#define _BIGNUMBER_H_ + +#include "ippcp.h" + +#include +#include +#include + +using namespace std; + +class BigNumber { +public: + BigNumber(Ipp32u value = 0); + BigNumber(Ipp32s value); + BigNumber(const IppsBigNumState* pBN); + BigNumber(const Ipp32u* pData, int length = 1, + IppsBigNumSGN sgn = IppsBigNumPOS); + BigNumber(const BigNumber& bn); + BigNumber(const char* s); + virtual ~BigNumber(); + + // set value + void Set(const Ipp32u* pData, int length = 1, + IppsBigNumSGN sgn = IppsBigNumPOS); + // conversion to IppsBigNumState + friend IppsBigNumState* BN(const BigNumber& bn) { return bn.m_pBN; } + operator IppsBigNumState*() const { return m_pBN; } + + // some useful constants + static const BigNumber& Zero(); + static const BigNumber& One(); + static const BigNumber& Two(); + + // arithmetic operators probably need + BigNumber& operator=(const BigNumber& bn); + BigNumber& operator+=(const BigNumber& bn); + BigNumber& operator-=(const BigNumber& bn); + BigNumber& operator*=(Ipp32u n); + BigNumber& operator*=(const BigNumber& bn); + BigNumber& operator/=(const BigNumber& bn); + BigNumber& operator%=(const BigNumber& bn); + friend BigNumber operator+(const BigNumber& a, const BigNumber& b); + friend BigNumber operator-(const BigNumber& a, const BigNumber& b); + friend BigNumber operator*(const BigNumber& a, const BigNumber& b); + friend BigNumber operator*(const BigNumber& a, Ipp32u); + friend BigNumber operator%(const BigNumber& a, const BigNumber& b); + friend BigNumber operator/(const BigNumber& a, const BigNumber& b); + + // modulo arithmetic + BigNumber Modulo(const BigNumber& a) const; + BigNumber ModAdd(const BigNumber& a, const BigNumber& b) const; + BigNumber ModSub(const BigNumber& a, const BigNumber& b) const; + BigNumber ModMul(const BigNumber& a, const BigNumber& b) const; + BigNumber InverseAdd(const BigNumber& a) const; + BigNumber InverseMul(const BigNumber& a) const; + + // comparisons + friend bool operator<(const BigNumber& a, const BigNumber& b); + friend bool operator>(const BigNumber& a, const BigNumber& b); + friend bool operator==(const BigNumber& a, const BigNumber& b); + friend bool operator!=(const BigNumber& a, const BigNumber& b); + friend bool operator<=(const BigNumber& a, const BigNumber& b) { + return !(a > b); + } + friend bool operator>=(const BigNumber& a, const BigNumber& b) { + return !(a < b); + } + + // easy tests + bool IsOdd() const; + bool IsEven() const { return !IsOdd(); } + + // size of BigNumber + int MSB() const; + int LSB() const; + int BitSize() const { return MSB() + 1; } + int DwordSize() const { return (BitSize() + 31) >> 5; } + friend int Bit(const vector& v, int n); + + // conversion and output + void num2hex(string& s) const; // convert to hex string + void num2vec(vector& v) const; // convert to 32-bit word vector + friend ostream& operator<<(ostream& os, const BigNumber& a); + +protected: + bool create(const Ipp32u* pData, int length, + IppsBigNumSGN sgn = IppsBigNumPOS); + int compare(const BigNumber&) const; + IppsBigNumState* m_pBN; +}; + +// convert bit size into 32-bit words +#define BITSIZE_WORD(n) ((((n) + 31) >> 5)) + +#endif // _BIGNUMBER_H_ diff --git a/module/heqat/heqat/include/heqat/misc/utils.h b/module/heqat/heqat/include/heqat/misc/utils.h new file mode 100644 index 0000000..3d0ae49 --- /dev/null +++ b/module/heqat/heqat/include/heqat/misc/utils.h @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ +#ifndef MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_MISC_UTILS_H_ +#define MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_MISC_UTILS_H_ + +#include + +#define RSIZE_MAX_STR (4UL << 10) /* 4Kb */ + +/** + * \brief + * The strnlen_s function computes the length of the string pointed to by dest. + * \param[in] dest pointer to string + * \param[in] dmax restricted maximum length. (default 4Kb) + * \return size_t + * The function returns the string length, excluding the terminating + * null character. If dest is NULL, then strnlen_s returns 0. + */ +size_t strlen_safe(const char* dest, size_t dmax = RSIZE_MAX_STR); + +#endif // MODULE_HEQAT_HEQAT_INCLUDE_HEQAT_MISC_UTILS_H_ diff --git a/module/heqat/heqat/misc/bignum.cpp b/module/heqat/heqat/misc/bignum.cpp new file mode 100644 index 0000000..c47a278 --- /dev/null +++ b/module/heqat/heqat/misc/bignum.cpp @@ -0,0 +1,395 @@ +/******************************************************************************* + * Copyright 2019-2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + +#include "heqat/misc/bignum.h" +#include "heqat/misc/utils.h" + +#include +#include + +////////////////////////////////////////////////////////////////////// +// +// BigNumber +// +////////////////////////////////////////////////////////////////////// +BigNumber::~BigNumber() { delete[](Ipp8u*) m_pBN; } + +bool BigNumber::create(const Ipp32u* pData, int length, IppsBigNumSGN sgn) { + int size; + ippsBigNumGetSize(length, &size); + m_pBN = (IppsBigNumState*)(new Ipp8u[size]); + if (!m_pBN) return false; + ippsBigNumInit(length, m_pBN); + if (pData) ippsSet_BN(sgn, length, pData, m_pBN); + return true; +} + +// +// constructors +// +BigNumber::BigNumber(Ipp32u value) { create(&value, 1, IppsBigNumPOS); } + +BigNumber::BigNumber(Ipp32s value) { + Ipp32s avalue = abs(value); + create((Ipp32u*)&avalue, 1, (value < 0) ? IppsBigNumNEG : IppsBigNumPOS); +} + +BigNumber::BigNumber(const IppsBigNumState* pBN) { + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, pBN); + + create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); +} + +BigNumber::BigNumber(const Ipp32u* pData, int length, IppsBigNumSGN sgn) { + create(pData, length, sgn); +} + +static char HexDigitList[] = "0123456789ABCDEF"; + +BigNumber::BigNumber(const char* s) { + bool neg = '-' == s[0]; + if (neg) s++; + bool hex = ('0' == s[0]) && (('x' == s[1]) || ('X' == s[1])); + + int dataLen; + Ipp32u base; + if (hex) { + s += 2; + base = 0x10; + dataLen = (int)(strlen_safe(s) + 7) / 8; + } else { + base = 10; + dataLen = (int)(strlen_safe(s) + 9) / 10; + } + + create(0, dataLen); + *(this) = Zero(); + while (*s) { + char tmp[2] = {s[0], 0}; + Ipp32u digit = (Ipp32u)strcspn(HexDigitList, tmp); + *this = (*this) * base + BigNumber(digit); + s++; + } + + if (neg) (*this) = Zero() - (*this); +} + +BigNumber::BigNumber(const BigNumber& bn) { + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); + + create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); +} + +// +// set value +// +void BigNumber::Set(const Ipp32u* pData, int length, IppsBigNumSGN sgn) { + ippsSet_BN(sgn, length, pData, BN(*this)); +} + +// +// constants +// +const BigNumber& BigNumber::Zero() { + static const BigNumber zero(0); + return zero; +} + +const BigNumber& BigNumber::One() { + static const BigNumber one(1); + return one; +} + +const BigNumber& BigNumber::Two() { + static const BigNumber two(2); + return two; +} + +// +// arithmetic operators +// +BigNumber& BigNumber::operator=(const BigNumber& bn) { + if (this != &bn) { // prevent self copy + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); + + delete[](Ipp8u*) m_pBN; + create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); + } + return *this; +} + +BigNumber& BigNumber::operator+=(const BigNumber& bn) { + int aBitLen; + ippsRef_BN(NULL, &aBitLen, NULL, *this); + int bBitLen; + ippsRef_BN(NULL, &bBitLen, NULL, bn); + int rBitLen = IPP_MAX(aBitLen, bBitLen) + 1; + + BigNumber result(0, BITSIZE_WORD(rBitLen)); + ippsAdd_BN(*this, bn, result); + *this = result; + return *this; +} + +BigNumber& BigNumber::operator-=(const BigNumber& bn) { + int aBitLen; + ippsRef_BN(NULL, &aBitLen, NULL, *this); + int bBitLen; + ippsRef_BN(NULL, &bBitLen, NULL, bn); + int rBitLen = IPP_MAX(aBitLen, bBitLen); + + BigNumber result(0, BITSIZE_WORD(rBitLen)); + ippsSub_BN(*this, bn, result); + *this = result; + return *this; +} + +BigNumber& BigNumber::operator*=(const BigNumber& bn) { + int aBitLen; + ippsRef_BN(NULL, &aBitLen, NULL, *this); + int bBitLen; + ippsRef_BN(NULL, &bBitLen, NULL, bn); + int rBitLen = aBitLen + bBitLen; + + BigNumber result(0, BITSIZE_WORD(rBitLen)); + ippsMul_BN(*this, bn, result); + *this = result; + return *this; +} + +BigNumber& BigNumber::operator*=(Ipp32u n) { + int aBitLen; + ippsRef_BN(NULL, &aBitLen, NULL, *this); + + BigNumber result(0, BITSIZE_WORD(aBitLen + 32)); + BigNumber bn(n); + ippsMul_BN(*this, bn, result); + *this = result; + return *this; +} + +BigNumber& BigNumber::operator%=(const BigNumber& bn) { + BigNumber remainder(bn); + ippsMod_BN(BN(*this), BN(bn), BN(remainder)); + *this = remainder; + return *this; +} + +BigNumber& BigNumber::operator/=(const BigNumber& bn) { + BigNumber quotient(*this); + BigNumber remainder(bn); + ippsDiv_BN(BN(*this), BN(bn), BN(quotient), BN(remainder)); + *this = quotient; + return *this; +} + +BigNumber operator+(const BigNumber& a, const BigNumber& b) { + BigNumber r(a); + return r += b; +} + +BigNumber operator-(const BigNumber& a, const BigNumber& b) { + BigNumber r(a); + return r -= b; +} + +BigNumber operator*(const BigNumber& a, const BigNumber& b) { + BigNumber r(a); + return r *= b; +} + +BigNumber operator*(const BigNumber& a, Ipp32u n) { + BigNumber r(a); + return r *= n; +} + +BigNumber operator/(const BigNumber& a, const BigNumber& b) { + BigNumber q(a); + return q /= b; +} + +BigNumber operator%(const BigNumber& a, const BigNumber& b) { + BigNumber r(b); + ippsMod_BN(BN(a), BN(b), BN(r)); + return r; +} + +// +// modulo arithmetic +// +BigNumber BigNumber::Modulo(const BigNumber& a) const { return a % *this; } + +BigNumber BigNumber::InverseAdd(const BigNumber& a) const { + BigNumber t = Modulo(a); + if (t == BigNumber::Zero()) + return t; + else + return *this - t; +} + +BigNumber BigNumber::InverseMul(const BigNumber& a) const { + BigNumber r(*this); + ippsModInv_BN(BN(a), BN(*this), BN(r)); + return r; +} + +BigNumber BigNumber::ModAdd(const BigNumber& a, const BigNumber& b) const { + BigNumber r = this->Modulo(a + b); + return r; +} + +BigNumber BigNumber::ModSub(const BigNumber& a, const BigNumber& b) const { + BigNumber r = this->Modulo(a + this->InverseAdd(b)); + return r; +} + +BigNumber BigNumber::ModMul(const BigNumber& a, const BigNumber& b) const { + BigNumber r = this->Modulo(a * b); + return r; +} + +// +// comparison +// +int BigNumber::compare(const BigNumber& bn) const { + Ipp32u result; + BigNumber tmp = *this - bn; + ippsCmpZero_BN(BN(tmp), &result); + return (result == IS_ZERO) ? 0 : (result == GREATER_THAN_ZERO) ? 1 : -1; +} + +bool operator<(const BigNumber& a, const BigNumber& b) { + return a.compare(b) < 0; +} +bool operator>(const BigNumber& a, const BigNumber& b) { + return a.compare(b) > 0; +} +bool operator==(const BigNumber& a, const BigNumber& b) { + return 0 == a.compare(b); +} +bool operator!=(const BigNumber& a, const BigNumber& b) { + return 0 != a.compare(b); +} + +// easy tests +// +bool BigNumber::IsOdd() const { + Ipp32u* bnData; + ippsRef_BN(NULL, NULL, &bnData, *this); + return bnData[0] & 1; +} + +// +// size of BigNumber +// +int BigNumber::LSB() const { + if (*this == BigNumber::Zero()) return 0; + + vector v; + num2vec(v); + + int lsb = 0; + vector::iterator i; + for (i = v.begin(); i != v.end(); i++) { + Ipp32u x = *i; + if (0 == x) + lsb += 32; + else { + while (0 == (x & 1)) { + lsb++; + x >>= 1; + } + break; + } + } + return lsb; +} + +int BigNumber::MSB() const { + if (*this == BigNumber::Zero()) return 0; + + vector v; + num2vec(v); + + int msb = (int)v.size() * 32 - 1; + vector::reverse_iterator i; + for (i = v.rbegin(); i != v.rend(); i++) { + Ipp32u x = *i; + if (0 == x) + msb -= 32; + else { + while (!(x & 0x80000000)) { + msb--; + x <<= 1; + } + break; + } + } + return msb; +} + +int Bit(const vector& v, int n) { + return 0 != (v[n >> 5] & (1 << (n & 0x1F))); +} + +// +// conversions and output +// +void BigNumber::num2vec(vector& v) const { + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(NULL, &bnBitLen, &bnData, *this); + + int len = BITSIZE_WORD(bnBitLen); + ; + for (int n = 0; n < len; n++) v.push_back(bnData[n]); +} + +void BigNumber::num2hex(string& s) const { + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, *this); + + int len = BITSIZE_WORD(bnBitLen); + + s.append(1, (bnSgn == ippBigNumNEG) ? '-' : ' '); + s.append(1, '0'); + s.append(1, 'x'); + for (int n = len; n > 0; n--) { + Ipp32u x = bnData[n - 1]; + for (int nd = 8; nd > 0; nd--) { + char c = HexDigitList[(x >> (nd - 1) * 4) & 0xF]; + s.append(1, c); + } + } +} + +ostream& operator<<(ostream& os, const BigNumber& a) { + string s; + a.num2hex(s); + os << s.c_str(); + return os; +} diff --git a/module/heqat/heqat/misc/misc.cpp b/module/heqat/heqat/misc/misc.cpp new file mode 100644 index 0000000..5116003 --- /dev/null +++ b/module/heqat/heqat/misc/misc.cpp @@ -0,0 +1,41 @@ +/// @file heqat/misc/misc.cpp +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "heqat/misc.h" + +#include +#include + +HE_QAT_STATUS binToBigNumber(BigNumber& bn, const unsigned char* data, + int nbits) { + if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; + int len_ = (nbits + 7) >> 3; // nbits/8; + + // Create BigNumber containing input data passed as argument + bn = BigNumber(reinterpret_cast(data), BITSIZE_WORD(nbits)); + Ipp32u* ref_bn_data_ = NULL; + ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); + + // Convert it to little endian format + unsigned char* data_ = reinterpret_cast(ref_bn_data_); + for (int i = 0; i < len_; i++) data_[i] = data[len_ - 1 - i]; + + return HE_QAT_STATUS_SUCCESS; +} + +HE_QAT_STATUS bigNumberToBin(unsigned char* data, int nbits, + const BigNumber& bn) { + if (nbits <= 0) return HE_QAT_STATUS_INVALID_PARAM; + int len_ = (nbits + 7) >> 3; // nbits/8; + + // Extract raw vector of data in little endian format + Ipp32u* ref_bn_data_ = NULL; + ippsRef_BN(NULL, NULL, &ref_bn_data_, BN(bn)); + + // Revert it to big endian format + unsigned char* data_ = reinterpret_cast(ref_bn_data_); + for (int i = 0; i < len_; i++) data[i] = data_[len_ - 1 - i]; + + return HE_QAT_STATUS_SUCCESS; +} diff --git a/module/heqat/heqat/misc/utils.cpp b/module/heqat/heqat/misc/utils.cpp new file mode 100644 index 0000000..e0ffc4f --- /dev/null +++ b/module/heqat/heqat/misc/utils.cpp @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + +#include "heqat/misc/utils.h" + +size_t strlen_safe(const char* dest, size_t dmax) { + size_t count; + + /* check null pointer */ + if (NULL == dest) { + return 0UL; + } + + /* check max equal zero */ + if (0UL == dmax) { + return 0UL; + } + + /* check dmax > 4Kb */ + if (dmax > RSIZE_MAX_STR) { + return 0UL; + } + + count = 0UL; + while (*dest && dmax) { + ++count; + --dmax; + ++dest; + } + + return count; +} diff --git a/module/heqat/scripts/auto_find_qat_install.sh b/module/heqat/scripts/auto_find_qat_install.sh new file mode 100755 index 0000000..07e5968 --- /dev/null +++ b/module/heqat/scripts/auto_find_qat_install.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# shellcheck disable=SC2143 +for item in $(locate QAT/build); do [ -d "$item" ] && [ "$(echo "$item" | grep "$HOME")" ] && echo "${item%/*}"; done diff --git a/module/heqat/scripts/reset_asym_buffer_size.sh b/module/heqat/scripts/reset_asym_buffer_size.sh new file mode 100755 index 0000000..a4d523d --- /dev/null +++ b/module/heqat/scripts/reset_asym_buffer_size.sh @@ -0,0 +1,76 @@ +#!/bin/bash + +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# shellcheck disable=SC2199 +if [[ -z "${@}" ]]; then + echo "Usage: ./reset_asym_buffer_size " + exit +fi + +OLD_BUFFER_SIZE=$1 + +if [[ -z ${2} ]]; then + echo "Error: second parameter missing" + echo "Usage: ./reset_asym_buffer_size " + exit +fi + +NEW_BUFFER_SIZE=$2 + +num_phys_dev=$(lspci -d 8086:4940 | wc -l) +num_virt_dev=$(lspci -d 8086:4941 | wc -l) + +# Update physical device configuration files +i=0 +while [ $i -lt "$num_phys_dev" ]; do + sudo sed -i /etc/4xxx_dev$i.conf -e "s/CyNumConcurrentAsymRequests = $OLD_BUFFER_SIZE/CyNumConcurrentAsymRequests = $NEW_BUFFER_SIZE/g" + i=$((i + 1)) +done + +# Update virtual function configuration files +i=0 +while [ $i -lt "$num_virt_dev" ]; do + sudo sed -i /etc/4xxxvf_dev$i.conf -e "s/CyNumConcurrentAsymRequests = $OLD_BUFFER_SIZE/CyNumConcurrentAsymRequests = $NEW_BUFFER_SIZE/g" + i=$((i + 1)) +done + +## Power Off PFs +#i=0; +#while [ $i -lt $num_phys_dev ]; +#do +# sudo adf_ctl qat_dev$i down; +# i=`expr $i + 1`; +#done +# +## Power On PFs +#i=0; +#while [ $i -lt $num_phys_dev ]; +#do +# sudo adf_ctl qat_dev$i up; +# i=`expr $i + 1`; +#done +# +## Restart QAT service (This will bring up PFs and VFs) +#echo "sudo service qat_service restart" +#sudo service qat_service restart +# +## Power Off All VFs +#i=$num_phys_dev; +#vf_per_pf=`expr $num_virt_dev / $num_phys_dev` +#n=`expr $vf_per_pf \\* $num_phys_dev` +#n=`expr $n + $num_phys_dev` +#while [ $i -lt $n ]; +#do +# sudo adf_ctl qat_dev$i down; +# i=`expr $i + 1`; +#done +# +## Power On One QAT VF per QAT PF +#i=$num_phys_dev; +#while [ $i -lt $n ]; +#do +# sudo adf_ctl qat_dev$i up; +# i=`expr $i + $vf_per_pf`; +#done diff --git a/module/heqat/scripts/restart_devices.sh b/module/heqat/scripts/restart_devices.sh new file mode 100755 index 0000000..c563a25 --- /dev/null +++ b/module/heqat/scripts/restart_devices.sh @@ -0,0 +1,126 @@ +#!/bin/bash + +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Refresh +echo "sudo service restart qat_service" +sudo service qat_service restart + +num_phys_dev=$(lspci -d 8086:4940 | wc -l) +if [ "$num_phys_dev" -eq 0 ]; then + echo "No QAT Device Found !" + exit +else + echo "$num_phys_dev QAT Devices Found !" +fi + +total_virt_func=$(lspci -d 8086:4941 | wc -l) +num_virt_func=$((total_virt_func / num_phys_dev)) +dev_step=1 + +if [ $# -eq 0 ]; then + echo "Usage: ./setup_devices " + echo " Parameters:" + echo " -- num_phys_dev: Number of physical devices to be active. (default: auto)" + echo " -- conf_virt_func: Number of configured virtual functions per device. (default: 0)" + echo " -- num_virt_func: Number of virtual functions to be active per device. (default: 0)" +fi + +nphysdev=$num_phys_dev +if [ -n "$1" ]; then + nphysdev=$1 + if [ "$nphysdev" -gt "$num_phys_dev" ]; then + nphysdev=$num_phys_dev + fi +fi + +conf_virt_func=0 +# Check if virtual function is enabled +if [ "$num_virt_func" -gt 0 ]; then + conf_virt_func=1 +fi + +if [ -n "$2" ]; then + conf_virt_func=$2 + # if user attempts to request higher than available + if [ "$conf_virt_func" -gt "$num_virt_func" ]; then + conf_virt_func=$num_virt_func + fi +fi + +# Shutdown QAT PFs +i=0 +while [ $i -lt "$num_phys_dev" ]; do + echo "sudo adf_ctl qat_dev$i down" + sudo adf_ctl qat_dev$i down + i=$((i + 1)) +done + +# Reconfigure Target QAT PFs +i=0 +n=$nphysdev +while [ $i -lt "$n" ]; do + echo "sudo adf_ctl qat_dev$i up" + sudo adf_ctl qat_dev$i up + i=$((i + 1)) +done + +# Refresh +echo "sudo service restart qat_service" +sudo systemctl restart qat_service + +# If Virtualization Mode Enabled +start=0 +if [ "$num_virt_func" -gt 0 ]; then + if [ "$conf_virt_func" -gt 0 ]; then + start=$num_phys_dev + dev_step=$num_virt_func + fi +fi + +# Shutdown QAT VFs +i=$start +stop=$((num_phys_dev * num_virt_func)) +stop=$((start + stop)) +while [ "$i" -lt "$stop" ]; do + echo "sudo adf_ctl qat_dev$i down" + sudo adf_ctl qat_dev"$i" down + i=$((i + 1)) +done + +i=0 +while [ $i -lt "$nphysdev" ]; do + # Start QAT PF + echo "sudo adf_ctl qat_dev$i up" + sudo adf_ctl qat_dev$i up + i=$((i + 1)) +done + +start=$num_phys_dev +i=$start +stop=$((nphysdev * num_virt_func)) +stop=$((start + stop)) +while [ "$i" -lt "$stop" ]; do + # Start QAT VF + echo "adf_ctl qat_dev$i up" + sudo adf_ctl qat_dev"$i" up + # Start up additional instances mapped to the same physical device + j=1 + while [ $j -lt "$conf_virt_func" ]; do + dev_id=$((i + j)) + # Start QAT VF + echo "adf_ctl qat_dev$dev_id up" + sudo adf_ctl qat_dev"$dev_id" up + j=$((j + 1)) + done + i=$((i + dev_step)) +done + +# Shutdown Unused QAT PFs +i=$nphysdev +while [ "$i" -lt "$num_phys_dev" ]; do + echo "sudo adf_ctl qat_dev$i down" + sudo adf_ctl qat_dev"$i" down + i=$((i + 1)) +done diff --git a/module/heqat/scripts/run.sh b/module/heqat/scripts/run.sh new file mode 100755 index 0000000..b4a5090 --- /dev/null +++ b/module/heqat/scripts/run.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +export HEQATLIB_INSTALL_DIR=$HEQATLIB_ROOT_DIR/install +ICP_ROOT=$("$HEQATLIB_ROOT_DIR"/scripts/auto_find_qat_install.sh) +export ICP_ROOT +export LD_LIBRARY_PATH=$HEQATLIB_INSTALL_DIR/lib:$ICP_ROOT/build:$LD_LIBRARY_PATH + +pushd "$HEQATLIB_INSTALL_DIR"/bin || exit + +for app in test_*; do + echo "*****************************************************************" + echo "* [START] RUNNING TEST SAMPLE $app *" + echo "*****************************************************************" + ./"$app" + echo "*****************************************************************" + echo "* [STOP] RUNNING TEST SAMPLE $app *" + echo "*****************************************************************" +done + +popd || exit diff --git a/module/heqat/scripts/setup_devices.sh b/module/heqat/scripts/setup_devices.sh new file mode 100755 index 0000000..57f56ee --- /dev/null +++ b/module/heqat/scripts/setup_devices.sh @@ -0,0 +1,149 @@ +#!/bin/bash + +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Refresh +echo "sudo service restart qat_service" +#sudo service qat_service restart +sudo systemctl restart qat_service.service + +num_phys_dev=$(lspci -d 8086:4940 | wc -l) +if [ "$num_phys_dev" -eq 0 ]; then + echo "No QAT Device Found !" + exit +else + echo "$num_phys_dev QAT Devices Found !" +fi + +total_virt_func=$(lspci -d 8086:4941 | wc -l) +num_virt_func=$((total_virt_func / num_phys_dev)) +dev_step=1 + +if [ $# -eq 0 ]; then + echo "Usage: ./setup_devices " + echo " Parameters:" + echo " -- num_phys_dev: Number of physical devices to be active. (default: auto)" + echo " -- conf_virt_func: Number of configured virtual functions per device. (default: 0)" + echo " -- num_virt_func: Number of virtual functions to be active per device. (default: 0)" +fi + +nphysdev=$num_phys_dev +if [ -n "$1" ]; then + nphysdev=$1 + if [ "$nphysdev" -gt "$num_phys_dev" ]; then + nphysdev=$num_phys_dev + fi +fi + +conf_virt_func=0 +# Check if virtual function is enabled +if [ "$num_virt_func" -gt 0 ]; then + conf_virt_func=1 +fi + +if [ -n "$2" ]; then + conf_virt_func=$2 + # if user attempts to request higher than available + if [ "$conf_virt_func" -gt "$num_virt_func" ]; then + conf_virt_func=$num_virt_func + fi +fi + +# Shutdown QAT PFs +i=0 +while [ $i -lt "$num_phys_dev" ]; do + echo "sudo adf_ctl qat_dev$i down" + sudo adf_ctl qat_dev$i down + i=$((i + 1)) +done + +# Reconfigure Target QAT PFs +i=0 +n=$nphysdev +while [ $i -lt "$n" ]; do + echo "sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf" + sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf + echo "sudo adf_ctl qat_dev$i up" + sudo adf_ctl qat_dev$i up + i=$((i + 1)) +done + +# Refresh +echo "sudo service restart qat_service" +#sudo service qat_service restart +sudo systemctl restart qat_service.service + +# If Virtualization Mode Enabled +start=0 +if [ "$num_virt_func" -gt 0 ]; then + if [ "$conf_virt_func" -gt 0 ]; then + start=$num_phys_dev + dev_step=$num_virt_func + fi +fi + +# Shutdown QAT VFs +i=$start +stop=$((num_phys_dev * num_virt_func)) +stop=$((start + stop)) +while [ "$i" -lt "$stop" ]; do + echo "sudo adf_ctl qat_dev$i down" + sudo adf_ctl qat_dev"$i" down + i=$((i + 1)) +done + +#i=0 +#while [ $i -lt $total_virt_func ]; +#do +# echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$i.conf"; +# sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$i.conf; +# i=`expr $i + 1`; +#done + +i=0 +while [ $i -lt "$nphysdev" ]; do + # Reconfigure QAT PF + echo "sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf" + sudo cp config/4xxx_dev0.conf /etc/4xxx_dev$i.conf + # Start QAT PF + echo "sudo adf_ctl qat_dev$i up" + sudo adf_ctl qat_dev$i up + i=$((i + 1)) +done + +start=$num_phys_dev +i=$start +stop=$((nphysdev * num_virt_func)) +stop=$((start + stop)) +while [ "$i" -lt "$stop" ]; do + k=$((i - start)) + # Reconfigure QAT VF (must match PF's config) + echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf" + sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev"$k".conf + # Start QAT VF + echo "adf_ctl qat_dev$i up" + sudo adf_ctl qat_dev"$i" up + # Start up additional instances mapped to the same physical device + j=1 + while [ $j -lt "$conf_virt_func" ]; do + dev_id=$((i + j)) + k=$((dev_id - start)) + # Reconfigure QAT VF (must match PF's config) + echo "sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev$k.conf" + sudo cp config/4xxxvf_dev0.conf /etc/4xxxvf_dev"$k".conf + # Start QAT VF + echo "adf_ctl qat_dev$dev_id up" + sudo adf_ctl qat_dev"$dev_id" up + j=$((j + 1)) + done + i=$((i + dev_step)) +done + +# Shutdown Unused QAT PFs +i=$nphysdev +while [ "$i" -lt "$num_phys_dev" ]; do + echo "sudo adf_ctl qat_dev$i down" + sudo adf_ctl qat_dev"$i" down + i=$((i + 1)) +done diff --git a/module/heqat/setup_env.sh b/module/heqat/setup_env.sh new file mode 100755 index 0000000..05d4dbc --- /dev/null +++ b/module/heqat/setup_env.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +HEQATLIB_ROOT_DIR=$(pwd) +export HEQATLIB_ROOT_DIR +ICP_ROOT=$("$PWD"/scripts/auto_find_qat_install.sh) +export ICP_ROOT diff --git a/module/heqat/test/CMakeLists.txt b/module/heqat/test/CMakeLists.txt new file mode 100644 index 0000000..2bd391f --- /dev/null +++ b/module/heqat/test/CMakeLists.txt @@ -0,0 +1,57 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 +############################################################################### + +macro(heqat_create_executable test_case language dependencies) + if(${language} STREQUAL "C" OR ${language} STREQUAL "c") + set(extension "c") + elseif(${language} STREQUAL "CXX" OR ${language} STREQUAL "cxx") + set(extension "cpp") + else() + message(FATAL_ERROR "Error language not supported. Options: C or CXX.") + endif() + + set(target test_${test_case}) + add_executable(${target} test_${test_case}.${extension}) + + target_include_directories(${target} PUBLIC ${HE_QAT_INC_DIR}) + + target_link_libraries(${target} PUBLIC he_qat) + + if(NOT ${dependencies} STREQUAL "") + message(STATUS "Target: ${target} Additional Dependencies: ${${dependencies}}") + target_link_libraries(${target} PUBLIC ${${dependencies}}) + endif() + + install(TARGETS ${target} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +endmacro() + +############################################################################## + +set(EXECUTABLE_DEPENDENCIES OpenSSL::SSL) + +# Sample testing the robustness of the heqatlib context functions +heqat_create_executable(context c "") + +# Sample demonstrating how to use API for BIGNUM inputs +heqat_create_executable(BIGNUMModExp C EXECUTABLE_DEPENDENCIES) + +if(HE_QAT_MISC) + add_compile_options(-fpermissive) + + list(APPEND EXECUTABLE_DEPENDENCIES IPPCP::ippcp) + + # Sample showing how to convert from/to BigNumber to/from CpaFlatBuffer + heqat_create_executable(bnConversion cxx EXECUTABLE_DEPENDENCIES) + + # Sample showing how to use bnModExp API + heqat_create_executable(bnModExp CXX EXECUTABLE_DEPENDENCIES) + + if(OpenMP_CXX_FOUND) + list(APPEND EXECUTABLE_DEPENDENCIES OpenMP::OpenMP_CXX) + # Sample showing how to use bnModExp_MT API for multithreaded applications + heqat_create_executable(bnModExp_MT CXX EXECUTABLE_DEPENDENCIES) + endif() +endif() + +############################################################################### diff --git a/module/heqat/test/test_BIGNUMModExp.c b/module/heqat/test/test_BIGNUMModExp.c new file mode 100644 index 0000000..612bfb3 --- /dev/null +++ b/module/heqat/test/test_BIGNUMModExp.c @@ -0,0 +1,134 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include + +#include "heqat/heqat.h" + +struct timeval start_time, end_time; +double time_taken = 0.0; + +const unsigned int BATCH_SIZE = 1; + +int main(int argc, const char** argv) { + const int bit_length = 4096; // 1024; + const size_t num_trials = 100; + + double avg_speed_up = 0.0; + double ssl_avg_time = 0.0; + double qat_avg_time = 0.0; + + double ssl_elapsed = 0.0; + double qat_elapsed = 0.0; + + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + // Set up QAT runtime context + acquire_qat_devices(); + + // Set up OpenSSL context (as baseline) + BN_CTX* ctx = BN_CTX_new(); + BN_CTX_start(ctx); + + for (size_t mod = 0; mod < num_trials; mod++) { + BIGNUM* bn_mod = generateTestBNData(bit_length); + + if (!bn_mod) continue; + +#ifdef HE_QAT_DEBUG + char* bn_str = BN_bn2hex(bn_mod); + HE_QAT_PRINT("Generated modulus: %s num_bytes: %d num_bits: %d\n", + bn_str, BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); + OPENSSL_free(bn_str); +#endif + // bn_exponent in [0..bn_mod] + BIGNUM* bn_exponent = BN_new(); + if (!BN_rand_range(bn_exponent, bn_mod)) { + BN_free(bn_mod); + continue; + } + + BIGNUM* bn_base = generateTestBNData(bit_length); + + // Perform OpenSSL ModExp Op + BIGNUM* ssl_res = BN_new(); + // start = clock(); + gettimeofday(&start_time, NULL); + BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); + // ssl_elapsed = clock() - start; + gettimeofday(&end_time, NULL); + time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; + time_taken = + (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; + ssl_elapsed = time_taken; + + if (!ERR_get_error()) { +#ifdef HE_QAT_DEBUG + bn_str = BN_bn2hex(ssl_res); + HE_QAT_PRINT("SSL BN mod exp: %s num_bytes: %d num_bits: %d\n", + bn_str, BN_num_bytes(ssl_res), BN_num_bits(ssl_res)); + showHexBN(ssl_res, bit_length); + OPENSSL_free(bn_str); +#endif + } else { + HE_QAT_PRINT_DBG("Modular exponentiation failed.\n"); + } + HE_QAT_PRINT_DBG("\nStarting QAT bnModExp...\n"); + + // Perform QAT ModExp Op + BIGNUM* qat_res = BN_new(); + // start = clock(); + gettimeofday(&start_time, NULL); + for (unsigned int j = 0; j < BATCH_SIZE; j++) + status = HE_QAT_BIGNUMModExp(qat_res, bn_base, bn_exponent, bn_mod, + bit_length); + getBnModExpRequest(BATCH_SIZE); + // qat_elapsed = clock() - start; + gettimeofday(&end_time, NULL); + time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; + time_taken = + (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; + qat_elapsed = time_taken; + + ssl_avg_time = (mod * ssl_avg_time + ssl_elapsed) / (mod + 1); + qat_avg_time = + (mod * qat_avg_time + qat_elapsed / BATCH_SIZE) / (mod + 1); + avg_speed_up = + (mod * avg_speed_up + (ssl_elapsed) / (qat_elapsed / BATCH_SIZE)) / + (mod + 1); + + HE_QAT_PRINT( + "Trial #%03lu\tOpenSSL: %.1lfus\tQAT: %.1lfus\tSpeed Up:%.1lfx\t", + (mod + 1), ssl_avg_time, qat_avg_time, avg_speed_up); + + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("\nQAT bnModExpOp failed\n"); + } else { + HE_QAT_PRINT_DBG("\nQAT bnModExpOp finished\n"); + } + + if (BN_cmp(qat_res, ssl_res) != 0) + HE_QAT_PRINT("\t** FAIL **\n"); + else + HE_QAT_PRINT("\t** PASS **\n"); + + BN_free(ssl_res); + BN_free(qat_res); + + BN_free(bn_mod); + BN_free(bn_base); + BN_free(bn_exponent); + } + + // Tear down OpenSSL context + BN_CTX_end(ctx); + + // Tear down QAT runtime context + release_qat_devices(); + + return (int)status; +} diff --git a/module/heqat/test/test_bnConversion.cpp b/module/heqat/test/test_bnConversion.cpp new file mode 100644 index 0000000..38d0dfa --- /dev/null +++ b/module/heqat/test/test_bnConversion.cpp @@ -0,0 +1,108 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include + +#include + +#include + +#include "heqat/heqat.h" + +struct timeval start_time, end_time; +double time_taken = 0.0; + +int main(int argc, const char** argv) { + const int bit_length = 1024; + const size_t num_trials = 4; + + double ssl_elapsed = 0.0; + double qat_elapsed = 0.0; + + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + // Set up OpenSSL context (as baseline) + BN_CTX* ctx = BN_CTX_new(); + BN_CTX_start(ctx); + + for (unsigned int mod = 0; mod < num_trials; mod++) { + BIGNUM* bn_mod = generateTestBNData(bit_length); + + if (!bn_mod) continue; + + char* bn_str = BN_bn2hex(bn_mod); + HE_QAT_PRINT("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, + BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); + OPENSSL_free(bn_str); + + int len_ = (bit_length + 7) >> 3; + + unsigned char* bn_mod_data_ = + (unsigned char*)calloc(len_, sizeof(unsigned char)); + if (NULL == bn_mod_data_) exit(1); + BN_bn2binpad(bn_mod, bn_mod_data_, len_); + + BN_free(bn_mod); + + BigNumber big_num((Ipp32u)0); + + gettimeofday(&start_time, NULL); + status = binToBigNumber(big_num, bn_mod_data_, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT("Failed at binToBigNumber()\n"); + exit(1); + } + gettimeofday(&end_time, NULL); + time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; + time_taken = + (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; + ssl_elapsed = time_taken; + HE_QAT_PRINT("Conversion to BigNumber has completed in %.1lfus.\n", + (ssl_elapsed)); + + int bit_len = 0; + ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); + std::string str; + big_num.num2hex(str); + HE_QAT_PRINT("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), + len_, bit_len); + + gettimeofday(&start_time, NULL); + unsigned char* ref_bn_data_ = + (unsigned char*)calloc(len_, sizeof(unsigned char)); + if (NULL == ref_bn_data_) exit(1); + status = bigNumberToBin(ref_bn_data_, bit_length, big_num); + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT("Failed at bigNumberToBin()\n"); + exit(1); + } + gettimeofday(&end_time, NULL); + time_taken = (end_time.tv_sec - start_time.tv_sec) * 1e6; + time_taken = + (time_taken + (end_time.tv_usec - start_time.tv_usec)); //*1e-6; + qat_elapsed = time_taken; + HE_QAT_PRINT("Conversion from BigNumber has completed %.1lfus.\n", + (qat_elapsed)); + + BIGNUM* ref_bin_ = BN_new(); + BN_bin2bn(ref_bn_data_, len_, ref_bin_); + bn_str = BN_bn2hex(ref_bin_); + HE_QAT_PRINT("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, + BN_num_bytes(ref_bin_), BN_num_bits(ref_bin_)); + HE_QAT_PRINT("-----------------------\n"); + + OPENSSL_free(bn_str); + free(bn_mod_data_); + free(ref_bn_data_); + BN_free(ref_bin_); + } + + // Tear down OpenSSL context + BN_CTX_end(ctx); + + return static_cast(status); +} diff --git a/module/heqat/test/test_bnModExp.cpp b/module/heqat/test/test_bnModExp.cpp new file mode 100644 index 0000000..9aae63e --- /dev/null +++ b/module/heqat/test/test_bnModExp.cpp @@ -0,0 +1,229 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include + +#include +#include +#include // NOLINT [build/c++11] + +#include "heqat/heqat.h" + +const unsigned int BATCH_SIZE = 48; + +int main(int argc, const char** argv) { + const int bit_length = 4096; + const size_t num_trials = 100; + + double avg_speed_up = 0.0; + double ssl_avg_time = 0.0; + double qat_avg_time = 0.0; + + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + // Set up QAT runtime context + acquire_qat_devices(); + + // Set up OpenSSL context (as baseline) + BN_CTX* ctx = BN_CTX_new(); + BN_CTX_start(ctx); + + for (unsigned int mod = 0; mod < num_trials; mod++) { + // Generate modulus number + BIGNUM* bn_mod = generateTestBNData(bit_length); + + if (!bn_mod) continue; + + char* bn_str = BN_bn2hex(bn_mod); +#ifdef HE_QAT_DEBUG + HE_QAT_PRINT("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, + BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); +#endif + OPENSSL_free(bn_str); + + // Generate exponent in [0..bn_mod] + BIGNUM* bn_exponent = BN_new(); + if (!BN_rand_range(bn_exponent, bn_mod)) { + BN_free(bn_mod); + continue; + } + + // Generate base number + BIGNUM* bn_base = generateTestBNData(bit_length); + + // Perform OpenSSL ModExp Op + BIGNUM* ssl_res = BN_new(); + auto start = std::chrono::high_resolution_clock::now(); + BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); + auto stop = std::chrono::high_resolution_clock::now(); + auto ssl_duration = + std::chrono::duration_cast(stop - start); + + int len_ = (bit_length + 7) >> 3; + + // Start QAT timer (including data conversion overhead) + start = std::chrono::high_resolution_clock::now(); + unsigned char* bn_base_data_ = + (unsigned char*)calloc(len_, sizeof(unsigned char)); + if (NULL == bn_base_data_) exit(1); + BN_bn2binpad(bn_base, bn_base_data_, len_); + unsigned char* bn_mod_data_ = + (unsigned char*)calloc(len_, sizeof(unsigned char)); + if (NULL == bn_mod_data_) exit(1); + BN_bn2binpad(bn_mod, bn_mod_data_, len_); + unsigned char* bn_exponent_data_ = + (unsigned char*)calloc(len_, sizeof(unsigned char)); + if (NULL == bn_exponent_data_) exit(1); + BN_bn2binpad(bn_exponent, bn_exponent_data_, len_); + unsigned char* bn_remainder_data_ = + (unsigned char*)calloc(len_, sizeof(unsigned char)); + if (NULL == bn_remainder_data_) exit(1); + stop = std::chrono::high_resolution_clock::now(); + auto cvt_duration = + std::chrono::duration_cast(stop - start); + + // Simulate input number in BigNumber representation + BigNumber big_num_base((Ipp32u)0); + BigNumber big_num_mod((Ipp32u)0); + BigNumber big_num_exponent((Ipp32u)0); + status = binToBigNumber(big_num_base, bn_base_data_, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("Failed at binToBigNumber()\n"); + exit(1); + } + status = binToBigNumber(big_num_mod, bn_mod_data_, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("Failed at binToBigNumber()\n"); + exit(1); + } + status = + binToBigNumber(big_num_exponent, bn_exponent_data_, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("Failed at binToBigNumber()\n"); + exit(1); + } + + // Reset numbers to 0 + memset(bn_base_data_, 0, len_); + memset(bn_mod_data_, 0, len_); + memset(bn_exponent_data_, 0, len_); + // Make sure variables are reset + if (memcmp(bn_base_data_, bn_mod_data_, len_) || + memcmp(bn_base_data_, bn_exponent_data_, len_)) { + HE_QAT_PRINT_ERR("Pointers are not reset to zero!"); + exit(1); + } + + start = std::chrono::high_resolution_clock::now(); + status = bigNumberToBin(bn_base_data_, bit_length, big_num_base); + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); + exit(1); + } + status = bigNumberToBin(bn_mod_data_, bit_length, big_num_mod); + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); + exit(1); + } + status = + bigNumberToBin(bn_exponent_data_, bit_length, big_num_exponent); + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); + exit(1); + } + cvt_duration += std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() - start); + + // Perform BigNumber modular exponentiation on QAT + start = std::chrono::high_resolution_clock::now(); + for (unsigned int b = 0; b < BATCH_SIZE; b++) + status = + HE_QAT_bnModExp(bn_remainder_data_, bn_base_data_, + bn_exponent_data_, bn_mod_data_, bit_length); + getBnModExpRequest(BATCH_SIZE); + stop = std::chrono::high_resolution_clock::now(); + auto qat_duration = + std::chrono::duration_cast(stop - start); + + ssl_avg_time = + (mod * ssl_avg_time + (static_cast(ssl_duration.count()))) / + (mod + 1); + qat_avg_time = + (mod * qat_avg_time + + (static_cast(qat_duration.count())) / BATCH_SIZE) / + (mod + 1); + avg_speed_up = + (mod * avg_speed_up + + (ssl_duration.count() / + static_cast(qat_duration.count() / BATCH_SIZE))) / + (mod + 1); + HE_QAT_PRINT("Request #%u\t", mod + 1); + HE_QAT_PRINT("Overhead: %.1luus", cvt_duration.count()); + HE_QAT_PRINT("\tOpenSSL: %.1lfus", ssl_avg_time); + HE_QAT_PRINT("\tQAT: %.1lfus", qat_avg_time); + HE_QAT_PRINT("\tSpeed-up: %.1lfx", avg_speed_up); + + BIGNUM* qat_res = BN_new(); + BN_bin2bn(bn_remainder_data_, len_, qat_res); + + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); + } +#ifdef HE_QAT_DEBUG + else + HE_QAT_PRINT("\nQAT bnModExpOp finished\n"); +#endif + + BigNumber big_num((Ipp32u)0); + status = binToBigNumber(big_num, bn_remainder_data_, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR( + "bn_remainder_data_: Failed at bigNumberToBin()\n"); + exit(1); + } + +#ifdef HE_QAT_DEBUG + bn_str = BN_bn2hex(qat_res); + HE_QAT_PRINT("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, + BN_num_bytes(qat_res), BN_num_bits(qat_res)); +#endif + +#ifdef HE_QAT_DEBUG + int bit_len = 0; + ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); + std::string str; + big_num.num2hex(str); + HE_QAT_PRINT("BigNumber: %s num_bytes: %d num_bits: %d\n", str.c_str(), + len_, bit_len); + HE_QAT_PRINT( + "---------------------################-----------------------\n"); +#endif + + if (BN_cmp(qat_res, ssl_res) != 0) + HE_QAT_PRINT("\t** FAIL **\n"); + else + HE_QAT_PRINT("\t** PASS **\n"); + + BN_free(bn_mod); + BN_free(bn_base); + BN_free(bn_exponent); + BN_free(qat_res); + BN_free(ssl_res); + + free(bn_mod_data_); + free(bn_base_data_); + free(bn_exponent_data_); + free(bn_remainder_data_); + } + + // Tear down OpenSSL context + BN_CTX_end(ctx); + + // Tear down QAT runtime context + release_qat_devices(); + + return static_cast(status); +} diff --git a/module/heqat/test/test_bnModExp_MT.cpp b/module/heqat/test/test_bnModExp_MT.cpp new file mode 100644 index 0000000..b511982 --- /dev/null +++ b/module/heqat/test/test_bnModExp_MT.cpp @@ -0,0 +1,270 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include +#include + +#include +#include +#include + +#include +#include +#include // NOLINT [build/c++11] + +#include "heqat/heqat.h" + +const unsigned int BATCH_SIZE = 4096; + +int main(int argc, const char** argv) { + const int bit_length = 4096; + const size_t num_trials = 20; + + double avg_speed_up = 0.0; + double ssl_avg_time = 0.0; + double qat_avg_time = 0.0; + + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + // Set up QAT runtime context + acquire_qat_devices(); + + // Set up OpenSSL context (as baseline) + BN_CTX* ctx = BN_CTX_new(); + BN_CTX_start(ctx); + + int nthreads = 4; + for (unsigned int mod = 0; mod < num_trials; mod++) { + // Generate modulus number + BIGNUM* bn_mod = generateTestBNData(bit_length); + + if (!bn_mod) continue; + + char* bn_str = BN_bn2hex(bn_mod); + + HE_QAT_PRINT_DBG("BIGNUM: %s num_bytes: %d num_bits: %d\n", bn_str, + BN_num_bytes(bn_mod), BN_num_bits(bn_mod)); + + OPENSSL_free(bn_str); + + // Generate exponent in [0..bn_mod] + BIGNUM* bn_exponent = BN_new(); + if (!BN_rand_range(bn_exponent, bn_mod)) { + BN_free(bn_mod); + continue; + } + + // Generate base number + BIGNUM* bn_base = generateTestBNData(bit_length); + + // Perform OpenSSL ModExp Op + BIGNUM* ssl_res = BN_new(); + auto start = std::chrono::high_resolution_clock::now(); + BN_mod_exp(ssl_res, bn_base, bn_exponent, bn_mod, ctx); + auto stop = std::chrono::high_resolution_clock::now(); + auto ssl_duration = + std::chrono::duration_cast(stop - start); + + int len_ = (bit_length + 7) >> 3; + + // Start QAT timer (including data conversion overhead) + start = std::chrono::high_resolution_clock::now(); + unsigned char* bn_base_data_ = + (unsigned char*)calloc(len_, sizeof(unsigned char)); + if (NULL == bn_base_data_) exit(1); + BN_bn2binpad(bn_base, bn_base_data_, len_); + unsigned char* bn_mod_data_ = + (unsigned char*)calloc(len_, sizeof(unsigned char)); + if (NULL == bn_mod_data_) exit(1); + BN_bn2binpad(bn_mod, bn_mod_data_, len_); + unsigned char* bn_exponent_data_ = + (unsigned char*)calloc(len_, sizeof(unsigned char)); + if (NULL == bn_exponent_data_) exit(1); + BN_bn2binpad(bn_exponent, bn_exponent_data_, len_); + unsigned char* bn_remainder_data_ = + (unsigned char*)calloc(nthreads * len_, sizeof(unsigned char)); + if (NULL == bn_remainder_data_) exit(1); + stop = std::chrono::high_resolution_clock::now(); + auto cvt_duration = + std::chrono::duration_cast(stop - start); + + // Simulate input number in BigNumber representation + BigNumber big_num_base((Ipp32u)0); + BigNumber big_num_mod((Ipp32u)0); + BigNumber big_num_exponent((Ipp32u)0); + status = binToBigNumber(big_num_base, bn_base_data_, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("Failed at binToBigNumber()\n"); + exit(1); + } + status = binToBigNumber(big_num_mod, bn_mod_data_, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("Failed at binToBigNumber()\n"); + exit(1); + } + status = + binToBigNumber(big_num_exponent, bn_exponent_data_, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("Failed at binToBigNumber()\n"); + exit(1); + } + + // Reset numbers to 0 + memset(bn_base_data_, 0, len_); + memset(bn_mod_data_, 0, len_); + memset(bn_exponent_data_, 0, len_); + // Make sure variables are reset + if (memcmp(bn_base_data_, bn_mod_data_, len_) || + memcmp(bn_base_data_, bn_exponent_data_, len_)) { + HE_QAT_PRINT_ERR("Pointers are not reset to zero!"); + exit(1); + } + + // start = clock(); + start = std::chrono::high_resolution_clock::now(); + status = bigNumberToBin(bn_base_data_, bit_length, big_num_base); + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); + exit(1); + } + status = bigNumberToBin(bn_mod_data_, bit_length, big_num_mod); + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); + exit(1); + } + status = + bigNumberToBin(bn_exponent_data_, bit_length, big_num_exponent); + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("bn_base_data_: failed at bigNumberToBin()\n"); + exit(1); + } + // cvt_elapsed += (clock() - start); + cvt_duration += std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() - start); + + omp_set_num_threads(nthreads); + + // Perform BigNumber modular exponentiation on QAT + start = std::chrono::high_resolution_clock::now(); + +#pragma omp parallel private(status) + { + int thread_id = omp_get_thread_num(); + unsigned int buffer_id = thread_id; + + // Secure one of the distributed outstanding buffers + status = acquire_bnModExp_buffer(&buffer_id); + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("Failed to acquire_bnModExp_buffer()\n"); + exit(1); + } + + HE_QAT_PRINT_DBG("Thread #%d HE QAT ACQUIRED BUFFER ID: %u\n", + thread_id, buffer_id); + + // Divide work among threads + unsigned int worksize = BATCH_SIZE / nthreads; + unsigned int begin = thread_id * worksize; + unsigned int end = begin + worksize; + + HE_QAT_PRINT_DBG("Thread #%d Begin: %u End: %u\n", thread_id, begin, + end); + + // For local thread, schedule work execution + for (unsigned int b = begin; b < end; b++) + status = HE_QAT_bnModExp_MT( + buffer_id, bn_remainder_data_ + thread_id * len_, + bn_base_data_, bn_exponent_data_, bn_mod_data_, bit_length); + + HE_QAT_PRINT_DBG("Thread #%d Waiting\n", thread_id); + + // Wait for the request to complete + release_bnModExp_buffer(buffer_id, BATCH_SIZE / nthreads); + + HE_QAT_PRINT_DBG("Thread #%d Completed\n", thread_id); + } // pragma omp parallel + + stop = std::chrono::high_resolution_clock::now(); + auto qat_duration = + std::chrono::duration_cast(stop - start); + + ssl_avg_time = + (mod * ssl_avg_time + (static_cast(ssl_duration.count()))) / + (mod + 1); + qat_avg_time = + (mod * qat_avg_time + + (static_cast(qat_duration.count())) / BATCH_SIZE) / + (mod + 1); + avg_speed_up = + (mod * avg_speed_up + + (ssl_duration.count() / + static_cast(qat_duration.count() / BATCH_SIZE))) / + (mod + 1); + + HE_QAT_PRINT("Request #%u\t", mod + 1); + HE_QAT_PRINT("Overhead: %.1luus", cvt_duration.count()); + HE_QAT_PRINT("\tOpenSSL: %.1lfus", ssl_avg_time); + HE_QAT_PRINT("\tQAT: %.1lfus", qat_avg_time); + HE_QAT_PRINT("\tSpeed-up: %.1lfx", avg_speed_up); + + BIGNUM* qat_res = BN_new(); + BN_bin2bn(bn_remainder_data_, len_, qat_res); + + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR("\nQAT bnModExp with BigNumber failed\n"); + exit(1); + } + + HE_QAT_PRINT_DBG("\nQAT bnModExpOp finished\n"); + + // start = clock(); + BigNumber big_num((Ipp32u)0); + status = binToBigNumber(big_num, bn_remainder_data_, bit_length); + if (HE_QAT_STATUS_SUCCESS != status) { + HE_QAT_PRINT_ERR( + "bn_remainder_data_: Failed at bigNumberToBin()\n"); + exit(1); + } + +#ifdef HE_QAT_DEBUG + bn_str = BN_bn2hex(qat_res); + HE_QAT_PRINT_DBG("Bin: %s num_bytes(%d) num_bits(%d)\n", bn_str, + BN_num_bytes(qat_res), BN_num_bits(qat_res)); +#endif + +#ifdef HE_QAT_DEBUG + int bit_len = 0; + ippsRef_BN(NULL, &bit_len, NULL, BN(big_num)); + std::string str; + big_num.num2hex(str); + HE_QAT_PRINT_DBG("BigNumber: %s num_bytes: %d num_bits: %d\n", + str.c_str(), len_, bit_len); + HE_QAT_PRINT_DBG( + "---------------------################-----------------------\n"); +#endif + + if (BN_cmp(qat_res, ssl_res) != 0) + HE_QAT_PRINT("\t** FAIL **\n"); + else + HE_QAT_PRINT("\t** PASS **\n"); + + BN_free(bn_mod); + BN_free(bn_base); + BN_free(bn_exponent); + BN_free(qat_res); + BN_free(ssl_res); + + free(bn_mod_data_); + free(bn_base_data_); + free(bn_exponent_data_); + free(bn_remainder_data_); + } + + // Tear down OpenSSL context + BN_CTX_end(ctx); + + // Tear down QAT runtime context + release_qat_devices(); + + return static_cast(status); +} diff --git a/module/heqat/test/test_context.c b/module/heqat/test/test_context.c new file mode 100644 index 0000000..2d4846f --- /dev/null +++ b/module/heqat/test/test_context.c @@ -0,0 +1,52 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "heqat/heqat.h" + +int main() { + HE_QAT_STATUS status = HE_QAT_STATUS_FAIL; + + status = release_qat_devices(); + if (HE_QAT_STATUS_SUCCESS == status) { + printf("Nothing to do by release_qat_devices().\n"); + } else { + printf("release_qat_devices() failed.\n"); + exit(1); + } + + status = acquire_qat_devices(); + if (HE_QAT_STATUS_SUCCESS == status) { + printf("Completed acquire_qat_devices() successfully.\n"); + } else { + printf("acquire_qat_devices() failed.\n"); + exit(1); + } + + status = acquire_qat_devices(); + if (HE_QAT_STATUS_SUCCESS == status) { + printf("QAT context already exists.\n"); + } else { + printf("acquire_qat_devices() failed.\n"); + exit(1); + } + + HE_QAT_SLEEP(5000, HE_QAT_MILLISEC); + + status = release_qat_devices(); + if (HE_QAT_STATUS_SUCCESS == status) { + printf("Completed release_qat_devices() successfully.\n"); + } else { + printf("release_qat_devices() failed.\n"); + exit(1); + } + + status = release_qat_devices(); + if (HE_QAT_STATUS_SUCCESS == status) { + printf("Nothing to do by release_qat_devices().\n"); + } else { + printf("release_qat_devices() failed.\n"); + exit(1); + } + + return 0; +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index fe6c6e9..4d7550d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -2,9 +2,11 @@ # SPDX-License-Identifier: Apache-2.0 # Unit tests -set(IPCL_UNITTEST_SRC main.cpp -test_cryptography.cpp -test_ops.cpp) +set(IPCL_UNITTEST_SRC + main.cpp + test_cryptography.cpp + test_ops.cpp +) add_executable(unittest_ipcl ${IPCL_UNITTEST_SRC}) target_include_directories(unittest_ipcl PRIVATE diff --git a/test/main.cpp b/test/main.cpp index 0ec6f12..178b34d 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -1,13 +1,45 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include - #include +#include "gtest/gtest.h" +#include "ipcl/context.hpp" + int main(int argc, char** argv) { +#ifdef IPCL_USE_QAT + ipcl::initializeContext("QAT"); + + if (ipcl::isQATActive()) + std::cout << "QAT Context: ACTIVE" << std::endl; + else + std::cout << "Error: QAT Context INACTIVE." << std::endl; + + if (ipcl::isQATRunning()) + std::cout << "QAT Instances: RUNNING" << std::endl; + else + std::cout << "Error: QAT Instances NOT RUNNING." << std::endl; +#else + ipcl::initializeContext("default"); +#endif // IPCL_USE_QAT + // Use system clock for seed srand(time(nullptr)); ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); + int status = RUN_ALL_TESTS(); + + ipcl::terminateContext(); + +#ifdef IPCL_USE_QAT + if (!ipcl::isQATActive()) + std::cout << "QAT Context: INACTIVE" << std::endl; + else + std::cout << "Error: QAT Context ACTIVE." << std::endl; + if (!ipcl::isQATRunning()) + std::cout << "QAT Instances: NOT RUNNING" << std::endl; + else + std::cout << "Error: QAT Instances STILL RUNNING." << std::endl; +#endif + + return status; } diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index bac47db..24d4fb9 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -2,17 +2,18 @@ // SPDX-License-Identifier: Apache-2.0 #include -#include #include #include #include "gtest/gtest.h" #include "ipcl/ipcl.hpp" -constexpr int SELF_DEF_NUM_VALUES = 9; +constexpr int SELF_DEF_NUM_VALUES = 18; +constexpr float SELF_DEF_HYBRID_QAT_RATIO = 0.5; TEST(CryptoTest, CryptoTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048, true); @@ -30,6 +31,9 @@ TEST(CryptoTest, CryptoTest) { } pt = ipcl::PlainText(exp_value); + + ipcl::setHybridRatio(qat_ratio); + ct = key.pub_key->encrypt(pt); dt = key.priv_key->decrypt(ct); @@ -151,6 +155,8 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { ipcl::PlainText pt; ipcl::CipherText ct; + ipcl::setHybridOff(); + key.pub_key->setRandom(ir_bn_v); pt = ipcl::PlainText(pt_bn_v); diff --git a/test/test_ops.cpp b/test/test_ops.cpp index 74064fe..7a33a1e 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -2,14 +2,14 @@ // SPDX-License-Identifier: Apache-2.0 #include -#include #include #include #include "gtest/gtest.h" #include "ipcl/ipcl.hpp" -constexpr int SELF_DEF_NUM_VALUES = 7; +constexpr int SELF_DEF_NUM_VALUES = 14; +constexpr float SELF_DEF_HYBRID_QAT_RATIO = 0.5; void CtPlusCt(ipcl::CipherText& res, const ipcl::CipherText& ct1, const ipcl::CipherText& ct2, const ipcl::keyPair key) { @@ -125,6 +125,7 @@ void PtMultiplyCtArray(ipcl::CipherText& res, const ipcl::PlainText& pt2, TEST(OperationTest, CtPlusCtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -143,6 +144,8 @@ TEST(OperationTest, CtPlusCtTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridRatio(qat_ratio); + ct1 = key.pub_key->encrypt(pt1); ct2 = key.pub_key->encrypt(pt2); @@ -166,6 +169,7 @@ TEST(OperationTest, CtPlusCtTest) { TEST(OperationTest, CtPlusCtArrayTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -184,6 +188,8 @@ TEST(OperationTest, CtPlusCtArrayTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridRatio(qat_ratio); + ct1 = key.pub_key->encrypt(pt1); ct2 = key.pub_key->encrypt(pt2); @@ -207,6 +213,7 @@ TEST(OperationTest, CtPlusCtArrayTest) { TEST(OperationTest, CtPlusPtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -225,6 +232,8 @@ TEST(OperationTest, CtPlusPtTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridRatio(qat_ratio); + ct1 = key.pub_key->encrypt(pt1); CtPlusPt(ct_sum, ct1, pt2, key); @@ -247,6 +256,7 @@ TEST(OperationTest, CtPlusPtTest) { TEST(OperationTest, CtPlusPtArrayTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -265,6 +275,8 @@ TEST(OperationTest, CtPlusPtArrayTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridRatio(qat_ratio); + ct1 = key.pub_key->encrypt(pt1); CtPlusPtArray(ct_sum, ct1, pt2, key); @@ -287,6 +299,7 @@ TEST(OperationTest, CtPlusPtArrayTest) { TEST(OperationTest, CtMultiplyPtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -305,6 +318,8 @@ TEST(OperationTest, CtMultiplyPtTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridRatio(qat_ratio); + ct1 = key.pub_key->encrypt(pt1); CtMultiplyPt(ct_product, ct1, pt2, key); @@ -327,6 +342,7 @@ TEST(OperationTest, CtMultiplyPtTest) { TEST(OperationTest, CtMultiplyZeroPtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -346,6 +362,8 @@ TEST(OperationTest, CtMultiplyZeroPtTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridRatio(qat_ratio); + ct1 = key.pub_key->encrypt(pt1); CtMultiplyPt(ct_product, ct1, pt2, key); @@ -368,6 +386,7 @@ TEST(OperationTest, CtMultiplyZeroPtTest) { TEST(OperationTest, CtMultiplyPtArrayTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -386,6 +405,8 @@ TEST(OperationTest, CtMultiplyPtArrayTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridRatio(qat_ratio); + ct1 = key.pub_key->encrypt(pt1); CtMultiplyPtArray(ct_product, ct1, pt2, key); @@ -408,6 +429,7 @@ TEST(OperationTest, CtMultiplyPtArrayTest) { TEST(OperationTest, AddSubTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -426,6 +448,8 @@ TEST(OperationTest, AddSubTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridRatio(qat_ratio); + ct1 = key.pub_key->encrypt(pt1); ct2 = key.pub_key->encrypt(pt2); @@ -449,6 +473,7 @@ TEST(OperationTest, AddSubTest) { TEST(OperationTest, PtPlusCtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -467,6 +492,8 @@ TEST(OperationTest, PtPlusCtTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridRatio(qat_ratio); + ct1 = key.pub_key->encrypt(pt1); PtPlusCt(ct_sum, pt2, ct1, key); @@ -489,6 +516,7 @@ TEST(OperationTest, PtPlusCtTest) { TEST(OperationTest, PtPlusCtArrayTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -507,6 +535,8 @@ TEST(OperationTest, PtPlusCtArrayTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridRatio(qat_ratio); + ct1 = key.pub_key->encrypt(pt1); PtPlusCtArray(ct_sum, pt2, ct1, key); @@ -529,6 +559,7 @@ TEST(OperationTest, PtPlusCtArrayTest) { TEST(OperationTest, PtMultiplyCtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -547,6 +578,8 @@ TEST(OperationTest, PtMultiplyCtTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridRatio(qat_ratio); + ct1 = key.pub_key->encrypt(pt1); PtMultiplyCt(ct_product, pt2, ct1, key); @@ -569,6 +602,7 @@ TEST(OperationTest, PtMultiplyCtTest) { TEST(OperationTest, PtMultiplyCtArrayTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; + const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; ipcl::keyPair key = ipcl::generateKeypair(2048); @@ -587,6 +621,8 @@ TEST(OperationTest, PtMultiplyCtArrayTest) { pt1 = ipcl::PlainText(exp_value1); pt2 = ipcl::PlainText(exp_value2); + ipcl::setHybridRatio(qat_ratio); + ct1 = key.pub_key->encrypt(pt1); PtMultiplyCtArray(ct_product, pt2, ct1, key); From e0f3383be0798e108de145a5418daf51a542a3a1 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Wed, 9 Nov 2022 17:35:28 -0800 Subject: [PATCH 351/364] Pre-commit update for HEQAT C codes - Add "-runtime/printf" entry from cpplint-c filter - Fix format strings for unsigned int and long - typo fix: Replace ```retry_count``` with ```request_count``` - Reverted cpplint suggestion for HE_QAT_PRINT macro --- .pre-commit-config.yaml | 2 +- module/heqat/heqat/bnops.c | 2 +- module/heqat/heqat/ctrl.c | 2 +- module/heqat/heqat/include/heqat/common/utils.h | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cbbdcc6..aecc032 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -57,7 +57,7 @@ repos: exclude: ipcl/include/ipcl/bignum.h|module/heqat/heqat/include/heqat/misc/bignum.h args: - --recursive - - --filter=-runtime/references,-whitespace/comments,-whitespace/indent,-readability/casting,-runtime/int + - --filter=-runtime/references,-whitespace/comments,-whitespace/indent,-readability/casting,-runtime/int,-runtime/printf - id: shellcheck name: shellcheck entry: shellcheck diff --git a/module/heqat/heqat/bnops.c b/module/heqat/heqat/bnops.c index 43b6673..65c7983 100644 --- a/module/heqat/heqat/bnops.c +++ b/module/heqat/heqat/bnops.c @@ -415,7 +415,7 @@ HE_QAT_STATUS HE_QAT_bnModExp_MT(unsigned int _buffer_id, unsigned char* r, HE_QAT_STATUS acquire_bnModExp_buffer(unsigned int* _buffer_id) { if (NULL == _buffer_id) return HE_QAT_STATUS_INVALID_PARAM; - HE_QAT_PRINT_DBG("acquire_bnModExp_buffer #%u\n", _buffer_id); + HE_QAT_PRINT_DBG("acquire_bnModExp_buffer #%ls\n", _buffer_id); pthread_mutex_lock(&outstanding.mutex); diff --git a/module/heqat/heqat/ctrl.c b/module/heqat/heqat/ctrl.c index 774a700..7c968f6 100644 --- a/module/heqat/heqat/ctrl.c +++ b/module/heqat/heqat/ctrl.c @@ -720,7 +720,7 @@ void* start_perform_op(void* _inst_config) { // Global tracking of number of requests request_count += 1; - HE_QAT_PRINT_DBG("retry_count = %d\n", retry_count); + HE_QAT_PRINT_DBG("request_count = %lu\n", request_count); #ifdef HE_QAT_SYNC_MODE // Wait until the callback function has been called if (!COMPLETION_WAIT(&request->callback, TIMEOUT_MS)) { diff --git a/module/heqat/heqat/include/heqat/common/utils.h b/module/heqat/heqat/include/heqat/common/utils.h index 21d19e2..e3e400d 100644 --- a/module/heqat/heqat/include/heqat/common/utils.h +++ b/module/heqat/heqat/include/heqat/common/utils.h @@ -41,7 +41,7 @@ extern "C" { #define HE_QAT_PRINT_DBG(args...) \ do { \ printf("%s(): ", __func__); \ - printf("%s", args); \ + printf(args); \ fflush(stdout); \ } while (0) #else @@ -52,7 +52,7 @@ extern "C" { #ifndef HE_QAT_PRINT #define HE_QAT_PRINT(args...) \ do { \ - printf("%s", args); \ + printf(args); \ } while (0) #endif @@ -60,7 +60,7 @@ extern "C" { #define HE_QAT_PRINT_ERR(args...) \ do { \ printf("%s(): ", __func__); \ - printf("%s", args); \ + printf(args); \ } while (0) #endif From df9d42829ffdbcc47891c7e63210ca59fdfb2828 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Tue, 15 Nov 2022 17:17:22 -0800 Subject: [PATCH 352/364] Remove deprecated test case file --- example/test.cpp | 40 ---------------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 example/test.cpp diff --git a/example/test.cpp b/example/test.cpp deleted file mode 100644 index 5ac7a31..0000000 --- a/example/test.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include - -int main() { - const uint32_t num_values = 9; - - ipcl::keyPair key = ipcl::generateKeypair(2048, true); - - std::vector exp_value(num_values); - ipcl::PlainText pt; - ipcl::CipherText ct; - ipcl::PlainText dt; - - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - - for (int i = 0; i < num_values; i++) { - exp_value[i] = dist(rng); - } - - pt = ipcl::PlainText(exp_value); - ct = key.pub_key->encrypt(pt); - dt = key.priv_key->decrypt(ct); - - for (int i = 0; i < num_values; i++) { - std::vector v = dt.getElementVec(i); - bool chk = v[0] == exp_value[i]; - std::cout << (chk ? "pass" : "fail") << std::endl; - } - - delete key.pub_key; - delete key.priv_key; -} From 84ed0af04e5ea70cee57f2ab543e80f93a6149a5 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Tue, 15 Nov 2022 17:19:12 -0800 Subject: [PATCH 353/364] Update CODEOWNERS --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index bff7bbc..7f77997 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -2,4 +2,4 @@ # SPDX-License-Identifier: Apache-2.0 # Default codeowner for all files -* @dpg-dbio-glade-creek-projectphe-owners +* @intel/pailliercryptolib-maintain From 33b0b81c1f069581a579af48d611255985fd1995 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Tue, 15 Nov 2022 21:58:41 -0800 Subject: [PATCH 354/364] Refactoring (#30) - Moved utility function sources and headers under utils folder - Added serialize function (TBD) --- CMakeLists.txt | 1 + benchmark/main.cpp | 2 +- cmake/cereal.cmake | 23 ++++++++ cmake/cpufeatures.cmake | 2 +- ipcl/CMakeLists.txt | 64 ++++++++++++++--------- ipcl/base_text.cpp | 2 +- ipcl/include/ipcl/bignum.h | 25 +++++++-- ipcl/include/ipcl/ciphertext.hpp | 2 +- ipcl/include/ipcl/ipcl.hpp | 3 +- ipcl/include/ipcl/pub_key.hpp | 31 +++++++++++ ipcl/include/ipcl/{ => utils}/common.hpp | 6 +-- ipcl/include/ipcl/{ => utils}/context.hpp | 6 +-- ipcl/include/ipcl/utils/serialize.hpp | 64 +++++++++++++++++++++++ ipcl/include/ipcl/{ => utils}/util.hpp | 8 +-- ipcl/mod_exp.cpp | 6 +-- ipcl/plaintext.cpp | 2 +- ipcl/pri_key.cpp | 5 +- ipcl/pub_key.cpp | 34 ++++++++++-- ipcl/{ => utils}/common.cpp | 7 ++- ipcl/{ => utils}/context.cpp | 2 +- ipcl/{ => utils}/util.cpp | 2 +- test/main.cpp | 2 +- 22 files changed, 239 insertions(+), 60 deletions(-) create mode 100644 cmake/cereal.cmake rename ipcl/include/ipcl/{ => utils}/common.hpp (91%) rename ipcl/include/ipcl/{ => utils}/context.hpp (89%) create mode 100644 ipcl/include/ipcl/utils/serialize.hpp rename ipcl/include/ipcl/{ => utils}/util.hpp (94%) rename ipcl/{ => utils}/common.cpp (95%) rename ipcl/{ => utils}/context.cpp (98%) rename ipcl/{ => utils}/util.cpp (93%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 83b11ea..e3db6c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -192,6 +192,7 @@ find_package(OpenSSL REQUIRED) # External dependencies include(cmake/ippcrypto.cmake) +include(cmake/cereal.cmake) if(IPCL_DETECT_CPU_RUNTIME) include(cmake/cpufeatures.cmake) diff --git a/benchmark/main.cpp b/benchmark/main.cpp index 915ed5b..d411fb7 100644 --- a/benchmark/main.cpp +++ b/benchmark/main.cpp @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "benchmark/benchmark.h" -#include "ipcl/context.hpp" +#include "ipcl/ipcl.hpp" int main(int argc, char** argv) { #ifdef IPCL_USE_QAT diff --git a/cmake/cereal.cmake b/cmake/cereal.cmake new file mode 100644 index 0000000..ff3c44d --- /dev/null +++ b/cmake/cereal.cmake @@ -0,0 +1,23 @@ +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +include(ExternalProject) +message(STATUS "Configuring cereal") +set(CEREAL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_cereal) +set(CEREAL_GIT_REPO_URL https://github.com/USCiLab/cereal.git) +set(CEREAL_GIT_LABEL ebef1e929807629befafbb2918ea1a08c7194554) # cereal - v1.3.2 + +ExternalProject_Add( + ext_cereal + PREFIX ${CEREAL_PREFIX} + GIT_REPOSITORY ${CEREAL_GIT_REPO_URL} + GIT_TAG ${CEREAL_GIT_LABEL} + UPDATE_COMMAND "" + EXCLUDE_FROM_ALL + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" +) + +ExternalProject_Get_Property(ext_cereal SOURCE_DIR BINARY_DIR) +set(CEREAL_INC_DIR ${SOURCE_DIR}/include) diff --git a/cmake/cpufeatures.cmake b/cmake/cpufeatures.cmake index 1da25f1..7c67092 100644 --- a/cmake/cpufeatures.cmake +++ b/cmake/cpufeatures.cmake @@ -3,7 +3,7 @@ include(ExternalProject) -message(STATUS "configuring cpu_features") +message(STATUS "Configuring cpu_features") set(CPUFEATURES_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_cpufeatures) set(CPUFEATURES_DESTDIR ${CPUFEATURES_PREFIX}/cpufeatures_install) set(CPUFEATURES_GIT_REPO_URL https://github.com/google/cpu_features.git) diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 44005bb..57ddf25 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -6,16 +6,14 @@ set(IPCL_SRCS pri_key.cpp keygen.cpp bignum.cpp mod_exp.cpp - context.cpp base_text.cpp plaintext.cpp ciphertext.cpp - util.cpp - common.cpp + utils/context.cpp + utils/util.cpp + utils/common.cpp ) -set(IPCL_PUBLIC_HEADER ${IPCL_INC_DIR}/ipcl/ipcl.hpp) - if(IPCL_SHARED) add_library(ipcl SHARED ${IPCL_SRCS}) else() @@ -24,7 +22,6 @@ endif() add_library(IPCL::ipcl ALIAS ipcl) -set_target_properties(ipcl PROPERTIES PUBLIC_HEADER ${IPCL_PUBLIC_HEADER}) set_target_properties(ipcl PROPERTIES BUILD_WITH_INSTALL_RPATH FALSE LINK_FLAGS "-Wl,-rpath,'$ORIGIN' -Wl,-rpath,'$ORIGIN'/ippcrypto -Wl,-rpath,'$ORIGIN'/cpufeatures") @@ -37,6 +34,40 @@ target_include_directories(ipcl PUBLIC $ ) +install(DIRECTORY ${IPCL_INC_DIR}/ + DESTINATION ${IPCL_INSTALL_INCLUDEDIR} + FILES_MATCHING + PATTERN "*.hpp" + PATTERN "*.h" +) + +# CEREAL (third party dep): include and install definition +target_include_directories(ipcl + PUBLIC $ + PUBLIC $ +) + +install(DIRECTORY ${CEREAL_INC_DIR}/ + DESTINATION ${IPCL_INSTALL_INCLUDEDIR} + FILES_MATCHING + PATTERN "*.hpp" + PATTERN "*.h" +) + +# IPP-Crypto (third party dep): include and install definition +target_include_directories(ipcl + PUBLIC $ + PUBLIC $ +) + +install(DIRECTORY ${IPPCRYPTO_INC_DIR}/ + DESTINATION ${IPCL_INSTALL_INCLUDEDIR} + FILES_MATCHING + PATTERN "*.hpp" + PATTERN "*.h" +) + +# CPU_FEATURES (third party dep): include and install definition if(IPCL_DETECT_IFMA_RUNTIME) target_include_directories(ipcl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} @@ -47,27 +78,12 @@ if(IPCL_DETECT_IFMA_RUNTIME) DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.hpp" - PATTERN "*.h") + PATTERN "*.h" + ) endif() -install(DIRECTORY ${IPCL_INC_DIR}/ - DESTINATION ${IPCL_INSTALL_INCLUDEDIR} - FILES_MATCHING - PATTERN "*.hpp" - PATTERN "*.h") -# include and install definition of IPP-Crypto -target_include_directories(ipcl - PUBLIC $ - PUBLIC $ -) - -install(DIRECTORY ${IPPCRYPTO_INC_DIR}/ - DESTINATION ${IPCL_INSTALL_INCLUDEDIR} - FILES_MATCHING - PATTERN "*.hpp" - PATTERN "*.h") # include and install definition of cpu_features if(IPCL_DETECT_CPU_RUNTIME) @@ -83,6 +99,7 @@ if(IPCL_DETECT_CPU_RUNTIME) endif() +# include and install definition of he_qat if(IPCL_ENABLE_QAT) ipcl_define_icp_variables(icp_inc_dir) target_include_directories(ipcl @@ -160,7 +177,6 @@ configure_package_config_file( install( TARGETS ipcl EXPORT IPCLTargets - PUBLIC_HEADER DESTINATION ${IPCL_INSTALL_INCLUDEDIR} ARCHIVE DESTINATION ${IPCL_INSTALL_LIBDIR} LIBRARY DESTINATION ${IPCL_INSTALL_LIBDIR} RUNTIME DESTINATION ${IPCL_INSTALL_LIBDIR} diff --git a/ipcl/base_text.cpp b/ipcl/base_text.cpp index 4a1b0a6..ab770da 100644 --- a/ipcl/base_text.cpp +++ b/ipcl/base_text.cpp @@ -3,7 +3,7 @@ #include "ipcl/base_text.hpp" -#include "ipcl/util.hpp" +#include "ipcl/utils/util.hpp" namespace ipcl { diff --git a/ipcl/include/ipcl/bignum.h b/ipcl/include/ipcl/bignum.h index c6531a1..2a069cd 100644 --- a/ipcl/include/ipcl/bignum.h +++ b/ipcl/include/ipcl/bignum.h @@ -19,12 +19,13 @@ #if !defined _BIGNUMBER_H_ #define _BIGNUMBER_H_ -#include - #include #include -class BigNumber { +#include "ipcl/utils/serialize.hpp" +#include "ippcp.h" + +class BigNumber : public ipcl::serialize::serializerBase { public: BigNumber(Ipp32u value = 0); BigNumber(Ipp32s value); @@ -128,6 +129,24 @@ class BigNumber { static bool toBin(unsigned char** data, int* len, const BigNumber& bn); protected: + friend class cereal::access; + template + void save(Archive& ar, const Ipp32u version) const { + std::vector vec; + num2vec(vec); + ar(cereal::make_nvp("BigNumber", vec)); + } + + template + void load(Archive& ar, const Ipp32u version) { + std::vector vec; + ar(cereal::make_nvp("BigNumber", vec)); + create(vec.data(), vec.size(), IppsBigNumPOS); + } + + std::string serializedName() const { return "BigNumber"; } + static Ipp32u serializedVersion() { return 1; } + bool create(const Ipp32u* pData, int length, IppsBigNumSGN sgn = IppsBigNumPOS); IppsBigNumState* m_pBN; diff --git a/ipcl/include/ipcl/ciphertext.hpp b/ipcl/include/ipcl/ciphertext.hpp index a742921..b344ad0 100644 --- a/ipcl/include/ipcl/ciphertext.hpp +++ b/ipcl/include/ipcl/ciphertext.hpp @@ -8,7 +8,7 @@ #include "ipcl/plaintext.hpp" #include "ipcl/pub_key.hpp" -#include "ipcl/util.hpp" +#include "ipcl/utils/util.hpp" namespace ipcl { diff --git a/ipcl/include/ipcl/ipcl.hpp b/ipcl/include/ipcl/ipcl.hpp index 2117c70..e06159e 100644 --- a/ipcl/include/ipcl/ipcl.hpp +++ b/ipcl/include/ipcl/ipcl.hpp @@ -4,9 +4,10 @@ #ifndef IPCL_INCLUDE_IPCL_IPCL_HPP_ #define IPCL_INCLUDE_IPCL_IPCL_HPP_ -#include "ipcl/context.hpp" #include "ipcl/mod_exp.hpp" #include "ipcl/pri_key.hpp" +#include "ipcl/utils/context.hpp" +#include "ipcl/utils/serialize.hpp" namespace ipcl { diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp index 130c5bd..4a1a715 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -116,6 +116,34 @@ class PublicKey { const void* addr = static_cast(this); private: + friend class cereal::access; + template + void save(Archive& ar, const Ipp32u version) const { + ar(::cereal::make_nvp("n", m_n)); + ar(::cereal::make_nvp("bits", m_bits)); + ar(::cereal::make_nvp("enable_DJN", m_enable_DJN)); + ar(::cereal::make_nvp("hs", m_hs)); + ar(::cereal::make_nvp("randbits", m_randbits)); + } + + template + void load(Archive& ar, const Ipp32u version) { + BigNumber n, hs; + bool enable_DJN; + int bits, randbits; + + ar(::cereal::make_nvp("n", m_n)); + ar(::cereal::make_nvp("bits", bits)); + ar(::cereal::make_nvp("enable_DJN", enable_DJN)); + ar(::cereal::make_nvp("hs", m_hs)); + ar(::cereal::make_nvp("randbits", randbits)); + + if (enable_DJN) + create(n, bits, hs, randbits); + else + create(n, bits); + } + BigNumber m_n; BigNumber m_g; BigNumber m_nsquare; @@ -128,6 +156,9 @@ class PublicKey { std::vector m_r; bool m_testv; + void create(const BigNumber& n, int bits, bool enableDJN_ = false); + void create(const BigNumber& n, int bits, const BigNumber& hs, int randbits); + /** * Big number vector multi buffer encryption * @param[in] pt plaintext of BigNumber vector type diff --git a/ipcl/include/ipcl/common.hpp b/ipcl/include/ipcl/utils/common.hpp similarity index 91% rename from ipcl/include/ipcl/common.hpp rename to ipcl/include/ipcl/utils/common.hpp index 674d944..67a26ad 100644 --- a/ipcl/include/ipcl/common.hpp +++ b/ipcl/include/ipcl/utils/common.hpp @@ -1,8 +1,8 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#ifndef IPCL_INCLUDE_IPCL_COMMON_HPP_ -#define IPCL_INCLUDE_IPCL_COMMON_HPP_ +#ifndef IPCL_INCLUDE_IPCL_UTILS_COMMON_HPP_ +#define IPCL_INCLUDE_IPCL_UTILS_COMMON_HPP_ #include "ipcl/bignum.h" @@ -46,4 +46,4 @@ IppStatus ippGenRandomBN(IppsBigNumState* rand, int bits, void* ctx); BigNumber getRandomBN(int bits); } // namespace ipcl -#endif // IPCL_INCLUDE_IPCL_COMMON_HPP_ +#endif // IPCL_INCLUDE_IPCL_UTILS_COMMON_HPP_ diff --git a/ipcl/include/ipcl/context.hpp b/ipcl/include/ipcl/utils/context.hpp similarity index 89% rename from ipcl/include/ipcl/context.hpp rename to ipcl/include/ipcl/utils/context.hpp index c528a0a..b70315b 100644 --- a/ipcl/include/ipcl/context.hpp +++ b/ipcl/include/ipcl/utils/context.hpp @@ -3,8 +3,8 @@ #pragma once -#ifndef IPCL_INCLUDE_IPCL_CONTEXT_HPP_ -#define IPCL_INCLUDE_IPCL_CONTEXT_HPP_ +#ifndef IPCL_INCLUDE_IPCL_UTILS_CONTEXT_HPP_ +#define IPCL_INCLUDE_IPCL_UTILS_CONTEXT_HPP_ #include @@ -44,4 +44,4 @@ bool isQATRunning(void); bool isQATActive(void); } // namespace ipcl -#endif // IPCL_INCLUDE_IPCL_CONTEXT_HPP_ +#endif // IPCL_INCLUDE_IPCL_UTILS_CONTEXT_HPP_ diff --git a/ipcl/include/ipcl/utils/serialize.hpp b/ipcl/include/ipcl/utils/serialize.hpp new file mode 100644 index 0000000..92a3e2c --- /dev/null +++ b/ipcl/include/ipcl/utils/serialize.hpp @@ -0,0 +1,64 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IPCL_INCLUDE_IPCL_UTILS_SERIALIZE_HPP_ +#define IPCL_INCLUDE_IPCL_UTILS_SERIALIZE_HPP_ + +#include +#include +#include +#include +#include +#include + +#include "cereal/archives/portable_binary.hpp" +#include "cereal/types/vector.hpp" + +namespace ipcl { + +namespace serialize { +template +void serialize(const T& obj, std::ostream& ss) { + cereal::PortableBinaryOutputArchive archive(ss); + archive(obj); +} + +template +void deserialize(T& obj, std::istream& ss) { + cereal::PortableBinaryInputArchive archive(ss); + archive(obj); +} + +template +bool serializeToFile(const std::string& fn, const T& obj) { + std::ofstream ofs(fn, std::ios::out | std::ios::binary); + if (ofs.is_open()) { + serialize::serialize(obj, ofs); + ofs.close(); + return true; + } + return false; +} + +template +bool deserializeFromFile(const std::string& fn, const T& obj) { + std::ifstream ifs(fn, std::ios::in | std::ios::binary); + if (ifs.is_open()) { + serialize::deserialize(obj, ifs); + ifs.close(); + return true; + } + return false; +} + +class serializerBase { + public: + virtual ~serializerBase() {} + virtual std::string serializedName() const = 0; +}; + +}; // namespace serialize + +} // namespace ipcl + +#endif // IPCL_INCLUDE_IPCL_UTILS_SERIALIZE_HPP_ diff --git a/ipcl/include/ipcl/util.hpp b/ipcl/include/ipcl/utils/util.hpp similarity index 94% rename from ipcl/include/ipcl/util.hpp rename to ipcl/include/ipcl/utils/util.hpp index c2ea76a..7a4b510 100644 --- a/ipcl/include/ipcl/util.hpp +++ b/ipcl/include/ipcl/utils/util.hpp @@ -1,8 +1,8 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#ifndef IPCL_INCLUDE_IPCL_UTIL_HPP_ -#define IPCL_INCLUDE_IPCL_UTIL_HPP_ +#ifndef IPCL_INCLUDE_IPCL_UTILS_UTIL_HPP_ +#define IPCL_INCLUDE_IPCL_UTILS_UTIL_HPP_ #ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES #include @@ -14,7 +14,7 @@ #include #include -#include "ipcl/common.hpp" +#include "ipcl/utils/common.hpp" namespace ipcl { @@ -89,4 +89,4 @@ static const bool has_rdrand = features.rdrnd && prefer_rdrand; } // namespace ipcl -#endif // IPCL_INCLUDE_IPCL_UTIL_HPP_ +#endif // IPCL_INCLUDE_IPCL_UTILS_UTIL_HPP_ diff --git a/ipcl/mod_exp.cpp b/ipcl/mod_exp.cpp index 0f82f9c..d56dfc5 100644 --- a/ipcl/mod_exp.cpp +++ b/ipcl/mod_exp.cpp @@ -3,19 +3,19 @@ #include "ipcl/mod_exp.hpp" -#include - #include #include #include #include //NOLINT +#include "crypto_mb/exp.h" + #ifdef IPCL_USE_QAT #include #include #endif -#include "ipcl/util.hpp" +#include "ipcl/utils/util.hpp" namespace ipcl { diff --git a/ipcl/plaintext.cpp b/ipcl/plaintext.cpp index 4e4498d..44c303d 100644 --- a/ipcl/plaintext.cpp +++ b/ipcl/plaintext.cpp @@ -6,7 +6,7 @@ #include #include "ipcl/ciphertext.hpp" -#include "ipcl/util.hpp" +#include "ipcl/utils/util.hpp" namespace ipcl { diff --git a/ipcl/pri_key.cpp b/ipcl/pri_key.cpp index 29201f6..9ab1fd9 100644 --- a/ipcl/pri_key.cpp +++ b/ipcl/pri_key.cpp @@ -3,12 +3,11 @@ #include "ipcl/pri_key.hpp" -#include - #include +#include "crypto_mb/exp.h" #include "ipcl/mod_exp.hpp" -#include "ipcl/util.hpp" +#include "ipcl/utils/util.hpp" namespace ipcl { /** diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index abbbd64..8c4afb6 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -3,16 +3,15 @@ #include "ipcl/pub_key.hpp" -#include - #include #include #include #include +#include "crypto_mb/exp.h" #include "ipcl/ciphertext.hpp" #include "ipcl/mod_exp.hpp" -#include "ipcl/util.hpp" +#include "ipcl/utils/util.hpp" namespace ipcl { @@ -31,7 +30,9 @@ PublicKey::PublicKey(const BigNumber& n, int bits, bool enableDJN_) m_dwords(BITSIZE_DWORD(bits * 2)), m_init_seed(randomUniformUnsignedInt()), m_enable_DJN(false), - m_testv(false) { + m_testv(false), + m_hs(0), + m_randbits(0) { if (enableDJN_) this->enableDJN(); // sets m_enable_DJN } @@ -140,4 +141,29 @@ void PublicKey::setDJN(const BigNumber& hs, int randbit) { m_randbits = randbit; m_enable_DJN = true; } + +void PublicKey::create(const BigNumber& n, int bits, bool enableDJN_) { + m_n = n; + m_g = n + 1; + m_nsquare = n * n; + m_bits = bits; + m_dwords = BITSIZE_DWORD(bits * 2); + m_enable_DJN = enableDJN_; + if (enableDJN_) { + this->enableDJN(); + } else { + m_hs = BigNumber::Zero(); + m_randbits = 0; + } + m_testv = false; + std::cout << "create complete" << std::endl; +} + +void PublicKey::create(const BigNumber& n, int bits, const BigNumber& hs, + int randbits) { + create(n, bits, false); // set DJN to false and manually set + m_hs = hs; + m_randbits = randbits; +} + } // namespace ipcl diff --git a/ipcl/common.cpp b/ipcl/utils/common.cpp similarity index 95% rename from ipcl/common.cpp rename to ipcl/utils/common.cpp index 67e7e1a..e0130aa 100644 --- a/ipcl/common.cpp +++ b/ipcl/utils/common.cpp @@ -1,11 +1,10 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include "ipcl/common.hpp" +#include "ipcl/utils/common.hpp" -#include - -#include "ipcl/util.hpp" +#include "crypto_mb/exp.h" +#include "ipcl/utils/util.hpp" namespace ipcl { diff --git a/ipcl/context.cpp b/ipcl/utils/context.cpp similarity index 98% rename from ipcl/context.cpp rename to ipcl/utils/context.cpp index d64f581..7f9b93f 100644 --- a/ipcl/context.cpp +++ b/ipcl/utils/context.cpp @@ -1,7 +1,7 @@ // Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include "ipcl/context.hpp" +#include "ipcl/utils/context.hpp" #include #include diff --git a/ipcl/util.cpp b/ipcl/utils/util.cpp similarity index 93% rename from ipcl/util.cpp rename to ipcl/utils/util.cpp index 1de2b49..06a1adc 100644 --- a/ipcl/util.cpp +++ b/ipcl/utils/util.cpp @@ -1,7 +1,7 @@ // Copyright (C) 2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#include "ipcl/util.hpp" +#include "ipcl/utils/util.hpp" #ifdef IPCL_USE_OMP #include diff --git a/test/main.cpp b/test/main.cpp index 178b34d..d0930de 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -4,7 +4,7 @@ #include #include "gtest/gtest.h" -#include "ipcl/context.hpp" +#include "ipcl/ipcl.hpp" int main(int argc, char** argv) { #ifdef IPCL_USE_QAT From a8503cfa9d69abe6c680984af1a5506e99dfac93 Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Thu, 17 Nov 2022 01:38:37 +0800 Subject: [PATCH 355/364] v2.0 fixup (#31) * pubkey: Remove unnecessary m_init_seed, randomUniformUnsignedInt() * plaintext: Make user define type conversion support const value Signed-off-by: Zhao Pengfei --- ipcl/include/ipcl/plaintext.hpp | 22 +++++++++++----------- ipcl/include/ipcl/pub_key.hpp | 1 - ipcl/plaintext.cpp | 6 +++--- ipcl/pub_key.cpp | 8 -------- 4 files changed, 14 insertions(+), 23 deletions(-) diff --git a/ipcl/include/ipcl/plaintext.hpp b/ipcl/include/ipcl/plaintext.hpp index fcdb49d..63618f7 100644 --- a/ipcl/include/ipcl/plaintext.hpp +++ b/ipcl/include/ipcl/plaintext.hpp @@ -58,29 +58,29 @@ class PlainText : public BaseText { * User define implicit type conversion * Convert 1st element to uint32_t vector. */ - operator std::vector(); + operator std::vector() const; /** - * PT + CT + * User define implicit type conversion + * Convert 1st element to type BigNumber. */ - CipherText operator+(const CipherText& other) const; + operator BigNumber() const; /** - * PT * CT + * User define implicit type conversion + * Convert all element to type BigNumber. */ - CipherText operator*(const CipherText& other) const; + operator std::vector() const; /** - * User define implicit type conversion - * Convert 1st element to type BigNumber. + * PT + CT */ - operator BigNumber(); + CipherText operator+(const CipherText& other) const; /** - * User define implicit type conversion - * Convert all element to type BigNumber. + * PT * CT */ - operator std::vector(); + CipherText operator*(const CipherText& other) const; /** * Rotate PlainText diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp index 4a1a715..88d57cf 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -151,7 +151,6 @@ class PublicKey { int m_bits; int m_randbits; int m_dwords; - unsigned int m_init_seed; bool m_enable_DJN; std::vector m_r; bool m_testv; diff --git a/ipcl/plaintext.cpp b/ipcl/plaintext.cpp index 44c303d..7273719 100644 --- a/ipcl/plaintext.cpp +++ b/ipcl/plaintext.cpp @@ -34,7 +34,7 @@ CipherText PlainText::operator*(const CipherText& other) const { return other.operator*(*this); } -PlainText::operator std::vector() { +PlainText::operator std::vector() const { ERROR_CHECK(m_size > 0, "PlainText: type conversion to uint32_t vector error"); std::vector v; @@ -43,12 +43,12 @@ PlainText::operator std::vector() { return v; } -PlainText::operator BigNumber() { +PlainText::operator BigNumber() const { ERROR_CHECK(m_size > 0, "PlainText: type conversion to BigNumber error"); return m_texts[0]; } -PlainText::operator std::vector() { +PlainText::operator std::vector() const { ERROR_CHECK(m_size > 0, "PlainText: type conversion to BigNumber vector error"); return m_texts; diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index 8c4afb6..5dc9311 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -15,20 +15,12 @@ namespace ipcl { -static inline auto randomUniformUnsignedInt() { - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - return dist(rng); -} - PublicKey::PublicKey(const BigNumber& n, int bits, bool enableDJN_) : m_n(n), m_g(n + 1), m_nsquare(n * n), m_bits(bits), m_dwords(BITSIZE_DWORD(bits * 2)), - m_init_seed(randomUniformUnsignedInt()), m_enable_DJN(false), m_testv(false), m_hs(0), From 2fcde46ae7f7d9d1b1cf5b61e1459d1dec2aacc0 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Thu, 17 Nov 2022 22:57:26 -0800 Subject: [PATCH 356/364] Refactor thread counts (#32) Added feature where if ```IPCL_DETECT_CPU_RUNTIME=ON```, the library will use built-in ```/proc/cpuinfo``` parser to acquire cpu details runtime, otherwise use info gathered during CMake configure time * Added cpu_parser feature * Added ```IPCL_THREAD_COUNT``` maximum number of threads checker when explicitly set * Minor typo fixes --- CMakeLists.txt | 21 ++++--- README.md | 16 ++--- cmake/ipcl/ipcl-util.cmake | 38 +++++++++--- ipcl/CMakeLists.txt | 3 +- ipcl/include/ipcl/utils/parse_cpuinfo.hpp | 74 +++++++++++++++++++++++ ipcl/include/ipcl/utils/util.hpp | 45 +++++++++----- ipcl/utils/parse_cpuinfo.cpp | 13 ++++ ipcl/utils/util.cpp | 12 ++-- 8 files changed, 174 insertions(+), 48 deletions(-) create mode 100644 ipcl/include/ipcl/utils/parse_cpuinfo.hpp create mode 100644 ipcl/utils/parse_cpuinfo.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e3db6c6..8fc6cc9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,9 +102,14 @@ endif() if(IPCL_ENABLE_OMP) add_compile_definitions(IPCL_USE_OMP) - if(IPCL_THREAD_COUNT) - add_compile_definitions(IPCL_NUM_THREADS=${IPCL_THREAD_COUNT}) + ipcl_get_core_thread_count(num_cores num_threads num_nodes) + if(IPCL_THREAD_COUNT) + # if thread_count is invalid, set to maximum threads + if(IPCL_THREAD_COUNT GREATER num_threads) + set(IPCL_THREAD_COUNT ${num_threads}) endif() + add_compile_definitions(IPCL_NUM_THREADS=${IPCL_THREAD_COUNT}) + endif() endif() if(IPCL_DETECT_CPU_RUNTIME) @@ -112,22 +117,22 @@ if(IPCL_DETECT_CPU_RUNTIME) add_compile_definitions(IPCL_RUNTIME_DETECT_CPU_FEATURES) set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};$ORIGIN/cpufeatures") else() + # set cpu node count parsed from lscpu precompile + add_compile_definitions(IPCL_NUM_NODES=${num_nodes}) + # check whether cpu support avx512ifma instructions - ipcl_detect_lscpu_flag("avx512ifma" FALSE) + ipcl_detect_lscpu_flag("avx512ifma") if(IPCL_FOUND_avx512ifma) add_compile_definitions(IPCL_CRYPTO_MB_MOD_EXP) - message(STATUS "Support AVX512IFMA instruction: True") endif() # check whether cpu support rdseed/rdrand instructions - ipcl_detect_lscpu_flag("rdseed" FALSE) + ipcl_detect_lscpu_flag("rdseed") if(IPCL_FOUND_rdseed) - message(STATUS "Support RDSEED instruction: True") add_compile_definitions(IPCL_RNG_INSTR_RDSEED) else() - ipcl_detect_lscpu_flag("rdrand" FALSE) + ipcl_detect_lscpu_flag("rdrand") if(IPCL_FOUND_rdrand) - message(STATUS "Support RDRAND instruction: True") add_compile_definitions(IPCL_RNG_INSTR_RDRAND) else() message(WARNING diff --git a/README.md b/README.md index 932bf11..03cfcea 100644 --- a/README.md +++ b/README.md @@ -60,21 +60,17 @@ The following libraries and tools are also required, ``` nasm >= 2.15 OpenSSL >= 1.1.0 -numa >= 2.0.12 ``` -On Ubuntu, ```OpenSSL``` and ```numa``` can be installed with: +```OpenSSL``` can be installed with: ```bash -sudo apt update -sudo apt install nasm # for Ubuntu 20.04 or higher -sudo apt install libssl-dev libnuma-dev +# Ubuntu +sudo apt install libssl-dev +# Fedora (RHEL 8, Centos) +sudo dnf install openssl-devel ``` -For Ubuntu 18.04, RHEL and CentOS, please refer to the [Netwide Assembler webpage](https://nasm.us/) for installation details. -For RHEL and CentOS, the required libraries can be installed via: -``` -sudo yum install numactl-devel openssl-devel -``` +In order to install ```nasm```, please refer to the [Netwide Assembler webpage](https://nasm.us/) for download and installation details. ### Instructions The library can be built using the following commands: diff --git a/cmake/ipcl/ipcl-util.cmake b/cmake/ipcl/ipcl-util.cmake index 625c150..65c1a74 100644 --- a/cmake/ipcl/ipcl-util.cmake +++ b/cmake/ipcl/ipcl-util.cmake @@ -31,19 +31,15 @@ function(ipcl_create_archive target dependency) endfunction() -function(ipcl_detect_lscpu_flag flag verbose) +function(ipcl_detect_lscpu_flag flag) # Detect IFMA by parsing lscpu set(LSCPU_FLAG ${flag}) execute_process(COMMAND lscpu COMMAND grep ${LSCPU_FLAG} OUTPUT_VARIABLE LSCPU_FLAG) if("${LSCPU_FLAG}" STREQUAL "") - if(verbose) - message(STATUS "Support ${flag}: False") - endif() + message(STATUS "Support ${flag}: False") set(IPCL_FOUND_${flag} FALSE PARENT_SCOPE) else() - if(verbose) - message(STATUS "Support ${flag}: True") - endif() + message(STATUS "Support ${flag}: True") set(IPCL_FOUND_${flag} TRUE PARENT_SCOPE) endif() endfunction() @@ -118,3 +114,31 @@ function(ipcl_define_icp_variables OutVariable) ${ICP_API_DIR}/include/lac PARENT_SCOPE) endfunction() + +function(ipcl_get_core_thread_count cores threads nodes) + include(ProcessorCount) + + # Get number threads + ProcessorCount(n_threads) + set(${threads} ${n_threads} PARENT_SCOPE) + message(STATUS "# of threads: ${n_threads}") + + # check hyperthreading + execute_process(COMMAND cat /sys/devices/system/cpu/smt/active OUTPUT_VARIABLE IS_HYPERTHREADING OUTPUT_STRIP_TRAILING_WHITESPACE) + if("${IS_HYPERTHREADING}" STREQUAL "1") + math(EXPR n_cores "${n_threads} / 2" ) + set(${cores} ${n_cores} PARENT_SCOPE) + else() + set(n_cores ${n_threads}) + endif() + + set(${cores} ${n_cores} PARENT_SCOPE) + message(STATUS "# of physical cores: ${n_cores}") + + # check number of nodes + execute_process(COMMAND lscpu COMMAND grep Socket OUTPUT_VARIABLE output_nodes OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REGEX MATCHALL "([^\ ]+\ |[^\ ]+$)" output_nodes_list "${output_nodes}") + list(GET output_nodes_list -1 n_nodes) + message(STATUS "# of nodes: ${n_nodes}") + set(${nodes} ${n_nodes} PARENT_SCOPE) +endfunction() diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index 57ddf25..b3a9e07 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -12,6 +12,7 @@ set(IPCL_SRCS pri_key.cpp utils/context.cpp utils/util.cpp utils/common.cpp + utils/parse_cpuinfo.cpp ) if(IPCL_SHARED) @@ -114,7 +115,7 @@ endif() find_package(OpenSSL REQUIRED) find_package(Threads REQUIRED) -target_link_libraries(ipcl PUBLIC OpenSSL::SSL OpenSSL::Crypto Threads::Threads -lnuma) +target_link_libraries(ipcl PUBLIC OpenSSL::SSL OpenSSL::Crypto Threads::Threads) if(IPCL_ENABLE_OMP) find_package(OpenMP REQUIRED) diff --git a/ipcl/include/ipcl/utils/parse_cpuinfo.hpp b/ipcl/include/ipcl/utils/parse_cpuinfo.hpp new file mode 100644 index 0000000..d0313c0 --- /dev/null +++ b/ipcl/include/ipcl/utils/parse_cpuinfo.hpp @@ -0,0 +1,74 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IPCL_INCLUDE_IPCL_UTILS_PARSE_CPUINFO_HPP_ +#define IPCL_INCLUDE_IPCL_UTILS_PARSE_CPUINFO_HPP_ + +#include +#include +#include +#include +#include + +namespace ipcl { +// trim from start (in place) +static inline void ltrim(std::string& s) { + s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) { + return !std::isspace(ch); + })); +} + +// trim from end (in place) +static inline void rtrim(std::string& s) { + s.erase(std::find_if(s.rbegin(), s.rend(), + [](unsigned char ch) { return !std::isspace(ch); }) + .base(), + s.end()); +} + +static inline void trim(std::string& s) { + ltrim(s); + rtrim(s); +} + +typedef struct { + int n_processors = 0; + int n_cores = 0; + int n_nodes = 0; +} linuxCPUInfo; + +static void parseCPUInfo(linuxCPUInfo& info) { + std::ifstream cpuinfo; + cpuinfo.exceptions(std::ifstream::badbit); + + try { + cpuinfo.open("/proc/cpuinfo", std::ios::in); + std::string line; + while (std::getline(cpuinfo, line)) { + std::stringstream ss(line); + std::string key, val; + if (std::getline(ss, key, ':') && std::getline(ss, val)) { + trim(key); + trim(val); + if (key == "processor") + info.n_processors++; + else if (key == "core id") + info.n_cores = std::max(info.n_cores, std::stoi(val)); + else if (key == "physical id") + info.n_nodes = std::max(info.n_nodes, std::stoi(val)); + } + } + info.n_nodes++; + info.n_cores = (info.n_cores + 1) * info.n_nodes; + } catch (const std::ifstream::failure& e) { + std::ostringstream log; + log << "\nFile: " << __FILE__ << "\nLine: " << __LINE__ << "\nError: " + << "cannot parse /proc/cpuinfo"; + throw std::runtime_error(log.str()); + } +} +linuxCPUInfo GetLinuxCPUInfo(void); + +} // namespace ipcl + +#endif // IPCL_INCLUDE_IPCL_UTILS_PARSE_CPUINFO_HPP_ diff --git a/ipcl/include/ipcl/utils/util.hpp b/ipcl/include/ipcl/utils/util.hpp index 7a4b510..a9f5ca6 100644 --- a/ipcl/include/ipcl/utils/util.hpp +++ b/ipcl/include/ipcl/utils/util.hpp @@ -6,6 +6,8 @@ #ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES #include + +#include "ipcl/utils/parse_cpuinfo.hpp" #endif // IPCL_RUNTIME_DETECT_CPU_FEATURES #include @@ -41,6 +43,22 @@ inline void vec_size_check(const std::vector& v, const char* file, #define VEC_SIZE_CHECK(v) vec_size_check(v, __FILE__, __LINE__) +#ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES +static const bool disable_avx512ifma = + (std::getenv("IPCL_DISABLE_AVX512IFMA") != nullptr); +static const bool prefer_rdrand = + (std::getenv("IPCL_PREFER_RDRAND") != nullptr); +static const bool prefer_ipp_prng = + (std::getenv("IPCL_PREFER_IPP_PRNG") != nullptr); +static const cpu_features::X86Features features = + cpu_features::GetX86Info().features; +static const bool has_avx512ifma = features.avx512ifma && !disable_avx512ifma; +static const bool has_rdseed = + features.rdseed && !prefer_rdrand && !prefer_ipp_prng; +static const bool has_rdrand = features.rdrnd && prefer_rdrand; + +#endif // IPCL_RUNTIME_DETECT_CPU_FEATURES + #ifdef IPCL_USE_OMP class OMPUtilities { public: @@ -57,9 +75,20 @@ class OMPUtilities { } private: +#ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES + static const linuxCPUInfo cpuinfo; + static const linuxCPUInfo getLinuxCPUInfo() { return GetLinuxCPUInfo(); } +#endif static const int nodes; static const int cpus; + static int getNodes() { +#ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES + return cpuinfo.n_nodes; +#else + return IPCL_NUM_NODES; +#endif // IPCL_RUNTIME_DETECT_CPU_FEATURES + } static int getMaxThreads() { #ifdef IPCL_NUM_THREADS return IPCL_NUM_THREADS; @@ -71,22 +100,6 @@ class OMPUtilities { #endif // IPCL_USE_OMP -#ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES -static const bool disable_avx512ifma = - (std::getenv("IPCL_DISABLE_AVX512IFMA") != nullptr); -static const bool prefer_rdrand = - (std::getenv("IPCL_PREFER_RDRAND") != nullptr); -static const bool prefer_ipp_prng = - (std::getenv("IPCL_PREFER_IPP_PRNG") != nullptr); -static const cpu_features::X86Features features = - cpu_features::GetX86Info().features; -static const bool has_avx512ifma = features.avx512ifma && !disable_avx512ifma; -static const bool has_rdseed = - features.rdseed && !prefer_rdrand && !prefer_ipp_prng; -static const bool has_rdrand = features.rdrnd && prefer_rdrand; - -#endif // IPCL_RUNTIME_DETECT_CPU_FEATURES - } // namespace ipcl #endif // IPCL_INCLUDE_IPCL_UTILS_UTIL_HPP_ diff --git a/ipcl/utils/parse_cpuinfo.cpp b/ipcl/utils/parse_cpuinfo.cpp new file mode 100644 index 0000000..2c1b135 --- /dev/null +++ b/ipcl/utils/parse_cpuinfo.cpp @@ -0,0 +1,13 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/utils/parse_cpuinfo.hpp" + +#include +#include + +ipcl::linuxCPUInfo ipcl::GetLinuxCPUInfo(void) { + ipcl::linuxCPUInfo info; + ipcl::parseCPUInfo(info); + return info; +} diff --git a/ipcl/utils/util.cpp b/ipcl/utils/util.cpp index 06a1adc..d0ffdfe 100644 --- a/ipcl/utils/util.cpp +++ b/ipcl/utils/util.cpp @@ -3,17 +3,17 @@ #include "ipcl/utils/util.hpp" -#ifdef IPCL_USE_OMP -#include -#endif // IPCL_USE_OMP +#include // NOLINT [build/c++11] namespace ipcl { #ifdef IPCL_USE_OMP -const int OMPUtilities::nodes = numa_num_configured_nodes(); -const int OMPUtilities::cpus = numa_num_configured_cpus(); +#ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES +const linuxCPUInfo OMPUtilities::cpuinfo = OMPUtilities::getLinuxCPUInfo(); +#endif // IPCL_RUNTIME_DETECT_CPU_FEATURES +const int OMPUtilities::cpus = std::thread::hardware_concurrency(); +const int OMPUtilities::nodes = OMPUtilities::getNodes(); const int OMPUtilities::MaxThreads = OMPUtilities::getMaxThreads(); - #endif // IPCL_USE_OMP } // namespace ipcl From a91c24430ecef172072a6a06eba67c3886a7f7e9 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Fri, 18 Nov 2022 10:47:46 -0800 Subject: [PATCH 357/364] Removed struct initial values --- ipcl/include/ipcl/utils/parse_cpuinfo.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ipcl/include/ipcl/utils/parse_cpuinfo.hpp b/ipcl/include/ipcl/utils/parse_cpuinfo.hpp index d0313c0..279aa4f 100644 --- a/ipcl/include/ipcl/utils/parse_cpuinfo.hpp +++ b/ipcl/include/ipcl/utils/parse_cpuinfo.hpp @@ -32,9 +32,9 @@ static inline void trim(std::string& s) { } typedef struct { - int n_processors = 0; - int n_cores = 0; - int n_nodes = 0; + int n_processors; + int n_cores; + int n_nodes; } linuxCPUInfo; static void parseCPUInfo(linuxCPUInfo& info) { From e794a0c264641d929a90cefbc2afca5f54840f56 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Fri, 18 Nov 2022 15:55:02 -0800 Subject: [PATCH 358/364] Updated github ci (#34) * Refactor CI/CD process --- .github/workflows/github-ci.yml | 173 ++++++++++++++++++++-------- example/CMakeLists.txt | 6 + example/example_add_mul.cpp | 6 + example/example_encrypt_decrypt.cpp | 6 + example/example_hybridmode.cpp | 6 + 5 files changed, 149 insertions(+), 48 deletions(-) diff --git a/.github/workflows/github-ci.yml b/.github/workflows/github-ci.yml index b84b3be..ee5e9c0 100644 --- a/.github/workflows/github-ci.yml +++ b/.github/workflows/github-ci.yml @@ -9,19 +9,25 @@ on: branches: - main - development - - "[0-9]+.[0-9]+.[0-9]+" + - "ipcl_v[0-9]+.[0-9]+.[0-9]+" push: branches: - main - development - - "[0-9]+.[0-9]+.[0-9]+" + - "ipcl_v[0-9]+.[0-9]+.[0-9]+" # Manually run this workflow on any specified branch. workflow_dispatch: -############## -# IceLake CI # -############## +################### +# Define env vars # +################### +env: + IPCL_VER: 2.0.0 + IPCL_DIR: ${GITHUB_WORKSPACE}/ipcl_install + IPCL_HINT_DIR: > + -DIPCL_HINT_DIR=${GITHUB_WORKSPACE}/ipcl_install/lib/cmake/ipcl-${IPCL_VER} + jobs: format: name: Format check @@ -37,69 +43,140 @@ jobs: run: pre-commit run --all-files build-and-test: - name: Build, test and run kernels - shared + name: '${{ matrix.build_type }} qat=${{ matrix.enable_qat }} detect_cpu_runtime=${{ matrix.detect_cpu_runtime }} shared=${{ matrix.shared_lib }}' needs: [format] runs-on: [self-hosted, linux, x64, icx] - # Use environment protection (require review) - environment: intel_workflow defaults: run: shell: bash - working-directory: . + strategy: + matrix: + build_type: [Release, Debug] + shared_lib: [ON, OFF] + detect_cpu_runtime: [ON, OFF] + # qat disabled for ICX - to be added with SPR runner + enable_qat: [OFF] + include: + # run minimum for debug mode + - build_type: Debug + benchmark_min_time: "--benchmark_min_time=0.001" + - build_type: Release + benchmark_min_time: "" steps: - uses: actions/checkout@v2 - - name: Validate paths + - name: Setup cmake + uses: jwlawson/actions-setup-cmake@v1.13 + with: + cmake-version: '3.16.x' + - name: Validate environment run: | + set -x + export CC=clang-10 + export CXX=clang++-10 + + # Validate paths whoami echo $HOME echo $GITHUB_WORKSPACE echo "Testing from branch:" echo $GITHUB_REF + cmake --version pwd - # Build library - - name: Build the repository + - name: Build library run: | - cmake -S . -B build -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=Release -DIPCL_ENABLE_QAT=ON - cmake --build build --target all -j + # QAT unavailable in ICX - to be added + cmake -S . -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type}} \ + -DIPCL_DETECT_CPU_RUNTIME=${{ matrix.detect_cpu_runtime }} \ + -DIPCL_ENABLE_QAT=${{ matrix.enable_qat }} \ + -DCMAKE_INSTALL_PREFIX=./ipcl_install + cmake --build build -j$(nproc) + cmake --build build --target install - # Unit tests and examples - - name: Run the unit tests - run: ./build/test/unittest_ipcl - - - name: Run the benchmarks - run: ./build/benchmark/bench_ipcl + - name: Run unittest + run: | + cmake --build build --target unittest - build-and-test-static: - name: Build, test and run kernels - static - needs: [format] - runs-on: [self-hosted, linux, x64, icx] - # Use environment protection (require review) - environment: intel_workflow - defaults: - run: - shell: bash - working-directory: . - steps: - - uses: actions/checkout@v2 - - name: Validate paths + - name: Run benchmark run: | - whoami - echo $HOME - echo $GITHUB_WORKSPACE - echo "Testing from branch:" - echo $GITHUB_REF - pwd + ./build/benchmark/bench_ipcl \ + --benchmark_out="${GITHUB_WORKFLOW}_${GITHUB_SHA}" \ + --benchmark_out_format=csv ${{ matrix.benchmark_min_time }} - # Build library - - name: Build the repository + - name: Build and run examples run: | - cmake -S . -B build -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=Release -DIPCL_ENABLE_QAT=ON -DIPCL_SHARED=OFF - cmake --build build --target all -j + cd $GITHUB_WORKSPACE/example + cmake -S . -B build ${{ env.IPCL_HINT_DIR }} + cmake --build build + cmake --build build --target run_all_examples + + - name: Archive benchmark results + uses: actions/upload-artifact@v2 + with: + name: bench_ipcl_${{ github.sha }}.csv + path: ${{ github.workspace }}/${{ github.workflow }}_${{ github.sha }} + retention-days: 90 + + + # name: Build, test and run kernels - shared + # needs: [format] + # runs-on: [self-hosted, linux, x64, icx] + # defaults: + # run: + # shell: bash + # working-directory: . + # steps: + # - uses: actions/checkout@v2 + # - name: Validate paths + # run: | + # whoami + # echo $HOME + # echo $GITHUB_WORKSPACE + # echo "Testing from branch:" + # echo $GITHUB_REF + # pwd + + # # Build library + # - name: Build the repository + # run: | + # cmake -S . -B build -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=Release -DIPCL_ENABLE_QAT=ON + # cmake --build build --target all -j + + # # Unit tests and examples + # - name: Run the unit tests + # run: ./build/test/unittest_ipcl + + # - name: Run the benchmarks + # run: ./build/benchmark/bench_ipcl + + # build-and-test-static: + # name: Build, test and run kernels - static + # needs: [format] + # runs-on: [self-hosted, linux, x64, icx] + # defaults: + # run: + # shell: bash + # working-directory: . + # steps: + # - uses: actions/checkout@v2 + # - name: Validate paths + # run: | + # whoami + # echo $HOME + # echo $GITHUB_WORKSPACE + # echo "Testing from branch:" + # echo $GITHUB_REF + # pwd + + # # Build library + # - name: Build the repository + # run: | + # cmake -S . -B build -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=Release -DIPCL_ENABLE_QAT=ON -DIPCL_SHARED=OFF + # cmake --build build --target all -j - # Unit tests and examples - - name: Run the unit tests - run: ./build/test/unittest_ipcl + # # Unit tests and examples + # - name: Run the unit tests + # run: ./build/test/unittest_ipcl - - name: Run the benchmarks - run: ./build/benchmark/bench_ipcl + # - name: Run the benchmarks + # run: ./build/benchmark/bench_ipcl diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 9e2de3a..67fe74a 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -12,7 +12,13 @@ set(CMAKE_CXX_EXTENSIONS OFF) find_package(IPCL 2.0.0 REQUIRED HINTS ${IPCL_HINT_DIR}) set(examples encrypt_decrypt add_mul hybridmode) + +add_custom_target(run_all_examples) + foreach(ex IN LISTS examples) add_executable(example_${ex} example_${ex}.cpp) target_link_libraries(example_${ex} PRIVATE IPCL::ipcl) + add_custom_command(TARGET run_all_examples POST_BUILD + COMMAND $) + add_dependencies(run_all_examples example_${ex}) endforeach() diff --git a/example/example_add_mul.cpp b/example/example_add_mul.cpp index 6d9ec22..d53a61f 100644 --- a/example/example_add_mul.cpp +++ b/example/example_add_mul.cpp @@ -12,6 +12,11 @@ #include "ipcl/ipcl.hpp" int main() { + std::cout << std::endl; + std::cout << "==============================================" << std::endl; + std::cout << "Example: Addition and Multiplication with IPCL" << std::endl; + std::cout << "==============================================" << std::endl; + ipcl::initializeContext("QAT"); const uint32_t num_total = 20; @@ -97,4 +102,5 @@ int main() { delete key.pub_key; delete key.priv_key; ipcl::terminateContext(); + std::cout << "Complete!" << std::endl; } diff --git a/example/example_encrypt_decrypt.cpp b/example/example_encrypt_decrypt.cpp index e8c0c7e..50f08c9 100644 --- a/example/example_encrypt_decrypt.cpp +++ b/example/example_encrypt_decrypt.cpp @@ -12,6 +12,11 @@ #include "ipcl/ipcl.hpp" int main() { + std::cout << std::endl; + std::cout << "======================================" << std::endl; + std::cout << "Example: Encrypt and Decrypt with IPCL" << std::endl; + std::cout << "======================================" << std::endl; + ipcl::initializeContext("QAT"); const uint32_t num_total = 20; @@ -52,4 +57,5 @@ int main() { delete key.pub_key; delete key.priv_key; ipcl::terminateContext(); + std::cout << "Complete!" << std::endl << std::endl; } diff --git a/example/example_hybridmode.cpp b/example/example_hybridmode.cpp index 4feaa1e..66da0e5 100644 --- a/example/example_hybridmode.cpp +++ b/example/example_hybridmode.cpp @@ -19,6 +19,11 @@ typedef std::chrono::high_resolution_clock::time_point tVar; std::chrono::duration_cast(tNow() - t).count() int main() { + std::cout << std::endl; + std::cout << "===================================" << std::endl; + std::cout << "Example: Hybrid Mode usage with QAT" << std::endl; + std::cout << "===================================" << std::endl; + ipcl::initializeContext("QAT"); tVar t; double elapsed(0.); @@ -93,4 +98,5 @@ int main() { delete key.pub_key; delete key.priv_key; ipcl::terminateContext(); + std::cout << "Complete!" << std::endl << std::endl; } From 1fe26169c4191e13e999d133e39364dcf7a271d2 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Sun, 20 Nov 2022 12:28:53 -0800 Subject: [PATCH 359/364] Detect preinstalled ippcrypto (#36) * Add feature to use pre-installed IPP-Crypto * Add ext_cereal dependency to avoid occasional compile error --- CMakeLists.txt | 3 +- cmake/ippcrypto.cmake | 183 +++++++++++++++++++++++++----------------- ipcl/CMakeLists.txt | 29 ++----- 3 files changed, 117 insertions(+), 98 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8fc6cc9..8303faa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,6 +70,7 @@ option(IPCL_DOCS "Enable document building" OFF) option(IPCL_SHARED "Build shared library" ON) option(IPCL_DETECT_CPU_RUNTIME "Detect CPU supported instructions during runtime" OFF) option(IPCL_INTERNAL_PYTHON_BUILD "Additional steps for IPCL_Python build" OFF) +option(IPCL_IPPCRYPTO_PATH "Use pre-installed IPP-Crypto library" OFF) # Used only for ipcl_python IPCL_INTERNAL_PYTHON_BUILD - additional check if invalid parameters if(IPCL_INTERNAL_PYTHON_BUILD) @@ -205,7 +206,7 @@ endif() if(IPCL_ENABLE_QAT) # preset values for including HE_QAT - set(HE_QAT_MISC OFF) # revisit later on + set(HE_QAT_MISC OFF) set(HE_QAT_DOCS ${IPCL_DOCS}) set(HE_QAT_SHARED ${IPCL_SHARED}) set(HE_QAT_TEST OFF) diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake index d9477f9..0952b4c 100644 --- a/cmake/ippcrypto.cmake +++ b/cmake/ippcrypto.cmake @@ -4,93 +4,128 @@ include(ExternalProject) message(STATUS "Configuring ipp-crypto") -set(IPPCRYPTO_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_ipp-crypto) -set(IPPCRYPTO_DESTDIR ${IPPCRYPTO_PREFIX}/ippcrypto_install) -set(IPPCRYPTO_DEST_INCLUDE_DIR include/ippcrypto) -set(IPPCRYPTO_GIT_REPO_URL https://github.com/intel/ipp-crypto.git) -set(IPPCRYPTO_GIT_LABEL ippcp_2021.6) -set(IPPCRYPTO_SRC_DIR ${IPPCRYPTO_PREFIX}/src/ext_ipp-crypto/) - -set(IPPCRYPTO_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS} -DNONPIC_LIB:BOOL=off -DMERGED_BLD:BOOL=on") - -set(IPPCRYPTO_ARCH intel64) -set(BUILD_x64 ON) -if(BUILD_x64) - if(NOT ${BUILD_x64}) - set(IPPCRYPTO_ARCH ia32) +if(IPCL_IPPCRYPTO_PATH) + if(IPCL_SHARED) + set(IPPCP_SHARED ON) + else() + set(IPPCP_SHARED OFF) endif() + + # ippcp version 11.4 - inline with ippcp_2021.6 + find_package(ippcp 11.4 HINTS ${IPCL_IPPCRYPTO_PATH}/lib/cmake/ippcp) endif() -ExternalProject_Add( - ext_ipp-crypto - GIT_REPOSITORY ${IPPCRYPTO_GIT_REPO_URL} - GIT_TAG ${IPPCRYPTO_GIT_LABEL} - PREFIX ${IPPCRYPTO_PREFIX} - INSTALL_DIR ${IPPCRYPTO_PREFIX} - CMAKE_ARGS ${IPPCRYPTO_CXX_FLAGS} - -DCMAKE_INSTALL_PREFIX=${IPPCRYPTO_PREFIX} - -DARCH=${IPPCRYPTO_ARCH} - -DCMAKE_ASM_NASM_COMPILER=nasm - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} - -DCMAKE_INSTALL_INCLUDEDIR=${IPPCRYPTO_DEST_INCLUDE_DIR} - UPDATE_COMMAND "" - PATCH_COMMAND git apply ${CMAKE_CURRENT_LIST_DIR}/patch/ippcrypto_patch.patch - INSTALL_COMMAND make DESTDIR=${IPPCRYPTO_DESTDIR} install -) - -set(IPPCRYPTO_INC_DIR ${IPPCRYPTO_DESTDIR}/${CMAKE_INSTALL_PREFIX}/include) -set(IPPCRYPTO_LIB_DIR ${IPPCRYPTO_DESTDIR}/${CMAKE_INSTALL_PREFIX}/lib/${IPPCRYPTO_ARCH}) -if(IPCL_SHARED) - add_library(IPPCP INTERFACE) - add_library(IPPCP::ippcp ALIAS IPPCP) - - add_dependencies(IPPCP ext_ipp-crypto) - - ExternalProject_Get_Property(ext_ipp-crypto SOURCE_DIR BINARY_DIR) - - target_include_directories(IPPCP SYSTEM INTERFACE ${IPPCRYPTO_INC_DIR}) - - # if ipcl python build - if(IPCL_INTERNAL_PYTHON_BUILD) - target_link_libraries(IPPCP INTERFACE - ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ippcrypto/libippcp.so - ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ippcrypto/libcrypto_mb.so - ) - - add_custom_command(TARGET ext_ipp-crypto - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory ${IPPCRYPTO_LIB_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ippcrypto - ) - else() - target_link_libraries(IPPCP INTERFACE - ${IPPCRYPTO_LIB_DIR}/libippcp.so - ${IPPCRYPTO_LIB_DIR}/libcrypto_mb.so - ) - endif() +if(ippcp_FOUND) + message(STATUS "IPP-Crypto Found - using pre-installed IPP-Crypto library") + get_target_property(IPPCRYPTO_INC_DIR IPPCP::ippcp INTERFACE_INCLUDE_DIRECTORIES) + get_target_property(IPPCRYPTO_IMPORTED_LOCATION IPPCP::ippcp IMPORTED_LOCATION) + get_filename_component(IPPCRYPTO_LIB_DIR ${IPPCRYPTO_IMPORTED_LOCATION} DIRECTORY) install( DIRECTORY ${IPPCRYPTO_LIB_DIR}/ DESTINATION "${IPCL_INSTALL_LIBDIR}/ippcrypto" USE_SOURCE_PERMISSIONS ) + else() + message(STATUS "IPP-Crypto NOT Found - building from source") + + set(IPPCRYPTO_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_ipp-crypto) + set(IPPCRYPTO_DESTDIR ${IPPCRYPTO_PREFIX}/ippcrypto_install) + set(IPPCRYPTO_DEST_INCLUDE_DIR include/ippcrypto) + set(IPPCRYPTO_GIT_REPO_URL https://github.com/intel/ipp-crypto.git) + set(IPPCRYPTO_GIT_LABEL ippcp_2021.6) #ippcp version 11.4 + set(IPPCRYPTO_SRC_DIR ${IPPCRYPTO_PREFIX}/src/ext_ipp-crypto/) + + set(IPPCRYPTO_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS} -DNONPIC_LIB:BOOL=off -DMERGED_BLD:BOOL=on") + + set(IPPCRYPTO_ARCH intel64) + set(BUILD_x64 ON) + if(BUILD_x64) + if(NOT ${BUILD_x64}) + set(IPPCRYPTO_ARCH ia32) + endif() + endif() - add_library(IPPCP::ippcp STATIC IMPORTED GLOBAL) - add_library(IPPCP::crypto_mb STATIC IMPORTED GLOBAL) + ExternalProject_Add( + ext_ipp-crypto + GIT_REPOSITORY ${IPPCRYPTO_GIT_REPO_URL} + GIT_TAG ${IPPCRYPTO_GIT_LABEL} + PREFIX ${IPPCRYPTO_PREFIX} + INSTALL_DIR ${IPPCRYPTO_PREFIX} + CMAKE_ARGS ${IPPCRYPTO_CXX_FLAGS} + -DCMAKE_INSTALL_PREFIX=${IPPCRYPTO_PREFIX} + -DARCH=${IPPCRYPTO_ARCH} + -DCMAKE_ASM_NASM_COMPILER=nasm + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + UPDATE_COMMAND "" + PATCH_COMMAND git apply ${CMAKE_CURRENT_LIST_DIR}/patch/ippcrypto_patch.patch + INSTALL_COMMAND make DESTDIR=${IPPCRYPTO_DESTDIR} install + ) - add_dependencies(IPPCP::ippcp ext_ipp-crypto) - add_dependencies(IPPCP::crypto_mb ext_ipp-crypto) + set(IPPCRYPTO_INC_DIR ${IPPCRYPTO_DESTDIR}/${CMAKE_INSTALL_PREFIX}/include) + set(IPPCRYPTO_LIB_DIR ${IPPCRYPTO_DESTDIR}/${CMAKE_INSTALL_PREFIX}/lib/${IPPCRYPTO_ARCH}) + if(IPCL_SHARED) + add_library(IPPCP_ippcp INTERFACE) + add_library(IPPCP::ippcp ALIAS IPPCP_ippcp) + + add_library(IPPCP_crypto_mb INTERFACE) + add_library(IPPCP::crypto_mb ALIAS IPPCP_crypto_mb) + + add_dependencies(IPPCP_ippcp ext_ipp-crypto) + add_dependencies(IPPCP_crypto_mb ext_ipp-crypto) + + target_include_directories(IPPCP_ippcp SYSTEM INTERFACE ${IPPCRYPTO_INC_DIR}) + target_include_directories(IPPCP_crypto_mb SYSTEM INTERFACE ${IPPCRYPTO_INC_DIR}) + + # if ipcl python build + if(IPCL_INTERNAL_PYTHON_BUILD) + target_link_libraries(IPPCP_ippcp INTERFACE + ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ippcrypto/libippcp.so + ) + target_link_libraries(IPPCP_crypto_mb INTERFACE + ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ippcrypto/libcrypto_mb.so + ) + + add_custom_command(TARGET ext_ipp-crypto + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory ${IPPCRYPTO_LIB_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ippcrypto + ) + else() + target_link_libraries(IPPCP_ippcp INTERFACE + ${IPPCRYPTO_LIB_DIR}/libippcp.so + ) + target_link_libraries(IPPCP_crypto_mb INTERFACE + ${IPPCRYPTO_LIB_DIR}/libcrypto_mb.so + ) + + endif() + + install( + DIRECTORY ${IPPCRYPTO_LIB_DIR}/ + DESTINATION "${IPCL_INSTALL_LIBDIR}/ippcrypto" + USE_SOURCE_PERMISSIONS + ) - find_package(OpenSSL REQUIRED) + else() - set_target_properties(IPPCP::ippcp PROPERTIES - IMPORTED_LOCATION ${IPPCRYPTO_LIB_DIR}/libippcp.a - INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} - ) + add_library(IPPCP::ippcp STATIC IMPORTED GLOBAL) + add_library(IPPCP::crypto_mb STATIC IMPORTED GLOBAL) - set_target_properties(IPPCP::crypto_mb PROPERTIES - IMPORTED_LOCATION ${IPPCRYPTO_LIB_DIR}/libcrypto_mb.a - INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} - ) + add_dependencies(IPPCP::ippcp ext_ipp-crypto) + add_dependencies(IPPCP::crypto_mb ext_ipp-crypto) + + find_package(OpenSSL REQUIRED) + + set_target_properties(IPPCP::ippcp PROPERTIES + IMPORTED_LOCATION ${IPPCRYPTO_LIB_DIR}/libippcp.a + INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} + ) + + set_target_properties(IPPCP::crypto_mb PROPERTIES + IMPORTED_LOCATION ${IPPCRYPTO_LIB_DIR}/libcrypto_mb.a + INCLUDE_DIRECTORIES ${IPPCRYPTO_INC_DIR} + ) + endif() endif() diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index b3a9e07..a601caf 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -43,6 +43,7 @@ install(DIRECTORY ${IPCL_INC_DIR}/ ) # CEREAL (third party dep): include and install definition +add_dependencies(ipcl ext_cereal) target_include_directories(ipcl PUBLIC $ PUBLIC $ @@ -57,35 +58,17 @@ install(DIRECTORY ${CEREAL_INC_DIR}/ # IPP-Crypto (third party dep): include and install definition target_include_directories(ipcl - PUBLIC $ + PUBLIC $ PUBLIC $ ) install(DIRECTORY ${IPPCRYPTO_INC_DIR}/ - DESTINATION ${IPCL_INSTALL_INCLUDEDIR} + DESTINATION ${IPCL_INSTALL_INCLUDEDIR}/ippcrypto FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h" ) -# CPU_FEATURES (third party dep): include and install definition -if(IPCL_DETECT_IFMA_RUNTIME) - target_include_directories(ipcl - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PUBLIC $ - PUBLIC $ - ) - install(DIRECTORY ${CPUFEATURES_INC_DIR}/ - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} - FILES_MATCHING - PATTERN "*.hpp" - PATTERN "*.h" - ) - -endif() - - - # include and install definition of cpu_features if(IPCL_DETECT_CPU_RUNTIME) target_include_directories(ipcl @@ -96,8 +79,8 @@ if(IPCL_DETECT_CPU_RUNTIME) DESTINATION ${IPCL_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.hpp" - PATTERN "*.h") - + PATTERN "*.h" + ) endif() # include and install definition of he_qat @@ -123,7 +106,7 @@ if(IPCL_ENABLE_OMP) endif() if(IPCL_SHARED) - target_link_libraries(ipcl PRIVATE IPPCP::ippcp) + target_link_libraries(ipcl PRIVATE IPPCP::ippcp IPPCP::crypto_mb) if(IPCL_DETECT_CPU_RUNTIME) target_link_libraries(ipcl PRIVATE libcpu_features) endif() From 10085f3803f10bed2e434e2005d7ca568a96814c Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Sun, 20 Nov 2022 22:47:24 -0800 Subject: [PATCH 360/364] Add initialization to avoid occasional error of retrieving values (#37) --- ipcl/include/ipcl/utils/parse_cpuinfo.hpp | 5 ++++- ipcl/include/ipcl/utils/util.hpp | 2 +- ipcl/utils/parse_cpuinfo.cpp | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ipcl/include/ipcl/utils/parse_cpuinfo.hpp b/ipcl/include/ipcl/utils/parse_cpuinfo.hpp index 279aa4f..5d81163 100644 --- a/ipcl/include/ipcl/utils/parse_cpuinfo.hpp +++ b/ipcl/include/ipcl/utils/parse_cpuinfo.hpp @@ -40,6 +40,9 @@ typedef struct { static void parseCPUInfo(linuxCPUInfo& info) { std::ifstream cpuinfo; cpuinfo.exceptions(std::ifstream::badbit); + info.n_cores = 0; + info.n_processors = 0; + info.n_nodes = 0; try { cpuinfo.open("/proc/cpuinfo", std::ios::in); @@ -67,7 +70,7 @@ static void parseCPUInfo(linuxCPUInfo& info) { throw std::runtime_error(log.str()); } } -linuxCPUInfo GetLinuxCPUInfo(void); +linuxCPUInfo getLinuxCPUInfoImpl(void); } // namespace ipcl diff --git a/ipcl/include/ipcl/utils/util.hpp b/ipcl/include/ipcl/utils/util.hpp index a9f5ca6..17c6c4e 100644 --- a/ipcl/include/ipcl/utils/util.hpp +++ b/ipcl/include/ipcl/utils/util.hpp @@ -77,7 +77,7 @@ class OMPUtilities { private: #ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES static const linuxCPUInfo cpuinfo; - static const linuxCPUInfo getLinuxCPUInfo() { return GetLinuxCPUInfo(); } + static const linuxCPUInfo getLinuxCPUInfo() { return getLinuxCPUInfoImpl(); } #endif static const int nodes; static const int cpus; diff --git a/ipcl/utils/parse_cpuinfo.cpp b/ipcl/utils/parse_cpuinfo.cpp index 2c1b135..a8b6141 100644 --- a/ipcl/utils/parse_cpuinfo.cpp +++ b/ipcl/utils/parse_cpuinfo.cpp @@ -6,7 +6,7 @@ #include #include -ipcl::linuxCPUInfo ipcl::GetLinuxCPUInfo(void) { +ipcl::linuxCPUInfo ipcl::getLinuxCPUInfoImpl(void) { ipcl::linuxCPUInfo info; ipcl::parseCPUInfo(info); return info; From e8e9cd820c6560ce609d4e948facad05b3dc1b28 Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Mon, 21 Nov 2022 19:05:32 -0800 Subject: [PATCH 361/364] Replace IPCL_IPPCRYPTO_PATH with CMAKE_PREFIX_PATH (#39) * Replace IPCL_IPPCRYPTO_PATH with CMAKE_PREFIX_PATH - Looks for installed IPP-Crypto on system with default locations at ${HOME}/intel and /opt/intel/ipp-crypto - Replace /opt/intel/ipp-crypto with /opt/intel --- CMakeLists.txt | 8 +++++++- cmake/ippcrypto.cmake | 15 +++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8303faa..71201cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,13 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "/opt/intel/ipcl") endif() +if(CMAKE_PREFIX_PATH) + message(STATUS "---- CMAKE_PREFIX_PATH is defined as ${CMAKE_PREFIX_PATH}") +else() + set(CMAKE_PREFIX_PATH $ENV{HOME}/intel /opt/intel) +endif() + + set(CMAKE_C_FLAGS "-O2 -Wno-error=deprecated-declarations -Wno-error=deprecated-copy") set(CMAKE_CXX_FLAGS "-O2 -fpermissive -Wno-error=deprecated-declarations -Wno-error=deprecated-copy") set(CMAKE_INSTALL_RPATH "$ORIGIN;$ORIGIN/${CMAKE_INSTALL_LIBDIR};$ORIGIN/ippcrypto") @@ -70,7 +77,6 @@ option(IPCL_DOCS "Enable document building" OFF) option(IPCL_SHARED "Build shared library" ON) option(IPCL_DETECT_CPU_RUNTIME "Detect CPU supported instructions during runtime" OFF) option(IPCL_INTERNAL_PYTHON_BUILD "Additional steps for IPCL_Python build" OFF) -option(IPCL_IPPCRYPTO_PATH "Use pre-installed IPP-Crypto library" OFF) # Used only for ipcl_python IPCL_INTERNAL_PYTHON_BUILD - additional check if invalid parameters if(IPCL_INTERNAL_PYTHON_BUILD) diff --git a/cmake/ippcrypto.cmake b/cmake/ippcrypto.cmake index 0952b4c..e0dc364 100644 --- a/cmake/ippcrypto.cmake +++ b/cmake/ippcrypto.cmake @@ -4,23 +4,23 @@ include(ExternalProject) message(STATUS "Configuring ipp-crypto") -if(IPCL_IPPCRYPTO_PATH) +set(IPPCRYPTO_VERSION 11.4) +set(IPPCRYPTO_GIT_LABEL ippcp_2021.6) #ippcp version 11.4 + +if(CMAKE_PREFIX_PATH) if(IPCL_SHARED) set(IPPCP_SHARED ON) else() set(IPPCP_SHARED OFF) endif() - - # ippcp version 11.4 - inline with ippcp_2021.6 - find_package(ippcp 11.4 HINTS ${IPCL_IPPCRYPTO_PATH}/lib/cmake/ippcp) + find_package(ippcp ${IPPCRYPTO_VERSION}) endif() if(ippcp_FOUND) - message(STATUS "IPP-Crypto Found - using pre-installed IPP-Crypto library") + message(STATUS "IPP-Crypto ${IPPCRYPTO_VERSION} found at ${ippcp_DIR}") get_target_property(IPPCRYPTO_INC_DIR IPPCP::ippcp INTERFACE_INCLUDE_DIRECTORIES) get_target_property(IPPCRYPTO_IMPORTED_LOCATION IPPCP::ippcp IMPORTED_LOCATION) get_filename_component(IPPCRYPTO_LIB_DIR ${IPPCRYPTO_IMPORTED_LOCATION} DIRECTORY) - install( DIRECTORY ${IPPCRYPTO_LIB_DIR}/ DESTINATION "${IPCL_INSTALL_LIBDIR}/ippcrypto" @@ -28,13 +28,12 @@ if(ippcp_FOUND) ) else() - message(STATUS "IPP-Crypto NOT Found - building from source") + message(STATUS "IPP-Crypto NOT found - building from source") set(IPPCRYPTO_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/ext_ipp-crypto) set(IPPCRYPTO_DESTDIR ${IPPCRYPTO_PREFIX}/ippcrypto_install) set(IPPCRYPTO_DEST_INCLUDE_DIR include/ippcrypto) set(IPPCRYPTO_GIT_REPO_URL https://github.com/intel/ipp-crypto.git) - set(IPPCRYPTO_GIT_LABEL ippcp_2021.6) #ippcp version 11.4 set(IPPCRYPTO_SRC_DIR ${IPPCRYPTO_PREFIX}/src/ext_ipp-crypto/) set(IPPCRYPTO_CXX_FLAGS "${IPCL_FORWARD_CMAKE_ARGS} -DNONPIC_LIB:BOOL=off -DMERGED_BLD:BOOL=on") From 0573d4bd5e77a2c6ec102117c0ada75b09c13743 Mon Sep 17 00:00:00 2001 From: sejunkim Date: Mon, 21 Nov 2022 19:54:35 -0800 Subject: [PATCH 362/364] Remove debug message --- CMakeLists.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 71201cb..15090aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,9 +43,7 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "/opt/intel/ipcl") endif() -if(CMAKE_PREFIX_PATH) - message(STATUS "---- CMAKE_PREFIX_PATH is defined as ${CMAKE_PREFIX_PATH}") -else() +if(NOT CMAKE_PREFIX_PATH) set(CMAKE_PREFIX_PATH $ENV{HOME}/intel /opt/intel) endif() @@ -154,6 +152,7 @@ message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}") message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}") message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") +message(STATUS "CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}") message(STATUS "IPCL_TEST: ${IPCL_TEST}") message(STATUS "IPCL_BENCHMARK: ${IPCL_BENCHMARK}") message(STATUS "IPCL_ENABLE_OMP: ${IPCL_ENABLE_OMP}") From c15487cba2986a994b25dec5c8c70dfaaf9fe89d Mon Sep 17 00:00:00 2001 From: Sejun Kim Date: Mon, 28 Nov 2022 15:37:56 +0900 Subject: [PATCH 363/364] Hotfix: Add gcc version check for "-Wno-deprecated-copy" flag (gnu>=9.1.0) (#42) Fix issue #40 --- CMakeLists.txt | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 15090aa..b9b9030 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,13 +47,6 @@ if(NOT CMAKE_PREFIX_PATH) set(CMAKE_PREFIX_PATH $ENV{HOME}/intel /opt/intel) endif() - -set(CMAKE_C_FLAGS "-O2 -Wno-error=deprecated-declarations -Wno-error=deprecated-copy") -set(CMAKE_CXX_FLAGS "-O2 -fpermissive -Wno-error=deprecated-declarations -Wno-error=deprecated-copy") -set(CMAKE_INSTALL_RPATH "$ORIGIN;$ORIGIN/${CMAKE_INSTALL_LIBDIR};$ORIGIN/ippcrypto") - -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) - # Compiler version check - icx/icpx-2021.3.0 is supported if(CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM") if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 2021.3.0) @@ -64,6 +57,20 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM") endif() endif() +set(CMAKE_C_FLAGS "-O2 -Wno-error=deprecated-declarations") +set(CMAKE_CXX_FLAGS "-O2 -fpermissive -Wno-error=deprecated-declarations") + +# Add -Wno-error=deprecated-copy if GNU>=9.1 +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 9.1.0) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=deprecated-copy") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=deprecated-copy") + endif() +endif() + +set(CMAKE_INSTALL_RPATH "$ORIGIN;$ORIGIN/${CMAKE_INSTALL_LIBDIR};$ORIGIN/ippcrypto") +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_LIBDIR}) + #--------------------------------------------------- option(IPCL_TEST "Enable testing" ON) option(IPCL_BENCHMARK "Enable benchmark" ON) From c5bf45bf9f0b521261799ec65173e61369ee6653 Mon Sep 17 00:00:00 2001 From: Pengfei Zhao Date: Wed, 30 Nov 2022 09:40:11 +0800 Subject: [PATCH 364/364] Refactor pub priv key with smark pointers (#38) * Major updates - pubkey, privkey: Refactor pubkey & privkey with shared_ptr and remove pubkey from privkey - Ciphertext: Support shared_ptr public key - keypair: refactor KeyPair structure - Add serialization support for BigNumber and PublicKey (PrivateKey and CipherText WIP) - Add GNU version check for "deprecated-copy" flag - address #40 * Minor Updates - unittest, benchmark, examples: Updated with smart ptr version pk, sk and keypair - Updated example/README markdown to reflect changes to ipcl::KeyPair and its members. - Minor typo fixes Signed-off-by: Zhao Pengfei Co-authored-by: skmono --- benchmark/bench_cryptography.cpp | 30 +++--- benchmark/bench_hybrid.cpp | 58 ++++------ benchmark/bench_ops.cpp | 41 +++----- example/README.md | 80 +++++++------- example/example_add_mul.cpp | 14 ++- example/example_encrypt_decrypt.cpp | 8 +- example/example_hybridmode.cpp | 16 ++- ipcl/ciphertext.cpp | 50 ++++----- ipcl/include/ipcl/bignum.h | 2 +- ipcl/include/ipcl/ciphertext.hpp | 13 +-- ipcl/include/ipcl/ipcl.hpp | 12 +-- ipcl/include/ipcl/keygen.hpp | 37 ------- ipcl/include/ipcl/pri_key.hpp | 57 +++++----- ipcl/include/ipcl/pub_key.hpp | 38 ++++--- ipcl/include/ipcl/utils/serialize.hpp | 19 ++-- ipcl/keygen.cpp | 8 +- ipcl/pri_key.cpp | 88 ++++++++++------ ipcl/pub_key.cpp | 45 ++++---- test/test_cryptography.cpp | 26 ++--- test/test_ops.cpp | 146 ++++++++++---------------- 20 files changed, 364 insertions(+), 424 deletions(-) delete mode 100644 ipcl/include/ipcl/keygen.hpp diff --git a/benchmark/bench_cryptography.cpp b/benchmark/bench_cryptography.cpp index a2febf0..33b0d12 100644 --- a/benchmark/bench_cryptography.cpp +++ b/benchmark/bench_cryptography.cpp @@ -65,7 +65,7 @@ const BigNumber HS_BN = static void BM_KeyGen(benchmark::State& state) { int64_t n_length = state.range(0); for (auto _ : state) { - ipcl::keyPair key = ipcl::generateKeypair(n_length, Enable_DJN); + ipcl::KeyPair key = ipcl::generateKeypair(n_length, Enable_DJN); } } BENCHMARK(BM_KeyGen)->Unit(benchmark::kMicrosecond)->ADD_SAMPLE_KEY_LENGTH_ARGS; @@ -75,12 +75,12 @@ static void BM_Encrypt(benchmark::State& state) { BigNumber n = P_BN * Q_BN; int n_length = n.BitSize(); - ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); - ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + ipcl::PublicKey pk(n, n_length, Enable_DJN); + ipcl::PrivateKey sk(pk, P_BN, Q_BN); std::vector r_bn_v(dsize, R_BN); - pub_key->setRandom(r_bn_v); - pub_key->setHS(HS_BN); + pk.setRandom(r_bn_v); + pk.setHS(HS_BN); std::vector exp_bn_v(dsize); for (size_t i = 0; i < dsize; i++) @@ -89,10 +89,7 @@ static void BM_Encrypt(benchmark::State& state) { ipcl::PlainText pt(exp_bn_v); ipcl::CipherText ct; - for (auto _ : state) ct = pub_key->encrypt(pt); - - delete pub_key; - delete priv_key; + for (auto _ : state) ct = pk.encrypt(pt); } BENCHMARK(BM_Encrypt) ->Unit(benchmark::kMicrosecond) @@ -103,23 +100,20 @@ static void BM_Decrypt(benchmark::State& state) { BigNumber n = P_BN * Q_BN; int n_length = n.BitSize(); - ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); - ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + ipcl::PublicKey pk(n, n_length, Enable_DJN); + ipcl::PrivateKey sk(pk, P_BN, Q_BN); std::vector r_bn_v(dsize, R_BN); - pub_key->setRandom(r_bn_v); - pub_key->setHS(HS_BN); + pk.setRandom(r_bn_v); + pk.setHS(HS_BN); std::vector exp_bn_v(dsize); for (size_t i = 0; i < dsize; i++) exp_bn_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); ipcl::PlainText pt(exp_bn_v), dt; - ipcl::CipherText ct = pub_key->encrypt(pt); - for (auto _ : state) dt = priv_key->decrypt(ct); - - delete pub_key; - delete priv_key; + ipcl::CipherText ct = pk.encrypt(pt); + for (auto _ : state) dt = sk.decrypt(ct); } BENCHMARK(BM_Decrypt) diff --git a/benchmark/bench_hybrid.cpp b/benchmark/bench_hybrid.cpp index d911301..ecab201 100644 --- a/benchmark/bench_hybrid.cpp +++ b/benchmark/bench_hybrid.cpp @@ -7,7 +7,7 @@ #include "ipcl/ipcl.hpp" -#define BENCH_HYBRID_DETAIL 1 +#define BENCH_HYBRID_DETAIL 0 #define INPUT_BN_NUM_MAX 256 #define INPUT_BN_NUM_MIN 16 @@ -85,12 +85,12 @@ static void BM_Hybrid_ModExp(benchmark::State& state) { BigNumber n = P_BN * Q_BN; int n_length = n.BitSize(); - ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); - ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + ipcl::PublicKey pk(n, n_length, Enable_DJN); + ipcl::PrivateKey sk(pk, P_BN, Q_BN); std::vector r_bn_v(dsize, R_BN); - pub_key->setRandom(r_bn_v); - pub_key->setHS(HS_BN); + pk.setRandom(r_bn_v); + pk.setHS(HS_BN); std::vector exp_bn_v(dsize); for (size_t i = 0; i < dsize; i++) @@ -98,11 +98,11 @@ static void BM_Hybrid_ModExp(benchmark::State& state) { ipcl::PlainText pt(exp_bn_v); - BigNumber lambda = priv_key->getLambda(); + BigNumber lambda = sk.getLambda(); std::vector pow(dsize, lambda); std::vector m(dsize, n * n); - ipcl::CipherText ct = pub_key->encrypt(pt); + ipcl::CipherText ct = pk.encrypt(pt); std::vector res(dsize); #if BENCH_HYBRID_DETAIL @@ -112,9 +112,6 @@ static void BM_Hybrid_ModExp(benchmark::State& state) { #endif for (auto _ : state) res = ipcl::modExp(ct.getTexts(), pow, m); // decryptRAW - - delete pub_key; - delete priv_key; } BENCHMARK(BM_Hybrid_ModExp)->Unit(benchmark::kMicrosecond)->Apply(customArgs); @@ -128,12 +125,12 @@ static void BM_Hybrid_Encrypt(benchmark::State& state) { BigNumber n = P_BN * Q_BN; int n_length = n.BitSize(); - ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); - ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + ipcl::PublicKey pk(n, n_length, Enable_DJN); + ipcl::PrivateKey sk(pk, P_BN, Q_BN); std::vector r_bn_v(dsize, R_BN); - pub_key->setRandom(r_bn_v); - pub_key->setHS(HS_BN); + pk.setRandom(r_bn_v); + pk.setHS(HS_BN); std::vector exp_bn_v(dsize); for (size_t i = 0; i < dsize; i++) @@ -147,10 +144,7 @@ static void BM_Hybrid_Encrypt(benchmark::State& state) { ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); #endif - for (auto _ : state) ct = pub_key->encrypt(pt); - - delete pub_key; - delete priv_key; + for (auto _ : state) ct = pk.encrypt(pt); } BENCHMARK(BM_Hybrid_Encrypt)->Unit(benchmark::kMicrosecond)->Apply(customArgs); @@ -164,19 +158,19 @@ static void BM_Hybrid_Decrypt(benchmark::State& state) { BigNumber n = P_BN * Q_BN; int n_length = n.BitSize(); - ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); - ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + ipcl::PublicKey pk(n, n_length, Enable_DJN); + ipcl::PrivateKey sk(pk, P_BN, Q_BN); std::vector r_bn_v(dsize, R_BN); - pub_key->setRandom(r_bn_v); - pub_key->setHS(HS_BN); + pk.setRandom(r_bn_v); + pk.setHS(HS_BN); std::vector exp_bn_v(dsize); for (size_t i = 0; i < dsize; i++) exp_bn_v[i] = P_BN - BigNumber((unsigned int)(i * 1024)); ipcl::PlainText pt(exp_bn_v), dt; - ipcl::CipherText ct = pub_key->encrypt(pt); + ipcl::CipherText ct = pk.encrypt(pt); #if BENCH_HYBRID_DETAIL ipcl::setHybridRatio(qat_ratio); @@ -184,10 +178,7 @@ static void BM_Hybrid_Decrypt(benchmark::State& state) { ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); #endif - for (auto _ : state) dt = priv_key->decrypt(ct); - - delete pub_key; - delete priv_key; + for (auto _ : state) dt = sk.decrypt(ct); } BENCHMARK(BM_Hybrid_Decrypt)->Unit(benchmark::kMicrosecond)->Apply(customArgs); @@ -201,12 +192,12 @@ static void BM_Hybrid_MulCTPT(benchmark::State& state) { BigNumber n = P_BN * Q_BN; int n_length = n.BitSize(); - ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); - ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + ipcl::PublicKey pk(n, n_length, Enable_DJN); + ipcl::PrivateKey sk(pk, P_BN, Q_BN); std::vector r_bn_v(dsize, R_BN); - pub_key->setRandom(r_bn_v); - pub_key->setHS(HS_BN); + pk.setRandom(r_bn_v); + pk.setHS(HS_BN); std::vector exp_bn1_v(dsize), exp_bn2_v(dsize); for (int i = 0; i < dsize; i++) { @@ -217,7 +208,7 @@ static void BM_Hybrid_MulCTPT(benchmark::State& state) { ipcl::PlainText pt1(exp_bn1_v); ipcl::PlainText pt2(exp_bn2_v); - ipcl::CipherText ct1 = pub_key->encrypt(pt1); + ipcl::CipherText ct1 = pk.encrypt(pt1); ipcl::CipherText product; #if BENCH_HYBRID_DETAIL @@ -227,8 +218,5 @@ static void BM_Hybrid_MulCTPT(benchmark::State& state) { #endif for (auto _ : state) product = ct1 * pt2; - - delete pub_key; - delete priv_key; } BENCHMARK(BM_Hybrid_MulCTPT)->Unit(benchmark::kMicrosecond)->Apply(customArgs); diff --git a/benchmark/bench_ops.cpp b/benchmark/bench_ops.cpp index cb0acfd..de97b06 100644 --- a/benchmark/bench_ops.cpp +++ b/benchmark/bench_ops.cpp @@ -67,12 +67,12 @@ static void BM_Add_CTCT(benchmark::State& state) { BigNumber n = P_BN * Q_BN; int n_length = n.BitSize(); - ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); - ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + ipcl::PublicKey pk(n, n_length, Enable_DJN); + ipcl::PrivateKey sk(pk, P_BN, Q_BN); std::vector r_bn_v(dsize, R_BN); - pub_key->setRandom(r_bn_v); - pub_key->setHS(HS_BN); + pk.setRandom(r_bn_v); + pk.setHS(HS_BN); std::vector exp_bn1_v(dsize), exp_bn2_v(dsize); for (int i = 0; i < dsize; i++) { @@ -83,14 +83,11 @@ static void BM_Add_CTCT(benchmark::State& state) { ipcl::PlainText pt1(exp_bn1_v); ipcl::PlainText pt2(exp_bn2_v); - ipcl::CipherText ct1 = pub_key->encrypt(pt1); - ipcl::CipherText ct2 = pub_key->encrypt(pt2); + ipcl::CipherText ct1 = pk.encrypt(pt1); + ipcl::CipherText ct2 = pk.encrypt(pt2); ipcl::CipherText sum; for (auto _ : state) sum = ct1 + ct2; - - delete pub_key; - delete priv_key; } BENCHMARK(BM_Add_CTCT) ->Unit(benchmark::kMicrosecond) @@ -101,12 +98,12 @@ static void BM_Add_CTPT(benchmark::State& state) { BigNumber n = P_BN * Q_BN; int n_length = n.BitSize(); - ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); - ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + ipcl::PublicKey pk(n, n_length, Enable_DJN); + ipcl::PrivateKey sk(pk, P_BN, Q_BN); std::vector r_bn_v(dsize, R_BN); - pub_key->setRandom(r_bn_v); - pub_key->setHS(HS_BN); + pk.setRandom(r_bn_v); + pk.setHS(HS_BN); std::vector exp_bn1_v(dsize), exp_bn2_v(dsize); for (int i = 0; i < dsize; i++) { @@ -117,13 +114,10 @@ static void BM_Add_CTPT(benchmark::State& state) { ipcl::PlainText pt1(exp_bn1_v); ipcl::PlainText pt2(exp_bn2_v); - ipcl::CipherText ct1 = pub_key->encrypt(pt1); + ipcl::CipherText ct1 = pk.encrypt(pt1); ipcl::CipherText sum; for (auto _ : state) sum = ct1 + pt2; - - delete pub_key; - delete priv_key; } BENCHMARK(BM_Add_CTPT) ->Unit(benchmark::kMicrosecond) @@ -133,12 +127,12 @@ static void BM_Mul_CTPT(benchmark::State& state) { size_t dsize = state.range(0); BigNumber n = P_BN * Q_BN; int n_length = n.BitSize(); - ipcl::PublicKey* pub_key = new ipcl::PublicKey(n, n_length, Enable_DJN); - ipcl::PrivateKey* priv_key = new ipcl::PrivateKey(pub_key, P_BN, Q_BN); + ipcl::PublicKey pk(n, n_length, Enable_DJN); + ipcl::PrivateKey sk(pk, P_BN, Q_BN); std::vector r_bn_v(dsize, R_BN); - pub_key->setRandom(r_bn_v); - pub_key->setHS(HS_BN); + pk.setRandom(r_bn_v); + pk.setHS(HS_BN); std::vector exp_bn1_v(dsize), exp_bn2_v(dsize); for (int i = 0; i < dsize; i++) { @@ -149,13 +143,10 @@ static void BM_Mul_CTPT(benchmark::State& state) { ipcl::PlainText pt1(exp_bn1_v); ipcl::PlainText pt2(exp_bn2_v); - ipcl::CipherText ct1 = pub_key->encrypt(pt1); + ipcl::CipherText ct1 = pk.encrypt(pt1); ipcl::CipherText product; for (auto _ : state) product = ct1 * pt2; - - delete pub_key; - delete priv_key; } BENCHMARK(BM_Mul_CTPT) ->Unit(benchmark::kMicrosecond) diff --git a/example/README.md b/example/README.md index b117c41..ca69b52 100644 --- a/example/README.md +++ b/example/README.md @@ -53,35 +53,13 @@ If the library is installed globally, `IPCL_DIR` or `IPCL_HINT_DIR` flag is not ## Using Intel Paillier Cryptosystem Library -### Enabling QAT usage -When QAT is enabled while building the library with the flag ```IPCL_ENABLE_QAT=ON```, it is essential to initialize and release the HE QAT context. -```C++ -// Initialize HE QAT context -ipcl::initializeContext("QAT"); - -// perform IPCL operations -auto ct = key.pub_key->encrypt(pt); -auto dec_pt = key.priv_key->decrypt(ct); - -// Release HE QAT context -ipcl::terminateContext(); -``` -If QAT is disabled, ```ipcl::initializeContext("QAT")``` statement will not do anything, thus safe to include in any codes using the library. - -### Hybrid mode configuration -The main accelerated operation - modular exponentiation - can be performed by either IPP-Crypto or the HE QAT. Our library provides a configurable method to distribute the workload between these two methods. +### Key Generation +The public key and private key pair can be generated by using the ```ipcl::generateKeypair``` function. ```C++ -// Use optimal mode -ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); - -// Use IPP-Crypto modexp only -ipcl::setHybridMode(ipcl::HybridMode::IPP); - -// Use QAT modexp only -ipcl::setHybridMode(ipcl::HybridMode::QAT); +// key.pub_key, key.priv_key +ipcl::KeyPair key = ipcl::generateKeypair(2048, true); // previously ipcl::keyPair ``` -By default, the hybrid mode is set to ```ipcl::HybridMode::OPTIMAL```. For more details about the modes, please refer to [```mod_exp.hpp```](../ipcl/include/ipcl/mod_exp.hpp#L16). - +- Note: With version ```v2.0.0``` and beyond, the key pair struct type has been changed from ```ipcl::keyPair``` to ```ipcl::KeyPair``` (uppercase ```K```). ### Data handling The library uses a container - ```ipcl::PlainText``` for encryption inputs and decryption outputs as well as plaintext HE operations. @@ -120,24 +98,15 @@ pt_copy.clear(); // empty the container ``` FOr more details, please refer to the [```base_text.hpp```](../ipcl/include/ipcl/base_text.hpp) and [```plaintext.hpp```](../ipcl/include/ipcl/plaintext.hpp). -### Key Generation -The public key and private key pair can be generated by using the ```ipcl::generateKeypair``` function. -```C++ -// key.pub_key, key.priv_key -ipcl::keyPair key = ipcl::generateKeypair(2048, true); -// After computation, need to delete the key objects -delete key.pub_key; -delete key.priv_key; -``` - ### Encryption and Decryption The public key is used to encrypt ```ipcl::PlainText``` objects for ```ipcl::CipherText``` outputs. In the same way, the private key is used to decrypt ```ipcl::CipherText``` objects for ```ipcl::PlainText``` outputs. ```C++ ipcl::PlainText pt(raw_data); -ipcl::CipherText ct = key.pub_key->encrypt(pt); -ipcl::PlainText dec_pt = key.priv_key->decrypt(ct); +ipcl::CipherText ct = key.pub_key.encrypt(pt); // previously key.pub_key->encrypt(pt) +ipcl::PlainText dec_pt = key.priv_key.decrypt(ct); // previously key.priv_key->decrypt(ct) ``` +- Note: With version ```v2.0.0``` and beyond, the keys in ```ipcl::KeyPair``` have been changed to be objects, hence the changes from ```key.pub_key->encrypt(pt)``` and ``` key.priv_key->decrypt(ct)``` to ```key.pub_key.encrypt(pt)``` and ```key.priv_key.decrypt(ct)```, respectively. ### HE Operations Since the Intel Paillier Cryptosystem Library being a partially homomorphic encryption scheme, while addition is supports both ciphertext operands, multiplication only supports single ciphertext operand. @@ -146,8 +115,8 @@ Since the Intel Paillier Cryptosystem Library being a partially homomorphic encr // setup ipcl::PlainText a, b; -ipcl::CipherText ct_a = key.pub_key->encrypt(a); -ipcl::CipherText ct_b = key.pub_key->encrypt(b); +ipcl::CipherText ct_a = key.pub_key.encrypt(a); +ipcl::CipherText ct_b = key.pub_key.encrypt(b); // Addition (all three end up being same values after decryption) ipcl::CipherText ct_c1 = ct_a + ct_b; // ciphertext + ciphertext @@ -158,3 +127,32 @@ ipcl::CipherText ct_c3 = ct_b + a; // ciphertext + plaintext ipcl::CipherText ct_d1 = ct_a * b; // ciphertext * plaintext ipcl::CipherText ct_d2 = ct_b * a; ``` + +### Enabling QAT usage +When QAT is enabled while building the library with the flag ```IPCL_ENABLE_QAT=ON```, it is essential to initialize and release the HE QAT context. +```C++ +// Initialize HE QAT context +ipcl::initializeContext("QAT"); + +// perform IPCL operations +auto ct = key.pub_key.encrypt(pt); +auto dec_pt = key.priv_key.decrypt(ct); + +// Release HE QAT context +ipcl::terminateContext(); +``` +If QAT is disabled, ```ipcl::initializeContext("QAT")``` statement will not do anything, thus safe to include in any codes using the library. + +### Hybrid mode configuration +The main accelerated operation - modular exponentiation - can be performed by either IPP-Crypto or the HE QAT. Our library provides a configurable method to distribute the workload between these two methods. +```C++ +// Use optimal mode +ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); + +// Use IPP-Crypto modexp only +ipcl::setHybridMode(ipcl::HybridMode::IPP); + +// Use QAT modexp only +ipcl::setHybridMode(ipcl::HybridMode::QAT); +``` +By default, the hybrid mode is set to ```ipcl::HybridMode::OPTIMAL```. For more details about the modes, please refer to [```mod_exp.hpp```](../ipcl/include/ipcl/mod_exp.hpp#L16). diff --git a/example/example_add_mul.cpp b/example/example_add_mul.cpp index d53a61f..b06fd15 100644 --- a/example/example_add_mul.cpp +++ b/example/example_add_mul.cpp @@ -21,7 +21,7 @@ int main() { const uint32_t num_total = 20; - ipcl::keyPair key = ipcl::generateKeypair(2048, true); + ipcl::KeyPair key = ipcl::generateKeypair(2048, true); std::vector x(num_total); std::vector y(num_total); @@ -41,13 +41,13 @@ int main() { ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); - ipcl::CipherText ct_x = key.pub_key->encrypt(pt_x); - ipcl::CipherText ct_y = key.pub_key->encrypt(pt_y); + ipcl::CipherText ct_x = key.pub_key.encrypt(pt_x); + ipcl::CipherText ct_y = key.pub_key.encrypt(pt_y); // Perform enc(x) + enc(y) std::cout << "--- IPCL CipherText + CipherText ---" << std::endl; ipcl::CipherText ct_add_ctx_cty = ct_x + ct_y; - ipcl::PlainText dt_add_ctx_cty = key.priv_key->decrypt(ct_add_ctx_cty); + ipcl::PlainText dt_add_ctx_cty = key.priv_key.decrypt(ct_add_ctx_cty); // verify result bool verify = true; @@ -65,7 +65,7 @@ int main() { // Perform enc(x) + y std::cout << "--- IPCL CipherText + PlainText ---" << std::endl; ipcl::CipherText ct_add_ctx_pty = ct_x + pt_y; - ipcl::PlainText dt_add_ctx_pty = key.priv_key->decrypt(ct_add_ctx_pty); + ipcl::PlainText dt_add_ctx_pty = key.priv_key.decrypt(ct_add_ctx_pty); // verify result verify = true; @@ -83,7 +83,7 @@ int main() { // Perform enc(x) * y std::cout << "--- IPCL CipherText * PlainText ---" << std::endl; ipcl::CipherText ct_mul_ctx_pty = ct_x * pt_y; - ipcl::PlainText dt_mul_ctx_pty = key.priv_key->decrypt(ct_mul_ctx_pty); + ipcl::PlainText dt_mul_ctx_pty = key.priv_key.decrypt(ct_mul_ctx_pty); // verify result verify = true; @@ -99,8 +99,6 @@ int main() { ipcl::setHybridOff(); - delete key.pub_key; - delete key.priv_key; ipcl::terminateContext(); std::cout << "Complete!" << std::endl; } diff --git a/example/example_encrypt_decrypt.cpp b/example/example_encrypt_decrypt.cpp index 50f08c9..e959a01 100644 --- a/example/example_encrypt_decrypt.cpp +++ b/example/example_encrypt_decrypt.cpp @@ -21,7 +21,7 @@ int main() { const uint32_t num_total = 20; - ipcl::keyPair key = ipcl::generateKeypair(2048, true); + ipcl::KeyPair key = ipcl::generateKeypair(2048, true); std::vector exp_value(num_total); @@ -37,8 +37,8 @@ int main() { ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); - ipcl::CipherText ct = key.pub_key->encrypt(pt); - ipcl::PlainText dt = key.priv_key->decrypt(ct); + ipcl::CipherText ct = key.pub_key.encrypt(pt); + ipcl::PlainText dt = key.priv_key.decrypt(ct); ipcl::setHybridOff(); @@ -54,8 +54,6 @@ int main() { std::cout << "Test pt == dec(enc(pt)) -- " << (verify ? "pass" : "fail") << std::endl; - delete key.pub_key; - delete key.priv_key; ipcl::terminateContext(); std::cout << "Complete!" << std::endl << std::endl; } diff --git a/example/example_hybridmode.cpp b/example/example_hybridmode.cpp index 66da0e5..4ac1f91 100644 --- a/example/example_hybridmode.cpp +++ b/example/example_hybridmode.cpp @@ -30,7 +30,7 @@ int main() { const uint32_t num_total = 64; - ipcl::keyPair key = ipcl::generateKeypair(2048, true); + ipcl::KeyPair key = ipcl::generateKeypair(2048, true); std::vector exp_value(num_total); @@ -56,12 +56,12 @@ int main() { // Encrypt/Decrypt - IPP-Crypto only mode ipcl::setHybridMode(ipcl::HybridMode::IPP); tStart(t); - ipcl::CipherText ct = key.pub_key->encrypt(pt); + ipcl::CipherText ct = key.pub_key.encrypt(pt); elapsed = tEnd(t); std::cout << " Encrypt - HybridMode::IPP = " << elapsed << "ms" << std::endl; tStart(t); - ipcl::PlainText dt = key.priv_key->decrypt(ct); + ipcl::PlainText dt = key.priv_key.decrypt(ct); elapsed = tEnd(t); std::cout << " Decrypt - HybridMode::IPP = " << elapsed << "ms" << std::endl @@ -70,12 +70,12 @@ int main() { // Encrypt/Decrypt - QAT only mode ipcl::setHybridMode(ipcl::HybridMode::QAT); tStart(t); - ct = key.pub_key->encrypt(pt); + ct = key.pub_key.encrypt(pt); elapsed = tEnd(t); std::cout << " Encrypt - HybridMode::QAT = " << elapsed << "ms" << std::endl; tStart(t); - dt = key.priv_key->decrypt(ct); + dt = key.priv_key.decrypt(ct); elapsed = tEnd(t); std::cout << " Decrypt - HybridMode::QAT = " << elapsed << "ms" << std::endl @@ -84,19 +84,17 @@ int main() { // Encrypt/Decrypt - OPTIMAL mode ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL); tStart(t); - ct = key.pub_key->encrypt(pt); + ct = key.pub_key.encrypt(pt); elapsed = tEnd(t); std::cout << " Encrypt - HybridMode::OPTIMAL = " << elapsed << "ms" << std::endl; tStart(t); - dt = key.priv_key->decrypt(ct); + dt = key.priv_key.decrypt(ct); elapsed = tEnd(t); std::cout << " Decrypt - HybridMode::OPTIMAL = " << elapsed << "ms" << std::endl << std::endl; - delete key.pub_key; - delete key.priv_key; ipcl::terminateContext(); std::cout << "Complete!" << std::endl << std::endl; } diff --git a/ipcl/ciphertext.cpp b/ipcl/ciphertext.cpp index 440e1d1..e0d4b23 100644 --- a/ipcl/ciphertext.cpp +++ b/ipcl/ciphertext.cpp @@ -8,27 +8,25 @@ #include "ipcl/mod_exp.hpp" namespace ipcl { -CipherText::CipherText(const PublicKey* pub_key, const uint32_t& n) - : BaseText(n), m_pubkey(pub_key) {} +CipherText::CipherText(const PublicKey& pk, const uint32_t& n) + : BaseText(n), m_pk(std::make_shared(pk)) {} -CipherText::CipherText(const PublicKey* pub_key, - const std::vector& n_v) - : BaseText(n_v), m_pubkey(pub_key) {} +CipherText::CipherText(const PublicKey& pk, const std::vector& n_v) + : BaseText(n_v), m_pk(std::make_shared(pk)) {} -CipherText::CipherText(const PublicKey* pub_key, const BigNumber& bn) - : BaseText(bn), m_pubkey(pub_key) {} +CipherText::CipherText(const PublicKey& pk, const BigNumber& bn) + : BaseText(bn), m_pk(std::make_shared(pk)) {} -CipherText::CipherText(const PublicKey* pub_key, - const std::vector& bn_v) - : BaseText(bn_v), m_pubkey(pub_key) {} +CipherText::CipherText(const PublicKey& pk, const std::vector& bn_v) + : BaseText(bn_v), m_pk(std::make_shared(pk)) {} CipherText::CipherText(const CipherText& ct) : BaseText(ct) { - this->m_pubkey = ct.m_pubkey; + this->m_pk = ct.m_pk; } CipherText& CipherText::operator=(const CipherText& other) { BaseText::operator=(other); - this->m_pubkey = other.m_pubkey; + this->m_pk = other.m_pk; return *this; } @@ -38,7 +36,7 @@ CipherText CipherText::operator+(const CipherText& other) const { std::size_t b_size = other.getSize(); ERROR_CHECK(this->m_size == b_size || b_size == 1, "CT + CT error: Size mismatch!"); - ERROR_CHECK(m_pubkey->getN() == other.m_pubkey->getN(), + ERROR_CHECK(*(m_pk->getN()) == *(other.m_pk->getN()), "CT + CT error: 2 different public keys detected!"); const auto& a = *this; @@ -46,7 +44,7 @@ CipherText CipherText::operator+(const CipherText& other) const { if (m_size == 1) { BigNumber sum = a.raw_add(a.m_texts.front(), b.getTexts().front()); - return CipherText(m_pubkey, sum); + return CipherText(*m_pk, sum); } else { std::vector sum(m_size); @@ -69,14 +67,14 @@ CipherText CipherText::operator+(const CipherText& other) const { for (std::size_t i = 0; i < m_size; i++) sum[i] = a.raw_add(a.m_texts[i], b.m_texts[i]); } - return CipherText(m_pubkey, sum); + return CipherText(*m_pk, sum); } } // CT + PT CipherText CipherText::operator+(const PlainText& other) const { // convert PT to CT - CipherText b = this->m_pubkey->encrypt(other, false); + CipherText b = this->m_pk->encrypt(other, false); // calculate CT + CT return this->operator+(b); } @@ -92,7 +90,7 @@ CipherText CipherText::operator*(const PlainText& other) const { if (m_size == 1) { BigNumber product = a.raw_mul(a.m_texts.front(), b.getTexts().front()); - return CipherText(m_pubkey, product); + return CipherText(*m_pk, product); } else { std::vector product; if (b_size == 1) { @@ -103,7 +101,7 @@ CipherText CipherText::operator*(const PlainText& other) const { // multiply vector by vector product = a.raw_mul(a.m_texts, b.getTexts()); } - return CipherText(m_pubkey, product); + return CipherText(*m_pk, product); } } @@ -111,10 +109,10 @@ CipherText CipherText::getCipherText(const size_t& idx) const { ERROR_CHECK((idx >= 0) && (idx < m_size), "CipherText::getCipherText index is out of range"); - return CipherText(m_pubkey, m_texts[idx]); + return CipherText(*m_pk, m_texts[idx]); } -const PublicKey* CipherText::getPubKey() const { return m_pubkey; } +std::shared_ptr CipherText::getPubKey() const { return m_pk; } CipherText CipherText::rotate(int shift) const { ERROR_CHECK(m_size != 1, "rotate: Cannot rotate single CipherText"); @@ -122,7 +120,7 @@ CipherText CipherText::rotate(int shift) const { "rotate: Cannot shift more than the test size"); if (shift == 0 || shift == m_size || shift == (-1) * static_cast(m_size)) - return CipherText(m_pubkey, m_texts); + return CipherText(*m_pk, m_texts); if (shift > 0) shift = m_size - shift; @@ -131,24 +129,26 @@ CipherText CipherText::rotate(int shift) const { std::vector new_bn = getTexts(); std::rotate(std::begin(new_bn), std::begin(new_bn) + shift, std::end(new_bn)); - return CipherText(m_pubkey, new_bn); + return CipherText(*m_pk, new_bn); } BigNumber CipherText::raw_add(const BigNumber& a, const BigNumber& b) const { // Hold a copy of nsquare for multi-threaded - const BigNumber& sq = m_pubkey->getNSQ(); + // The BigNumber % operator is not thread safe + // const BigNumber& sq = *(m_pk->getNSQ()); + const BigNumber sq = *(m_pk->getNSQ()); return a * b % sq; } BigNumber CipherText::raw_mul(const BigNumber& a, const BigNumber& b) const { - const BigNumber& sq = m_pubkey->getNSQ(); + const BigNumber& sq = *(m_pk->getNSQ()); return modExp(a, b, sq); } std::vector CipherText::raw_mul( const std::vector& a, const std::vector& b) const { std::size_t v_size = a.size(); - std::vector sq(v_size, m_pubkey->getNSQ()); + std::vector sq(v_size, *(m_pk->getNSQ())); // If hybrid OPTIMAL mode is used, use a special ratio if (isHybridOptimal()) { diff --git a/ipcl/include/ipcl/bignum.h b/ipcl/include/ipcl/bignum.h index 2a069cd..27760a0 100644 --- a/ipcl/include/ipcl/bignum.h +++ b/ipcl/include/ipcl/bignum.h @@ -25,7 +25,7 @@ #include "ipcl/utils/serialize.hpp" #include "ippcp.h" -class BigNumber : public ipcl::serialize::serializerBase { +class BigNumber : public ipcl::serializer::serializerBase { public: BigNumber(Ipp32u value = 0); BigNumber(Ipp32s value); diff --git a/ipcl/include/ipcl/ciphertext.hpp b/ipcl/include/ipcl/ciphertext.hpp index b344ad0..8c116af 100644 --- a/ipcl/include/ipcl/ciphertext.hpp +++ b/ipcl/include/ipcl/ciphertext.hpp @@ -4,6 +4,7 @@ #ifndef IPCL_INCLUDE_IPCL_CIPHERTEXT_HPP_ #define IPCL_INCLUDE_IPCL_CIPHERTEXT_HPP_ +#include #include #include "ipcl/plaintext.hpp" @@ -20,10 +21,10 @@ class CipherText : public BaseText { /** * CipherText constructors */ - CipherText(const PublicKey* pub_key, const uint32_t& n); - CipherText(const PublicKey* pub_key, const std::vector& n_v); - CipherText(const PublicKey* pub_key, const BigNumber& bn); - CipherText(const PublicKey* pub_key, const std::vector& bn_vec); + CipherText(const PublicKey& pk, const uint32_t& n); + CipherText(const PublicKey& pk, const std::vector& n_v); + CipherText(const PublicKey& pk, const BigNumber& bn); + CipherText(const PublicKey& pk, const std::vector& bn_vec); /** * CipherText copy constructor @@ -49,7 +50,7 @@ class CipherText : public BaseText { /** * Get public key */ - const PublicKey* getPubKey() const; + std::shared_ptr getPubKey() const; /** * Rotate CipherText @@ -63,7 +64,7 @@ class CipherText : public BaseText { std::vector raw_mul(const std::vector& a, const std::vector& b) const; - const PublicKey* m_pubkey; ///< Public key used to encrypt big number + std::shared_ptr m_pk; ///< Public key used to encrypt big number }; } // namespace ipcl diff --git a/ipcl/include/ipcl/ipcl.hpp b/ipcl/include/ipcl/ipcl.hpp index e06159e..4aca630 100644 --- a/ipcl/include/ipcl/ipcl.hpp +++ b/ipcl/include/ipcl/ipcl.hpp @@ -13,12 +13,12 @@ namespace ipcl { /** * Paillier key structure contains a public key and private key - * pub_key: paillier public key - * priv_key: paillier private key + * pk: paillier public key + * sk: paillier private key */ -struct keyPair { - PublicKey* pub_key; - PrivateKey* priv_key; +struct KeyPair { + PublicKey pub_key; + PrivateKey priv_key; }; /** @@ -34,7 +34,7 @@ BigNumber getPrimeBN(int maxBitSize); * @param[in] enable_DJN Enable DJN (default=true) * @return The function return the public and private key pair */ -keyPair generateKeypair(int64_t n_length, bool enable_DJN = true); +KeyPair generateKeypair(int64_t n_length, bool enable_DJN = true); } // namespace ipcl #endif // IPCL_INCLUDE_IPCL_IPCL_HPP_ diff --git a/ipcl/include/ipcl/keygen.hpp b/ipcl/include/ipcl/keygen.hpp deleted file mode 100644 index c254db8..0000000 --- a/ipcl/include/ipcl/keygen.hpp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#ifndef IPCL_INCLUDE_IPCL_KEYGEN_HPP_ -#define IPCL_INCLUDE_IPCL_KEYGEN_HPP_ - -#include "ipcl/pri_key.hpp" - -namespace ipcl { - -/** - * Paillier key structure contains a public key and private key - * pub_key: paillier public key - * priv_key: paillier private key - */ -struct keyPair { - PublicKey* pub_key; - PrivateKey* priv_key; -}; - -/** - * Generate prime number - * @param[in] maxBitSize Maximum bit length of to be generated prime number - * @return The function return a prime big number - */ -BigNumber getPrimeBN(int maxBitSize); - -/** - * Generate a public/private key pair - * @param[in] n_length Bit length of key size - * @param[in] enable_DJN Enable DJN (default=true) - * @return The function return the public and private key pair - */ -keyPair generateKeypair(int64_t n_length, bool enable_DJN = true); - -} // namespace ipcl -#endif // IPCL_INCLUDE_IPCL_KEYGEN_HPP_ diff --git a/ipcl/include/ipcl/pri_key.hpp b/ipcl/include/ipcl/pri_key.hpp index d351d03..6e79e0c 100644 --- a/ipcl/include/ipcl/pri_key.hpp +++ b/ipcl/include/ipcl/pri_key.hpp @@ -4,6 +4,8 @@ #ifndef IPCL_INCLUDE_IPCL_PRI_KEY_HPP_ #define IPCL_INCLUDE_IPCL_PRI_KEY_HPP_ +#include +#include #include #include "ipcl/ciphertext.hpp" @@ -13,14 +15,24 @@ namespace ipcl { class PrivateKey { public: + PrivateKey() = default; + ~PrivateKey() = default; + /** * PrivateKey constructor - * @param[in] public_key paillier public key + * @param[in] pk paillier public key * @param[in] p p of private key in paillier scheme * @param[in] q q of private key in paillier scheme */ - PrivateKey(const PublicKey* public_key, const BigNumber& p, - const BigNumber& q); + PrivateKey(const PublicKey& pk, const BigNumber& p, const BigNumber& q); + + /** + * PrivateKey constructor + * @param[in] pk paillier public key + * @param[in] p p of private key in paillier scheme + * @param[in] q q of private key in paillier scheme + */ + PrivateKey(const BigNumber& n, const BigNumber& p, const BigNumber& q); /** * Enable Chinese Remainder Theorem @@ -40,27 +52,17 @@ class PrivateKey { /** * Get N of public key in paillier scheme */ - BigNumber getN() const { return m_n; } + std::shared_ptr getN() const { return m_n; } /** * Get p of private key in paillier scheme */ - BigNumber getP() const { return m_p; } + std::shared_ptr getP() const { return m_p; } /** * Get q of private key in paillier scheme */ - BigNumber getQ() const { return m_q; } - - /** - * Get bits of key - */ - int getBits() const { return m_bits; } - - /** - * Get public key - */ - const PublicKey* getPubKey() const { return m_pubkey; } + std::shared_ptr getQ() const { return m_q; } /** * @brief Support function for ISO/IEC 18033-6 compliance check @@ -69,13 +71,21 @@ class PrivateKey { */ BigNumber getLambda() const { return m_lambda; } + /** + * Check whether priv key is initialized + */ + bool isInitialized() { return m_isInitialized; } + private: - const PublicKey* m_pubkey; - BigNumber m_n; - BigNumber m_nsquare; - BigNumber m_g; - BigNumber m_p; - BigNumber m_q; + bool m_isInitialized = false; + bool m_enable_crt = false; + + std::shared_ptr m_n; + std::shared_ptr m_nsquare; + std::shared_ptr m_g; + std::shared_ptr m_p; + std::shared_ptr m_q; + BigNumber m_pminusone; BigNumber m_qminusone; BigNumber m_psquare; @@ -85,9 +95,6 @@ class PrivateKey { BigNumber m_hq; BigNumber m_lambda; BigNumber m_x; - int m_bits; - int m_dwords; - bool m_enable_crt; /** * Compute L function in paillier scheme diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp index 88d57cf..377a916 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -4,6 +4,8 @@ #ifndef IPCL_INCLUDE_IPCL_PUB_KEY_HPP_ #define IPCL_INCLUDE_IPCL_PUB_KEY_HPP_ +#include +#include #include #include "ipcl/bignum.h" @@ -15,6 +17,9 @@ class CipherText; class PublicKey { public: + PublicKey() = default; + ~PublicKey() = default; + /** * PublicKey constructor * @param[in] n n of public key in paillier scheme @@ -30,6 +35,7 @@ class PublicKey { * @param[in] bits bit length of public key(default value is 1024) * @param[in] enableDJN_ enables DJN scheme(default value is false) */ + explicit PublicKey(const Ipp32u n, int bits = 1024, bool enableDJN_ = false) : PublicKey(BigNumber(n), bits, enableDJN_) {} @@ -56,17 +62,17 @@ class PublicKey { /** * Get N of public key in paillier scheme */ - BigNumber getN() const { return m_n; } + std::shared_ptr getN() const { return m_n; } /** * Get NSQ of public key in paillier scheme */ - BigNumber getNSQ() const { return m_nsquare; } + std::shared_ptr getNSQ() const { return m_nsquare; } /** * Get G of public key in paillier scheme */ - BigNumber getG() const { return m_g; } + std::shared_ptr getG() const { return m_g; } /** * Get bits of key @@ -113,13 +119,21 @@ class PublicKey { return -1; } + /** + * Check whether pub key is initialized + */ + bool isInitialized() { return m_isInitialized; } + + void create(const BigNumber& n, int bits, bool enableDJN_ = false); + void create(const BigNumber& n, int bits, const BigNumber& hs, int randbits); + const void* addr = static_cast(this); private: friend class cereal::access; template void save(Archive& ar, const Ipp32u version) const { - ar(::cereal::make_nvp("n", m_n)); + ar(::cereal::make_nvp("n", *m_n)); ar(::cereal::make_nvp("bits", m_bits)); ar(::cereal::make_nvp("enable_DJN", m_enable_DJN)); ar(::cereal::make_nvp("hs", m_hs)); @@ -132,7 +146,7 @@ class PublicKey { bool enable_DJN; int bits, randbits; - ar(::cereal::make_nvp("n", m_n)); + ar(::cereal::make_nvp("n", *m_n)); ar(::cereal::make_nvp("bits", bits)); ar(::cereal::make_nvp("enable_DJN", enable_DJN)); ar(::cereal::make_nvp("hs", m_hs)); @@ -144,20 +158,18 @@ class PublicKey { create(n, bits); } - BigNumber m_n; - BigNumber m_g; - BigNumber m_nsquare; - BigNumber m_hs; + bool m_isInitialized = false; + std::shared_ptr m_n; + std::shared_ptr m_g; + std::shared_ptr m_nsquare; int m_bits; - int m_randbits; int m_dwords; + BigNumber m_hs; + int m_randbits; bool m_enable_DJN; std::vector m_r; bool m_testv; - void create(const BigNumber& n, int bits, bool enableDJN_ = false); - void create(const BigNumber& n, int bits, const BigNumber& hs, int randbits); - /** * Big number vector multi buffer encryption * @param[in] pt plaintext of BigNumber vector type diff --git a/ipcl/include/ipcl/utils/serialize.hpp b/ipcl/include/ipcl/utils/serialize.hpp index 92a3e2c..59863d7 100644 --- a/ipcl/include/ipcl/utils/serialize.hpp +++ b/ipcl/include/ipcl/utils/serialize.hpp @@ -16,15 +16,20 @@ namespace ipcl { -namespace serialize { +class PublicKey; +class PrivateKey; +class CipherText; + +namespace serializer { + template -void serialize(const T& obj, std::ostream& ss) { +void serialize(std::ostream& ss, const T& obj) { cereal::PortableBinaryOutputArchive archive(ss); archive(obj); } template -void deserialize(T& obj, std::istream& ss) { +void deserialize(std::istream& ss, T& obj) { cereal::PortableBinaryInputArchive archive(ss); archive(obj); } @@ -33,7 +38,7 @@ template bool serializeToFile(const std::string& fn, const T& obj) { std::ofstream ofs(fn, std::ios::out | std::ios::binary); if (ofs.is_open()) { - serialize::serialize(obj, ofs); + serializer::serialize(obj, ofs); ofs.close(); return true; } @@ -41,10 +46,10 @@ bool serializeToFile(const std::string& fn, const T& obj) { } template -bool deserializeFromFile(const std::string& fn, const T& obj) { +bool deserializeFromFile(const std::string& fn, T& obj) { std::ifstream ifs(fn, std::ios::in | std::ios::binary); if (ifs.is_open()) { - serialize::deserialize(obj, ifs); + serializer::deserialize(obj, ifs); ifs.close(); return true; } @@ -57,7 +62,7 @@ class serializerBase { virtual std::string serializedName() const = 0; }; -}; // namespace serialize +}; // namespace serializer } // namespace ipcl diff --git a/ipcl/keygen.cpp b/ipcl/keygen.cpp index 41301d0..fe064bb 100644 --- a/ipcl/keygen.cpp +++ b/ipcl/keygen.cpp @@ -83,7 +83,7 @@ static void getDJNBN(int64_t n_length, BigNumber& p, BigNumber& q, BigNumber& n, isClosePrimeBN(p, q, ref_dist)); // gcd(p-1,q-1)=2 } -keyPair generateKeypair(int64_t n_length, bool enable_DJN) { +KeyPair generateKeypair(int64_t n_length, bool enable_DJN) { /* https://www.intel.com/content/www/us/en/develop/documentation/ipp-crypto-reference/top/multi-buffer-cryptography-functions/modular-exponentiation/mbx-exp-1024-2048-3072-4096-mb8.html modulus size = n * n (keySize * keySize ) @@ -104,10 +104,10 @@ keyPair generateKeypair(int64_t n_length, bool enable_DJN) { else getNormalBN(n_length, p, q, n, ref_dist); - PublicKey* public_key = new PublicKey(n, n_length, enable_DJN); - PrivateKey* private_key = new PrivateKey(public_key, p, q); + PublicKey pk(n, n_length, enable_DJN); + PrivateKey sk(pk, p, q); - return keyPair{public_key, private_key}; + return KeyPair{pk, sk}; } } // namespace ipcl diff --git a/ipcl/pri_key.cpp b/ipcl/pri_key.cpp index 9ab1fd9..923686d 100644 --- a/ipcl/pri_key.cpp +++ b/ipcl/pri_key.cpp @@ -22,37 +22,61 @@ static inline BigNumber lcm(const BigNumber& p, const BigNumber& q) { return p * q / gcd; } -PrivateKey::PrivateKey(const PublicKey* public_key, const BigNumber& p, +PrivateKey::PrivateKey(const PublicKey& pk, const BigNumber& p, const BigNumber& q) - : m_pubkey(public_key), - m_n(m_pubkey->getN()), - m_nsquare(m_pubkey->getNSQ()), - m_g(m_pubkey->getG()), - m_p((q < p) ? q : p), - m_q((q < p) ? p : q), - m_pminusone(m_p - 1), - m_qminusone(m_q - 1), - m_psquare(m_p * m_p), - m_qsquare(m_q * m_q), - m_pinverse(m_q.InverseMul(m_p)), - m_hp(computeHfun(m_p, m_psquare)), - m_hq(computeHfun(m_q, m_qsquare)), - // lcm(P-1,Q-1) = (P-1)*(Q-1)/gcd(P-1,Q-1), gcd in ipp-crypto is - // ippsGcd_BN + : m_n(pk.getN()), + m_nsquare(pk.getNSQ()), + m_g(pk.getG()), + m_enable_crt(true), + m_p((q < p) ? std::make_shared(q) + : std::make_shared(p)), + m_q((q < p) ? std::make_shared(p) + : std::make_shared(q)), + m_pminusone(*m_p - 1), + m_qminusone(*m_q - 1), + m_psquare((*m_p) * (*m_p)), + m_qsquare((*m_q) * (*m_q)), + m_pinverse((*m_q).InverseMul(*m_p)), + m_hp(computeHfun(*m_p, m_psquare)), + m_hq(computeHfun(*m_q, m_qsquare)), m_lambda(lcm(m_pminusone, m_qminusone)), - // TODO(bwang30): check if ippsModInv_BN does the same thing with - // mpz_invert - m_x(m_n.InverseMul((modExp(m_g, m_lambda, m_nsquare) - 1) / m_n)), - m_bits(m_pubkey->getBits()), - m_dwords(m_pubkey->getDwords()), - m_enable_crt(true) { - ERROR_CHECK(p * q == m_n, + m_x((*m_n).InverseMul((modExp(*m_g, m_lambda, *m_nsquare) - 1) / + (*m_n))) { + ERROR_CHECK((*m_p) * (*m_q) == *m_n, "PrivateKey ctor: Public key does not match p * q."); - ERROR_CHECK(p != q, "PrivateKey ctor: p and q are same"); + ERROR_CHECK(*m_p != *m_q, "PrivateKey ctor: p and q are same"); + m_isInitialized = true; +} + +PrivateKey::PrivateKey(const BigNumber& n, const BigNumber& p, + const BigNumber& q) + : m_n(std::make_shared(n)), + m_nsquare(std::make_shared((*m_n) * (*m_n))), + m_g(std::make_shared((*m_n) + 1)), + m_enable_crt(true), + m_p((q < p) ? std::make_shared(q) + : std::make_shared(p)), + m_q((q < p) ? std::make_shared(p) + : std::make_shared(q)), + m_pminusone(*m_p - 1), + m_qminusone(*m_q - 1), + m_psquare((*m_p) * (*m_p)), + m_qsquare((*m_q) * (*m_q)), + m_pinverse((*m_q).InverseMul(*m_p)), + m_hp(computeHfun(*m_p, m_psquare)), + m_hq(computeHfun(*m_q, m_qsquare)), + m_lambda(lcm(m_pminusone, m_qminusone)), + m_x((*m_n).InverseMul((modExp(*m_g, m_lambda, *m_nsquare) - 1) / + (*m_n))) { + ERROR_CHECK((*m_p) * (*m_q) == *m_n, + "PrivateKey ctor: Public key does not match p * q."); + ERROR_CHECK(*m_p != *m_q, "PrivateKey ctor: p and q are same"); + m_isInitialized = true; } PlainText PrivateKey::decrypt(const CipherText& ct) const { - ERROR_CHECK(ct.getPubKey()->getN() == m_pubkey->getN(), + ERROR_CHECK(m_isInitialized, "decrypt: Private key is NOT initialized."); + ERROR_CHECK(*(ct.getPubKey()->getN()) == *(this->getN()), "decrypt: The value of N in public key mismatch."); std::size_t ct_size = ct.getSize(); @@ -82,7 +106,7 @@ void PrivateKey::decryptRAW(std::vector& plaintext, std::size_t v_size = plaintext.size(); std::vector pow_lambda(v_size, m_lambda); - std::vector modulo(v_size, m_nsquare); + std::vector modulo(v_size, *m_nsquare); std::vector res = modExp(ciphertext, pow_lambda, modulo); #ifdef IPCL_USE_OMP @@ -91,7 +115,7 @@ void PrivateKey::decryptRAW(std::vector& plaintext, OMPUtilities::assignOMPThreads(omp_remaining_threads, v_size)) #endif // IPCL_USE_OMP for (int i = 0; i < v_size; i++) { - BigNumber nn = m_n; + BigNumber nn = *m_n; BigNumber xx = m_x; BigNumber m = ((res[i] - 1) / nn) * xx; plaintext[i] = m % nn; @@ -127,16 +151,16 @@ void PrivateKey::decryptCRT(std::vector& plaintext, OMPUtilities::assignOMPThreads(omp_remaining_threads, v_size)) #endif // IPCL_USE_OMP for (int i = 0; i < v_size; i++) { - BigNumber dp = computeLfun(resp[i], m_p) * m_hp % m_p; - BigNumber dq = computeLfun(resq[i], m_q) * m_hq % m_q; + BigNumber dp = computeLfun(resp[i], *m_p) * m_hp % (*m_p); + BigNumber dq = computeLfun(resq[i], *m_q) * m_hq % (*m_q); plaintext[i] = computeCRT(dp, dq); } } BigNumber PrivateKey::computeCRT(const BigNumber& mp, const BigNumber& mq) const { - BigNumber u = (mq - mp) * m_pinverse % m_q; - return mp + (u * m_p); + BigNumber u = (mq - mp) * m_pinverse % (*m_q); + return mp + (u * (*m_p)); } BigNumber PrivateKey::computeLfun(const BigNumber& a, @@ -148,7 +172,7 @@ BigNumber PrivateKey::computeHfun(const BigNumber& a, const BigNumber& b) const { // Based on the fact a^b mod n = (a mod n)^b mod n BigNumber xm = a - 1; - BigNumber base = m_g % b; + BigNumber base = *m_g % b; BigNumber pm = modExp(base, xm, b); BigNumber lcrt = computeLfun(pm, a); return a.InverseMul(lcrt); diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index 5dc9311..d5b2c88 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -16,32 +16,33 @@ namespace ipcl { PublicKey::PublicKey(const BigNumber& n, int bits, bool enableDJN_) - : m_n(n), - m_g(n + 1), - m_nsquare(n * n), + : m_n(std::make_shared(n)), + m_g(std::make_shared(*m_n + 1)), + m_nsquare(std::make_shared((*m_n) * (*m_n))), m_bits(bits), - m_dwords(BITSIZE_DWORD(bits * 2)), + m_dwords(BITSIZE_DWORD(m_bits * 2)), m_enable_DJN(false), m_testv(false), m_hs(0), m_randbits(0) { if (enableDJN_) this->enableDJN(); // sets m_enable_DJN + m_isInitialized = true; } void PublicKey::enableDJN() { BigNumber gcd; BigNumber rmod; do { - int rand_bit = m_n.BitSize(); + int rand_bit = (*m_n).BitSize(); BigNumber rand = getRandomBN(rand_bit + 128); - rmod = rand % m_n; - gcd = rand.gcd(m_n); + rmod = rand % (*m_n); + gcd = rand.gcd(*m_n); } while (gcd.compare(1)); BigNumber rmod_sq = rmod * rmod; BigNumber rmod_neg = rmod_sq * -1; - BigNumber h = rmod_neg % m_n; - m_hs = modExp(h, m_n, m_nsquare); + BigNumber h = rmod_neg % (*m_n); + m_hs = modExp(h, *m_n, *m_nsquare); m_randbits = m_bits >> 1; // bits/2 m_enable_DJN = true; @@ -50,7 +51,7 @@ void PublicKey::enableDJN() { std::vector PublicKey::getDJNObfuscator(std::size_t sz) const { std::vector r(sz); std::vector base(sz, m_hs); - std::vector sq(sz, m_nsquare); + std::vector sq(sz, *m_nsquare); if (m_testv) { r = m_r; @@ -64,15 +65,15 @@ std::vector PublicKey::getDJNObfuscator(std::size_t sz) const { std::vector PublicKey::getNormalObfuscator(std::size_t sz) const { std::vector r(sz); - std::vector sq(sz, m_nsquare); - std::vector pown(sz, m_n); + std::vector sq(sz, *m_nsquare); + std::vector pown(sz, *m_n); if (m_testv) { r = m_r; } else { for (int i = 0; i < sz; i++) { r[i] = getRandomBN(m_bits); - r[i] = r[i] % (m_n - 1) + 1; + r[i] = r[i] % (*m_n - 1) + 1; } } return modExp(r, pown, sq); @@ -82,7 +83,7 @@ void PublicKey::applyObfuscator(std::vector& ciphertext) const { std::size_t sz = ciphertext.size(); std::vector obfuscator = m_enable_DJN ? getDJNObfuscator(sz) : getNormalObfuscator(sz); - BigNumber sq = m_nsquare; + BigNumber sq = *m_nsquare; for (std::size_t i = 0; i < sz; ++i) ciphertext[i] = sq.ModMul(ciphertext[i], obfuscator[i]); @@ -102,7 +103,7 @@ std::vector PublicKey::raw_encrypt(const std::vector& pt, std::vector ct(pt_size); for (std::size_t i = 0; i < pt_size; i++) - ct[i] = (m_n * pt[i] + 1) % m_nsquare; + ct[i] = (*m_n * pt[i] + 1) % (*m_nsquare); if (make_secure) applyObfuscator(ct); @@ -110,6 +111,8 @@ std::vector PublicKey::raw_encrypt(const std::vector& pt, } CipherText PublicKey::encrypt(const PlainText& pt, bool make_secure) const { + ERROR_CHECK(m_isInitialized, "encrypt: Public key is NOT initialized."); + std::size_t pt_size = pt.getSize(); ERROR_CHECK(pt_size > 0, "encrypt: Cannot encrypt empty PlainText"); std::vector ct_bn_v(pt_size); @@ -123,7 +126,7 @@ CipherText PublicKey::encrypt(const PlainText& pt, bool make_secure) const { } ct_bn_v = raw_encrypt(pt.getTexts(), make_secure); - return CipherText(this, ct_bn_v); + return CipherText(*this, ct_bn_v); } void PublicKey::setDJN(const BigNumber& hs, int randbit) { @@ -135,11 +138,11 @@ void PublicKey::setDJN(const BigNumber& hs, int randbit) { } void PublicKey::create(const BigNumber& n, int bits, bool enableDJN_) { - m_n = n; - m_g = n + 1; - m_nsquare = n * n; + m_n = std::make_shared(n); + m_g = std::make_shared(*m_n + 1); + m_nsquare = std::make_shared((*m_n) * (*m_n)); m_bits = bits; - m_dwords = BITSIZE_DWORD(bits * 2); + m_dwords = BITSIZE_DWORD(m_bits * 2); m_enable_DJN = enableDJN_; if (enableDJN_) { this->enableDJN(); @@ -148,12 +151,14 @@ void PublicKey::create(const BigNumber& n, int bits, bool enableDJN_) { m_randbits = 0; } m_testv = false; + m_isInitialized = true; std::cout << "create complete" << std::endl; } void PublicKey::create(const BigNumber& n, int bits, const BigNumber& hs, int randbits) { create(n, bits, false); // set DJN to false and manually set + m_enable_DJN = true; m_hs = hs; m_randbits = randbits; } diff --git a/test/test_cryptography.cpp b/test/test_cryptography.cpp index 24d4fb9..db233e1 100644 --- a/test/test_cryptography.cpp +++ b/test/test_cryptography.cpp @@ -15,7 +15,7 @@ TEST(CryptoTest, CryptoTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; - ipcl::keyPair key = ipcl::generateKeypair(2048, true); + ipcl::KeyPair key = ipcl::generateKeypair(2048, true); std::vector exp_value(num_values); ipcl::PlainText pt; @@ -34,16 +34,13 @@ TEST(CryptoTest, CryptoTest) { ipcl::setHybridRatio(qat_ratio); - ct = key.pub_key->encrypt(pt); - dt = key.priv_key->decrypt(ct); + ct = key.pub_key.encrypt(pt); + dt = key.priv_key.decrypt(ct); for (int i = 0; i < num_values; i++) { std::vector v = dt.getElementVec(i); EXPECT_EQ(v[0], exp_value[i]); } - - delete key.pub_key; - delete key.priv_key; } TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { @@ -65,10 +62,10 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { BigNumber n = p * q; int n_length = n.BitSize(); - ipcl::PublicKey* public_key = new ipcl::PublicKey(n, n_length); - ipcl::PrivateKey* private_key = new ipcl::PrivateKey(public_key, p, q); + ipcl::PublicKey pk(n, n_length); + ipcl::PrivateKey sk(pk, p, q); - ipcl::keyPair key = {public_key, private_key}; + ipcl::KeyPair key = {pk, sk}; std::vector pt_bn_v(num_values); std::vector ir_bn_v(num_values); @@ -157,13 +154,13 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { ipcl::setHybridOff(); - key.pub_key->setRandom(ir_bn_v); + key.pub_key.setRandom(ir_bn_v); pt = ipcl::PlainText(pt_bn_v); - ct = key.pub_key->encrypt(pt); + ct = key.pub_key.encrypt(pt); ipcl::PlainText dt; - dt = key.priv_key->decrypt(ct); + dt = key.priv_key.decrypt(ct); for (int i = 0; i < num_values; i++) { EXPECT_EQ(dt.getElement(i), pt_bn_v[i]); } @@ -185,10 +182,7 @@ TEST(CryptoTest, ISO_IEC_18033_6_ComplianceTest) { std::string str4; ipcl::PlainText dt_sum; - dt_sum = key.priv_key->decrypt(sum); + dt_sum = key.priv_key.decrypt(sum); m1m2.num2hex(str4); EXPECT_EQ(str4, dt_sum.getElementHex(0)); - - delete key.pub_key; - delete key.priv_key; } diff --git a/test/test_ops.cpp b/test/test_ops.cpp index 7a33a1e..2484c59 100644 --- a/test/test_ops.cpp +++ b/test/test_ops.cpp @@ -12,7 +12,7 @@ constexpr int SELF_DEF_NUM_VALUES = 14; constexpr float SELF_DEF_HYBRID_QAT_RATIO = 0.5; void CtPlusCt(ipcl::CipherText& res, const ipcl::CipherText& ct1, - const ipcl::CipherText& ct2, const ipcl::keyPair key) { + const ipcl::CipherText& ct2, const ipcl::KeyPair key) { int size = ct1.getSize(); std::vector sum_bn_v(size); @@ -26,12 +26,12 @@ void CtPlusCt(ipcl::CipherText& res, const ipcl::CipherText& ct1, } void CtPlusCtArray(ipcl::CipherText& res, const ipcl::CipherText& ct1, - const ipcl::CipherText& ct2, const ipcl::keyPair key) { + const ipcl::CipherText& ct2) { res = ct1 + ct2; } void CtPlusPt(ipcl::CipherText& res, const ipcl::CipherText& ct1, - const ipcl::PlainText& pt2, const ipcl::keyPair key) { + const ipcl::PlainText& pt2, const ipcl::KeyPair key) { int size = ct1.getSize(); std::vector sum_bn_v(size); @@ -45,12 +45,12 @@ void CtPlusPt(ipcl::CipherText& res, const ipcl::CipherText& ct1, } void CtPlusPtArray(ipcl::CipherText& res, const ipcl::CipherText& ct1, - const ipcl::PlainText& pt2, const ipcl::keyPair key) { + const ipcl::PlainText& pt2) { res = ct1 + pt2; } void CtMultiplyPt(ipcl::CipherText& res, const ipcl::CipherText& ct1, - const ipcl::PlainText& pt2, const ipcl::keyPair key) { + const ipcl::PlainText& pt2, const ipcl::KeyPair key) { int size = ct1.getSize(); std::vector product_bn_v(size); @@ -64,12 +64,12 @@ void CtMultiplyPt(ipcl::CipherText& res, const ipcl::CipherText& ct1, } void CtMultiplyPtArray(ipcl::CipherText& res, const ipcl::CipherText& ct1, - const ipcl::PlainText& pt2, const ipcl::keyPair key) { + const ipcl::PlainText& pt2) { res = ct1 * pt2; } void AddSub(ipcl::CipherText& res, const ipcl::CipherText& ct1, - const ipcl::CipherText& ct2, const ipcl::keyPair key) { + const ipcl::CipherText& ct2, const ipcl::KeyPair key) { int size = ct1.getSize(); std::vector sum_bn_v(size); @@ -86,7 +86,7 @@ void AddSub(ipcl::CipherText& res, const ipcl::CipherText& ct1, } void PtPlusCt(ipcl::CipherText& res, const ipcl::PlainText& pt2, - const ipcl::CipherText& ct1, const ipcl::keyPair key) { + const ipcl::CipherText& ct1, const ipcl::KeyPair key) { int size = ct1.getSize(); std::vector sum_bn_v(size); @@ -100,12 +100,12 @@ void PtPlusCt(ipcl::CipherText& res, const ipcl::PlainText& pt2, } void PtPlusCtArray(ipcl::CipherText& res, const ipcl::PlainText& pt2, - const ipcl::CipherText& ct1, const ipcl::keyPair key) { + const ipcl::CipherText& ct1) { res = pt2 + ct1; } void PtMultiplyCt(ipcl::CipherText& res, const ipcl::PlainText& pt2, - const ipcl::CipherText& ct1, const ipcl::keyPair key) { + const ipcl::CipherText& ct1, const ipcl::KeyPair key) { int size = ct1.getSize(); std::vector product_bn_v(size); @@ -119,7 +119,7 @@ void PtMultiplyCt(ipcl::CipherText& res, const ipcl::PlainText& pt2, } void PtMultiplyCtArray(ipcl::CipherText& res, const ipcl::PlainText& pt2, - const ipcl::CipherText& ct1, const ipcl::keyPair key) { + const ipcl::CipherText& ct1) { res = pt2 * ct1; } @@ -127,7 +127,7 @@ TEST(OperationTest, CtPlusCtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; - ipcl::keyPair key = ipcl::generateKeypair(2048); + ipcl::KeyPair key = ipcl::generateKeypair(2048); std::vector exp_value1(num_values), exp_value2(num_values); ipcl::PlainText pt1, pt2, dt_sum; @@ -146,12 +146,12 @@ TEST(OperationTest, CtPlusCtTest) { ipcl::setHybridRatio(qat_ratio); - ct1 = key.pub_key->encrypt(pt1); - ct2 = key.pub_key->encrypt(pt2); + ct1 = key.pub_key.encrypt(pt1); + ct2 = key.pub_key.encrypt(pt2); CtPlusCt(ct_sum, ct1, ct2, key); - dt_sum = key.priv_key->decrypt(ct_sum); + dt_sum = key.priv_key.decrypt(ct_sum); for (int i = 0; i < num_values; i++) { std::vector v = dt_sum.getElementVec(i); @@ -162,16 +162,13 @@ TEST(OperationTest, CtPlusCtTest) { EXPECT_EQ(sum, exp_sum); } - - delete key.pub_key; - delete key.priv_key; } TEST(OperationTest, CtPlusCtArrayTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; - ipcl::keyPair key = ipcl::generateKeypair(2048); + ipcl::KeyPair key = ipcl::generateKeypair(2048); std::vector exp_value1(num_values), exp_value2(num_values); ipcl::PlainText pt1, pt2, dt_sum; @@ -190,12 +187,12 @@ TEST(OperationTest, CtPlusCtArrayTest) { ipcl::setHybridRatio(qat_ratio); - ct1 = key.pub_key->encrypt(pt1); - ct2 = key.pub_key->encrypt(pt2); + ct1 = key.pub_key.encrypt(pt1); + ct2 = key.pub_key.encrypt(pt2); - CtPlusCtArray(ct_sum, ct1, ct2, key); + CtPlusCtArray(ct_sum, ct1, ct2); - dt_sum = key.priv_key->decrypt(ct_sum); + dt_sum = key.priv_key.decrypt(ct_sum); for (int i = 0; i < num_values; i++) { std::vector v = dt_sum.getElementVec(i); @@ -206,16 +203,13 @@ TEST(OperationTest, CtPlusCtArrayTest) { EXPECT_EQ(sum, exp_sum); } - - delete key.pub_key; - delete key.priv_key; } TEST(OperationTest, CtPlusPtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; - ipcl::keyPair key = ipcl::generateKeypair(2048); + ipcl::KeyPair key = ipcl::generateKeypair(2048); std::vector exp_value1(num_values), exp_value2(num_values); ipcl::PlainText pt1, pt2, dt_sum; @@ -234,11 +228,11 @@ TEST(OperationTest, CtPlusPtTest) { ipcl::setHybridRatio(qat_ratio); - ct1 = key.pub_key->encrypt(pt1); + ct1 = key.pub_key.encrypt(pt1); CtPlusPt(ct_sum, ct1, pt2, key); - dt_sum = key.priv_key->decrypt(ct_sum); + dt_sum = key.priv_key.decrypt(ct_sum); for (int i = 0; i < num_values; i++) { std::vector v = dt_sum.getElementVec(i); @@ -249,16 +243,13 @@ TEST(OperationTest, CtPlusPtTest) { EXPECT_EQ(sum, exp_sum); } - - delete key.pub_key; - delete key.priv_key; } TEST(OperationTest, CtPlusPtArrayTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; - ipcl::keyPair key = ipcl::generateKeypair(2048); + ipcl::KeyPair key = ipcl::generateKeypair(2048); std::vector exp_value1(num_values), exp_value2(num_values); ipcl::PlainText pt1, pt2, dt_sum; @@ -277,11 +268,11 @@ TEST(OperationTest, CtPlusPtArrayTest) { ipcl::setHybridRatio(qat_ratio); - ct1 = key.pub_key->encrypt(pt1); + ct1 = key.pub_key.encrypt(pt1); - CtPlusPtArray(ct_sum, ct1, pt2, key); + CtPlusPtArray(ct_sum, ct1, pt2); - dt_sum = key.priv_key->decrypt(ct_sum); + dt_sum = key.priv_key.decrypt(ct_sum); for (int i = 0; i < num_values; i++) { std::vector v = dt_sum.getElementVec(i); @@ -292,16 +283,13 @@ TEST(OperationTest, CtPlusPtArrayTest) { EXPECT_EQ(sum, exp_sum); } - - delete key.pub_key; - delete key.priv_key; } TEST(OperationTest, CtMultiplyPtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; - ipcl::keyPair key = ipcl::generateKeypair(2048); + ipcl::KeyPair key = ipcl::generateKeypair(2048); std::vector exp_value1(num_values), exp_value2(num_values); ipcl::PlainText pt1, pt2, dt_product; @@ -320,11 +308,11 @@ TEST(OperationTest, CtMultiplyPtTest) { ipcl::setHybridRatio(qat_ratio); - ct1 = key.pub_key->encrypt(pt1); + ct1 = key.pub_key.encrypt(pt1); CtMultiplyPt(ct_product, ct1, pt2, key); - dt_product = key.priv_key->decrypt(ct_product); + dt_product = key.priv_key.decrypt(ct_product); for (int i = 0; i < num_values; i++) { std::vector v = dt_product.getElementVec(i); @@ -335,16 +323,13 @@ TEST(OperationTest, CtMultiplyPtTest) { EXPECT_EQ(product, exp_product); } - - delete key.pub_key; - delete key.priv_key; } TEST(OperationTest, CtMultiplyZeroPtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; - ipcl::keyPair key = ipcl::generateKeypair(2048); + ipcl::KeyPair key = ipcl::generateKeypair(2048); std::vector exp_value1(num_values), exp_value2(num_values); ipcl::PlainText pt1, pt2, dt_product; @@ -364,11 +349,11 @@ TEST(OperationTest, CtMultiplyZeroPtTest) { ipcl::setHybridRatio(qat_ratio); - ct1 = key.pub_key->encrypt(pt1); + ct1 = key.pub_key.encrypt(pt1); CtMultiplyPt(ct_product, ct1, pt2, key); - dt_product = key.priv_key->decrypt(ct_product); + dt_product = key.priv_key.decrypt(ct_product); for (int i = 0; i < num_values; i++) { std::vector v = dt_product.getElementVec(i); @@ -379,16 +364,13 @@ TEST(OperationTest, CtMultiplyZeroPtTest) { EXPECT_EQ(product, exp_product); } - - delete key.pub_key; - delete key.priv_key; } TEST(OperationTest, CtMultiplyPtArrayTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; - ipcl::keyPair key = ipcl::generateKeypair(2048); + ipcl::KeyPair key = ipcl::generateKeypair(2048); std::vector exp_value1(num_values), exp_value2(num_values); ipcl::PlainText pt1, pt2, dt_product; @@ -407,11 +389,11 @@ TEST(OperationTest, CtMultiplyPtArrayTest) { ipcl::setHybridRatio(qat_ratio); - ct1 = key.pub_key->encrypt(pt1); + ct1 = key.pub_key.encrypt(pt1); - CtMultiplyPtArray(ct_product, ct1, pt2, key); + CtMultiplyPtArray(ct_product, ct1, pt2); - dt_product = key.priv_key->decrypt(ct_product); + dt_product = key.priv_key.decrypt(ct_product); for (int i = 0; i < num_values; i++) { std::vector v = dt_product.getElementVec(i); @@ -422,16 +404,13 @@ TEST(OperationTest, CtMultiplyPtArrayTest) { EXPECT_EQ(product, exp_product); } - - delete key.pub_key; - delete key.priv_key; } TEST(OperationTest, AddSubTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; - ipcl::keyPair key = ipcl::generateKeypair(2048); + ipcl::KeyPair key = ipcl::generateKeypair(2048); std::vector exp_value1(num_values), exp_value2(num_values); ipcl::PlainText pt1, pt2, dt_sum; @@ -450,12 +429,12 @@ TEST(OperationTest, AddSubTest) { ipcl::setHybridRatio(qat_ratio); - ct1 = key.pub_key->encrypt(pt1); - ct2 = key.pub_key->encrypt(pt2); + ct1 = key.pub_key.encrypt(pt1); + ct2 = key.pub_key.encrypt(pt2); AddSub(ct_sum, ct1, ct2, key); - dt_sum = key.priv_key->decrypt(ct_sum); + dt_sum = key.priv_key.decrypt(ct_sum); for (int i = 0; i < num_values; i++) { std::vector v = dt_sum.getElementVec(i); @@ -466,16 +445,13 @@ TEST(OperationTest, AddSubTest) { EXPECT_EQ(sum, exp_sum); } - - delete key.pub_key; - delete key.priv_key; } TEST(OperationTest, PtPlusCtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; - ipcl::keyPair key = ipcl::generateKeypair(2048); + ipcl::KeyPair key = ipcl::generateKeypair(2048); std::vector exp_value1(num_values), exp_value2(num_values); ipcl::PlainText pt1, pt2, dt_sum; @@ -494,11 +470,11 @@ TEST(OperationTest, PtPlusCtTest) { ipcl::setHybridRatio(qat_ratio); - ct1 = key.pub_key->encrypt(pt1); + ct1 = key.pub_key.encrypt(pt1); PtPlusCt(ct_sum, pt2, ct1, key); - dt_sum = key.priv_key->decrypt(ct_sum); + dt_sum = key.priv_key.decrypt(ct_sum); for (int i = 0; i < num_values; i++) { std::vector v = dt_sum.getElementVec(i); @@ -509,16 +485,13 @@ TEST(OperationTest, PtPlusCtTest) { EXPECT_EQ(sum, exp_sum); } - - delete key.pub_key; - delete key.priv_key; } TEST(OperationTest, PtPlusCtArrayTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; - ipcl::keyPair key = ipcl::generateKeypair(2048); + ipcl::KeyPair key = ipcl::generateKeypair(2048); std::vector exp_value1(num_values), exp_value2(num_values); ipcl::PlainText pt1, pt2, dt_sum; @@ -537,11 +510,11 @@ TEST(OperationTest, PtPlusCtArrayTest) { ipcl::setHybridRatio(qat_ratio); - ct1 = key.pub_key->encrypt(pt1); + ct1 = key.pub_key.encrypt(pt1); - PtPlusCtArray(ct_sum, pt2, ct1, key); + PtPlusCtArray(ct_sum, pt2, ct1); - dt_sum = key.priv_key->decrypt(ct_sum); + dt_sum = key.priv_key.decrypt(ct_sum); for (int i = 0; i < num_values; i++) { std::vector v = dt_sum.getElementVec(i); @@ -552,16 +525,13 @@ TEST(OperationTest, PtPlusCtArrayTest) { EXPECT_EQ(sum, exp_sum); } - - delete key.pub_key; - delete key.priv_key; } TEST(OperationTest, PtMultiplyCtTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; - ipcl::keyPair key = ipcl::generateKeypair(2048); + ipcl::KeyPair key = ipcl::generateKeypair(2048); std::vector exp_value1(num_values), exp_value2(num_values); ipcl::PlainText pt1, pt2, dt_product; @@ -580,11 +550,11 @@ TEST(OperationTest, PtMultiplyCtTest) { ipcl::setHybridRatio(qat_ratio); - ct1 = key.pub_key->encrypt(pt1); + ct1 = key.pub_key.encrypt(pt1); PtMultiplyCt(ct_product, pt2, ct1, key); - dt_product = key.priv_key->decrypt(ct_product); + dt_product = key.priv_key.decrypt(ct_product); for (int i = 0; i < num_values; i++) { std::vector v = dt_product.getElementVec(i); @@ -595,16 +565,13 @@ TEST(OperationTest, PtMultiplyCtTest) { EXPECT_EQ(product, exp_product); } - - delete key.pub_key; - delete key.priv_key; } TEST(OperationTest, PtMultiplyCtArrayTest) { const uint32_t num_values = SELF_DEF_NUM_VALUES; const float qat_ratio = SELF_DEF_HYBRID_QAT_RATIO; - ipcl::keyPair key = ipcl::generateKeypair(2048); + ipcl::KeyPair key = ipcl::generateKeypair(2048); std::vector exp_value1(num_values), exp_value2(num_values); ipcl::PlainText pt1, pt2, dt_product; @@ -623,11 +590,11 @@ TEST(OperationTest, PtMultiplyCtArrayTest) { ipcl::setHybridRatio(qat_ratio); - ct1 = key.pub_key->encrypt(pt1); + ct1 = key.pub_key.encrypt(pt1); - PtMultiplyCtArray(ct_product, pt2, ct1, key); + PtMultiplyCtArray(ct_product, pt2, ct1); - dt_product = key.priv_key->decrypt(ct_product); + dt_product = key.priv_key.decrypt(ct_product); for (int i = 0; i < num_values; i++) { std::vector v = dt_product.getElementVec(i); @@ -638,7 +605,4 @@ TEST(OperationTest, PtMultiplyCtArrayTest) { EXPECT_EQ(product, exp_product); } - - delete key.pub_key; - delete key.priv_key; }