From cc649f38eee35b95af5901832c5dd043081b3a09 Mon Sep 17 00:00:00 2001 From: PastaPastaPasta <6443210+PastaPastaPasta@users.noreply.github.com> Date: Thu, 5 Dec 2024 23:38:55 -0600 Subject: [PATCH] feat: serialize on the stack (#75) * feat: implement std::array based serialization * fixup add const * add SerializeToArray for PrivateKey * simplify G1Element::Serialize by using G1Element::SerializeToArray * refactor: continued reduced duplication * fixup: apply code review comments --- include/dashbls/elements.hpp | 3 +++ include/dashbls/privatekey.hpp | 1 + src/elements.cpp | 28 ++++++++++++++++++++++++---- src/privatekey.cpp | 7 +++++++ 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/include/dashbls/elements.hpp b/include/dashbls/elements.hpp index 6832b31f3..95937f62d 100644 --- a/include/dashbls/elements.hpp +++ b/include/dashbls/elements.hpp @@ -59,6 +59,7 @@ class G1Element { GTElement Pair(const G2Element &b) const; uint32_t GetFingerprint(bool fLegacy = false) const; std::vector Serialize(bool fLegacy = false) const; + std::array SerializeToArray(bool fLegacy = false) const; G1Element Copy(); friend bool operator==(const G1Element &a, const G1Element &b); @@ -102,6 +103,7 @@ class G2Element { G2Element Negate() const; GTElement Pair(const G1Element &a) const; std::vector Serialize(bool fLegacy = false) const; + std::array SerializeToArray(bool fLegacy = false) const; G2Element Copy(); friend bool operator==(G2Element const &a, G2Element const &b); @@ -127,6 +129,7 @@ class GTElement { void Serialize(uint8_t *buffer) const; std::vector Serialize() const; + std::array SerializeToArray() const; friend bool operator==(GTElement const &a, GTElement const &b); friend bool operator!=(GTElement const &a, GTElement const &b); diff --git a/include/dashbls/privatekey.hpp b/include/dashbls/privatekey.hpp index beebbb05a..d02a7d292 100644 --- a/include/dashbls/privatekey.hpp +++ b/include/dashbls/privatekey.hpp @@ -82,6 +82,7 @@ class PrivateKey { // Serialize the key into bytes void Serialize(uint8_t *buffer) const; std::vector Serialize(bool fLegacy = false) const; + std::array SerializeToArray(bool fLegacy = false) const; G2Element SignG2( const uint8_t *msg, diff --git a/src/elements.cpp b/src/elements.cpp index 278af8cd8..b0c747af8 100644 --- a/src/elements.cpp +++ b/src/elements.cpp @@ -171,11 +171,16 @@ uint32_t G1Element::GetFingerprint(const bool fLegacy) const } std::vector G1Element::Serialize(const bool fLegacy) const { + const auto arr = G1Element::SerializeToArray(fLegacy); + return std::vector{arr.begin(), arr.end()}; +} + +std::array G1Element::SerializeToArray(const bool fLegacy) const { uint8_t buffer[G1Element::SIZE + 1]; g1_write_bin(buffer, G1Element::SIZE + 1, p, 1); + std::array result{}; if (buffer[0] == 0x00) { // infinity - std::vector result(G1Element::SIZE, 0); result[0] = 0xc0; return result; } @@ -187,7 +192,9 @@ std::vector G1Element::Serialize(const bool fLegacy) const { if (!fLegacy) { buffer[1] |= 0x80; // indicate compression } - return std::vector(buffer + 1, buffer + 1 + G1Element::SIZE); + + std::copy_n(buffer + 1, G1Element::SIZE, result.begin()); + return result; } bool operator==(const G1Element & a, const G1Element &b) @@ -386,11 +393,18 @@ G2Element G2Element::Negate() const GTElement G2Element::Pair(const G1Element& a) const { return a & (*this); } std::vector G2Element::Serialize(const bool fLegacy) const { + const auto arr = G2Element::SerializeToArray(fLegacy); + return std::vector{arr.begin(), arr.end()}; +} + +std::array G2Element::SerializeToArray(const bool fLegacy) const { uint8_t buffer[G2Element::SIZE + 1]; g2_write_bin(buffer, G2Element::SIZE + 1, (g2_st*)q, 1); + std::array result{}; + if (buffer[0] == 0x00) { // infinity - std::vector result(G2Element::SIZE, 0); + result.fill(0); result[0] = 0xc0; return result; } @@ -410,7 +424,6 @@ std::vector G2Element::Serialize(const bool fLegacy) const { } } - std::vector result(G2Element::SIZE, 0); if (fLegacy) { std::memcpy(result.data(), buffer + 1, G2Element::SIZE); } else { @@ -551,4 +564,11 @@ std::vector GTElement::Serialize() const return data; } +std::array GTElement::SerializeToArray() const +{ + std::array data{}; + Serialize(data.data()); + return data; +} + } // end namespace bls diff --git a/src/privatekey.cpp b/src/privatekey.cpp index 865507dfc..d4dd32d11 100644 --- a/src/privatekey.cpp +++ b/src/privatekey.cpp @@ -284,6 +284,13 @@ std::vector PrivateKey::Serialize(const bool fLegacy) const return data; } +std::array PrivateKey::SerializeToArray(bool fLegacy) const +{ + std::array data{}; + Serialize(data.data()); + return data; +} + G2Element PrivateKey::SignG2( const uint8_t *msg, size_t len,