diff --git a/include/ircd/m/event.h b/include/ircd/m/event.h index fbf514fef..2c8216e2c 100644 --- a/include/ircd/m/event.h +++ b/include/ircd/m/event.h @@ -119,6 +119,7 @@ struct ircd::m::event static ed25519::sig sign(json::iov &event, const json::iov &content, const ed25519::sk &); static ed25519::sig sign(json::iov &event, const json::iov &content); static string_view signatures(const mutable_buffer &, json::iov &event, const json::iov &content); + friend event signatures(const mutable_buffer &, const m::event &); friend bool verify_sha256b64(const event &, const string_view &); friend bool verify_hash(const event &, const sha256::buf &); diff --git a/ircd/m/event.cc b/ircd/m/event.cc index 85b122a2c..61bb5f92e 100644 --- a/ircd/m/event.cc +++ b/ircd/m/event.cc @@ -723,6 +723,48 @@ ircd::m::event::signatures(const mutable_buffer &out, return json::stringify(mutable_buffer{out}, sigs); } +ircd::m::event +ircd::m::signatures(const mutable_buffer &out, + const m::event &event_) +{ + thread_local char content[64_KiB]; + m::event event + { + essential(event_, content) + }; + + thread_local char buf[64_KiB]; + const json::object &preimage + { + stringify(buf, event) + }; + + const ed25519::sig sig + { + sign(preimage) + }; + + thread_local char sigb64buf[b64encode_size(sizeof(sig))]; + const json::member my_sig + { + my_host(), json::members + { + { self::public_key_id, b64encode_unpadded(sigb64buf, sig) } + } + }; + + static const size_t SIG_MAX{64}; + thread_local std::array sigs; + + size_t i(0); + sigs.at(i++) = my_sig; + for(const auto &other : json::get<"signatures"_>(event_)) + sigs.at(i++) = { other.first, other.second }; + + json::get<"signatures"_>(event) = json::stringify(mutable_buffer{out}, sigs.data(), sigs.data() + i); + return event; +} + ircd::ed25519::sig ircd::m::event::sign(json::iov &event, const json::iov &contents)