Регистрация и аккаунт

Почему не нужны логин и пароль?

Во время регистрации приложение получает от сервера небольшую криптографическую задачу (Proof of Work) и решает её — это защита от автоматической регистрации ботами. Параллельно генерируются уникальные идентификаторы устройства и несколько наборов ключей шифрования: долгосрочные ключи идентичности, подписанные предварительные ключи и одноразовые предварительные ключи (включая постквантовые ML-KEM-1024). На сервер уходят только публичные части этих ключей и результат PoW-задачи. Приватные ключи никогда не покидают устройство. Пароля нет: аккаунт определяют ключи, а вернуть доступ к нему на новом устройстве можно ключом восстановления из 12 слов.

Можно ли выйти из аккаунта и войти заново?

Да, с ключом восстановления из 12 слов: на новом устройстве или после переустановки выберите «Восстановить» и введите слова. Вернётся аккаунт и его адрес; старые сообщения и сессии остаются на прежнем устройстве и не переносятся. Без этих слов потеря устройства или удаление приложения означает потерю аккаунта навсегда.

Как не потерять аккаунт при смене телефона?

Ключ восстановления создаётся сам при регистрации — ничего делать не нужно. Сохранить его копию (12 слов) можно позже, в Настройках: приложение напомнит, а до выхода из аккаунта попросит обязательно. Пока копия не сделана, слова хранятся на устройстве зашифрованными и открываются только после Face ID, отпечатка или кода телефона; после копии они с устройства стираются. Запишите их и храните в надёжном месте — у Konstruct нет вашего телефона и почты, это единственный способ вернуть аккаунт.

Контакты

Как написать кому-то?

Система устроена так, что незнакомый человек не может просто начать вам писать. Чтобы начать разговор, один делится QR-кодом или инвайт-ссылкой, а другой сканирует её или переходит по ней. Они одноразовые: QR-код живёт пять минут, ссылка — двенадцать часов, — принятую однажды ссылку использовать повторно нельзя. Отдельно вы можете включить в настройках обнаружение и стать находимым по имени пользователя; по умолчанию оно выключено, так что пока вы его не включили, инвайт — единственный путь.

Зачем такое ограничение? Это же неудобно.

Это намеренное решение. В большинстве мессенджеров достаточно знать номер телефона или никнейм, чтобы начать засыпать человека сообщениями. Здесь взаимное согласие зашито в архитектуру, а не просто задекларировано в политике.

Что будет, если кто-то поделится моим QR-кодом без моего ведома?

Код принимается только один раз, поэтому по разошедшейся ссылке сможет добавиться не больше одного человека, а уже использованная ссылка не сделает ничего. Кроме того, ссылка перестаёт действовать через двенадцать часов после создания, а QR-код — через пять минут. Если кто-то всё же добавился, вы увидите новый разговор и сможете сразу его заблокировать.

Шифрование и приватность

Как работает шифрование?

Все сообщения шифруются на устройстве отправителя перед отправкой и расшифровываются только на устройстве получателя. Сервер видит лишь зашифрованный поток и маршрутизирует его — прочитать содержимое он не может. Для установки сессии используется X3DH, расширенный постквантовым согласованием ключей (PQXDH): отправитель инкапсулирует секрет ML-KEM-1024 в Kyber-предключ получателя, и этот секрет входит в исходный ключ сессии вместе с классическими — именно это ограничивает сценарий «записать сейчас, расшифровать квантовым компьютером потом». Постквантовая защита действует с первого сообщения, а сессию без неё приложение не установит. Дальше работает Double Ratchet, меняющий ключи с каждым сообщением, — и у каждого сообщения есть ещё и свой постквантовый ключ, — так что компрометация одного ключа не раскрывает ни прошлых, ни будущих сообщений. Кто отправил сообщение, тоже скрыто постквантово; звонки защищены постквантовым DTLS, когда его поддерживают оба приложения. Пока классические: подписи сервера (сертификаты отправителя, журнал прозрачности ключей), вход устройства и восстановление аккаунта, токены Privacy Pass и транспортный TLS; групп пока нет; полный список — в спецификации протокола.

Что именно видит сервер?

