P2PMsg («Gryzov») — руководство пользователя
Приватный мессенджер со сквозным (E2E) шифрованием: личные и групповые чаты,
голосовые/видеозвонки, медиа- и голосовые сообщения. Сервер видит только
зашифрованные конверты — переписку и звонки расшифровать не может.
- Платформы: Android (Kotlin/Compose) и iOS (Swift/SwiftUI) поверх общего крипто-ядра на Rust.
- Крипто: личные чаты — X3DH + Double Ratchet; группы — MLS (RFC 9420). Ключи не покидают устройство.
- Сервер:
gryzov.com — только релей зашифрованных сообщений, каталог prekey-ключей, офлайн-очередь и push-побудка.
В парах скриншотов слева — iOS, справа — Android.
1. Установка
Android
- Откройте в браузере телефона https://gryzov.com и введите пароль загрузки (его даёт владелец).
- Скачайте один из двух APK:
- Обычная сборка (F-Droid / UnifiedPush) — без сервисов Google. Для фоновых пушей нужен распространитель (ntfy или Gotify).
- «Версия с Google-пушами» (Play / FCM) — фоновые пуши через Google, без стороннего приложения. Текст сообщений всё равно E2E.
- Разрешите установку из этого источника, установите APK, откройте приложение.
iOS
Приложение раздаётся через TestFlight (ссылку-приглашение даёт владелец). Установите TestFlight из App Store → примите приглашение → установите P2PMsg.
2. Первый запуск и регистрация
При первом старте — заставка, затем экран входа/регистрации.

Заставка приложения (Android)
- Регистрация: придумайте имя пользователя (username) — это ваш адрес в сети. Устройство создаёт постоянную личность (Ed25519-ключ) и решает proof-of-work (пара секунд).
- Восстановление личности возможно только через заранее сохранённый ключ восстановления (§8). Пароля/почты для восстановления нет — это часть приватности.
3. Экран «Чаты»
Список личных диалогов. Сверху — профиль и кнопка + / ✎ (новый чат), снизу — вкладки Чаты · Группы · Настройки.
 iOS — Чаты |
 Android — Чаты |
- Строка — собеседник, превью последнего сообщения и время.
- Мелкий hex под именем (
67:e3:06:…) — отпечаток ключа собеседника. Полная сверка — §7.
- Красная плашка «Аутентификация WS не удалась (нужен логин)» — сессия на сервере истекла, нужно перелогиниться. E2E-содержимое не страдает.
Как начать чат
Нажмите + / ✎ → введите точный username → приложение загрузит его prekey-набор и откроет диалог. Первое сообщение автоматически устанавливает защищённую сессию (X3DH).
4. Переписка
 iOS — диалог |
 Android — диалог |
- Текст — поле «Сообщение» + кнопка отправки.
- Медиа — 📎/камера: фото, видео, файлы. Шифруются AES-256-GCM; сервер хранит только зашифрованный blob.
- Голосовые — кнопка микрофона. Перед отправкой открывается редактор: убрать шум, вырезать паузы, выровнять громкость. Обработка идёт на устройстве, оригинал не меняется, «Отмена» отправляет запись как есть.
- Транскрибация голосовых — текст под голосовым, включается в настройках (§8). Считается на самом устройстве.
- Ответ-цитата и подписи к медиа.
- Статусы:
✓ отправлено, ✓✓/«доставлено» — получено, «lost» — не доставлено.
- Исчезающие сообщения — иконка ⏱ в шапке: TTL 1 ч / 24 ч / 7 д / 30 д.
- Иконки в шапке: щит-с-галочкой (сверка ключа), 📞 звонок, ⏱ таймер (исчезающие) и меню «тип чата» — выбор транспорта (через сервер / прямой P2P / P2P через TURN) и переименование контакта.
Системные сообщения (серым/жёлтым по центру) — уведомления приложения, не переписка: напр. «Не удалось расшифровать…создана новая сессия» (см. FAQ) или предупреждение о смене ключа (§7).
5. Звонки
Из окна чата — кнопка звонка 📞 (аудио). WebRTC (DTLS-SRTP), NAT-обход STUN/TURN. Сигналинг едет по зашифрованному каналу, поэтому SDP-обмен тоже защищён.
- iOS: входящий звонок — нативный CallKit, побудка в фоне — VoIP-push (PushKit).
- Android: входящий поднимает полноэкранное уведомление поверх локскрина с рингтоном.
- Видео — камеру можно включить как сразу, так и посреди разговора; переключение фронтальной/тыловой на ходу.
- Картинка в картинке — свернув приложение во время видеозвонка, вы продолжаете видеть собеседника в плавающем окне поверх других приложений.
6. Группы
Вкладка Группы. Групповые чаты используют MLS — содержимое шифруется только на устройствах, сервер его прочитать не может. Но идентификатор группы и (при приглашении) её имя передаются в служебном заголовке открытым текстом — в сочетании с видимыми серверу метаданными доставки (§9) состав и имя группы технически восстановимы.
 iOS — Группы |
 Android — Группы |
