Skip to content

Commit

Permalink
feat: version 0.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
PETAce committed Jun 26, 2024
1 parent ead22f6 commit 60c6301
Show file tree
Hide file tree
Showing 23 changed files with 2,261 additions and 480 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,9 @@

- Added hashing tables: Cuckoo hashing and simple hashing.
- Added partially homomorphic encryption: the Paillier cryptosystem.

## Version 0.3.0

### Features

- Added a GMP-based generic implementation of the Paillier cryptosystem.
51 changes: 43 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ if(NOT CMAKE_BUILD_TYPE)
endif()
message(STATUS "Build type (CMAKE_BUILD_TYPE): ${CMAKE_BUILD_TYPE}")

project(SOLO VERSION 0.2.0 LANGUAGES CXX C)
project(SOLO VERSION 0.3.0 LANGUAGES CXX C)

########################
# Global configuration #
Expand Down Expand Up @@ -101,15 +101,15 @@ set(SOLO_THIRDPARTY_INCLUDES_INSTALL_DIR ${SOLO_INCLUDES_INSTALL_DIR}/thirdparty
set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY OFF)

# Supported target operating systems are Linux and macOS.
if (NOT DEFINED LINUX)
if(NOT DEFINED LINUX)
if (UNIX AND NOT APPLE AND NOT CYGWIN AND NOT MINGW)
set(LINUX ON)
endif()
endif()
if (UNIX AND APPLE)
if(UNIX AND APPLE)
set(MACOS ON)
endif()
if (NOT LINUX AND NOT MACOS)
if(NOT LINUX AND NOT MACOS)
message(FATAL_ERROR "Supported target operating systems are Linux and macOS")
endif()

Expand Down Expand Up @@ -139,13 +139,13 @@ CHECK_CXX_SOURCE_RUNS("
SOLO_AMD64
)
set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_OLD})
if (NOT SOLO_AMD64 AND NOT SOLO_ARM64)
if(NOT SOLO_AMD64 AND NOT SOLO_ARM64)
message(FATAL_ERROR "Supported target architectures are x86_64 and arm64")
endif()

# AES, SSE, and AVX
CHECK_INCLUDE_FILE_CXX("wmmintrin.h" SOLO_USE_AES_INTRIN)
if (SOLO_USE_AES_INTRIN)
if(SOLO_USE_AES_INTRIN)
add_compile_options(-msse4.2 -mavx -maes)
endif()

Expand All @@ -158,8 +158,6 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND SOLO_ENABLE_GCOV)
set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -fprofile-arcs -ftest-coverage -lgcov")
endif()

set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -ldl -lrt")

#########################
# External dependencies #
#########################
Expand Down Expand Up @@ -211,6 +209,9 @@ if(SOLO_USE_IPCL)
else()
message(FATAL_ERROR "IPCL: not found, please download and install manually")
endif()
else()
solo_fetch_thirdparty_content(ExternalGMP)
set(SOLO_BUILD_GMP TRUE CACHE BOOL "" FORCE)
endif()

# Require Threads::Threads
Expand All @@ -220,6 +221,18 @@ if(NOT TARGET Threads::Threads)
find_package(Threads REQUIRED)
endif()

if(NOT SOLO_USE_IPCL)
# OpenMP::OpenMP_CXX
if(NOT TARGET OpenMP::OpenMP_CXX)
find_package(OpenMP REQUIRED)
if(NOT OpenMP_FOUND)
message(FATAL_ERROR "OpenMP: not found")
else()
message(STATUS "OpenMP: found")
endif()
endif()
endif()

####################
# SOLO C++ library #
####################
Expand Down Expand Up @@ -274,6 +287,13 @@ if(NOT SOLO_BUILD_SHARED_LIBS)