Очень мало, и ничто из этого — вы. Чтобы доставить сообщение, серверу нужны непрозрачный идентификатор аккаунта получателя, размер шифротекста и время получения; ещё он хранит ваши публичные ключи и, на iOS, push-токен. Это весь список. Он не видит ни содержимого, ни вашего имени, ни аватара, ни списка контактов — и, на постоянно включённом пути защиты отправителя, не видит, кто отправил сообщение. Сообщения лежат у сервера только зашифрованными и удаляются по сроку хранения (около 7 дней), а не в момент доставки. Имя пользователя необязательно, в маршрутизации не участвует и хранится только ключевым хешем ради одной задачи — чтобы вас могли найти; сам поиск выключен, пока вы не включите обнаружение, так что по умолчанию аккаунт нельзя найти по имени вообще.

А метаданные? Кто с кем общается?

Это более трудная часть. Сервер всё ещё видит, что кто-то доставил шифротекст устройству B (получатель, время, размер). При постоянно включённой защите отправителя он не узнаёт, кто именно написал, — см. следующий вопрос. Защита от блокировок частично скрывает сетевой путь. Полная анонимность на уровне маршрутизации (спрятаться и от получателя, и от корреляции по IP и таймингам) — задача другого порядка, и сегодня она не решена.

Знает ли сервер, кто отправил сообщение?

Нет — поле отправителя не кладётся в конверт, и это всегда включено для обычного трафика (сообщения, квитанции о доставке, установка звонка, обмен профилями). Переключателя, который можно забыть, нет. Ваше устройство запечатывает подписанный сертификат отправителя на ключ получателя: получатель может его открыть и проверить, кто написал, а сервер — нет. Несколько внутренних путей — поддержание соединения, синхронизация ваших собственных устройств, служебные сообщения сессии — по замыслу по-прежнему несут отправителя.

Стоит уточнить, что именно скрывается, потому что это не личность. Её у сервера никогда и не было: аккаунт здесь — это пара ключей и непрозрачный идентификатор, без номера телефона, почты и настоящего имени, так что сопоставлять с человеком изначально нечего. Защита отправителя убирает последнюю связь между двумя такими идентификаторами — кто кому написал. Сетевой уровень — отдельный разговор, он выше: время и IP остаются видимыми, и именно там работает наблюдатель с ресурсами.

Ограничения: Защита отправителя скрывает его личность от сервера, но не время, размер или IP — это видно на сетевом/транспортном уровне. Токены Privacy Pass могут идти вместе с sealed-отправкой для анти-спама; server-side enforcement ещё раскатывается — rate-control на токенах пока дорабатывается и не завершён.

Вы собираете аналитику или телеметрию?

Нет — вообще. Никакой аналитики, метрик использования, поведенческих событий, отправки крашей, рекламных идентификаторов. Не «собрано и обезличено» — не собрано вовсе. В приложении нет сторонних трекеров (ни Firebase, ни Crashlytics, ни Sentry, ни Amplitude, ни Segment); единственные внешние зависимости — транспорт/медиа и на iOS — локальная библиотека распознавания речи. Релизные сборки к тому же не пишут диагностических логов на диск и не дают экрана дебага или экспорта логов. Когда нам нужны логи для починки бага, их отправляете вы кнопкой «поделиться» в бета-сборке — никакой тихой отправки.

Профиль

Зачем нужен Display Name?

Ваше отображаемое имя и аватар живут на устройстве; они не часть публичного профиля, и найти их никто не может. Когда вы начинаете новый разговор, собеседник видит только сгенерированный псевдоним — детерминированный, для данного ID всегда один и тот же. Чтобы показать настоящее имя и фото, откройте профиль собеседника и включите «Поделиться моим профилем»: и то, и другое пойдёт по зашифрованному каналу. Одно исключение: при отправке запроса в контакты к нему прикладываются ваше имя пользователя и отображаемое имя, чтобы получатель понимал, кто просит. Сервер хранит этот снимок зашифрованным, но под собственным ключом — это не сквозное шифрование; аватар в снимок не входит никогда.

Почему сгенерированное имя, а не просто пустое?

Пустое имя неудобно: в списке чатов вы видели бы безликие строки и не могли бы отличить один контакт от другого. Сгенерированное имя стабильно — «Быстрый Сокол» всегда будет «Быстрым Соколом» для этого ID, на любом устройстве.

Если у пользователя задан username, я его вижу?

