From 66f004f725a16900997db0ff39f6accf528a9e0d Mon Sep 17 00:00:00 2001 From: evgeny Date: Wed, 21 Oct 2026 15:52:45 +0200 Subject: [PATCH] docs: describe actual DM identity derivation and crypto modules --- doc/dm_arch.md | 10 ++++++++-- src/dm/dm_crypto.h | 13 +++++++------ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/doc/dm_arch.md b/doc/dm_arch.md index 890d7b2d..df566674 100644 --- a/doc/dm_arch.md +++ b/doc/dm_arch.md @@ -19,12 +19,17 @@ ## Идентичность и шифрование ```text -conv_id = SHA256("utun_dm_v1" || min(node_a,node_b) || max(node_a,node_b))[..63] +conv_hash = SHA256("utun_dm_v" || min(node_a,node_b) || max(node_a,node_b)) +conv_id = native_u64(conv_hash[0:8]) & 0x7FFFFFFFFFFFFFFF content_key = SHA256(X25519(my_private, target_public) || "utun_dm_content") msg_nonce = SHA256(conv_id || author || seq)[..13] media_nonce = SHA256("utun_dm_media" || author || media_id || part)[..13] ``` +Префикс conv_hash — 9 ASCII-байт без NUL. ID узлов подаются в хеш в порядке +байтов хоста; native_u64 читает первые 8 байт хеша в том же порядке. +Нулевой conv_id заменяется на 1. + Сообщения и медиа используют один content_key target, без ключей отдельных файлов. AES-256-CCM: nonce 13 байт, tag 16 байт. Максимальная порция plaintext — 65535 байт; порция медиа — 32768 байт. UUID медиа новый для каждой подготовки. Повтор доставки @@ -62,7 +67,8 @@ tags, точный размер и хеш; владелец публикует - `dm_core`: беседы, история, outbox и подтверждение получателя. - `dm_mailbox`: промежуточные сообщения суперузла и квитанции. -- `dm_crypto`: вывод ключей, nonce, CCM и файловые примитивы без БД/сети. +- `dm_crypto`: вывод conv_id, content_key и nonce сообщений без БД/сети. +- `media_crypto`: общие CCM и потоковые файловые примитивы для DM и групповых вложений. - `dm_media`: файлы endpoint, загрузки и отдельная custody M. - `dm_mailbox_media`: durable задания S, выбор M и повтор удаления до DELETE_ACK. - `file_transfer`: подписанная передача байтов, backpressure и отдельный CM handle каждой операции. diff --git a/src/dm/dm_crypto.h b/src/dm/dm_crypto.h index 782c9328..e17159cb 100644 --- a/src/dm/dm_crypto.h +++ b/src/dm/dm_crypto.h @@ -1,10 +1,9 @@ /* * dm_crypto.h — криптография прямого чата (DM) * - * Детерминированная идентичность и E2E-шифрование: - * - conv_id / content_key выводятся обеими сторонами из своих ключей и - * pubkey пира (известен из общей группы) — без переговоров. - * - шифрование AES-256-CCM с детерминированным nonce из (dir, seq). + * conv_id выводится из ID двух узлов, content_key — из своего X25519-ключа и + * публичного ключа пира. Переговоров нет; nonce сообщения зависит от conv_id/author/seq. + * CCM и файловые примитивы предоставляет общий media_crypto.h. */ #ifndef DM_CRYPTO_H @@ -25,8 +24,10 @@ extern "C" { #define DM_CCM_PLAIN_MAX 65535u #define DM_MEDIA_PLAIN_SIZE 32768u -/* conv_id = SHA256("utun_dm_v1" || min(a,b) || max(a,b))[..8] & 0x7FFF..., - * 63-битное число, одинаковое на обеих сторонах (одна ветка на пару). */ +/* conv_id: SHA256("utun_dm_v" || min(a,b) || max(a,b)), префикс — 9 ASCII-байт без NUL. + * ID узлов хешируются в порядке байтов хоста; первые 8 байт SHA256 читаются как uint64_t того же порядка. + * Снимается старший бит (маска 0x7FFFFFFFFFFFFFFF), нулевой результат заменяется на 1. + * Положительное 63-битное число, одинаковое для обоих направлений пары узлов. */ uint64_t dm_derive_conv_id(uint64_t a, uint64_t b); /* content_key = SHA256(X25519(my_priv, peer_pub) || "utun_dm_content").