Skip to content

Commit

Permalink
Version 0.12.0
Browse files Browse the repository at this point in the history
Signed-off-by: Vlad Gheorghiu <[email protected]>
  • Loading branch information
vsoftco committed Jan 14, 2025
1 parent 908c893 commit 98823ed
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 15 deletions.
16 changes: 14 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
# 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)
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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -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
Expand Down
8 changes: 4 additions & 4 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# liboqs-cpp version 0.10.0
# liboqs-cpp version 0.12.0

---

Expand All @@ -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, 2025. 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).
58 changes: 56 additions & 2 deletions include/oqs_cpp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ class KeyEncapsulation {
std::shared_ptr<C::OQS_KEM> 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
Expand Down Expand Up @@ -484,7 +484,7 @@ class Signature {
std::shared_ptr<C::OQS_SIG> 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:
/**
Expand Down Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions prettyprint.sh
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
59 changes: 57 additions & 2 deletions unit_tests/tests/test_sig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@

// no_thread_sig_patterns lists sig patterns that have issues running in a
// separate thread
static std::vector<std::string> no_thread_sig_patterns{"Rainbow-III",
"Rainbow-V"};
static std::vector<std::string> no_thread_sig_patterns{
"cross-rsdp", "cross-rsdpg", "SPHINCS+", "Falcon", "MAYO"};

// used for thread-safe console output
static std::mutex mu;
Expand All @@ -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<std::mutex> 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) {
{
Expand Down Expand Up @@ -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<std::thread> thread_pool;
std::vector<std::string> 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<std::thread> thread_pool;
Expand Down

0 comments on commit 98823ed

Please sign in to comment.