Да. Приоритет отображения: Display Name (если поделился) → username → сгенерированное имя. Если человек зарегистрировался с username @john, вы увидите именно его, а не «Мирный Кит».

Сообщения

Что означают статусы у сообщений?
  • Отправляется шифруется на вашем устройстве
  • Отправлено ушло с устройства, сервер его принял
  • Доставлено устройство получателя расшифровало его и прислало подтверждение
  • В очереди ещё не ушло — приложение продолжает попытки само; нажмите, если не хотите ждать
  • Не отправлено отклонено по причине, которую повтор не исправит, поэтому само ничего не произойдёт; нажмите, чтобы попробовать снова

Статуса «прочитано» нет, и это сделано намеренно: отметка о прочтении сообщила бы отправителю, когда вы открыли приложение, — факт о вас, который сообщению не нужен. «Доставлено» — это зашифрованная квитанция от устройства получателя, а не сообщение сервера о том, что он что-то переслал.

Можно ли редактировать отправленные сообщения?

Да, редактирование поддерживается. После изменения у сообщения появляется пометка «изменено». Редактирование распространяется на устройство получателя через тот же механизм доставки, что и обычные сообщения.

Почему иногда не приходят уведомления, когда приложение закрыто?

На iOS уведомления приходят через Apple Push Notification Service (APNs): нужен стабильный интернет, и если телефон в авиарежиме, за VPN с агрессивной фильтрацией или Apple сочла пуш «низкоприоритетным», уведомление может задержаться или не прийти. На Android push-сервисов нет вообще: приложение держит собственное соединение, о чём говорит постоянное уведомление; агрессивная экономия батареи или заблокированная сеть могут задержать сообщения. Когда приложение снова откроется, сообщения подтянутся автоматически.

Защита от блокировок

Работает ли Konstruct там, где мессенджеры блокируют?

В приложении есть режим защиты от блокировок: он меняет то, как приложение выходит в сеть, когда прямое соединение блокируется. В настройках это один переключатель на три положения — выкл, автоматически, вкл, — и по умолчанию стоит «автоматически»: пока прямое соединение работает, используется оно, переключение происходит только после доказанного отказа. Настраивать нечего, адреса вводить не нужно, всё происходит в фоне. Реализация открыта, так что дизайн может изучить кто угодно.

Защита от блокировок всегда включена?

По умолчанию — автоматически: прямое соединение быстрее, поэтому пока оно работает, используется оно, а переключение происходит только при доказанном отказе. Можно также принудительно включить или выключить. Чего мы намеренно не публикуем — какие именно техники сейчас в строю и где они сейчас проходят или не проходят: публичная и актуальная сводка по этому вопросу — бесплатная обратная связь для тех, кто блокирует. По той же причине этого не показывает и само приложение.

Устойчивость сети и жизнеспособность

Что будет если серверы Конструкта отключатся?

Обмен сообщениями останавливается до его возвращения. Альфа работает на одном доверенном сервере, и второго пути сегодня нет — ни реле, ни соединений напрямую, ни другого узла, на который можно опереться. Всё зашифрованное остаётся зашифрованным, ничего не теряется — просто не движется. Дорожная карта существует ровно ради того, чтобы это перестало быть правдой, и ничего из неё пока не выпущено.

Базовый мессенджинг всегда будет бесплатным?

Да — безусловно. Отправка сообщений, получение сообщений, E2EE и все функции безопасности никогда не окажутся за платным барьером. Модель только на донатах исторически оказалась хрупкой для privacy-проектов, поэтому Конструкт планирует комбинацию: добровольные пожертвования, опциональные premium-функции (большие файлы, расширенная история, темы — никогда функции безопасности) и B2B-хостинг для организаций. Ядро всегда будет бесплатным.

На что живёт Konstruct? Можно задонатить?

Без рекламы, без перепродажи данных, без телеметрии — обратная сторона в том, что Konstruct живёт на добровольных донатах. Они идут напрямую на разработку и сервер. Если цените приватность — предпочтите Monero (XMR), в отличие от биткоина его цепочка не публична. Перед отправкой всегда сверяйте адрес с репозиторием проекта на случай подмены страницы.

  • Monero (XMR) — рекомендуется:
    496i5qvPzRtJPQjiPXnLvEGutjHFth4pWDQaJwbbMreyaTYg4qfbo48MXrTnYH32MHiAn5GcSEN1c48EYBvVkrx9Pi5BWvn
  • Bitcoin (BTC):
    bc1q5cthgu6k9utg9hk2mx2xshdtsrhvu54ysmqhmm
  • Ko-fi — удобно, но не приватно: платёжный сервис знает, кто вы:
    ko-fi.com/construct_msg
