Сбор

A swarm (group chat) is a set of participants capable of resilient, decentralized communication. For example, if two participants lose connectivity with the rest of the group (e.g., during an Internet outage) but can still reach each other over a LAN or subnetwork, they can exchange messages locally and then synchronize with the rest of the group once connectivity is restored.

A swarm is defined by the following properties:

  1. Ability to split and merge based on network connectivity.

  2. History synchronization. Every participant must be able to send a message to the entire group.

  3. Няма централен орган, не може да разчита на сървър.

  4. Non-repudiation. Devices must be able to verify past messages‘ validity and to replay the entire history.

  5. Perfect Forward Secrecy (PFS) is provided on the transport channels. Storage is handled by each device.

Основната идея е да се синхронизира дървото Меркл с участниците.

We identified four modes for swarms that we want to implement:

  • ONE_TO_ONE: A private conversation between two endpoints—either between two users or with yourself.

  • ADMIN_INVITES_ONLY: A swarm in which only the administrator can invite members (for example, a teacher-managed classroom).

  • INVITES_ONLY: A closed swarm that admits members strictly by invitation; no one may join without explicit approval.

  • PUBLIC: A public swarm that anyone can join without prior invitation (For example a forum).

Сценарии

Създавайте скоп

Боб иска да създаде нов рог.

  1. Bob creates a local Git repository.

  2. След това той създава първоначално подписано ангажимент с следното:

    • Публичният му ключ в /admins

    • Сертификат за устройството му в ̀ /устройства `

    • СНД му е в ̀ /crls`

  3. Хашият на първото ангажиране става идентификатор на разговора.

  4. Bob announces to his other devices that he created a new conversation. This is done via an invite to join the group sent through the DHT to other devices linked to that account.

Добавяне на някой

Bob adds Alice

  1. Bob adds Alice to the repo:

    • Добавя поканата URI в /invited

    • Добавя КРЛ до /crls

  2. Bob sends a request on the DHT.

Приемане на покана

Alice gets the invite to join the previously created swarm

  1. Alice accepts the invite (if she declines, nothing happens; she will remain in the „invited“ list, and will never receive any messages)

  2. A peer-to-peer connection is established between Alice and Bob.

  3. Alice pulls the Git repository from Bob. WARNING this means that messages require a connection, not from the DHT as it is today.

  4. Alice validates the commits from Bob.

  5. To validate that Alice is a member, she removes the invite from /invited directory, then adds her certificate to the /members directory

  6. Once all commits are validated and syncronized to her device, Alice discovers other members of the group. with these peers, she will then construct the DRT with Bob as a bootstrap.

Изпращане на съобщение

Alice sends a message to Bob

  1. Alice creates a commit message. She constructs a JSON payload containing the MIME type and message body. For example:

{
    "type": "text/plain",
    "body": "hello"
}
  1. Alice ensure her device credentials are present. If Alice’s device certificate or its associated CRL isn’t already stored in the repository, she adds them so that other participants can verify the commit.

  2. Alice commits to the repository (Because Jami relies primarily on commit-message metadata rather than file contents, merge conflicts are rare; the only potential conflicts would involve CRLs or certificates, which are versioned in a dedicated location).

  3. Alice announces the commit via the DRT with a service message and pings the DHT for mobile devices (they must receive a push notification).

Note

To notify other devices, the sender transmits a SIP message with type: application/im-gitmessage-id. The JSON payload includes the deviceId (the sender’s), the conversationId and the reference (hash) of the new commit.

Приемане на съобщение

Bob receives a message from Alice

  1. Bob performs a Git pull on Alice’s repository.

  2. All incoming commits MUST be verified by a hook.

  3. If all commits are valid, commits are stored and displayed.Bob then announces the message via the DRT for other devices.

  4. If any commit is invalid, pull is aborted. Alice must restore her repository to a correct state before retrying.

Валидиране на ангажимент

За да се избегне използването на нежелани ангажименти (с конфликти, фалшиви съобщения и т.н.), всеки ангажимент (от най-стария до най-новия) трябва да бъде валидиран преди сливането на дистанционна клонка:

