From 069ae987a1fafe77be3d5d7b5bcdd20697ced378 Mon Sep 17 00:00:00 2001 From: PETAce Date: Thu, 23 Jan 2025 18:14:22 +0800 Subject: [PATCH] feat: version 0.4.0 --- CHANGELOG.md | 4 ++++ CMakeLists.txt | 2 +- README.md | 8 ++++---- bench/CMakeLists.txt | 4 ++-- example/CMakeLists.txt | 4 ++-- src/solo/ahe_paillier.cpp | 4 ++-- src/solo/ec_openssl.cpp | 29 +++++++++++++++++++++++++++++ src/solo/ec_openssl.h | 23 +++++++++++++++++++++++ test/CMakeLists.txt | 4 ++-- test/ahe_paillier_test.cpp | 8 ++++---- test/ec_openssl_test.cpp | 9 +++++++++ 11 files changed, 82 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce9e755..f9a6363 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,3 +21,7 @@ ### Features - Added a GMP-based generic implementation of the Paillier cryptosystem. + +## Version 0.4.0 + +- No update. diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e53924..386b650 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ if(NOT CMAKE_BUILD_TYPE) endif() message(STATUS "Build type (CMAKE_BUILD_TYPE): ${CMAKE_BUILD_TYPE}") -project(SOLO VERSION 0.3.0 LANGUAGES CXX C) +project(SOLO VERSION 0.4.0 LANGUAGES CXX C) ######################## # Global configuration # diff --git a/README.md b/README.md index 4cc0d95..ddd57e5 100644 --- a/README.md +++ b/README.md @@ -86,14 +86,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.3.0 +### Version 0.4.0 ```tex @misc{petace, - title = {PETAce (release 0.3.0)}, + title = {PETAce (release 0.4.0)}, howpublished = {\url{https://github.com/tiktok-privacy-innovation/PETAce}}, - month = Jun, - year = 2024, + month = Jan, + year = 2025, note = {TikTok Pte. Ltd.}, key = {PETAce} } diff --git a/bench/CMakeLists.txt b/bench/CMakeLists.txt index 9dcba74..85e0bb1 100644 --- a/bench/CMakeLists.txt +++ b/bench/CMakeLists.txt @@ -14,13 +14,13 @@ cmake_minimum_required(VERSION 3.14) -project(SOLOBench VERSION 0.3.0 LANGUAGES CXX) +project(SOLOBench VERSION 0.4.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.3.0 EXACT REQUIRED) + find_package(PETAce-Solo 0.4.0 EXACT REQUIRED) # Must define these variables and include macros set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 29f83e5..94b4296 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -14,14 +14,14 @@ cmake_minimum_required(VERSION 3.14) -project(SOLOExample VERSION 0.3.0 LANGUAGES CXX) +project(SOLOExample VERSION 0.4.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.3.0 EXACT REQUIRED) + find_package(PETAce-Solo 0.4.0 EXACT REQUIRED) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) endif() diff --git a/src/solo/ahe_paillier.cpp b/src/solo/ahe_paillier.cpp index 9270716..65513c1 100644 --- a/src/solo/ahe_paillier.cpp +++ b/src/solo/ahe_paillier.cpp @@ -33,8 +33,8 @@ namespace petace { namespace solo { namespace ahepaillier { -constexpr std::size_t kAHEMaxRandomBits = 8192; -constexpr std::size_t kAHEMaxRandomByteCount = 1024; +constexpr std::size_t kAHEMaxRandomBits = 16384; +constexpr std::size_t kAHEMaxRandomByteCount = 2048; PublicKey::PublicKey(std::size_t key_length, bool enable_djn) : key_length_(key_length), n_byte_count_((key_length_ + 7) / 8), enable_djn_(enable_djn), pk_set_(false) { diff --git a/src/solo/ec_openssl.cpp b/src/solo/ec_openssl.cpp index c56ff55..948f0a2 100644 --- a/src/solo/ec_openssl.cpp +++ b/src/solo/ec_openssl.cpp @@ -427,5 +427,34 @@ void ECOpenSSL::point_from_bytes(const Byte* in, std::size_t in_byte_count, Poin } } +void ECOpenSSL::secret_key_from_bytes(const Byte* in, std::size_t in_byte_count, SecretKey& out) const { + if (in_byte_count == 0) { + throw std::invalid_argument("in_byte_count is zero"); + } + if (in == nullptr && in_byte_count != 0) { + throw std::invalid_argument("in is nullptr"); + } + if (out.data() == nullptr) { + throw std::invalid_argument("out is nullptr"); + } + if (BN_bin2bn(reinterpret_cast(in), static_cast(in_byte_count), out.data()) == nullptr) { + throw std::runtime_error("openssl error: " + std::to_string(ERR_get_error())); + } +} + +std::size_t ECOpenSSL::secret_key_to_bytes(const SecretKey& in, std::size_t out_byte_count, Byte* out) const { + if (in.data() == nullptr) { + throw std::invalid_argument("in is nullptr"); + } + if (out == nullptr) { + return static_cast(BN_num_bytes(in.data())); + } + std::size_t res = static_cast(BN_bn2bin(in.data(), reinterpret_cast(out))); + if (res > out_byte_count) { + throw std::runtime_error("the buffer is not large enough."); + } + return res; +} + } // namespace solo } // namespace petace diff --git a/src/solo/ec_openssl.h b/src/solo/ec_openssl.h index bd7d019..d7f40b5 100644 --- a/src/solo/ec_openssl.h +++ b/src/solo/ec_openssl.h @@ -313,6 +313,29 @@ class ECOpenSSL { */ void point_from_bytes(const Byte* in, std::size_t in_byte_count, Point& out) const; + /** + * @brief Reads a secret key from a byte buffer. + * + * @param[in] in The byte buffer to read from. + * @param[in] in_byte_count The size of the input byte buffer. + * @param[out] The secret key to write to. + * @throws std::invalid_argument if the input buffer's byte size is zero or either input or output is nullptr. + * @throws std::runtime_error if an OpenSSL command fails or if the buffer is not large enough. + */ + void secret_key_from_bytes(const Byte* in, std::size_t in_byte_count, SecretKey& out) const; + + /** + * @brief Writes a secret key into a byte buffer and returns the number of bytes written (if the byte buffer is + * empty). + * + * @param[in] in The secret key to be written. + * @param[in] out_byte_count The size of the output byte buffer. + * @param[out] The byte buffer to write to. + * @throws std::invalid_argument if the input is nullptr. + * @throws std::runtime_error if an OpenSSL command fails or if the buffer is not large enough. + */ + std::size_t secret_key_to_bytes(const SecretKey& in, std::size_t out_byte_count, Byte* out = nullptr) const; + private: void hash_to_field( std::shared_ptr hash, const Byte* in, std::size_t in_byte_count, BIGNUM* out, BN_CTX* ctx) const; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index aee4c17..a515eff 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -14,13 +14,13 @@ cmake_minimum_required(VERSION 3.14) -project(SOLOTest VERSION 0.3.0 LANGUAGES CXX C) +project(SOLOTest VERSION 0.4.0 LANGUAGES CXX C) # If not called from root CMakeLists.txt if(NOT DEFINED SOLO_BUILD_TEST) set(SOLO_BUILD_TEST ON) - find_package(PETAce-Solo 0.3.0 EXACT REQUIRED) + find_package(PETAce-Solo 0.4.0 EXACT REQUIRED) # Must define these variables and include macros set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib) diff --git a/test/ahe_paillier_test.cpp b/test/ahe_paillier_test.cpp index ecf1d14..65684b9 100644 --- a/test/ahe_paillier_test.cpp +++ b/test/ahe_paillier_test.cpp @@ -221,8 +221,8 @@ TEST(AHEPaillierTest, Serialization) { { petace::solo::PRNGFactory prng_factory = petace::solo::PRNGFactory(petace::solo::PRNGScheme::BLAKE2Xb); auto prng = prng_factory.create(); - std::size_t illegal_bits = 8200; - std::size_t illegal_byte_count = 1025; + std::size_t illegal_bits = 16385; + std::size_t illegal_byte_count = 2049; std::vector bn_bytes(illegal_byte_count); prng->generate(illegal_byte_count, bn_bytes.data()); #ifdef SOLO_USE_IPCL @@ -319,7 +319,7 @@ TEST(AHEPaillierTest, Serialization) { { petace::solo::PRNGFactory prng_factory = petace::solo::PRNGFactory(petace::solo::PRNGScheme::BLAKE2Xb); auto prng = prng_factory.create(); - std::size_t illegal_byte_count = 1025; + std::size_t illegal_byte_count = 2049; std::vector bn_bytes(illegal_byte_count); prng->generate(illegal_byte_count, bn_bytes.data()); petace::solo::ahepaillier::Plaintext pt; @@ -330,7 +330,7 @@ TEST(AHEPaillierTest, Serialization) { { petace::solo::PRNGFactory prng_factory = petace::solo::PRNGFactory(petace::solo::PRNGScheme::BLAKE2Xb); auto prng = prng_factory.create(); - std::size_t illegal_byte_count = 1025; + std::size_t illegal_byte_count = 2049; std::vector bn_bytes(illegal_byte_count); prng->generate(illegal_byte_count, bn_bytes.data()); std::shared_ptr sk = nullptr; diff --git a/test/ec_openssl_test.cpp b/test/ec_openssl_test.cpp index 9071a61..4e0cf4e 100644 --- a/test/ec_openssl_test.cpp +++ b/test/ec_openssl_test.cpp @@ -36,9 +36,18 @@ TEST(ECOpenSSLTest, ECScheme) { ASSERT_THROW(ec.create_secret_key(nullptr, sk), std::invalid_argument); ec.create_secret_key(prng, sk); ec.create_secret_key(prng, sk_new); + + std::size_t sk_byte_count = ec.secret_key_to_bytes(sk, 0, nullptr); + std::vector sk_byte_array(sk_byte_count); + ASSERT_EQ(ec.secret_key_to_bytes(sk, sk_byte_count, sk_byte_array.data()), sk_byte_count); + EC::SecretKey sk_deserialized; + ec.secret_key_from_bytes(sk_byte_array.data(), sk_byte_count, sk_deserialized); + ASSERT_THROW(ec.hash_to_curve(nullptr, 64, plaintext), std::invalid_argument); ec.hash_to_curve(input, 64, plaintext); ec.encrypt(plaintext, sk, ciphertext); + ec.encrypt(plaintext, sk_deserialized, ciphertext_new); + ASSERT_TRUE(ec.are_equal(ciphertext, ciphertext_new)); ec.switch_key(ciphertext, sk, sk_new, ciphertext_new); ec.decrypt(ciphertext_new, sk_new, plaintext_new); ASSERT_TRUE(ec.are_equal(plaintext_new, plaintext));