Что такое P2P-режим и когда он активируется?

Режим P2P запланирован, но пока не реализован — весь трафик сейчас идёт через центральный сервер. Целевой замысел: когда оба собеседника одновременно онлайн и подключены к серверу Konstruct, сервер даст им сигнал перейти на прямое P2P-соединение поверх QUIC. После установки сервер уходит с пути доставки — трафик идёт напрямую между устройствами. Если одна из сторон уходит в офлайн, доставка возвращается на сервер.

Безопасность и защита

Что если мне начнут массово писать незнакомые люди?

Для этого в приложении есть «Режим защиты». Когда он включён, уведомления и оповещения приходят только от людей, которые были у вас в контактах на момент его активации. Сообщения от новых отправителей всё равно сохраняются — они просто не будут вас тревожить. Режим полезен, если вы публичный человек и хотите временно закрыться от новых контактов.

А если один конкретный человек начнёт спамить сотнями сообщений?

Если от одного отправителя приходит подозрительно много сообщений за короткое время (больше ~10 за 30 секунд), клиент автоматически покажет предупреждение и заглушит уведомления от него. Вы сможете либо разрешить его, либо заблокировать. Важно: это защита на стороне получателя и работает независимо от того, каким клиентом пользуется отправитель.

Технические вопросы

Что такое «сессия» и почему она иногда «ломается»?

Сессия — это установленный зашифрованный канал между двумя устройствами. Она строится на одноразовых ключах, которые нельзя переиспользовать, и ключи вращаются с каждым сообщением. Если приложение долго не работало, устройство переустановили или собеседник удалил чат — входящее сообщение может оказаться нечитаемым. Тогда приложение получателя сообщает отправителю, на каком состоянии сессии было написано это сообщение; приложение отправителя открывает новое состояние и отправляет сообщение ещё раз. Пользователь, как правило, ничего не замечает — сообщение просто приходит.

Поддерживается ли несколько устройств?

Привязать второе устройство в публичных сборках пока нельзя. Нативный десктоп-клиент заморожен, в разработке — консольный (TUI). Поскольку идентичность привязана к ключам, а не к аккаунту на сервере, многоустройственность требует отдельного механизма привязки ключей — над этим работаем.

Какой транспорт у Конструкта для live-сообщений?

Live-сообщения идут по двунаправленному gRPC MessageStream — один долгоживущий поток для heartbeat’ов, входящих сообщений и receipt’ов, без request/response polling. На актуальных iOS-сборках боевой путь — QUIC (construct-transport); если QUIC режется или handshake не проходит, клиент автоматически падает на gRPC поверх HTTP/2 + TLS 1.3. Сквозное шифрование не зависит от транспорта: по проводу едет только sealed ciphertext.

Для тестировщиков

Что проверять в первую очередь?
  • Регистрация и добавление контакта по QR-коду
  • Отправка и получение сообщений (в обе стороны)
  • Статусы доставки — доходит ли сообщение до «доставлено», и повторяют ли отправку «в очереди» и «не отправлено» по нажатию?
  • Редактирование сообщений — видит ли получатель изменения?
  • Уведомления при свёрнутом приложении
  • Поведение на плохой связи (авиарежим → восстановление)
  • Восстановление аккаунта по ключу восстановления после переустановки
  • Копия ключа восстановления из Настроек
Как сообщить о баге?

В диагностических (внутренних) сборках путь такой: Настройки → Диагностика и логи → Поделиться логами. Публичные сборки логов не ведут и этот экран вообще не компилируют — если в вашей сборке такой строки нет, опишите сценарий, и мы выдадим вам диагностическую сборку. Чем точнее описание (что делали, что ожидали, что произошло), тем быстрее мы разберёмся. Для проблемы с сессией приложите логи с обоих устройств.

Почему в логах так много повторяющихся строк?

В отладочных сборках некоторые компоненты пишут в лог при каждом обновлении интерфейса — для разработки это нормально. Строки вида FRC updated: 69 message(s) in window — это обновление списка чатов, они не означают проблемы.