diff --git a/include/ircd/m/event.h b/include/ircd/m/event.h index 75aee7794..c4e867460 100644 --- a/include/ircd/m/event.h +++ b/include/ircd/m/event.h @@ -78,6 +78,14 @@ struct ircd::m::event using closure = std::function; using closure_bool = std::function; + static ed25519::sig sign(const m::event &); + 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); + + static sha256::buf hash(const m::event &); + static sha256::buf hash(json::iov &event, const string_view &content); + static string_view hashes(const mutable_buffer &, json::iov &event, const string_view &content); + using super_type::tuple; using super_type::operator=; diff --git a/include/ircd/m/vm.h b/include/ircd/m/vm.h index ed87e166a..502b276fd 100644 --- a/include/ircd/m/vm.h +++ b/include/ircd/m/vm.h @@ -29,7 +29,7 @@ namespace ircd::m::vm extern ctx::shared_view accept; extern const opts default_opts; - event::id::buf commit(json::iov &event); + event::id::buf commit(const m::event &); event::id::buf commit(json::iov &event, const json::iov &content); } diff --git a/ircd/m/event.cc b/ircd/m/event.cc index 6de712958..f0407cbc4 100644 --- a/ircd/m/event.cc +++ b/ircd/m/event.cc @@ -413,6 +413,119 @@ ircd::m::event::event(const id &id, new (this) m::event(obj); } +ircd::string_view +ircd::m::event::hashes(const mutable_buffer &out, + json::iov &event, + const string_view &content) +{ + const sha256::buf hash_ + { + hash(event, content) + }; + + static const size_t hashb64sz + { + size_t(sizeof(hash_) * 1.34) + 1 + }; + + thread_local char hashb64buf[hashb64sz]; + const json::members hashes + { + { "sha256", b64encode_unpadded(hashb64buf, hash_) } + }; + + return json::stringify(mutable_buffer{out}, hashes); +} + +ircd::sha256::buf +ircd::m::event::hash(json::iov &event, + const string_view &content) +{ + const json::iov::push _content + { + event, { "content", content } + }; + + return hash(event); +} + +ircd::sha256::buf +ircd::m::event::hash(const m::event &event) +{ + thread_local char buf[64_KiB]; + const string_view preimage + { + stringify(buf, event) + }; + + const sha256::buf hash + { + sha256{preimage} + }; + + return hash; +} + +ircd::string_view +ircd::m::event::signatures(const mutable_buffer &out, + json::iov &event, + const json::iov &content) +{ + const ed25519::sig sig + { + sign(event, content) + }; + + static const size_t sigb64sz + { + size_t(sizeof(sig) * 1.34) + 1 + }; + + thread_local char sigb64buf[sigb64sz]; + const json::members sigb64 + { + { self::public_key_id, b64encode_unpadded(sigb64buf, sig) } + }; + + const json::members sigs + { + { my_host(), sigb64 } + }; + + return json::stringify(mutable_buffer{out}, sigs); +} + +ircd::ed25519::sig +ircd::m::event::sign(json::iov &event, + const json::iov &content) +{ + //TODO: essential keys + const json::iov::push _content + { + event, { "content", "{}" } + }; + + return sign(event); +} + +ircd::ed25519::sig +ircd::m::event::sign(const m::event &event) +{ + thread_local char buf[64_KiB]; + const string_view preimage + { + stringify(buf, event) + }; + + const ed25519::sig sig + { + self::secret_key.sign(preimage) + }; + + assert(self::public_key.verify(preimage, sig)); + return sig; +} + // // event::prev // diff --git a/ircd/m/vm.cc b/ircd/m/vm.cc index 6ab53bd83..bdccc5161 100644 --- a/ircd/m/vm.cc +++ b/ircd/m/vm.cc @@ -42,85 +42,55 @@ ircd::m::event::id::buf ircd::m::vm::commit(json::iov &event, const json::iov &contents) { - const auto &room_id - { - event.at("room_id") - }; - - // derp - const json::strung content - { - contents - }; - const json::iov::set set[] { { event, { "origin_server_ts", ircd::time() }}, { event, { "origin", my_host() }}, }; - thread_local char preimage_buf[64_KiB]; - const_buffer preimage + const json::strung content { - stringify(mutable_buffer{preimage_buf}, event) + contents }; - sha256::buf hash + // event_id + + sha256::buf event_id_hash; { - sha256{preimage} - }; + thread_local char preimage_buf[64_KiB]; + event_id_hash = sha256{stringify(mutable_buffer{preimage_buf}, event)}; + } event::id::buf eid_buf; - const json::iov::set _event_id + const auto event_id { - event, { "event_id", m::event_id(event, eid_buf, hash) } + m::event_id(event, eid_buf, event_id_hash) }; - char hashes_buf[128]; - string_view hashes; + const json::iov::set _event_id { - const json::iov::push _content - { - event, { "content", string_view{content} } - }; + event, { "event_id", event_id } + }; - // derp - preimage = stringify(mutable_buffer{preimage_buf}, event); - hash = sha256{preimage}; + // hashes - // derp - thread_local char hashb64[hash.size() * 2]; - hashes = stringify(mutable_buffer{hashes_buf}, json::members - { - { "sha256", b64encode_unpadded(hashb64, hash) } - }); - } + char hashes_buf[128]; + const string_view hashes + { + m::event::hashes(hashes_buf, event, content) + }; const json::iov::push _hashes { event, { "hashes", hashes } }; - // derp - ed25519::sig sig; - { - const json::iov::push _content - { - event, { "content", "{}" } - }; + // sigs - preimage = stringify(mutable_buffer{preimage_buf}, event); - sig = self::secret_key.sign(preimage); - assert(self::public_key.verify(preimage, sig)); - } - - char sigb64[size_t(size(sig) * 1.34) + 1]; - const json::members sigs + char sigs_buf[384]; + const string_view sigs { - { my_host(), json::members - { - { self::public_key_id, b64encode_unpadded(sigb64, sig) } - }} + m::event::signatures(sigs_buf, event, contents) }; const json::iov::push _final[] @@ -162,13 +132,8 @@ ircd::m::vm::commit_hook /// out /// ircd::m::event::id::buf -ircd::m::vm::commit(json::iov &iov) +ircd::m::vm::commit(const event &event) { - const m::event event - { - iov - }; - check_size(event); log.debug("injecting event(mark: %ld) %s",