Note

  1. If the validation fails, the fetch is ignored and we do not merge the branch (and remove the data), and the user should be notified.

  2. If a fetch is too big, it’s not merged.

  • For each incoming commit, ensure that the sending device is currently authorized and that the issuer’s certificate exists under /members or /admins, and the device’s certificate under /devices.

  • Then handle one of three cases, based on the commit’s parent count:

    • Merge Commit (2 parents). No further validation is required, merges are always accepted.

    • Initial Commit (0 parents). Validate that this is the very first repository snapshot:

      • Admin certificate is added.

      • Device certificate is added.

      • CRLs (Certificate Revocation Lists) are added.

      • No other files are present.

    • Ordinary Commit (1 parent). The commit message must be JSON with a top‑level type field. Handle each type as follows:

      • If text (or any non–file‑modifying MIME type)

        • Signature is valid against the author’s certificate in the repo.

        • No unexpected files are added or removed.

      • If vote

        • voteType is one of the supported values (e.g. „ban“, „unban“).

        • The vote matches the signing user.

        • The signer is an admin, their device is present, and not themselves banned.

        • No unexpected files are added or removed.

      • If member

        • If adds

          • Properly signed by the inviter.

          • New member’s URI appears under /invited.

          • No unexpected files are added or removed.

          • If ONE_TO_ONE, ensure exactly one admin and one member.

          • If ADMIN_INVITES_ONLY, the inviter must be an admin.

        • If joins

          • Properly signed by the joining device.

          • Device certificate added under /devices.

          • Corresponding invite removed from /invited and certificate added to /members.

          • No unexpected files are added or removed.

        • If banned

          • Vote is valid per the vote rules above.

          • Ban is issued by an admin.

          • Target’s certificate moved to /banned.

          • Only files related to the ban vote are removed.

          • No unexpected files are added or removed.

      • Fallback. If the commit’s type or structure is unrecognized, reject it and notify the peer (or user) that they may be running an outdated version or attempting unauthorized changes.

Забране на устройството

Important

Jami source code tends to use the terms (un)ban, while the user interface uses the terms (un)block.

Alice, Bob, Carla, Denys are in a swarm. Alice issues a ban against Denys.

In a fully peer‑to‑peer system with no central authority, this simple action exposes three core challenges:

  1. Untrusted Timestamps: Commit timestamps cannot be relied upon for ordering ban events, as any device can forge or replay commits with arbitrary dates.

  2. Conflicting bans: In cases where multiple admin devices exist, network partitions can result in conflicting ban decisions. For instance, if Alice can communicate with Bob but not with Denys and Carla, while Carla can communicate with Denys, conflicting bans may occur. If Denys bans Alice while Alice bans Denys, the group’s state becomes unclear when all members eventually reconnect and merge their conversation histories.

  3. Compromised or expired devices: Devices can be compromised, stolen, or have their certificates expire. The system must allow banning such devices and ensure they cannot manipulate their certificate or commit timestamps to send unauthorized messages or falsify their expiration status.

Подобни системи (с разпределени групи) не са толкова много, но това са някои примери:

  • [mpOTR не определя как да забраняваш някого]

  • Сигналът, без централен сървър за групови чатове (EDIT: те наскоро променят тази точка), не дава възможност да забрани някой от група.

This voting system needs a human action to ban someone or must be based on the CRLs info from the repository (because we can not trust external CRLs).

Извадете устройството от разговора

Това е единствената част, която трябва да има консенсус, за да избегне разпадане на разговора, като ако двама членове се изритат един друг от разговора, какво ще види третата?

Това е необходимо, за да се открият оттеглените устройства или просто да се избегне присъствието на нежелани хора в обществена зала.

Алис премахва Боб

Important

