core: group member/owner keys for signing important messages (#6597)

* rfc: member keys

* update plan

* new encoding for message batches

* send new batch encoding in relay-based groups

* mvp launch plan

* update plan

* core: verify group member keys (#6669)

* core: verify group member keys

* refactor, process forwards

* refactor parsing

* refactor parsing 2

* refactor parser 3

* update rfc

* simplify

* simplify

* log tag

* refactor tag logging

* refactor withVerifiedSig

* simplify

* refactor more

* comment

* fix encoding

* fix sending as group for the new binary batch encoding

* unify types

* update api docs

* clean up

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>

* core: signing messages with member keys (#6675)

* core: signing messages with member keys (types)

* sign messages

* refactor batching

* better

* refactor

* remove unused Eq

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>

* core: forward signed messages as unchanged binary strings (#6678)

* core: forward signed messages as unchanged binary strings

* refactor

* consolidate types

* refactor VerifiedMsg

* refactor more

* undo rename

Co-authored-by: Evgeny <evgeny@poberezkin.com>

* update schema and plans

* add signed status to chat items and events

* test signed chat items

* unify parser

* PostgreSQL fix, remove unused fields, option to send inline files in the tests

* change inline files config

* revert inline config change

* use different characters in batch encoding, to avoid conflict with inline files

* fix test, api docs, query plans

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>

---------

Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
This commit is contained in:
Evgeny
2026-03-16 10:46:35 +00:00
committed by GitHub
co-authored by spaced4ndy Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
parent 4e16792ddc
commit 2db92ff6ed
35 changed files with 2325 additions and 443 deletions
@@ -75,6 +75,11 @@ CREATE INDEX idx_group_relays_chat_relay_id ON group_relays(chat_relay_id);
ALTER TABLE group_members ADD COLUMN relay_link BLOB;
ALTER TABLE group_members ADD COLUMN member_pub_key BLOB;
ALTER TABLE messages ADD COLUMN msg_chat_binding TEXT;
ALTER TABLE messages ADD COLUMN msg_signatures BLOB;
ALTER TABLE chat_items ADD COLUMN msg_signed INTEGER NOT NULL DEFAULT 0;
|]
down_m20260222_chat_relays :: Query
@@ -113,4 +118,9 @@ DROP TABLE chat_relays;
ALTER TABLE group_members DROP COLUMN relay_link;
ALTER TABLE group_members DROP COLUMN member_pub_key;
ALTER TABLE messages DROP COLUMN msg_chat_binding;
ALTER TABLE messages DROP COLUMN msg_signatures;
ALTER TABLE chat_items DROP COLUMN msg_signed;
|]
@@ -652,9 +652,9 @@ SEARCH contacts USING COVERING INDEX idx_contacts_contact_group_member_id (conta
Query:
INSERT INTO messages (
msg_sent, chat_msg_event, msg_body, connection_id, group_id,
msg_sent, chat_msg_event, msg_body, msg_chat_binding, msg_signatures, connection_id, group_id,
shared_msg_id, shared_msg_id_user, created_at, updated_at
) VALUES (?,?,?,?,?,?,?,?,?)
) VALUES (?,?,?,?,?,?,?,?,?,?,?)
Plan:
@@ -1231,9 +1231,9 @@ Plan:
Query:
INSERT INTO messages
(msg_sent, chat_msg_event, msg_body, broker_ts, created_at, updated_at, connection_id, group_id,
(msg_sent, chat_msg_event, msg_body, msg_chat_binding, msg_signatures, broker_ts, created_at, updated_at, connection_id, group_id,
shared_msg_id, author_group_member_id, forwarded_by_group_member_id)
VALUES (?,?,?,?,?,?,?,?,?,?,?)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)
Plan:
@@ -1257,7 +1257,7 @@ Query:
i.chat_item_id, i.item_ts, i.item_sent, i.item_content, i.item_text, i.item_status, i.via_proxy, i.shared_msg_id,
i.item_deleted, i.item_deleted_ts, i.item_edited, i.created_at, i.updated_at,
i.fwd_from_tag, i.fwd_from_chat_name, i.fwd_from_msg_dir, i.fwd_from_contact_id, i.fwd_from_group_id, i.fwd_from_chat_item_id,
i.timed_ttl, i.timed_delete_at, i.item_live, i.user_mention, i.has_link,
i.timed_ttl, i.timed_delete_at, i.item_live, i.user_mention, i.has_link, i.msg_signed,
-- CIFile
f.file_id, f.file_name, f.file_size, f.file_path, f.file_crypto_key, f.file_crypto_nonce, f.ci_file_status, f.protocol
FROM chat_items i
@@ -1274,7 +1274,7 @@ Query:
i.chat_item_id, i.item_ts, i.item_sent, i.item_content, i.item_text, i.item_status, i.via_proxy, i.shared_msg_id,
i.item_deleted, i.item_deleted_ts, i.item_edited, i.created_at, i.updated_at,
i.fwd_from_tag, i.fwd_from_chat_name, i.fwd_from_msg_dir, i.fwd_from_contact_id, i.fwd_from_group_id, i.fwd_from_chat_item_id,
i.timed_ttl, i.timed_delete_at, i.item_live, i.user_mention, i.has_link,
i.timed_ttl, i.timed_delete_at, i.item_live, i.user_mention, i.has_link, i.msg_signed,
-- CIFile
f.file_id, f.file_name, f.file_size, f.file_path, f.file_crypto_key, f.file_crypto_nonce, f.ci_file_status, f.protocol,
-- CIMeta forwardedByMember, showGroupAsSender
@@ -1327,7 +1327,7 @@ Query:
i.chat_item_id, i.item_ts, i.item_sent, i.item_content, i.item_text, i.item_status, i.via_proxy, i.shared_msg_id,
i.item_deleted, i.item_deleted_ts, i.item_edited, i.created_at, i.updated_at,
i.fwd_from_tag, i.fwd_from_chat_name, i.fwd_from_msg_dir, i.fwd_from_contact_id, i.fwd_from_group_id, i.fwd_from_chat_item_id,
i.timed_ttl, i.timed_delete_at, i.item_live, i.user_mention, i.has_link,
i.timed_ttl, i.timed_delete_at, i.item_live, i.user_mention, i.has_link, i.msg_signed,
-- CIFile
f.file_id, f.file_name, f.file_size, f.file_path, f.file_crypto_key, f.file_crypto_nonce, f.ci_file_status, f.protocol,
-- DirectQuote
@@ -3224,7 +3224,7 @@ Query:
SELECT
t.delivery_task_id,
t.worker_scope, t.job_scope_spec_tag, t.job_scope_include_pending, t.job_scope_support_gm_id,
m.group_member_id, m.member_id, p.display_name, msg.broker_ts, msg.msg_body, t.message_from_channel
m.group_member_id, m.member_id, p.display_name, msg.broker_ts, msg.msg_body, msg.msg_chat_binding, msg.msg_signatures, t.message_from_channel
FROM delivery_tasks t
JOIN messages msg ON msg.message_id = t.message_id
JOIN group_members m ON m.group_member_id = t.sender_group_member_id
@@ -3664,7 +3664,7 @@ SEARCH m USING INDEX idx_group_members_user_id (user_id=?)
SEARCH p USING INTEGER PRIMARY KEY (rowid=?)
Query:
SELECT pgm.message_id, m.shared_msg_id, m.msg_body
SELECT pgm.message_id, m.shared_msg_id, m.msg_body, m.msg_chat_binding, m.msg_signatures
FROM pending_group_messages pgm
JOIN messages m USING (message_id)
WHERE pgm.group_member_id = ?
@@ -4464,12 +4464,12 @@ Query:
user_id, created_by_msg_id, contact_id, group_id, group_member_id, note_folder_id, group_scope_tag, group_scope_group_member_id,
-- meta
item_sent, item_ts, item_content, item_content_tag, item_text, item_status, msg_content_tag, shared_msg_id,
forwarded_by_group_member_id, include_in_history, created_at, updated_at, item_live, user_mention, has_link, show_group_as_sender, timed_ttl, timed_delete_at,
forwarded_by_group_member_id, include_in_history, created_at, updated_at, item_live, user_mention, has_link, show_group_as_sender, msg_signed, timed_ttl, timed_delete_at,
-- quote
quoted_shared_msg_id, quoted_sent_at, quoted_content, quoted_sent, quoted_member_id,
-- forwarded from
fwd_from_tag, fwd_from_chat_name, fwd_from_msg_dir, fwd_from_contact_id, fwd_from_group_id, fwd_from_chat_item_id
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
Plan:
@@ -5877,9 +5877,6 @@ SEARCH chat_items USING COVERING INDEX idx_chat_items_notes_created_at (user_id=
Query: CREATE TABLE temp_delete_members (contact_profile_id INTEGER, member_profile_id INTEGER, local_display_name TEXT)
Error: SQLite3 returned ErrorError while attempting to perform prepare "explain query plan CREATE TABLE temp_delete_members (contact_profile_id INTEGER, member_profile_id INTEGER, local_display_name TEXT)": table temp_delete_members already exists
Query: DELETE FROM app_settings
Plan:
Query: DELETE FROM calls WHERE user_id = ? AND contact_id = ?
Plan:
SEARCH calls USING INDEX idx_calls_contact_id (contact_id=?)
@@ -6300,9 +6297,6 @@ Plan:
Query: DROP TABLE temp_delete_members
Plan:
Query: INSERT INTO app_settings (app_settings) VALUES (?)
Plan:
Query: INSERT INTO chat_item_mentions (chat_item_id, group_id, member_id, display_name) VALUES (?, ?, ?, ?)
Plan:
@@ -404,7 +404,9 @@ CREATE TABLE messages(
shared_msg_id_user INTEGER,
author_group_member_id INTEGER REFERENCES group_members ON DELETE SET NULL,
forwarded_by_group_member_id INTEGER REFERENCES group_members ON DELETE SET NULL,
broker_ts TEXT
broker_ts TEXT,
msg_chat_binding TEXT,
msg_signatures BLOB
) STRICT;
CREATE TABLE pending_group_messages(
pending_group_message_id INTEGER PRIMARY KEY,
@@ -458,7 +460,8 @@ CREATE TABLE chat_items(
group_scope_tag TEXT,
group_scope_group_member_id INTEGER REFERENCES group_members(group_member_id) ON DELETE CASCADE,
show_group_as_sender INTEGER NOT NULL DEFAULT 0,
has_link INTEGER NOT NULL DEFAULT 0
has_link INTEGER NOT NULL DEFAULT 0,
msg_signed INTEGER NOT NULL DEFAULT 0
) STRICT;
CREATE TABLE sqlite_sequence(name,seq);
CREATE TABLE chat_item_messages(