From 74c7a6db644874cd53470ff288fe8cff4d3608f5 Mon Sep 17 00:00:00 2001 From: Amaury Chamayou Date: Tue, 24 Mar 2026 09:37:28 +0000 Subject: [PATCH 1/2] COSE comparison --- CMakeLists.txt | 5 + src/crypto/test/cose_bench.cpp | 177 +++++++++++++++++++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 src/crypto/test/cose_bench.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 42ba5299852..66b7e83f1c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -891,6 +891,11 @@ if(BUILD_TESTS) SRCS src/crypto/test/bench.cpp LINK_LIBS ) + add_picobench( + cose_bench + SRCS src/crypto/test/cose_bench.cpp + LINK_LIBS + ) add_picobench( history_bench SRCS src/node/test/history_bench.cpp src/enclave/thread_local.cpp diff --git a/src/crypto/test/cose_bench.cpp b/src/crypto/test/cose_bench.cpp new file mode 100644 index 00000000000..77e90b75e99 --- /dev/null +++ b/src/crypto/test/cose_bench.cpp @@ -0,0 +1,177 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the Apache 2.0 License. + +#include "ccf/crypto/cose_verifier.h" +#include "crypto/cbor.h" +#include "crypto/cose.h" +#include "crypto/openssl/cose_sign.h" +#include "crypto/openssl/ec_key_pair.h" + +#define PICOBENCH_UNIQUE_SYM_SUFFIX __COUNTER__ +#define PICOBENCH_IMPLEMENT_WITH_MAIN +#include + +using namespace std; +using namespace ccf::crypto; + +static const string lorem_ipsum = + "Lorem ipsum dolor sit amet, consectetur adipiscing " + "elit, sed do eiusmod tempor incididunt ut labore et" + " dolore magna aliqua. Ut enim ad minim veniam, quis" + " nostrud exercitation ullamco laboris nisi ut " + "aliquip ex ea commodo consequat. Duis aute irure " + "dolor in reprehenderit in voluptate velit esse " + "cillum dolore eu fugiat nulla pariatur. Excepteur " + "sint occaecat cupidatat non proident, sunt in culpa " + "qui officia deserunt mollit anim id est laborum."; + +template +inline void do_not_optimize(A const& value) +{ + asm volatile("" : : "r,m"(value) : "memory"); +} + +inline void clobber_memory() +{ + asm volatile("" : : : "memory"); +} + +template +vector make_contents() +{ + vector contents(NBytes); + size_t written = 0; + while (written < NBytes) + { + const auto write_size = min(lorem_ipsum.size(), NBytes - written); + memcpy(contents.data() + written, lorem_ipsum.data(), write_size); + written += write_size; + } + return contents; +} + +static ccf::cbor::Value make_protected_headers(std::span kid) +{ + namespace cbor = ccf::cbor; + + std::vector phdr; + phdr.emplace_back( + cbor::make_signed(ccf::cose::header::iana::KID), cbor::make_bytes(kid)); + phdr.emplace_back( + cbor::make_signed(ccf::cose::header::iana::VDS), + cbor::make_signed(ccf::cose::value::CCF_LEDGER_SHA256)); + return cbor::make_map(std::move(phdr)); +} + +template +static void benchmark_cose_sign(picobench::state& s) +{ + ECKeyPair_OpenSSL kp(Curve); + auto payload = make_contents(); + auto kid_pem = kp.public_key_pem(); + std::span kid( + reinterpret_cast(kid_pem.data()), kid_pem.size()); + + s.start_timer(); + for (auto _ : s) + { + (void)_; + auto phdr = make_protected_headers(kid); + auto envelope = cose_sign1(kp, phdr, payload); + do_not_optimize(envelope); + clobber_memory(); + } + s.stop_timer(); +} + +template +static void benchmark_cose_verify(picobench::state& s) +{ + ECKeyPair_OpenSSL kp(Curve); + auto payload = make_contents(); + auto kid_pem = kp.public_key_pem(); + std::span kid( + reinterpret_cast(kid_pem.data()), kid_pem.size()); + + auto phdr = make_protected_headers(kid); + auto envelope = cose_sign1(kp, phdr, payload); + auto verifier = make_cose_verifier_from_key(kp.public_key_pem()); + + s.start_timer(); + for (auto _ : s) + { + (void)_; + auto ok = verifier->verify_detached(envelope, payload); + do_not_optimize(ok); + clobber_memory(); + } + s.stop_timer(); +} + +const std::vector sizes = {10}; + +#define PICO_SUFFIX() iterations(sizes) + +PICOBENCH_SUITE("cose sign secp256r1"); +namespace COSE_SIGN_SECP256R1 +{ + auto sign_256r1_1byte = + benchmark_cose_sign; + PICOBENCH(sign_256r1_1byte).PICO_SUFFIX(); + + auto sign_256r1_1k = + benchmark_cose_sign; + PICOBENCH(sign_256r1_1k).PICO_SUFFIX(); + + auto sign_256r1_100k = + benchmark_cose_sign; + PICOBENCH(sign_256r1_100k).PICO_SUFFIX(); +} + +PICOBENCH_SUITE("cose sign secp384r1"); +namespace COSE_SIGN_SECP384R1 +{ + auto sign_384r1_1byte = + benchmark_cose_sign; + PICOBENCH(sign_384r1_1byte).PICO_SUFFIX(); + + auto sign_384r1_1k = + benchmark_cose_sign; + PICOBENCH(sign_384r1_1k).PICO_SUFFIX(); + + auto sign_384r1_100k = + benchmark_cose_sign; + PICOBENCH(sign_384r1_100k).PICO_SUFFIX(); +} + +PICOBENCH_SUITE("cose verify secp256r1"); +namespace COSE_VERIFY_SECP256R1 +{ + auto verify_256r1_1byte = + benchmark_cose_verify; + PICOBENCH(verify_256r1_1byte).PICO_SUFFIX(); + + auto verify_256r1_1k = + benchmark_cose_verify; + PICOBENCH(verify_256r1_1k).PICO_SUFFIX(); + + auto verify_256r1_100k = + benchmark_cose_verify; + PICOBENCH(verify_256r1_100k).PICO_SUFFIX(); +} + +PICOBENCH_SUITE("cose verify secp384r1"); +namespace COSE_VERIFY_SECP384R1 +{ + auto verify_384r1_1byte = + benchmark_cose_verify; + PICOBENCH(verify_384r1_1byte).PICO_SUFFIX(); + + auto verify_384r1_1k = + benchmark_cose_verify; + PICOBENCH(verify_384r1_1k).PICO_SUFFIX(); + + auto verify_384r1_100k = + benchmark_cose_verify; + PICOBENCH(verify_384r1_100k).PICO_SUFFIX(); +} From 4e6479b8e2254987367210fde13a0cbbf194280f Mon Sep 17 00:00:00 2001 From: Amaury Chamayou Date: Tue, 24 Mar 2026 10:42:14 +0000 Subject: [PATCH 2/2] close to rust version --- src/crypto/test/cose_bench.cpp | 46 ++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/src/crypto/test/cose_bench.cpp b/src/crypto/test/cose_bench.cpp index 77e90b75e99..5035d4f3c06 100644 --- a/src/crypto/test/cose_bench.cpp +++ b/src/crypto/test/cose_bench.cpp @@ -50,16 +50,48 @@ vector make_contents() return contents; } -static ccf::cbor::Value make_protected_headers(std::span kid) +static const string bench_kid = "bench-kid"; +static const string bench_issuer = "bench-issuer"; +static const string bench_subject = "bench-subject"; +static const string bench_txid = "2.42"; +static const int64_t bench_iat = 1700000000; + +static ccf::cbor::Value make_protected_headers() { namespace cbor = ccf::cbor; + std::vector ccf_headers; + ccf_headers.emplace_back( + cbor::make_string(ccf::cose::header::custom::TX_ID), + cbor::make_string(bench_txid)); + + std::vector cwt_headers; + cwt_headers.emplace_back( + cbor::make_signed(ccf::cwt::header::iana::IAT), + cbor::make_signed(bench_iat)); + cwt_headers.emplace_back( + cbor::make_signed(ccf::cwt::header::iana::ISS), + cbor::make_string(bench_issuer)); + cwt_headers.emplace_back( + cbor::make_signed(ccf::cwt::header::iana::SUB), + cbor::make_string(bench_subject)); + std::vector phdr; phdr.emplace_back( - cbor::make_signed(ccf::cose::header::iana::KID), cbor::make_bytes(kid)); + cbor::make_signed(ccf::cose::header::iana::KID), + cbor::make_bytes(std::span( + reinterpret_cast(bench_kid.data()), + bench_kid.size()))); phdr.emplace_back( cbor::make_signed(ccf::cose::header::iana::VDS), cbor::make_signed(ccf::cose::value::CCF_LEDGER_SHA256)); + phdr.emplace_back( + cbor::make_signed(ccf::cose::header::iana::CWT_CLAIMS), + cbor::make_map(std::move(cwt_headers))); + phdr.emplace_back( + cbor::make_string(ccf::cose::header::custom::CCF_V1), + cbor::make_map(std::move(ccf_headers))); + return cbor::make_map(std::move(phdr)); } @@ -68,15 +100,12 @@ static void benchmark_cose_sign(picobench::state& s) { ECKeyPair_OpenSSL kp(Curve); auto payload = make_contents(); - auto kid_pem = kp.public_key_pem(); - std::span kid( - reinterpret_cast(kid_pem.data()), kid_pem.size()); s.start_timer(); for (auto _ : s) { (void)_; - auto phdr = make_protected_headers(kid); + auto phdr = make_protected_headers(); auto envelope = cose_sign1(kp, phdr, payload); do_not_optimize(envelope); clobber_memory(); @@ -89,11 +118,8 @@ static void benchmark_cose_verify(picobench::state& s) { ECKeyPair_OpenSSL kp(Curve); auto payload = make_contents(); - auto kid_pem = kp.public_key_pem(); - std::span kid( - reinterpret_cast(kid_pem.data()), kid_pem.size()); - auto phdr = make_protected_headers(kid); + auto phdr = make_protected_headers(); auto envelope = cose_sign1(kp, phdr, payload); auto verifier = make_cose_verifier_from_key(kp.public_key_pem());