From 96726adccc3b51cde58d2877b702f2a909a93452 Mon Sep 17 00:00:00 2001 From: Vlad Gheorghiu Date: Tue, 14 Jan 2025 11:44:17 -0500 Subject: [PATCH 1/2] V0.12.0 (#22) Version 0.12 Signed-off-by: Vlad Gheorghiu --- CHANGES.md | 16 ++++++++-- CMakeLists.txt | 2 +- Doxyfile | 2 +- LICENSE | 2 +- RELEASE.md | 8 ++--- include/oqs_cpp.hpp | 58 ++++++++++++++++++++++++++++++++-- prettyprint.sh | 6 ++-- unit_tests/tests/test_sig.cpp | 59 +++++++++++++++++++++++++++++++++-- 8 files changed, 138 insertions(+), 15 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index d311bd2..b004dc3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,14 @@ +# Version 0.12.0 - 14 January, 2024 + +- Fixes https://github.com/open-quantum-safe/liboqs-cpp/issues/21. The API that + NIST has introduced in [FIPS 204](https://csrc.nist.gov/pubs/fips/204/final) + for ML-DSA includes a context string of length >= 0. Added new API for + signing with a context string: + - `bytes Signature::sign_with_ctx_str(const bytes& message, +const bytes& context) const` + - `bool Signature::verify_with_ctx_str(const bytes& message, +const bytes& signature, const bytes& context, const bytes& public_key) const` + # Version 0.10.0 - March 27, 2024 - Replaced CHANGES by @@ -25,6 +36,7 @@ - Minimalistic Docker support - Removed AppVeyor and CircleCI, all continuous integration is now done via GitHub actions +- Changed header files extension from `.h` to `.hpp` # Version 0.7.2 - September 1, 2022 @@ -67,7 +79,7 @@ # Version 0.2.0 - October 8, 2019 -- Minor changes to accomodate for liboqs API changes +- Minor changes to accommodate for liboqs API changes # Version 0.1.2 - July 9, 2019 @@ -77,7 +89,7 @@ # Version 0.1.1 - May 29, 2019 -- Minor API change in `oqs_cpp.h`: `Signature::alg_details_::length_signature` +- Minor API change: `Signature::alg_details_::length_signature` is replaced by `Signature::alg_details_::max_length_signature` # Version 0.1.0 - April 23, 2019 diff --git a/CMakeLists.txt b/CMakeLists.txt index b2ffedb..16aa517 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.15) -set(LIBOQS_CPP_VERSION_NUM 0.10.0) +set(LIBOQS_CPP_VERSION_NUM 0.12.0) set(LIBOQS_CPP_VERSION_STR "${LIBOQS_CPP_VERSION_NUM}") project( liboqs-cpp diff --git a/Doxyfile b/Doxyfile index 6ce057d..64768b8 100644 --- a/Doxyfile +++ b/Doxyfile @@ -48,7 +48,7 @@ PROJECT_NAME = liboqs-cpp # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 0.10.0 +PROJECT_NUMBER = 0.12.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/LICENSE b/LICENSE index a945cbb..80dd311 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019-2024 Open Quantum Safe +Copyright (c) 2019-2025 Open Quantum Safe Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/RELEASE.md b/RELEASE.md index 90584bc..1d21899 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,4 +1,4 @@ -# liboqs-cpp version 0.10.0 +# liboqs-cpp version 0.12.0 --- @@ -24,13 +24,13 @@ See in particular limitations on intended use. ## Release notes -This release of liboqs-cpp was released on March 27, 2024. Its release page +This release of liboqs-cpp was released on January 14, 2024. Its release page on GitHub is -https://github.com/open-quantum-safe/liboqs-cpp/releases/tag/0.10.0. +https://github.com/open-quantum-safe/liboqs-cpp/releases/tag/0.12.0. --- ## What's New -This is the 14th release of liboqs-cpp. For a list of changes see +This is the 15th release of liboqs-cpp. For a list of changes see [CHANGES.md](https://github.com/open-quantum-safe/liboqs-cpp/blob/main/CHANGES.md). diff --git a/include/oqs_cpp.hpp b/include/oqs_cpp.hpp index 7785c8f..7875452 100644 --- a/include/oqs_cpp.hpp +++ b/include/oqs_cpp.hpp @@ -167,7 +167,7 @@ class KeyEncapsulation { std::shared_ptr kem_{nullptr, [](C::OQS_KEM* p) { C::OQS_KEM_free(p); }}; ///< liboqs smart pointer to C::OQS_KEM - bytes secret_key_{}; ///< secret key + bytes secret_key_{}; ///< secret key public: /** * \brief KEM algorithm details @@ -484,7 +484,7 @@ class Signature { std::shared_ptr sig_{nullptr, [](C::OQS_SIG* p) { C::OQS_SIG_free(p); }}; ///< liboqs smart pointer to C::OQS_SIG - bytes secret_key_{}; ///< secret key + bytes secret_key_{}; ///< secret key public: /** @@ -646,6 +646,60 @@ class Signature { return signature; } + /** + * \brief Sign message with context string + * \param message Message + * \param context Context string + * \return Message signature + */ + bytes sign_with_ctx_str(const bytes& message, const bytes& context) const { + if (secret_key_.size() != alg_details_.length_secret_key) + throw std::runtime_error( + "Incorrect secret key length, make sure you " + "specify one in the constructor or run " + "oqs::Signature::generate_keypair()"); + + bytes signature(alg_details_.max_length_signature, 0); + + std::size_t len_sig; + OQS_STATUS rv_ = C::OQS_SIG_sign_with_ctx_str( + sig_.get(), signature.data(), &len_sig, message.data(), + message.size(), context.data(), context.size(), secret_key_.data()); + + if (rv_ != OQS_STATUS::OQS_SUCCESS) + throw std::runtime_error( + "Can not sign message with context string"); + + signature.resize(len_sig); + + return signature; + } + + /** + * \brief Verify signature with context string + * \param message Message + * \param signature Signature + * \param context Context string + * \param public_key Public key + * \return True if the signature is valid, false otherwise + */ + bool verify_with_ctx_str(const bytes& message, const bytes& signature, + const bytes& context, + const bytes& public_key) const { + if (public_key.size() != alg_details_.length_public_key) + throw std::runtime_error("Incorrect public key length"); + + if (signature.size() > alg_details_.max_length_signature) + throw std::runtime_error("Incorrect signature size"); + + OQS_STATUS rv_ = C::OQS_SIG_verify_with_ctx_str( + sig_.get(), message.data(), message.size(), signature.data(), + signature.size(), context.data(), context.size(), + public_key.data()); + + return rv_ == OQS_STATUS::OQS_SUCCESS; + } + /** * \brief Verify signature * \param message Message diff --git a/prettyprint.sh b/prettyprint.sh index 8c7fad5..cadfc4f 100755 --- a/prettyprint.sh +++ b/prettyprint.sh @@ -1,10 +1,12 @@ #!/bin/sh -# $@ - List of directories - # Code beautifier with clang-format # Recursively parses the directories passed as command line arguments +# Arguments: +# +# $@ - List of directories + if test -z "$CLANG_FORMAT"; then echo "Please set the CLANG_FORMAT environment variable to point to the \ location of clang-format" diff --git a/unit_tests/tests/test_sig.cpp b/unit_tests/tests/test_sig.cpp index b64e0db..d327abd 100644 --- a/unit_tests/tests/test_sig.cpp +++ b/unit_tests/tests/test_sig.cpp @@ -12,8 +12,8 @@ // no_thread_sig_patterns lists sig patterns that have issues running in a // separate thread -static std::vector no_thread_sig_patterns{"Rainbow-III", - "Rainbow-V"}; +static std::vector no_thread_sig_patterns{ + "cross-rsdp", "cross-rsdpg", "SPHINCS+", "Falcon", "MAYO"}; // used for thread-safe console output static std::mutex mu; @@ -33,6 +33,29 @@ void test_sig_correctness(const std::string& sig_name, const oqs::bytes& msg) { EXPECT_TRUE(is_valid); } +void test_sig_correctness_with_ctx_str(const std::string& sig_name, + const oqs::bytes& msg) { + if (sig_name.substr(0, 6) != "ML-DSA") + return; + { + std::lock_guard lg{mu}; + std::cout << "Correctness with context string - " << sig_name + << std::endl; + } + oqs::Signature signer{sig_name}; + oqs::bytes context_str{"some context"_bytes}; + oqs::bytes signer_public_key = signer.generate_keypair(); + oqs::bytes signature = signer.sign_with_ctx_str(msg, context_str); + oqs::Signature verifier{sig_name}; + bool is_valid = verifier.verify_with_ctx_str(msg, signature, context_str, + signer_public_key); + if (!is_valid) + std::cerr << sig_name + << ": signature with context string verification failed" + << std::endl; + EXPECT_TRUE(is_valid); +} + void test_sig_wrong_signature(const std::string& sig_name, const oqs::bytes& msg) { { @@ -101,6 +124,38 @@ TEST(oqs_Signature, Correctness) { elem.join(); } +TEST(oqs_Signature, CorrectnessWithContextString) { + oqs::bytes message = "This is our favourite message to sign"_bytes; + std::vector thread_pool; + std::vector enabled_sigs = oqs::Sigs::get_enabled_sigs(); + // first test sigs that belong to no_thread_sig_patterns[] in the main + // thread (stack size is 8Mb on macOS), due to issues with stack size being + // too small in macOS (512Kb for threads) + for (auto&& sig_name : enabled_sigs) { + for (auto&& no_thread_sig : no_thread_sig_patterns) { + if (sig_name.find(no_thread_sig) != std::string::npos) { + test_sig_correctness_with_ctx_str(sig_name, message); + } + } + } + // test the remaining sigs in separate threads + for (auto&& sig_name : enabled_sigs) { + bool test_in_thread = true; + for (auto&& no_thread_sig : no_thread_sig_patterns) { + if (sig_name.find(no_thread_sig) != std::string::npos) { + test_in_thread = false; + break; + } + } + if (test_in_thread) + thread_pool.emplace_back(test_sig_correctness_with_ctx_str, + sig_name, message); + } + // join the rest of the threads + for (auto&& elem : thread_pool) + elem.join(); +} + TEST(oqs_Signature, WrongSignature) { oqs::bytes message = "This is our favourite message to sign"_bytes; std::vector thread_pool; From 0c3a965a2eeb9f1bb0afbb5d26367e19cba3292f Mon Sep 17 00:00:00 2001 From: Vlad Gheorghiu Date: Tue, 14 Jan 2025 12:53:00 -0500 Subject: [PATCH 2/2] Version 0.12.0 (#23) Signed-off-by: Vlad Gheorghiu --- CHANGES.md | 2 +- RELEASE.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index b004dc3..66c239d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,4 @@ -# Version 0.12.0 - 14 January, 2024 +# Version 0.12.0 - 14 January, 2025 - Fixes https://github.com/open-quantum-safe/liboqs-cpp/issues/21. The API that NIST has introduced in [FIPS 204](https://csrc.nist.gov/pubs/fips/204/final) diff --git a/RELEASE.md b/RELEASE.md index 1d21899..ee5a3c2 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -24,7 +24,7 @@ See in particular limitations on intended use. ## Release notes -This release of liboqs-cpp was released on January 14, 2024. Its release page +This release of liboqs-cpp was released on January 14, 2025. Its release page on GitHub is https://github.com/open-quantum-safe/liboqs-cpp/releases/tag/0.12.0.