Skip to content

Commit fbbff88

Browse files
authored
Add curve functions wrappers (#671)
* Add curve functions wrappers * Add curve CI job and fix the libzmq build
1 parent 8bace31 commit fbbff88

File tree

4 files changed

+110
-7
lines changed

4 files changed

+110
-7
lines changed

.github/workflows/ci.yml

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ jobs:
1616
cc: ["gcc-10"]
1717
cxx: ["g++-10"]
1818
drafts: ["ON"]
19+
curve: ["OFF"]
1920
libzmq: ["4.3.5"]
2021
libzmqbuild: ["cmake"]
2122
include:
2223
# older libzmq and without draft
2324
- os: "ubuntu-22.04"
2425
cppstd: "11"
25-
cc: "gcc-9"
26-
cxx: "g++-9"
26+
cc: "gcc-11"
27+
cxx: "g++-11"
2728
drafts: "OFF"
2829
libzmq: "4.2.0"
2930
libzmqbuild: "pkgconfig"
@@ -35,12 +36,21 @@ jobs:
3536
drafts: "OFF"
3637
libzmq: "4.3.5"
3738
libzmqbuild: "cmake"
39+
# with curve
40+
- os: "ubuntu-24.04"
41+
cppstd: "23"
42+
cc: "gcc-13"
43+
cxx: "g++-13"
44+
curve: "ON"
45+
libzmq: "4.3.5"
46+
libzmqbuild: "cmake"
3847
# coverage (gcc version should match gcov version)
3948
- os: "ubuntu-22.04"
4049
cppstd: "17"
41-
cc: "gcc-9"
42-
cxx: "g++-9"
50+
cc: "gcc-11"
51+
cxx: "g++-11"
4352
drafts: "ON"
53+
curve: "ON"
4454
libzmq: "4.3.5"
4555
libzmqbuild: "cmake"
4656
coverage: "-DCOVERAGE=ON"
@@ -108,11 +118,17 @@ jobs:
108118
- name: build_libzmq_cmake
109119
if: ${{ matrix.libzmqbuild == 'cmake' }}
110120
run: |
121+
if [ ! "${{ matrix.os }}" = 'windows-2022' ]; then
122+
export CXXFLAGS="-Wno-error=stringop-truncation -Wno-stringop-overflow"
123+
export CFLAGS="-Wno-error=stringop-truncation -Wno-stringop-overflow"
124+
fi
111125
cmake -Hlibzmq-${{ matrix.libzmq }} -Blibzmq-build ${{ matrix.platform}} \
112126
-DWITH_PERF_TOOL=OFF \
113127
-DZMQ_BUILD_TESTS=OFF \
128+
-DLIBZMQ_WERROR=OFF \
114129
-DCMAKE_BUILD_TYPE=Release \
115-
-DENABLE_DRAFTS=${{ matrix.drafts }}
130+
-DENABLE_DRAFTS=${{ matrix.drafts }} \
131+
-DENABLE_CURVE=${{ matrix.curve }}
116132
cmake --build libzmq-build --config ${BUILDTYPE} -j ${THREADS}
117133
echo "LIBZMQ=${PWD}/libzmq-build" >> ${GITHUB_ENV}
118134
@@ -126,6 +142,8 @@ jobs:
126142
if: ${{ matrix.libzmqbuild == 'pkgconfig' }}
127143
working-directory: libzmq-${{ matrix.libzmq }}
128144
run: |
145+
export CXXFLAGS="-Wno-error=stringop-truncation -Wno-stringop-overflow"
146+
export CFLAGS="-Wno-error=stringop-truncation -Wno-stringop-overflow"
129147
./autogen.sh &&
130148
./configure --prefix=${PWD}/libzmq-build &&
131149
make -j ${THREADS}

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ add_executable(
3131
monitor.cpp
3232
utilities.cpp
3333
timers.cpp
34+
curve.cpp
3435
)
3536

3637
target_include_directories(unit_tests PUBLIC ${CATCH_MODULE_PATH})

tests/curve.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#include <catch2/catch_all.hpp>
2+
#include <zmq.hpp>
3+
4+
#ifdef ZMQ_HAVE_CURVE
5+
6+
TEST_CASE("curve_keypair", "[curve]")
7+
{
8+
auto keys = zmq::curve_keypair();
9+
auto public_key = keys.first;
10+
auto secret_key = keys.second;
11+
CHECK(!public_key.empty());
12+
CHECK(!secret_key.empty());
13+
}
14+
15+
TEST_CASE("curve_public", "[curve]")
16+
{
17+
auto secret_key = "D:)Q[IlAW!ahhC2ac:9*A}h:p?([4%wOTJ%JR%cs";
18+
auto public_key = zmq::curve_public(secret_key);
19+
CHECK(public_key == "Yne@$w-vo<fVvi]a<NY6T1ed:M$fCG*[IaLV{hID");
20+
}
21+
22+
#endif
23+
24+
TEST_CASE("z85_encode", "[curve]")
25+
{
26+
std::vector<uint8_t> data{1,2,3,4,5,6,7,8};
27+
auto encoded = zmq::z85_encode(data);
28+
CHECK(encoded.size() == std::string("0rJua1Qkhq").size());
29+
CHECK(encoded == "0rJua1Qkhq");
30+
}
31+
32+
TEST_CASE("z85_decode", "[curve]")
33+
{
34+
auto decoded = zmq::z85_decode("0rJua1Qkhq");
35+
CHECK(decoded == std::vector<uint8_t>{1,2,3,4,5,6,7,8});
36+
}

zmq.hpp

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107

108108
#include <cassert>
109109
#include <cstring>
110+
#include <cstdint>
110111

111112
#include <type_traits>
112113
#include <algorithm>
@@ -539,7 +540,7 @@ class message_t
539540
throw error_t();
540541
memcpy(data(), data_, size_);
541542
}
542-
543+
543544
void rebuild(const std::string &str)
544545
{
545546
rebuild(str.data(), str.size());
@@ -2492,7 +2493,7 @@ class monitor_t
24922493
(void) addr_;
24932494
}
24942495