if(SOLO_USE_IPCL)
target_link_libraries(solo PUBLIC IPCL::ipcl)
else()
add_dependencies(solo gmpxx gmp)
target_include_directories(solo PUBLIC $<BUILD_INTERFACE:${GMP_INCLUDE_DIR}>)
solo_combine_archives(solo gmpxx)
solo_combine_archives(solo gmp)
target_link_libraries(solo PUBLIC OpenMP::OpenMP_CXX)
set(SOLO_CARRY_GMP TRUE)
endif()
target_link_libraries(solo PUBLIC Threads::Threads)

Expand Down Expand Up @@ -310,6 +330,11 @@ else()

if(SOLO_USE_IPCL)
target_link_libraries(solo_shared PUBLIC IPCL::ipcl)
else()
add_dependencies(solo_shared gmpxx_shared gmp_shared)
target_include_directories(solo_shared PUBLIC $<BUILD_INTERFACE:${GMP_INCLUDE_DIR}>)
target_link_libraries(solo_shared PUBLIC gmpxx_shared gmp_shared OpenMP::OpenMP_CXX)
set(SOLO_CARRY_GMP FALSE)
endif()
target_link_libraries(solo_shared PUBLIC Threads::Threads)
endif()
Expand Down Expand Up @@ -369,6 +394,16 @@ if(SOLO_BUILD_DEPS)
DIRECTORY ${OPENSSL_INCLUDE_DIR}
DESTINATION ${SOLO_THIRDPARTY_INCLUDES_INSTALL_DIR}/openssl)
endif()
if(SOLO_BUILD_GMP)
if(SOLO_BUILD_SHARED_LIBS)
install(
FILES ${GMP_C_SHARED_LIBRARY} ${GMP_CXX_SHARED_LIBRARY}
DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
install(
FILES ${GMP_INCLUDE_DIR}/gmp.h ${GMP_INCLUDE_DIR}/gmpxx.h
DESTINATION ${SOLO_THIRDPARTY_INCLUDES_INSTALL_DIR})
endif()
endif()

####################
Expand Down
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ PETAce-Solo implements or wraps the following primitives that involves only one
| Required dependency | Tested version | Use |
|-----------------------------------------------|----------------|--------------------------|
| [OpenSSL](https://github.com/openssl/openssl) | 1.1.1 | Cryptographic primitives |
| [GMP](https://gmplib.org) | 6.3.0 | Bignumer operations for GMP-based Paillier|

| Optional dependency | Tested version | Use |
|--------------------------------------------------------|----------------|------------------------|
Expand Down Expand Up @@ -48,13 +49,16 @@ Output binaries can be found in `build/lib/` and `build/bin/` directories.
| `SOLO_BUILD_EXAMPLE` | ON/OFF | ON | Build C++ example if set to ON. |
| `SOLO_BUILD_TEST` | ON/OFF | ON | Build C++ test if set to ON. |
| `SOLO_BUILD_DEPS` | ON/OFF | ON | Download and build unmet dependencies if set to ON. |
| `SOLO_USE_IPCL` | ON/OFF | OFF | Add PHE and depends on IPCL if set to ON. |
| `SOLO_USE_IPCL` | ON/OFF | OFF | BUILD IPCL-based PHE if set to ON, GMP-based PHE if set to off|

### Adding Partially Homomorphic Encryption

Follow instructions of [Intel Paillier Cryptosystem Library](https://github.com/intel/pailliercryptolib) and install it to `${IPCL_INSTALL_DIR}`.
By default, the Paillier cryptosystem is a generic implementation that uses the GMP library.
For power users who seek extreme performance on supported processors, we provide the option to switch to the IPCL-based implementation.
To use the IPCL-based Paillier, follow instructions of [Intel Paillier Cryptosystem Library](https://github.com/intel/pailliercryptolib) and install it to `${IPCL_INSTALL_DIR}`.
We recommend the commit `495beaad1f6e70741f2b5cf1279cb919fd66d894` instead of v2.0.0.
Build PETAce-Solo library with extra configuration:

```bash
cmake -S . -B build -DSOLO_USE_IPCL=ON -DIPCL_DIR=${IPCL_INSTALL_DIR}/lib/cmake/ipcl-2.0.0
```
Expand All @@ -75,14 +79,14 @@ This project is licensed under the [Apache-2.0 License](LICENSE).

To cite PETAce in academic papers, please use the following BibTeX entries.

### Version 0.2.0
### Version 0.3.0

```tex
@misc{petace,
title = {PETAce (release 0.2.0)},
title = {PETAce (release 0.3.0)},
howpublished = {\url{https://github.com/tiktok-privacy-innovation/PETAce}},
month = Oct,
year = 2023,
month = Jun,
year = 2024,
note = {TikTok Pte. Ltd.},
key = {PETAce}
}
Expand Down
5 changes: 2 additions & 3 deletions bench/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@

cmake_minimum_required(VERSION 3.14)

project(SOLOBench VERSION 0.2.0 LANGUAGES CXX)
project(SOLOBench VERSION 0.3.0 LANGUAGES CXX)

# If not called from root CMakeLists.txt
if(NOT DEFINED SOLO_BUILD_BENCH)
set(SOLO_BUILD_BENCH ON)

find_package(PETAce-Solo 0.2.0 EXACT REQUIRED)
find_package(PETAce-Solo 0.3.0 EXACT REQUIRED)

# Must define these variables and include macros
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
Expand Down Expand Up @@ -70,7 +70,6 @@ if(SOLO_BUILD_BENCH)
${CMAKE_CURRENT_LIST_DIR}/sampling_bench.cpp
)

set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -ldl -lrt")
add_executable(solo_bench ${SOLO_BENCH_FILES})

if(TARGET PETAce-Solo::solo)
Expand Down
4 changes: 4 additions & 0 deletions bench/bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,14 @@ int main(int argc, char** argv) {
PETACE_REG_BENCH(Hash, BLAKE2, bm_hash_blake2, petace::solo::Byte(0));
PETACE_REG_BENCH(petace::solo::PRNG, SHAKE_128, bm_prng_shake_128, std::size_t(4096));
PETACE_REG_BENCH(petace::solo::PRNG, BLAKE2X, bm_prng_blake2x, std::size_t(4096));
#ifdef SOLO_USE_AES_INTRIN
PETACE_REG_BENCH(petace::solo::PRNG, AES_ECB_CTR, bm_prng_aes_ctr, std::size_t(4096));
#endif
PETACE_REG_BENCH(Sampling, UNIFORM_BYTE_ARRAY_SHAKE_128, bm_sample_uniform_byte_array_shake_128, std::size_t(4096));
PETACE_REG_BENCH(Sampling, UNIFORM_BYTE_ARRAY_BLAKE2X, bm_sample_uniform_byte_array_blake2x, std::size_t(4096));
#ifdef SOLO_USE_AES_INTRIN
PETACE_REG_BENCH(Sampling, UNIFORM_BYTE_ARRAY_AES_ECB_CTR, bm_sample_uniform_byte_array_aes_ctr, std::size_t(4096));
#endif
PETACE_REG_BENCH(EC_OpenSSL, hash_to_curve, bm_ec_hash_to_curve, petace::solo::Byte(0));
PETACE_REG_BENCH(EC_OpenSSL, encrypt, bm_ec_encrypt, petace::solo::Byte(0));
PETACE_REG_BENCH(EC_OpenSSL, decrypt, bm_ec_decrypt, petace::solo::Byte(0));
Expand Down
4 changes: 4 additions & 0 deletions bench/bench.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,15 @@ void bm_hash_blake2(benchmark::State& state, petace::solo::Byte value);
// PRNG benchmark cases
void bm_prng_shake_128(benchmark::State& state, std::size_t byte_count);
void bm_prng_blake2x(benchmark::State& state, std::size_t byte_count);
#ifdef SOLO_USE_AES_INTRIN
void bm_prng_aes_ctr(benchmark::State& state, std::size_t byte_count);
#endif
// Sampling benchmark cases
void bm_sample_uniform_byte_array_shake_128(benchmark::State& state, std::size_t byte_count);
void bm_sample_uniform_byte_array_blake2x(benchmark::State& state, std::size_t byte_count);
#ifdef SOLO_USE_AES_INTRIN
void bm_sample_uniform_byte_array_aes_ctr(benchmark::State& state, std::size_t byte_count);
#endif
// EC OpenSSL benchmark cases
void bm_ec_hash_to_curve(benchmark::State& state, petace::solo::Byte value);
void bm_ec_encrypt(benchmark::State& state, petace::solo::Byte value);
Expand Down
2 changes: 2 additions & 0 deletions bench/prng_bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ void bm_prng_blake2x(benchmark::State& state, std::size_t byte_count) {
}
}

#ifdef SOLO_USE_AES_INTRIN
void bm_prng_aes_ctr(benchmark::State& state, std::size_t byte_count) {
std::vector<petace::solo::Byte> output(byte_count);
petace::solo::PRNGFactory prng_factory(petace::solo::PRNGScheme::AES_ECB_CTR, kSeedByteCount);
Expand All @@ -53,3 +54,4 @@ void bm_prng_aes_ctr(benchmark::State& state, std::size_t byte_count) {
prng->generate(byte_count, output.data());
}
}
#endif
2 changes: 2 additions & 0 deletions bench/sampling_bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ void bm_sample_uniform_byte_array_blake2x(benchmark::State& state, std::size_t b
}
}

#ifdef SOLO_USE_AES_INTRIN
void bm_sample_uniform_byte_array_aes_ctr(benchmark::State& state, std::size_t byte_count) {
std::vector<petace::solo::Byte> output(byte_count);
petace::solo::PRNGFactory prng_factory(petace::solo::PRNGScheme::AES_ECB_CTR, kSeedByteCount);
Expand All @@ -54,3 +55,4 @@ void bm_sample_uniform_byte_array_aes_ctr(benchmark::State& state, std::size_t b
sample_uniform_byte_array(*prng, byte_count, output.data());
}
}
#endif
72 changes: 72 additions & 0 deletions cmake/ExternalGMP.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Copyright 2023 TikTok Pte. Ltd.
#
# 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(ExternalProject)

set(GMP_SOURCES_DIR ${SOLO_THIRDPARTY_DIR}/gmp)
set(GMP_INSTALL_DIR "${GMP_SOURCES_DIR}/install")
set(GMP_INCLUDE_DIR "${GMP_INSTALL_DIR}/include")
set(GMP_NAME "gmp")

include(ProcessorCount)
ProcessorCount(NUM_OF_PROCESSOR)

if((NOT DEFINED GMP_URL) OR (NOT DEFINED GMP_VER))
message(STATUS "use pre defined download url")
set(GMP_VER "gmp-6.3.0" CACHE STRING "" FORCE)
set(GMP_URL "https://gmplib.org/download/gmp/${GMP_VER}.tar.bz2" CACHE STRING "" FORCE)
endif()

ExternalProject_Add(
extern_gmp
PREFIX ${GMP_SOURCES_DIR}
DOWNLOAD_COMMAND wget --no-check-certificate ${GMP_URL} -c -q -O ${GMP_NAME}.tar.bz2
&& tar -xvf ${GMP_NAME}.tar.bz2
SOURCE_DIR ${GMP_SOURCES_DIR}/src/${GMP_VER}
CONFIGURE_COMMAND ./configure CFLAGS=-fPIC CXXFLAGS=-fPIC --prefix=${GMP_INSTALL_DIR}
--enable-cxx --with-pic
BUILD_COMMAND make -j ${NUM_OF_PROCESSOR}
INSTALL_COMMAND make install
BUILD_IN_SOURCE 1
)

set(GMP_C_STATIC_LIBRARY "${GMP_INSTALL_DIR}/lib/libgmp.a")
set(GMP_CXX_STATIC_LIBRARY "${GMP_INSTALL_DIR}/lib/libgmpxx.a")

if(LINUX)
set(GMP_C_SHARED_LIBRARY "${GMP_INSTALL_DIR}/lib/libgmp.so")
set(GMP_CXX_SHARED_LIBRARY "${GMP_INSTALL_DIR}/lib/libgmpxx.so")
elseif(MACOS)
set(GMP_C_SHARED_LIBRARY "${GMP_INSTALL_DIR}/lib/libgmp.dylib")
set(GMP_CXX_SHARED_LIBRARY "${GMP_INSTALL_DIR}/lib/libgmpxx.dylib")
endif()

add_library(gmp STATIC IMPORTED GLOBAL)
set_property(TARGET gmp PROPERTY IMPORTED_LOCATION ${GMP_C_STATIC_LIBRARY})

add_library(gmp_shared SHARED IMPORTED GLOBAL)
set_property(TARGET gmp_shared PROPERTY IMPORTED_LOCATION ${GMP_C_SHARED_LIBRARY})

add_library(gmpxx STATIC IMPORTED GLOBAL)
set_property(TARGET gmpxx PROPERTY IMPORTED_LOCATION ${GMP_CXX_STATIC_LIBRARY})

add_library(gmpxx_shared SHARED IMPORTED GLOBAL)
set_property(TARGET gmpxx_shared PROPERTY IMPORTED_LOCATION ${GMP_CXX_SHARED_LIBRARY})

add_dependencies(gmp extern_gmp)
add_dependencies(gmpxx extern_gmp)
add_dependencies(gmp_shared extern_gmp)
add_dependencies(gmpxx_shared extern_gmp)

include_directories(${GMP_INCLUDE_DIR})
2 changes: 2 additions & 0 deletions cmake/PETAce-SoloConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ if (NOT SOLO_CARRY_OPENSSL)
endif()
if (SOLO_USE_IPCL)
solo_find_dependency(IPCL)
else()
solo_find_dependency(OpenMP)
endif()

include(${CMAKE_CURRENT_LIST_DIR}/PETAce-SoloTargets.cmake)
Expand Down
6 changes: 2 additions & 4 deletions example/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@

cmake_minimum_required(VERSION 3.14)

project(SOLOExample VERSION 0.2.0 LANGUAGES CXX)
project(SOLOExample VERSION 0.3.0 LANGUAGES CXX)

# If not called from root CMakeLists.txt
if(NOT DEFINED SOLO_BUILD_EXAMPLE)
set(SOLO_BUILD_EXAMPLE ON)

# Import PETAce-Solo
find_package(PETAce-Solo 0.2.0 EXACT REQUIRED)
find_package(PETAce-Solo 0.3.0 EXACT REQUIRED)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
endif()
Expand All @@ -34,8 +34,6 @@ if(SOLO_BUILD_EXAMPLE)
${CMAKE_CURRENT_LIST_DIR}/example.cpp
)

set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -ldl -lrt")

add_executable(solo_example ${SOLO_EXAMPLE_FILES})

if(TARGET PETAce-Solo::solo)
Expand Down
4 changes: 2 additions & 2 deletions example/example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ void example_sampling() {
<< std::endl;

std::cout << std::endl;
std::cout << "Use AES_ECB_CTR to create our PRNG" << std::endl;
petace::solo::PRNGFactory prng_factory(petace::solo::PRNGScheme::AES_ECB_CTR, seed.size());
std::cout << "Use BLAKE2Xb to create our PRNG" << std::endl;
petace::solo::PRNGFactory prng_factory(petace::solo::PRNGScheme::BLAKE2Xb, seed.size());
auto prng = prng_factory.create(seed);

std::cout << " Generate a random 32-bit unsigned integer: " << sample_uniform_uint32(*prng) << std::endl;
Expand Down
Loading

0 comments on commit 60c6301

Please sign in to comment.