Alice MUST be an admin to vote.

  • Първо, тя гласува за забрана на Боб. За да направи това, тя създава файла в /votes/ban/members/uri_bob/uri_alice (членките могат да бъдат заменени с устройства за устройство, или покани за покани или администратори за администратори) и ангажира

  • След това тя проверява дали гласуването е решено. Това означава, че >50% от администраторите са съгласни да забранят Боб (ако е сама, то е сигурно, че е повече от 50%).

  • Ако гласуването е разрешено, файловете в /votes/ban могат да бъдат премахнати, всички файлове за Боб в /members, /admins, /invited, /CRLs, /devices могат да бъдат премахнати (или само в /devices, ако е устройство, което е забранено) и сертификатът на Боб може да бъде поставен в /banned/members/bob_uri.crt (или /banned/devices/uri.crt, ако е забранено устройство) и да се ангажира с repo

  • След това Алис информира другите потребители (извън Боб)

Alice (admin) re-adds Bob (banned member)

  • If she votes for unbanning Bob. To do that, she creates the file in /votes/unban/members/uri_bob/uri_alice (members can be replaced by devices for a device, or invited for invites or admins for admins) and commits

  • След това тя проверява дали гласуването е решено. Това означава, че >50% от администраторите са съгласни да забранят Боб (ако е сама, то е сигурно, че е повече от 50%).

  • Ако гласуването е разрешено, файловете в /votes/unban могат да бъдат премахнати, всички файлове за Боб в /members, /admins, /invited, /CRLs, могат да бъдат добавени отново (или само в /devices, ако е устройство, което е забранено) и да се ангажират с repo

Изтрий разговора

  1. Запазвайте в convInfos removed=time::now() (като премахванеКонтакт запазва в контактите) че разговора е премахнат и синхронизиран с устройствата на други потребители

  2. Ако получим нов ангажимент за този разговор, ще го игнорираме.

  3. Ако Джами стартира и репото е все още налице, разговорът не е обявен на клиентите.

  4. Two cases: a. If no other member in the conversation we can immediately remove the repository b. If still other members, commit that we leave the conversation, and now wait that at least another device sync this message. This avoids the fact that other members will still detect the user as a valid member and still sends new message notifications.

  5. Когато сме сигурни, че някой е синхронизиран, премахнете изтрито=времето::сега() и синхронизирайте с устройствата на други потребители

  6. Всички устройства, собственост на потребителя, могат да изтрият архива и свързаните с него файлове.

Как да се посочи режим

Модовете не могат да бъдат променени с времето. Или това е друг разговор. Така че, тези данни се съхраняват в първоначалното съобщение за ангажиране.

{
    "type": "initial",
    "mode": 0,
}

Засега „mode“ приема стойности 0 (ONE_TO_ONE), 1 (ADMIN_INVITES_ONLY), 2 (INVITES_ONLY), 3 (PUBLIC)

Processes for 1:1 chats

The goal here is to keep the old API (addContact/removeContact, sendTrustRequest/acceptTrustRequest/discardTrustRequest) to create a chat with a peer and its contact. This still implies some changes that we cannot ignore:

Процесът е все още същият, акаунтът може да добавя контакт чрез addContact, след което да изпрати TrustRequest чрез DHT. Но са необходими две промени:

  1. TrustRequest вгражда „conversationId“, за да информира връстника кой разговор да клонира при приемане на искането

  2. TrustRequest се изпробва отново, когато контактът се върне в интернет. Това не е така днес (както не искаме да генерираме нов TrustRequest, ако връстникът отхвърли първия). Така че, ако акаунт получава искане за доверие, то автоматично ще бъде игнориран, ако искането с свързан разговор е отхвърлено (като convRequests се синхронизират)

След това, когато контактът прие искането, е необходим период на синхронизация, защото контактът сега трябва да клонира разговора.

removeContact() ще премахне контакта и свързаните с него разговори 1:1 (с същия процес като „Рамъквайте разговор“). Единствената бележка тук е, че ако забраним контакт, не чакаме синхронизация, просто премахваме всички свързани файлове.

Трудни сценарии

Има някои случаи, в които може да се създадат две разговори.

  1. Alice adds Bob.

  2. Bob accepts.

  3. Alice removes Bob.

  4. Alice adds Bob.

или

  1. Alice adds Bob and Bob adds Alice at the same time, but both are not connected together.