2495-
protected:
2496+
protected:
24962497
bool process_event(short events)
24972498
{
24982499
zmq::message_t eventMsg;
@@ -2874,6 +2875,53 @@ class timers
28742875

28752876
#endif // defined(ZMQ_CPP11) && defined(ZMQ_HAVE_TIMERS)
28762877

2878+
#ifdef ZMQ_HAVE_CURVE
2879+
2880+
inline std::pair<std::string, std::string> curve_keypair()
2881+
{
2882+
char public_key_buffer[41];
2883+
char secret_key_buffer[41];
2884+
int rc = zmq_curve_keypair(public_key_buffer, secret_key_buffer);
2885+
if (rc == -1)
2886+
throw zmq::error_t();
2887+
return {public_key_buffer, secret_key_buffer};
2888+
}
2889+
2890+
inline std::string curve_public(const std::string& secret)
2891+
{
2892+
if (secret.size() != 40)
2893+
throw std::runtime_error("Invalid secret string size");
2894+
char public_key_buffer[41];
2895+
int rc = zmq_curve_public(public_key_buffer, secret.c_str());
2896+
if (rc == -1)
2897+
throw zmq::error_t();
2898+
return public_key_buffer;
2899+
}
2900+
2901+
#endif
2902+
2903+
inline std::string z85_encode(const std::vector<uint8_t>& data)
2904+
{
2905+
size_t buffer_size = data.size() * size_t{6} / size_t{5} + 1;
2906+
std::string buffer(buffer_size, '\0');
2907+
auto *result = zmq_z85_encode(&buffer[0], data.data(), data.size());
2908+
if (result == nullptr)
2909+
throw zmq::error_t();
2910+
while (buffer.back() == '\0')
2911+
buffer.pop_back();
2912+
return buffer;
2913+
}
2914+
2915+
inline std::vector<uint8_t> z85_decode(const std::string& encoded)
2916+
{
2917+
size_t dest_size = encoded.size() * size_t{4} / size_t{5};
2918+
std::vector<uint8_t> dest(dest_size);
2919+
auto *result = zmq_z85_decode(dest.data(), encoded.c_str());
2920+
if (result == nullptr)
2921+
throw zmq::error_t();
2922+
return dest;
2923+
}
2924+
28772925
} // namespace zmq
28782926

28792927
#endif // __ZMQ_HPP_INCLUDED__

0 commit comments

Comments
 (0)