- Создать группу: + → имя + участники (через запятую).
- Приглашение двухфазное: приглашённый принимает/отклоняет; добавляется только после согласия.
- Выход и удаление участника поддерживаются; состав меняется системными сообщениями.
- В настройках можно запретить добавлять вас в группы.
7. Проверка собеседника (Safety numbers)
Чтобы исключить «человека посередине», сверьте отпечаток ключа: иконка щита в шапке чата → 60-значный код. Он должен совпадать у обоих (сравните по другому каналу).
⚠️ «Ключ безопасности собеседника изменился. Так бывает при переустановке приложения, но может означать подмену — сверьте отпечаток по доверенному каналу.»
Обычно это переустановка/сброс у собеседника. Если не уверены — свяжитесь с ним другим способом и сверьте отпечаток.
8. Настройки и безопасность
 iOS — Настройки |
 Android — Безопасность |

Android — Настройки (нижняя часть)
- Аккаунт — ваш username.
- Внешний вид — тема Системная / Светлая / Тёмная.
- Биометрическая блокировка — вход по Face ID / Touch ID / PIN.
- Crypto-binding БД к биометрии (Android) — ключ базы оборачивается биометрическим ключом.
- Надёжность в фоне (Android) — отключить оптимизацию батареи.
- Анонимные логи на сервере — сервер не пишет имя и IP в логи.
- Не принимать приглашения/чат от незнакомцев — гейт от спама.
- Mesh / Локальная сеть — обмен напрямую по Wi-Fi без интернета (mDNS; username виден в сети).
- Распознавание голосовых — локальная транскрибация (Android — Vosk, iOS — Speech framework); голос не уходит на сервер.
- Ключ восстановления — сохранить (зашифрован паролем), чтобы вернуть доступ после переустановки.
- Опасная зона · Сбросить идентичность — стирает ключ, чаты и настройки; требует ввода слова «СБРОС».
- UnifiedPush distributor (Android f-droid) — выбрать ntfy/Gotify для фоновых пушей.
9. Приватность — что видит сервер
- Не видит: тексты, медиа, голос, содержимое звонков (SDP тоже зашифрован), ключи.
- Видит (by design): метаданные доставки (кто→кому/когда), факт онлайна, а для групп — group_id и (при приглашении) имя группы открытым текстом в заголовке, из чего восстановим состав. Режим «анонимные логи» уменьшает следы.
- Push: тело пуша — только «сигнал проснуться». У Google-сборки через Google идёт факт пуша и
is_call — поэтому это осознанный opt-in отдельной сборкой.
10. Частые вопросы (FAQ)
Почему «Не удалось расшифровать сообщение… будет создана новая сессия»?
Ключи диалога рассинхронизировались (устройство было офлайн или собеседник переустановил приложение). Самолечится: при следующей отправке создаётся новая сессия. Если тишина — отправьте сообщение сами, чтобы форсировать пересоздание.
Почему в фоне ничего не приходит (Android, F-Droid)?
Нужен распространитель UnifiedPush (ntfy/Gotify) — установите и выберите в Настройках, либо поставьте «Версию с Google-пушами». Ещё включите «Надёжность в фоне».
На iPhone звонок в фоне не звонит?
Проверьте, что разрешены уведомления и приложение зарегистрировало VoIP-токен. Фоновые пуши работают на устройстве, установленном через TestFlight.
Что за жёлтое «Ключ безопасности собеседника изменился»?
Ключ собеседника сменился (обычно переустановка/сброс). Для гарантии сверьте отпечаток (§7).
Красная плашка «Аутентификация WS не удалась»?
Сессия истекла (токен живёт 30 дней). Перелогиньтесь. История и ключи сохраняются.
Переустановил приложение — где чаты?
Чаты и ключи хранятся только на устройстве, в облако не выгружаются. Без ключа восстановления (§8) начинается новая личность. Сохраняйте ключ заранее.
Чем отличаются две Android-сборки?
Функционально одинаковы. F-Droid — без Google, пуши через UnifiedPush. Play — фоновые пуши через Google (FCM). Тексты в обоих E2E.
Совместимы ли iOS и Android?
Да, полностью (общее ядро и формат «на проводе»): чат, медиа, голосовые, группы, звонки, safety numbers — кроссплатформенно.
Как убедиться, что сервер меня не читает?
E2E гарантируется криптографией: сервер хранит только зашифрованные конверты. Дополнительно сверьте safety number.
Можно ли запретить незнакомцам писать/добавлять в группы?
Да — переключатели «Не принимать приглашения/чат от незнакомцев» и «Разрешить добавлять меня в группы».