In this case, two conversations are generated. We don’t want to remove messages from users or choose one conversation here. So, sometimes two conversations between the same members will be shown. It will generate some bugs during the transition time (as we don’t want to break API, the inferred conversation will be one of the two shown conversations, but for now it’s „ok-ish“, will be fixed when clients will fully handle conversationId for all APIs (calls, file transfer, etc)).

Important

After accepting a conversation’s request, there is a time the daemon needs to retrieve the distant repository. During this time, clients MUST show a syncing view to give informations to the user. While syncing:

  • ConfigurationManager::getConversations() will return the conversation’s id even while syncing.

  • ConfigurationManager::conversationInfos() ще върне {{„синхронизиране“: „true“}} при синхронизиране.

  • ConfigurationManager::getConversationMembers() will return a map of two URIs (the current account and the peer who sent the request).

Разговорите изискват спецификация

Заявленията за разговори са представени с Map<String, String> с следните клавиши:

  • id: the conversation ID

  • from: URI of the sender

  • Приети: часови печат

  • заглавие: (необязателно) име на разговора

  • Описание: (необязателно)

  • avatar: (optional) the profile picture

Синхронизация на профила на разговора

За да бъде идентифицирана, разговорът обикновено се нуждае от някои метаданни, като заглавие (напр. Jami), описание (напр. някои връзки, какъв е проектът и т.н.), и изображение (логото на проекта). Тези метаданни са неправомерни, но се споделят между всички членове, така че трябва да бъдат синхронизирани и включени в заявките.

Съхранение в хранилището

Профилът на разговора се съхранява в класически файл vCard в корен (/profile.vcf) като:

BEGIN:VCARD
VERSION:2.1
FN:TITLE
DESCRIPTION:DESC
END:VCARD

Синхронизация

To update the vCard, a user with enough permissions (by default: =ADMIN) needs to edit /profile.vcf and will commit the file with the mimetype application/update-profile. The new message is sent via the same mechanism and all peers will receive the MessageReceived signal from the daemon. The branch is dropped if the commit contains other files or too big or if done by a non-authorized member (by default: <ADMIN).

Последният показ

В синхронизираните данни всяко устройство изпраща на други устройства състоянието на разговорите. В това състояние се изпраща последното, което се показва.

Подкрепя се 5 сценария:

  • Ако последната показвана от други устройства е същата като настоящата, няма какво да се направи.

  • ако за текущото устройство не е излъчено последно съобщение, се използва излъчването на дистанционно съобщение.

  • Ако последният разстояние показан не е наличен в репото, това означава, че ще бъде взето по-късно, така че да запазите резултата

  • Ако дистанционното устройство вече е извлечено, ние проверяваме дали последният локален показано е преди в историята, за да го замени

  • И накрая, ако се обяви съобщение от същия автор, това означава, че трябва да актуализираме последния, който е бил показан.

Преференции

