From 73d954c315107c427ffd68a66ea45affea1557d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ka=C4=9Fan=20Can=20=C5=9Eit?= Date: Sun, 9 Nov 2025 20:13:38 +0300 Subject: [PATCH] Add std::array support to BigInt::serialize --- src/lib/math/bigint/bigint.h | 24 ++++++++++++++++----- src/tests/test_bigint.cpp | 42 ++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/src/lib/math/bigint/bigint.h b/src/lib/math/bigint/bigint.h index c17f36da310..32d65e1b16f 100644 --- a/src/lib/math/bigint/bigint.h +++ b/src/lib/math/bigint/bigint.h @@ -9,6 +9,7 @@ #ifndef BOTAN_BIGINT_H_ #define BOTAN_BIGINT_H_ +#include #include #include #include @@ -708,11 +709,8 @@ class BOTAN_PUBLIC_API(2, 0) BigInt final { * Throws if the BigInt is too large to encode in the length * specified. */ - template > + template > T serialize(size_t len) const { - // TODO this supports std::vector and secure_vector - // it would be nice if this also could work with std::array as in - // bn.serialize_to>(32); T out(len); this->serialize_to(out); return out; @@ -721,11 +719,27 @@ class BOTAN_PUBLIC_API(2, 0) BigInt final { /** * Serialize the value of this BigInt as a big endian encoding. */ - template > + template > T serialize() const { return serialize(this->bytes()); } + /** + * Serialize the BigInt into a fixed-size std::array. + * + * This is a convenience method for serialization into compile-time fixed + * size arrays. + * + * @tparam len the size of the output array in bytes + * @return std::array containing the serialized BigInt (big-endian) + */ + template + std::array serialize_to_array() const { + std::array out{}; + serialize_to(out); + return out; + } + /** * Store BigInt-value in a given byte array * @param buf destination byte array for the integer value diff --git a/src/tests/test_bigint.cpp b/src/tests/test_bigint.cpp index e4e66e15dcb..d365ef6ce78 100644 --- a/src/tests/test_bigint.cpp +++ b/src/tests/test_bigint.cpp @@ -982,6 +982,48 @@ std::vector test_bigint_serialization() { b.binary_encode(enc5.data(), enc5.size()); res.test_bin_eq("BigInt::binary_encode", enc5, "000000000000000000000000FEDCBA9876543210BAADC0FFEE"); }), + + CHECK("BigInt std::array serialization", + [](Test::Result& res) { + const Botan::BigInt testData(0x1234567890ABCDEF); + + const auto arr32 = testData.serialize_to_array<32>(); + res.test_sz_eq("BigInt::serialize std::array size", arr32.size(), size_t{32}); + res.test_bin_eq("BigInt::serialize array compare", + arr32, + "0000000000000000000000000000000000000000000000001234567890ABCDEF"); + + const auto vec32 = testData.serialize>(32); + res.test_bin_eq("BigInt::serialize std::array matches vector", + std::span(arr32), + std::span(vec32)); + + res.test_u8_eq("BigInt::serialize std::array last byte", arr32[31], uint8_t{0xEF}); + res.test_u8_eq("BigInt::serialize std::array first bytes zeroed", arr32[0], uint8_t{0x00}); + + res.test_throws("BigInt::serialize_to_array too small", [&testData]() { + [[maybe_unused]] const auto arr = testData.serialize_to_array<4>(); + }); + + const Botan::BigInt smallTestData = Botan::BigInt::from_u64(0xFF); + const auto arr8 = smallTestData.serialize_to_array<8>(); + res.test_sz_eq("BigInt::serialize std::array small size", arr8.size(), size_t{8}); + res.test_u8_eq("BigInt::serialize std::array small value last byte", arr8[7], uint8_t{0xFF}); + res.test_u8_eq("BigInt::serialize std::array small value zeroed", arr8[0], uint8_t{0x00}); + + const Botan::BigInt zero = Botan::BigInt::zero(); + const auto arr0 = zero.serialize_to_array<4>(); + res.test_sz_eq("BigInt::serialize std::array zero serialization size", arr0.size(), 4); + res.test_bin_eq("BigInt::serialize std::array all zeros", + std::span(arr0), + std::vector(arr0.size(), 0x00)); + + const Botan::BigInt large("0xFEDCBA9876543210FEDCBA9876543210"); + const auto arr16 = large.serialize_to_array<16>(); + res.test_sz_eq("BigInt::serialize std::array large size", arr16.size(), size_t{16}); + res.test_u8_eq("BigInt::serialize std::array large first byte", arr16[0], uint8_t{0xFE}); + res.test_u8_eq("BigInt::serialize std::array large last byte", arr16[15], uint8_t{0x10}); + }), }; }