Всеки разговор има прикрепен преференции, определени от потребителя. Тези преференции се синхронизират между устройствата на потребителя. Това може да бъде цветът на разговора, ако потребителят иска да игнорира уведомленията, ограничаване на размера на файловия трансфер и т.н. Засега признатите ключове са:

  • „color“ - the color of the conversation (#RRGGBB format)

  • „неубеди уведомленията“ - да игнорирате уведомленията за нови съобщения в този разговор

  • „символ“ - да се дефинира дефолт емоджи.

Тези предпочитания се съхраняват в пакет MapStringString, съхраняван в accountDir/conversation_data/conversationId/preferences и се изпращат само между устройствата на един и същи потребител чрез SyncMsg.

API за взаимодействие с предпочитанията са:

// Update preferences
void setConversationPreferences(const std::string& accountId,
                                const std::string& conversationId,
                                const std::map<std::string, std::string>& prefs);
// Retrieve preferences
std::map<std::string, std::string> getConversationPreferences(const std::string& accountId,
                                                              const std::string& conversationId);
// Emitted when preferences are updated (via setConversationPreferences or by syncing with other devices)
struct ConversationPreferencesUpdated
{
    constexpr static const char* name = "ConversationPreferencesUpdated";
    using cb_type = void(const std::string& /*accountId*/,
                            const std::string& /*conversationId*/,
                            std::map<std::string, std::string> /*preferences*/);
};

Управление на конфликтите с сливане

Тъй като два администратора могат да променят описанието едновременно, може да възникне конфликт на сливане на profile.vcf. В този случай ще бъде избран commit с по-висок хаш (например ffffff > 000000).

АПИ

Потребителят има 2 начина да получи и зададе метаданните на разговора:

       <method name="updateConversationInfos" tp:name-for-bindings="updateConversationInfos">
           <tp:added version="10.0.0"/>
           <tp:docstring>
               Update conversation's infos (supported keys: title, description, avatar)
           </tp:docstring>
           <arg type="s" name="accountId" direction="in"/>
           <arg type="s" name="conversationId" direction="in"/>
           <annotation name="org.qtproject.QtDBus.QtTypeName.In2" value="VectorMapStringString"/>
           <arg type="a{ss}" name="infos" direction="in"/>
       </method>

       <method name="conversationInfos" tp:name-for-bindings="conversationInfos">
           <tp:added version="10.0.0"/>
           <tp:docstring>
               Get conversation's infos (mode, title, description, avatar)
           </tp:docstring>
           <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorMapStringString"/>
           <arg type="a{ss}" name="infos" direction="out"/>
           <arg type="s" name="accountId" direction="in"/>
           <arg type="s" name="conversationId" direction="in"/>
       </method>

където инфо е карта<str, str> с следните клавиши:

  • режим: само за четене

  • заглавие

  • Описание

  • avatar: the profile picture

Използвани протоколи

Git

Защо този избор

Each conversation will be a Git repository. This choice is motivated by:

  1. Трябва да синхронизираме и нареждаме съобщения. Дървото на Меркел е идеалната структура за това и може да бъде линеализирано чрез сливане на клонове. Освен това, тъй като е масово използвано от Git, е лесно да се синхронизира между устройствата.

  2. Разпространяван от природата, широко използван, много задвижвания и включващ се.

  3. Може да провери ангажименти чрез хакове и широко използвани крипто

  4. Може да бъде съхраняван в база данни, ако е необходимо

  5. Избягват се конфликтите чрез използване на съобщения, а не файлове.

Какво трябва да потвърдим

  • Изпълнение? git.lock може да бъде ниско

  • Крак в libgit2

  • Многократни стрелби едновременно?

Ограничения

За да изтриете разговор, устройството трябва да напусне разговора и да създаде друг.

Въпреки това нестоянните съобщения (като съобщения, които могат да бъдат четени само за няколко минути) могат да бъдат изпращани чрез специално съобщение чрез DRT (като уведомления за вписване или четене).

Структура

/
 - invited
 - admins (public keys)
 - members (public keys)
 - devices (certificates of authors to verify commits)
 - banned
   - devices
   - invited
   - admins
   - members
 - votes
    - ban
        - members
            - uri
                - uriAdmin
        - devices
            - uri
                - uriAdmin
    - unban
        - members
            - uri
                - uriAdmin
 - CRLs

Прехвърляне на файлове

This new system overhauls file sharing: the entire history is now kept in sync, so any device in the conversation can instantly access past files. Rather than forcing the sender to push files directly—an approach that was fragile in the face of connection drops and often required manual retries—devices simply download files when they need them. Moreover, once one device has downloaded a file, it can act as a host for others, ensuring files remain available even if the original sender goes offline.

Протокол

Изпращачът добавя нов ангажимент в разговора с следния формат:

value["tid"] = "RANDOMID";
value["displayName"] = "DISPLAYNAME";
value["totalSize"] = "SIZE OF THE FILE";
value["sha3sum"] = "SHA3SUM OF THE FILE";
value["type"] = "application/data-transfer+json";

и създава връзка в ${data_path}/conversation_data/${conversation_id}/${file_id}, където file_id=${commitid}_${value["tid"]}.${extension}

След това получателят може да изтегли файловете, като се свърже с устройствата, които хостват файла, като отвори канал с name="data-transfer://" + conversationId + "/" + currentDeviceId() + "/" + fileId и да съхранява информацията, че файлът чака в ${data_path}/conversation_data/${conversation_id}/waiting

Устройството, получаващо връзката, ще приеме канала, като провери дали файлът може да бъде изпратен (ако sha3sum е верен и ако файлът съществува). Приемникът ще запази първия отворен канал, ще затвори останалите и ще запише в файл (с същия път като изпращача: ${data_path}/conversation_data/${conversation_id}/${file_id}) всички входящи данни.

Когато прехвърлянето е приключено или каналът е затворен, sha3sum се проверява, за да се потвърди, че файлът е правилният (или е изтрит).

В случай на провал, когато устройството на разговора се върне в интернет, ще поискаме всички файлове, които чакат по същия начин.

Call in Swarm

Идеята

A swarm conversation can have multiple rendez-vous. A rendez-vous is defined by the following URI:

„accountUri/deviceId/conversationId/confId“ където accountUri/deviceId описва хоста.

Хостингът може да бъде определен по два начина:

  • In the swarm metadatas. Where it’s stored like the title/desc/avatar (profile picture) of the room

  • Или първоначалното обаждане.

When starting a call, the host will add a new commit to the repository, with the URI to join (accountUri/deviceId/conversationId/confId). This will be valid till the end of the call (announced by a commit with the duration to show)

Така че всяка част ще получи информацията, че обаждането е започнало и ще може да се присъедини към него, като го обади.

Нападения?

  • Avoid Git bombs

Записки

Временният печат на ангажимент може да бъде доверен, защото е редактируем. Само времето на потребителя може да бъде доверено.

TLS

Операциите на Git, съобщенията за управление, файловете и други неща ще използват връзка P2P TLS v1.3 с само шифри, които гарантират PFS.

DHT (UDP)

Използва се за изпращане на съобщения за мобилни устройства (за да се активират уведомленията за натискане) и за иницииране на TCP връзки.

Мрежова дейност

Процес за покана на някого

Алис иска да покани Боб:

  1. Алис добавя Боб към разговора.

  2. Alice generates an invite: { „application/invite+json“ : { „conversationId“: „$id“, „members“: [{…}] }}

  3. Две възможности за изпращане на съобщението a. Ако не е свързано, чрез DHT b. Иначе, Алис изпраща по SIP канал

  4. Две възможности за Боб a. Приема поканата, сигнал се излъчва за клиента b. Не е свързан, така че никога няма да получи искането, защото Алис не трябва да знае дали Боб просто игнорира или блокира Алис. Единственият начин е да регенерират ново покана чрез ново съобщение (вж. следващия сценарий)

Процес за изпращане на съобщение на някого

Алис иска да изпрати съобщение на Боб:

  1. Алис добавя съобщение в репото, даващо самоличност

  2. Алис получава съобщение (от себе си) ако успее

  3. В двата случая се създава съобщение: { „приложение/im-gitmessage-id“ : „{„id“:“\(convId", "commit":"\)commitId“, „deviceId“: „$alice_device_hash“}“}.

  4. Четири възможности за Боб: а. Боб не е свързан с Алиса, така че ако вярва на Алиса, попитайте за ново свързване и отидете на b. b. Ако е свързан, вземете от Алис и обявите нови съобщения c. Боб не знае този разговор. Попитайте чрез DHT да получите покана първо, за да можете да приемете този разговор ({„приложение/ покана“, разговорId}) d. Боб е отключен (без мрежа или просто затворен). Той няма да получи новия съобщение, но ще се опита да синхронизира, когато следващото свързване ще се случи

Изпълнение

! Diagram: класове за чат в сварка

Supported messages

Initial message

{
    "type": "initial",
    "mode": 0,
    "invited": "URI"
}

Represents the first commit of a repository and contains the mode:

enum class ConversationMode : int { ONE_TO_ONE = 0, ADMIN_INVITES_ONLY, INVITES_ONLY, PUBLIC }

and invited if mode = 0.

Text message

{
    "type": "text/plain",
    "body": "content",
    "react-to": "id (optional)"
}

Or for an edition:

{
    "type": "application/edited-message",
    "body": "content",
    "edit": "id of the edited commit"
}

Обаждания

Show the end of a call (duration in milliseconds):

{
    "type": "application/call-history+json",
    "to": "URI",
    "duration": "3000"
}

Or for hosting a call in a group (when it starts)

{
    "type": "application/call-history+json",
    "uri": "host URI",
    "device": "device of the host",
    "confId": "hosted confId"
}

A second commit with the same JSON + duration is added at the end of the call when hosted.

Add a file

{
    "type": "application/data-transfer+json",
    "tid": "unique identifier of the file",
    "displayName": "File name",
    "totalSize": "3000",
    "sha3sum": "a sha3 sum"
}

totalSize is in bits,

Updating profile

{
    "type": "application/update-profile",
}

Member event

{
    "type": "member",
    "uri": "member URI",
    "action": "add/join/remove/ban"
}

When a member is invited, join or leave or is kicked from a conversation

Vote event

Generated by administrators to add a vote for kicking or un-kicking someone.

{
    "type": "vote",
    "uri": "member URI",
    "action": "ban/unban"
}

!! Старият проект!!

Note

Following notes are not organized yet. Just some line of thoughts.

Крипто подобрения.

За сериозен групен чат, ние също така имаме нужда от сериозни крипто.С настоящия дизайн, ако сертификатът е откраднат като предишните стойности на DHT на разговора, разговора може да бъде дешифриран.

Note

A lib might exist to implement group conversations.

Нуждае се от подкрепа на ECC в OpenDHT

Използване

Добавяме ли роли?

Има два основни случая за използване на групови разговори:

  1. Нещо като Mattermost в компания, с частни канали, и някои роли (админ/спектър/бот/т.н.) или за образование (където само няколко са активни).

  2. Хоризонталните разговори са като разговорите между приятели.

Jami will be for which one?

Идея за изпълнение

Сертификат за група, която подписва потребител с флаг за роля.

Присъединете се към разговор.

  • Само чрез пряко покана

  • Чрез връзка/КР код/ каквото и да е

  • Via a room name? (a hash on the DHT)

Какво ни трябва?

  • Конфиденциалност: членовете извън групата не трябва да могат да четат съобщенията в групата

  • Предоставяне на тайна: ако е компрометиран ключ от групата, предишните съобщения трябва да останат поверителни (по-голяма от възможността)

  • Поръчане на съобщения: Необходимо е съобщенията да са в правилния ред

  • Синхронизация: Също така е необходимо да се уверите, че всички съобщения са налице възможно най-скоро.

  • Продължителност: Всъщност съобщение на DHT живее само 10 минути. Защото това е най-доброто време, изчислено за този вид DHT. За да се запазят данни, възелът трябва да поставя отново стойността на DHT на всеки 10 минути. Друг начин да се направи, когато възелът е офлайн, е да позволите на възелите да поставят отново данните. Но, ако след 10 минути, 8 възела са все още тук, те ще направят 64 заявки (и това е експоненциално).

Други разпределени начини

  • Трябва да проведем разследване.

  • Трябва да разследваме.

  • Трябва да проверим малко разследване.

Въз основа на текущата работа, която имаме

Групичният разговор може да се основава на същата работа, която вече имаме за много устройства (но тук, с групичен сертификат).

  1. Това трябва да премести базата данни от клиента в демона.

  2. Ако никой не е свързан, синхронизацията не може да се направи, и човекът никога няма да види разговора

Още един DHT

Като DHT с супер потребител.

Прехвърляне на файлове

В момента алгоритъмът за прехвърляне на файлове се основава на връзка TURN (вж. Прехвърляне на файлове). В случай на голяма група, това ще бъде лошо. Първо се нуждаем от p2p инсталация за прехвърляне на файлове.

Other problem: currently there is no implementation for TCP support for ICE in PJSIP. This is mandatory for this point (in PJSIP or homemade)

Ресурси

  • https://eprint.iacr.org/2017/666.pdf

  • Устойчива разпределена синхронизация на мрежови линеални системи с интермитираща информация (Сен Филипс и Рикардо Г.Санфелис)