/* i18n strings for F.E.A.R. landing — RU + EN */ const I18N = { ru: { nav: { home: "Главная", security: "Безопасность", servers: "Серверы", docs: "Документация", github: "GitHub", }, hero: { tagline: "Fully Encrypted Anonymous Routing", slogan: "Бояться — это нормально…", sub: "Мессенджер со сквозным шифрованием и возможностью развёртывания собственной серверной компоненты. Привязка идентификатора пользователя к номеру телефона не используется. Серверная компонента не имеет доступа к открытому тексту сообщений и не выполняет роль централизованного посредника.", download: "Скачать", github: "Открыть на GitHub", }, home: { whatTitle: "О проекте", whatBody: "F.E.A.R. (Fully Encrypted Anonymous Routing) — кроссплатформенная система обмена сообщениями со сквозным шифрованием текста, голоса и видеотрафика. Серверная компонента не имеет доступа к закрытым ключам и не способна расшифровать передаваемые сообщения. Серверу принадлежат только публичный реестр псевдонимов и непрозрачные зашифрованные хранилища пользовательских данных, целостность которых обеспечивается клиентом.\n\nКлиентское программное обеспечение реализовано в виде настольного приложения для Linux (графический интерфейс на Qt и интерфейс командной строки; сборка для Windows находится в разработке) и мобильного приложения для Android. Идентификация пользователя осуществляется через пару ключей Ed25519; привязка к номеру телефона или адресу электронной почты не используется.", featuresTitle: "Ключевые свойства", stackTitle: "Технологический стек", stackCols: { component: "Компонент", tech: "Технология", purpose: "Назначение" }, expand: "развернуть", collapse: "свернуть", stack: [ ["Языки реализации", "C11 (сервер и CLI), C++17 (графический интерфейс на Qt), Kotlin (Android)", "Совмещение производительности нативного кода и переносимости"], ["Графический интерфейс (настольный)", "Qt 6.2+ (Widgets)", "Графический интерфейс для Linux и Windows"], ["Графический интерфейс (мобильный)", "Jetpack Compose, Material 3", "Декларативный пользовательский интерфейс для Android"], ["Система сборки", "CMake 3.12+ (настольная сборка), Gradle 8.13 (Android)", "Воспроизводимая многоплатформенная сборка"], ["Криптографические примитивы", "libsodium, Lazysodium-Android", "AES-256-GCM, Ed25519, X25519, BLAKE2b, Argon2id"], ["Серверное состояние", "SQLite", "Публичный реестр псевдонимов и таблица непрозрачных пользовательских контейнеров (user_blobs)"], ["Локальное хранилище переписки", "SQLite (настольная сборка), Room (Android)", "Кэш сообщений на устройстве с полнотекстовым поиском"], ["Защита идентификатора в покое", "EncryptedFile, Android Keystore (Android)", "Закрытый ключ Ed25519 хранится на диске в зашифрованном виде"], ["Формат резервной копии идентификатора", "FBK1 (Argon2id, XSalsa20-Poly1305)", "Переносимый между платформами экспорт"], ["Кодирование и распознавание QR", "libqrencode, libzbar (настольная сборка); ZXing (Android)", "Перенос идентификатора между устройствами"], ["Аудиокодек", "Opus, PortAudio (настольная сборка), Oboe (Android)", "Голосовая связь с низкой задержкой"], ["Видеокодек", "VP8 (libvpx через FFmpeg)", "Кодирование видеопотока в режиме реального времени"], ["Захват видео", "FFmpeg/libavdevice (настольная сборка), CameraX (Android)", "Унифицированный доступ к камере на всех целевых платформах"], ["Отрисовка видео", "SDL3", "Аппаратно-ускоренный рендеринг YUV"], ["Канал обновлений", "libcurl, GitHub Releases API", "Проверка наличия новой версии при запуске"], ], features: [ { t: "Сквозное шифрование", d: "Каждое сообщение шифруется AES-256-GCM на ключе соответствующей комнаты. Обмен ключом комнаты выполняется через X25519/crypto_box. Идентификатор пользователя — пара ключей Ed25519, которая отображается в форме «имя#короткий-отпечаток» либо «псевдоним@сервер»; перенос идентификатора между устройствами выполняется зашифрованным файлом резервной копии или через QR-код.", }, { t: "Возможность развёртывания собственного сервера", d: "Эталонная серверная сборка распространяется в виде Docker-образа для архитектур amd64 и arm64. Сервер хранит публичный реестр псевдонимов и непрозрачные пользовательские контейнеры в SQLite; содержимое сообщений на сервере не сохраняется. Централизованный каталог пользователей не предусмотрен.", }, { t: "Открытый исходный код", d: "Лицензия AGPLv3, исходный код доступен в репозитории на GitHub. Архитектурные решения зафиксированы в восемнадцати разделах проектной документации; ход реализации каждой фазы прослеживается по истории коммитов.", }, ], statusTitle: "Статус серверов", statusSub: "Публичные узлы для теста. IP не публикуем — это лишняя поверхность атаки.", statusCols: { node: "Узел", region: "Регион", uptime: "Аптайм", status: "Статус" }, online: "online", offline: "offline", checking: "проверка…", downloadTitle: "Скачать", downloadSub: "Подписанные сборки. Проверяйте подпись перед запуском.", tabs: { win: "Windows", lin: "Linux", and: "Android" }, selfHostHint: "Хотите запустить свой сервер?", selfHostLink: "Серверы → Быстрый старт через Docker", sha256: "SHA-256", copy: "Копировать", copied: "Скопировано", sigBtn: "Скачать .sig", verifyHow: "Как проверить подпись", }, sec: { title: "Безопасность", intro: "Архитектура F.E.A.R. строится на пессимистических допущениях о среде эксплуатации: канал связи рассматривается как контролируемый противником, сервер — как потенциально скомпрометированный, конечное устройство — как потенциально враждебное. Каждое архитектурное решение оценивается с точки зрения сохранения конфиденциальности и целостности при реализации этих допущений.", cryptoTitle: "Криптографические примитивы", crypto: [ ["Идентификатор пользователя", "Ed25519, доверие на основе модели Trust-on-First-Use; короткое представление — имя и четырёхбайтовый отпечаток"], ["Обмен ключом комнаты", "X25519 в схеме crypto_box (XSalsa20-Poly1305)"], ["Шифрование сообщений и медиа", "AES-256-GCM на ключе комнаты"], ["Цифровые подписи", "Ed25519 (аутентификация отправителя, регистрация псевдонима, запись пользовательского контейнера)"], ["Функция выведения ключей", "BLAKE2b для доменных ключей; Argon2id для ключа, выводимого из парольной фразы пользователя"], ["Формат резервной копии (FBK1)", "Argon2id (opslimit=3, memlimit=64 МБ) и XSalsa20-Poly1305"], ["Контейнер списка контактов (FCN1)", "Ключ K = BLAKE2b(input=«fear.contacts.v1», key=закрытый_ключ_идентификатора), полезная нагрузка — XSalsa20-Poly1305"], ["Идентификатор канала прямой переписки", "BLAKE2b конкатенации двух открытых ключей участников в каноническом порядке (16 байт), кодирование base64url"], ["Верификация отправителя", "Trust-on-First-Use; явная отметка отпечатка по внеполосному каналу"], ], noSeeTitle: "Сведения, недоступные серверу", noSee: [ "Открытый текст сообщений: на канал передаётся только AES-GCM-шифротекст", "Закрытые ключи: ключ Ed25519 не покидает устройство; на Android он хранится в EncryptedFile под защитой Android Keystore", "Содержимое голосовых, видео- и файловых вложений: шифрование выполняется клиентом до передачи", "Список контактов пользователя: на сервере находится только зашифрованный непрозрачный контейнер, ключ для расшифровки выводится из закрытого ключа идентификатора", "Парольная фраза резервной копии: используется исключительно на устройстве для выведения симметричного ключа", ], seeTitle: "Сведения, доступные серверу (метаданные)", see: [ "Время установления соединения и факт наличия активной TCP-сессии", "Размеры передаваемых зашифрованных пакетов", "Имя комнаты и отображаемое имя отправителя в каждом кадре (в редакции протокола v0.6.0 будут заменены на значения, выведенные через HMAC)", "Записи реестра псевдонимов: соответствие «псевдоним — открытый ключ» доступно по запросу как часть публичной функциональности", "Сетевой адрес подключающегося клиента, если соединение не туннелируется через Tor либо VPN", ], threatTitle: "Модель угроз", defendTitle: "Защита обеспечивается от", defend: [ "Активного посредника (man-in-the-middle) в канале связи", "Пассивного перехвата сетевого трафика", "Компрометации сервера, включая получение доступа к содержимому дисковых хранилищ и оперативной памяти", "Раскрытия переписки при изъятии серверного оборудования", ], noDefendTitle: "Защита не обеспечивается от", noDefend: [ "Компрометации конечного устройства пользователя", "Вредоносного программного обеспечения на стороне клиента", "Физического принуждения владельца ключа", "Глобального пассивного наблюдателя, обладающего доступом к ключевым узлам сетевой инфраструктуры", ], knownTitle: "Известные ограничения", known: [ { t: "Метаданные комнаты и отправителя передаются в открытом виде", s: "open", d: "В каждом кадре TCP-протокола поля имени комнаты и отображаемого имени отправителя представлены в виде открытого текста. Это позволяет серверу или активному наблюдателю восстанавливать социальный граф взаимодействий.", w: "В редакции протокола v0.6.0 запланирована замена этих полей на значения, выведенные через HMAC: room_id = HMAC(K_room, «room-id»), sender_alias = HMAC(K_room, открытый_ключ_идентификатора).", }, { t: "Единый ключ комнаты на всё время существования", s: "open", d: "Раскрытие текущего ключа комнаты компрометирует как уже отправленные, так и последующие сообщения. Свойство прямой секретности (forward secrecy) на уровне комнаты не обеспечивается.", w: "В фазе C запланирована двухуровневая иерархия ключей: K_room (мастер-ключ комнаты, ротируется при изменении состава участников) и K_epoch, выводимый из K_room с интервалом в один час.", }, { t: "Отсутствие защиты от повторного воспроизведения сообщений (replay)", s: "open", d: "Захваченное противником сообщение может быть повторно отправлено в канал и принято получателем как новое.", w: "В фазе D запланировано введение монотонного счётчика sender_seq в составе AAD и серверного кэша last_seq для отбрасывания дубликатов.", }, { t: "Отсутствие отложенной доставки сообщений", s: "open", d: "Сервер не хранит передаваемые сообщения; при отсутствии получателя в сети сообщение теряется. Оба участника должны находиться в сети одновременно.", w: "В фазе E запланирована реализация серверного буфера входящих сообщений: шифротекст сохраняется до подтверждённой доставки получателю.", }, { t: "Отсутствие механизма push-уведомлений", s: "open", d: "Приложение должно быть открыто для приёма сообщений. При закрытом приложении уведомления не доставляются.", w: "В фазе E запланирована опциональная интеграция с Firebase Cloud Messaging. Содержимое сообщений сохраняет сквозное шифрование; внешнему сервису доступен только факт пробуждения клиента.", }, { t: "Доступны только сборки для Android и Linux", s: "open", d: "Сборки для iOS и Windows на момент актуальной версии не публикуются.", w: "Сборка для Windows на основе MSYS2 и MinGW64 выполняется автоматически средствами GitHub Actions и публикуется как переносимый архив на странице релизов. Работа над сборкой для iOS запланирована на этап после выпуска версии v0.6.0 в статусе стабильной.", }, ], }, srv: { title: "Серверная инфраструктура и развёртывание собственного узла", warn: "Публичные узлы предоставляются для целей тестирования и демонстрации. Для эксплуатации в условиях повышенных требований к конфиденциальности рекомендуется развёртывание собственного экземпляра серверной компоненты.", pickTitle: "Алгоритм выбора сервера клиентом", pick: [ "Адрес сервера, используемый по умолчанию (fear-project.ru:8888), задан в исходном коде клиента в качестве предустановленного значения.", "На экране подключения предусмотрена возможность указания произвольного значения host:port.", "В текущей версии клиент работает только с одним сервером в течение сессии. Многосерверное переключение и автоматический выбор по приоритету запланированы в фазе E.", "Имя комнаты и открытый ключ идентификатора не зависят от выбранного сервера; псевдоним вида «псевдоним@сервер» регистрируется на каждом сервере отдельно.", ], storedTitle: "Сведения, размещаемые на сервере (после реализации фаз B-2 и B-3)", stored: [ "Таблица псевдонимов handles: (псевдоним, открытый ключ идентификатора, момент регистрации). Открытый реестр.", "Таблица пользовательских контейнеров user_blobs: (открытый ключ идентификатора, тип контейнера, шифротекст) для непрозрачных контейнеров, формируемых клиентом (например, список контактов).", "Сведения об активных TCP-соединениях в оперативной памяти (имя комнаты и отображаемое имя пользователя). Открытый текст сообщений не сохраняется.", "Содержимое сообщений на сервере не сохраняется. Передача осуществляется в режиме реальной транзитной ретрансляции; реализация буферизованной доставки запланирована в фазе E.", ], offTitle: "Возможность полного отказа от публичных серверов", offBody: "Поддерживается. На экране подключения указывается адрес собственного сервера, после чего клиент использует только указанный узел. Идентификатор и резервная копия переносимы; на новом сервере выполняется отдельная регистрация псевдонима.", fallbackTitle: "Поведение при недоступности сервера", fallback: "В текущей версии клиент работает в режиме строгой онлайн-связности: разрыв TCP-соединения приводит к потере недоставленных сообщений. Перезапуск приложения восстанавливает соединение с тем же сервером. Реализация серверного буфера для отложенной доставки запланирована в фазе E. Автоматическое переключение между разными серверами не предусмотрено.", qsTitle: "Развёртывание серверной компоненты средствами Docker", qsSub: "Эталонный образ опубликован в GitHub Container Registry. Развёртывание выполняется одной командой. Поддерживаются архитектуры linux/amd64 и linux/arm64.", qsRequirementsTitle: "Системные требования", qsRequirements: [ "Операционная система Linux (архитектура x86_64 либо ARM, в том числе одноплатные компьютеры класса Raspberry Pi).", "TCP-порт 8888, доступный для входящих соединений: используется клиентами для подключения к серверу.", "Установленный исполняемый модуль Docker (см. шаг 1, если он ещё не установлен).", ], step: "Шаг", steps: [ { t: "Установка Docker", d: "Шаг может быть пропущен, если Docker уже установлен. Приведённый официальный скрипт корректно отрабатывает в Ubuntu, Debian, Arch и большинстве других распространённых дистрибутивов.", code: "curl -fsSL https://get.docker.com | sh", lang: "bash", }, { t: "Запуск контейнера", d: "Серверная компонента не требует подключения томов. Порт 8888 пробрасывается на хост; параметр --restart обеспечивает автоматический перезапуск сервера после перезагрузки операционной системы.", code: "docker run -d --name fear -p 8888:8888 \\\n --restart unless-stopped \\\n ghcr.io/shchuchkin-pkims/fear-server:latest", lang: "bash", }, { t: "Проверка работоспособности", d: "Убедитесь, что контейнер запущен и принимает соединения на указанном порту.", code: "docker ps\ndocker logs -f fear", lang: "bash", }, ], qsAfterTitle: "Дальнейшие действия", qsAfter: [ { t: "Подключение клиентов", d: "В клиентском приложении (настольном либо мобильном) на экране подключения укажите адрес собственного сервера в формате host:8888 (либо IP-адрес VPS). Имя комнаты задаётся произвольно; режим подключения — автоматический. Обмен ключом выполняется протоколом ECDH без участия пользователя.", }, { t: "Обновление до новой версии", d: "Тег :latest указывает на актуальную сборку. При необходимости можно зафиксировать конкретную версию (например, :0.5.0).", code: "docker pull ghcr.io/shchuchkin-pkims/fear-server:latest\ndocker restart fear", lang: "bash", }, { t: "Использование TLS и собственного доменного имени", d: "Для доступа через домен с использованием TLS (например, my-fear.example.com:443) перед контейнером следует разместить обратный прокси (Caddy либо nginx). Серверная компонента в текущей реализации работает по протоколу TCP без TLS.", }, ], }, doc: { title: "Документация", intro: "Полная техническая документация публикуется в GitHub Wiki проекта и организована в виде четырёх крупных разделов: руководство пользователя, безопасность и криптография, архитектура, материалы для разработчиков. Ниже перечислены тематические подразделы со ссылками на соответствующие страницы.", goto: "Открыть Wiki", readWiki: "Открыть страницу", sections: [ { t: "Быстрый старт", d: "Три типовых сценария ввода в эксплуатацию за пять минут: подключение к публичному серверу с двух устройств, развёртывание собственного сервера, открытие личного диалога с конкретным контактом.", href: "https://github.com/shchuchkin-pkims/fear/wiki/Quick-Start", }, { t: "Установка клиентов", d: "Пошаговые руководства для клиента Android (системные требования, установка APK, регистрация короткого имени, типичные неполадки) и для клиента Desktop (Linux и Windows, перенос идентичности с телефона, консольный клиент, сборка из исходных текстов).", href: "https://github.com/shchuchkin-pkims/fear/wiki/Installation-Android", }, { t: "Развёртывание собственного сервера", d: "Системные требования, подготовка сети и проброс портов через NAT, развёртывание через Docker, альтернативная установка из исходных текстов как systemd-юнита, обновление, резервное копирование, мониторинг.", href: "https://github.com/shchuchkin-pkims/fear/wiki/Installation-Server", }, { t: "Резервное копирование идентичности", d: "Форматы резервных копий (зашифрованный файл .fbk и QR-код), порядок создания и восстановления, перенос идентичности между Android и Desktop, рекомендации по хранению, последствия потери идентичности без резервной копии.", href: "https://github.com/shchuchkin-pkims/fear/wiki/Identity-Backup", }, { t: "Возможности приложения", d: "Перечень пользовательских возможностей версии 0.5.0 в разбивке по платформам: текстовые сообщения с подписью, личные диалоги, групповые комнаты, голосовые и видеовызовы, передача файлов, локальный полнотекстовый поиск, темы оформления, локализация.", href: "https://github.com/shchuchkin-pkims/fear/wiki/Features", }, { t: "Криптографические примитивы и протоколы", d: "Подробное описание применяемых конструкций: AES-256-GCM, Ed25519, X25519, BLAKE2b, Argon2id. Форматы пакетов, схемы вывода ключей, доменные строки, защита от повторов через sender_seq в AAD, детерминированный ключ личной комнаты K_pm через ECDH.", href: "https://github.com/shchuchkin-pkims/fear/wiki/Security-Cryptography", }, { t: "Модель угроз", d: "Формальное описание категорий противника от пассивного сетевого наблюдателя до противника, скомпрометировавшего идентичность собеседника. Таблица гарантий приложения для каждой категории, перечень ситуаций, находящихся вне модели угроз.", href: "https://github.com/shchuchkin-pkims/fear/wiki/Security-Threat-Model", }, { t: "Известные ограничения и способы их минимизации", d: "Открытый перечень слабостей текущей версии с указанием серьёзности, влияния на пользователя, обходных путей и плана устранения. В числе наиболее значимых — отсутствие forward secrecy, открытое имя комнаты на проводе, отсутствие шифрования транспортного уровня по умолчанию.", href: "https://github.com/shchuchkin-pkims/fear/wiki/Security-Known-Issues", }, { t: "Архитектура и сетевой протокол", d: "Логические компоненты системы и поток данных. Кодовая база: разделяемая C-библиотека идентичности, консольный клиент и сервер на C, графический клиент Desktop на Qt, клиент Android на Kotlin. Полное описание байтового формата всех типов кадров.", href: "https://github.com/shchuchkin-pkims/fear/wiki/Architecture", }, { t: "Дорожная карта", d: "Завершённые фазы 0, A и B. Планируемые фазы C (двухуровневая иерархия ключей с автоматической ротацией для forward secrecy), D (опаковые идентификаторы комнат на проводе), E (серверный inbox для офлайн-доставки и push-уведомления), F (выпуск стабильной версии).", href: "https://github.com/shchuchkin-pkims/fear/wiki/Roadmap", }, { t: "Участие в разработке", d: "Структура репозитория, инструкции по сборке всех компонентов, стиль кода для C, C++ и Kotlin, порядок открытия pull request, проверка подписей релизных артефактов через minisign.", href: "https://github.com/shchuchkin-pkims/fear/wiki/For-Contributors", }, { t: "Часто задаваемые вопросы", d: "Сравнение с Signal и Matrix, ответы на типичные вопросы по безопасности и приватности, по установке и работе сервера, по повседневному использованию приложения.", href: "https://github.com/shchuchkin-pkims/fear/wiki/FAQ", }, ], }, foot: { slogan: "Бояться — это нормально.", sec: "evgenii@fear-project.ru", secLabel: "Поддержка", lic: "AGPLv3", }, a11y: { langSwitch: "Переключить язык", menu: "Открыть меню", copyHash: "Скопировать хеш", external: "Внешняя ссылка", }, }, en: { nav: { home: "Home", security: "Security", servers: "Servers", docs: "Documentation", github: "GitHub", }, hero: { tagline: "Fully Encrypted Anonymous Routing", slogan: "Being afraid is normal…", sub: "An end-to-end encrypted messaging system that supports the deployment of an independent server instance. The user identifier is not bound to a telephone number. The server component has no access to message plaintext and does not function as a centralized intermediary.", download: "Download", github: "Open on GitHub", }, home: { whatTitle: "About the project", whatBody: "F.E.A.R. (Fully Encrypted Anonymous Routing) is a cross-platform messaging system providing end-to-end encryption of text, voice, and video traffic. The server component has no access to private keys and is not in a position to decrypt the messages it relays. The server retains only a public registry of pseudonyms and opaque encrypted user containers, the integrity of which is enforced on the client side.\n\nThe client software is implemented as a desktop application for Linux (with a Qt-based graphical interface and a command-line interface; a Windows build is in progress) and as a mobile application for Android. User identification is performed via an Ed25519 keypair; binding to a telephone number or email address is not used.", featuresTitle: "Key properties", stackTitle: "Technology stack", stackCols: { component: "Component", tech: "Technology", purpose: "Purpose" }, expand: "expand", collapse: "collapse", stack: [ ["Implementation languages", "C11 (server and CLI), C++17 (Qt GUI), Kotlin (Android)", "Combines native performance with portable code"], ["Desktop graphical interface", "Qt 6.2+ (Widgets)", "Cross-platform desktop UI for Linux and Windows"], ["Mobile graphical interface", "Jetpack Compose, Material 3", "Declarative user interface for Android"], ["Build system", "CMake 3.12+ (desktop), Gradle 8.13 (Android)", "Reproducible multi-platform builds"], ["Cryptographic primitives", "libsodium, Lazysodium-Android", "AES-256-GCM, Ed25519, X25519, BLAKE2b, Argon2id"], ["Server-side persistent state", "SQLite", "Public pseudonym registry and table of opaque user containers (user_blobs)"], ["Local message storage", "SQLite (desktop), Room (Android)", "On-device message cache with full-text search"], ["Identifier protection at rest", "EncryptedFile, Android Keystore (Android)", "Ed25519 private key stored on disk in encrypted form"], ["Identifier backup format", "FBK1 (Argon2id, XSalsa20-Poly1305)", "Cross-platform export of the identifier"], ["QR encoding and decoding", "libqrencode, libzbar (desktop); ZXing (Android)", "Identifier transport between devices"], ["Audio codec", "Opus, PortAudio (desktop), Oboe (Android)", "Low-latency voice communication"], ["Video codec", "VP8 (libvpx via FFmpeg)", "Real-time video stream encoding"], ["Video capture", "FFmpeg/libavdevice (desktop), CameraX (Android)", "Unified camera access on all target platforms"], ["Video rendering", "SDL3", "Hardware-accelerated YUV rendering"], ["Update channel", "libcurl, GitHub Releases API", "Verification of available new versions on launch"], ], features: [ { t: "End-to-end encryption", d: "Each message is encrypted with AES-256-GCM under the corresponding room key. The room key is exchanged via X25519/crypto_box. The user identifier is an Ed25519 keypair shown in the form 'name#short-fingerprint' or 'pseudonym@server'; cross-device transfer is performed via an encrypted backup file or a QR code.", }, { t: "Independent server deployment", d: "The reference server build is distributed as a Docker image for the amd64 and arm64 architectures. The server stores a public pseudonym registry and opaque user containers in SQLite; message content is not retained on the server. A centralized user directory is not provided.", }, { t: "Open source code", d: "AGPLv3 license, source code published on GitHub. Architectural decisions are documented in eighteen sections of the design specification; the implementation status of each phase is traceable through the commit history.", }, ], statusTitle: "Server status", statusSub: "Public test nodes. We do not publish IPs — that's just an unnecessary attack surface.", statusCols: { node: "Node", region: "Region", uptime: "Uptime", status: "Status" }, online: "online", offline: "offline", checking: "checking…", downloadTitle: "Download", downloadSub: "Signed builds. Verify the signature before running.", tabs: { win: "Windows", lin: "Linux", and: "Android" }, selfHostHint: "Want to run your own server?", selfHostLink: "Servers → Quick start with Docker", sha256: "SHA-256", copy: "Copy", copied: "Copied", sigBtn: "Download .sig", verifyHow: "How to verify the signature", }, sec: { title: "Security", intro: "The architecture of F.E.A.R. is built on pessimistic assumptions about the operating environment: the communication channel is treated as adversary-controlled, the server as potentially compromised, and the endpoint device as potentially hostile. Every architectural decision is evaluated for its ability to preserve confidentiality and integrity under those assumptions.", cryptoTitle: "Cryptographic primitives", crypto: [ ["User identifier", "Ed25519 with Trust-on-First-Use; the short representation comprises a display name and a four-byte fingerprint"], ["Room key exchange", "X25519 within the crypto_box scheme (XSalsa20-Poly1305)"], ["Message and media cipher", "AES-256-GCM under the room key"], ["Digital signatures", "Ed25519 (sender authentication, pseudonym registration, write to user container)"], ["Key derivation function", "BLAKE2b for domain keys; Argon2id for the key derived from the user passphrase"], ["Identifier backup format (FBK1)", "Argon2id (opslimit=3, memlimit=64 MB) and XSalsa20-Poly1305"], ["Contact list container (FCN1)", "Key K = BLAKE2b(input='fear.contacts.v1', key=identity_secret_key); payload protected by XSalsa20-Poly1305"], ["Direct-message channel identifier", "BLAKE2b of the canonical concatenation of both participants' public keys (16 bytes), encoded as base64url"], ["Sender verification", "Trust-on-First-Use; an explicit out-of-band fingerprint comparison is offered to the user"], ], noSeeTitle: "Data not accessible to the server", noSee: [ "Message plaintext: only AES-GCM ciphertext is transmitted over the channel", "Private keys: the Ed25519 secret key does not leave the device; on Android it is stored within EncryptedFile under Android Keystore protection", "Content of voice, video, and file attachments: encryption is performed by the client prior to transmission", "User contact list: the server holds only an encrypted opaque container; the decryption key is derived from the identifier secret key", "Backup passphrase: used exclusively on the device for symmetric key derivation", ], seeTitle: "Data accessible to the server (metadata)", see: [ "Times of connection establishment and the presence of an active TCP session", "Sizes of the transmitted encrypted packets", "Room name and sender display name within each frame (in protocol revision v0.6.0 these will be replaced with HMAC-derived values)", "Pseudonym registry entries: the mapping (pseudonym, public key) is queryable as part of the public functionality", "Network address of the connecting client unless the connection is tunneled through Tor or a VPN", ], threatTitle: "Threat model", defendTitle: "Protection is provided against", defend: [ "An active man-in-the-middle adversary on the communication channel", "Passive interception of network traffic", "Compromise of the server, including access to disk storage and main memory", "Disclosure of message content following physical seizure of the server", ], noDefendTitle: "Protection is not provided against", noDefend: [ "Compromise of the user's endpoint device", "Malicious software running on the client side", "Physical coercion of the key holder", "A global passive adversary with access to key network infrastructure", ], knownTitle: "Known limitations", known: [ { t: "Room and sender metadata are transmitted in plaintext", s: "open", d: "In each frame of the TCP protocol, the room name and sender display name fields are conveyed as plaintext. This permits the server, or an active observer, to reconstruct the social graph of interactions.", w: "Protocol revision v0.6.0 introduces replacement of these fields with HMAC-derived values: room_id = HMAC(K_room, 'room-id'), sender_alias = HMAC(K_room, identity_public_key).", }, { t: "A single room key is used for the entire lifetime of the room", s: "open", d: "Disclosure of the current room key compromises both already-transmitted and subsequent messages. The forward-secrecy property is not provided at the room level.", w: "A two-tier key hierarchy is planned in Phase C: K_room (the master room key, rotated upon changes in room membership) and K_epoch, derived from K_room at one-hour intervals.", }, { t: "No protection against message replay", s: "open", d: "A message captured by an adversary can be resubmitted to the channel and accepted by the recipient as new.", w: "Phase D introduces a monotonic sender_seq counter as part of the additional authenticated data and a server-side last_seq cache that drops duplicates.", }, { t: "No deferred message delivery", s: "open", d: "The server does not retain transmitted messages; if the recipient is offline, the message is lost. Both participants must be online concurrently.", w: "A server-side inbox is planned in Phase E: ciphertext is retained until delivery to the recipient has been acknowledged.", }, { t: "No push-notification mechanism", s: "open", d: "The application must remain open in order to receive messages. Notifications are not delivered when the application is closed.", w: "Optional integration with Firebase Cloud Messaging is planned in Phase E. End-to-end encryption of message content is preserved; the external service has access only to the wake-up event.", }, { t: "Builds available only for Android and Linux", s: "open", d: "Builds for iOS and Windows are not published as of the current version.", w: "The Windows build, based on MSYS2 and MinGW64, is produced automatically by GitHub Actions and published as a portable archive on the releases page. Work on the iOS build is scheduled to follow the release of v0.6.0 in stable status.", }, ], }, srv: { title: "Server infrastructure and independent deployment", warn: "The public nodes are provided for the purposes of testing and demonstration. For operation under elevated confidentiality requirements, deployment of an independent instance of the server component is recommended.", pickTitle: "Server selection algorithm on the client side", pick: [ "The default server address (fear-project.ru:8888) is hard-coded into the client as a preset value.", "The connection screen permits the user to specify an arbitrary host:port value.", "The current version of the client operates with a single server within a session. Multi-server failover and automatic priority-based selection are scheduled for Phase E.", "The room name and the public key of the identifier are independent of the chosen server. The pseudonym of the form 'pseudonym@server' is registered on each server separately.", ], storedTitle: "Data placed on the server (following implementation of Phases B-2 and B-3)", stored: [ "Pseudonym table 'handles': (pseudonym, identifier public key, registration timestamp). A public registry.", "User-container table 'user_blobs': (identifier public key, container type, ciphertext) for opaque containers produced by the client (e.g., the contact list).", "Information about active TCP sessions held in main memory (room name and user display name). Message plaintext is not retained.", "Message content is not retained on the server. Transmission is performed in transit-relay mode in real time; the implementation of buffered delivery is scheduled for Phase E.", ], offTitle: "Complete avoidance of the public servers", offBody: "Supported. The address of an independent server is specified on the connection screen, after which the client communicates only with that node. The identifier and the backup file are fully portable; pseudonym registration on the new server is performed independently.", fallbackTitle: "Behaviour when the server is unavailable", fallback: "In the current version the client operates in a strict online-connectivity mode: the loss of the TCP connection results in the loss of undelivered messages. Restarting the application restores the connection to the same server. The implementation of a server-side buffer for deferred delivery is scheduled for Phase E. Automatic switching between different servers is not provided.", qsTitle: "Deployment of the server component using Docker", qsSub: "The reference image is published in the GitHub Container Registry. Deployment is performed with a single command. The architectures linux/amd64 and linux/arm64 are supported.", qsRequirementsTitle: "System requirements", qsRequirements: [ "An operating system based on the Linux kernel (architecture x86_64 or ARM, including single-board computers of the Raspberry Pi class).", "TCP port 8888 reachable for incoming connections; used by clients to connect to the server.", "An installed Docker runtime (refer to step 1 if it is not yet installed).", ], step: "Step", steps: [ { t: "Installation of Docker", d: "This step may be skipped if Docker is already installed. The official script provided below operates correctly on Ubuntu, Debian, Arch, and most other widely used distributions.", code: "curl -fsSL https://get.docker.com | sh", lang: "bash", }, { t: "Container launch", d: "The server component does not require attached volumes. Port 8888 is forwarded to the host; the --restart parameter ensures automatic restart of the server following an operating-system reboot.", code: "docker run -d --name fear -p 8888:8888 \\\n --restart unless-stopped \\\n ghcr.io/shchuchkin-pkims/fear-server:latest", lang: "bash", }, { t: "Verification of operability", d: "Confirm that the container is running and accepting connections on the specified port.", code: "docker ps\ndocker logs -f fear", lang: "bash", }, ], qsAfterTitle: "Subsequent steps", qsAfter: [ { t: "Connecting clients", d: "In the client application (desktop or mobile), specify the address of the independent server on the connection screen in the form host:8888 (or the IP address of the VPS). The room name is set arbitrarily; the connection mode is automatic. The key exchange is performed via the ECDH protocol without user intervention.", }, { t: "Updating to a new version", d: "The :latest tag refers to the current build. A specific version can be pinned if required (for example, :0.5.0).", code: "docker pull ghcr.io/shchuchkin-pkims/fear-server:latest\ndocker restart fear", lang: "bash", }, { t: "Use of TLS and an independent domain name", d: "For access via a domain with TLS (for example, my-fear.example.com:443), a reverse proxy (Caddy or nginx) should be placed in front of the container. The server component, in its current implementation, operates over the TCP protocol without TLS.", }, ], }, doc: { title: "Documentation", intro: "Comprehensive technical documentation is published in the project's GitHub Wiki and organised into four major sections: user guide, security and cryptography, architecture, and developer materials. The thematic subsections with links to the corresponding pages are listed below.", goto: "Open the Wiki", readWiki: "Open page", sections: [ { t: "Quick start", d: "Three typical commissioning scenarios in five minutes: connecting two devices to the public server, deploying one's own server, opening a personal conversation with a specific contact.", href: "https://github.com/shchuchkin-pkims/fear/wiki/Quick-Start", }, { t: "Client installation", d: "Step-by-step instructions for the Android client (system requirements, APK installation, short-name registration, common troubleshooting) and for the Desktop client (Linux and Windows, identity transfer from a phone, command-line client, building from source).", href: "https://github.com/shchuchkin-pkims/fear/wiki/Installation-Android", }, { t: "Self-hosted server deployment", d: "System requirements, network preparation and NAT port forwarding, deployment via Docker, alternative installation from source as a systemd unit, updating, backup, monitoring.", href: "https://github.com/shchuchkin-pkims/fear/wiki/Installation-Server", }, { t: "Identity backup", d: "Backup formats (encrypted .fbk file and QR code), creation and restoration procedures, identity transfer between Android and Desktop, storage recommendations, consequences of identity loss without a backup.", href: "https://github.com/shchuchkin-pkims/fear/wiki/Identity-Backup", }, { t: "Application features", d: "List of user-facing features in version 0.5.0 broken down by platform: signed text messages, personal conversations, group rooms, voice and video calls, file transfer, local full-text search, themes, localisation.", href: "https://github.com/shchuchkin-pkims/fear/wiki/Features", }, { t: "Cryptographic primitives and protocols", d: "Detailed description of the constructions in use: AES-256-GCM, Ed25519, X25519, BLAKE2b, Argon2id. Wire formats, key derivation schemes, domain-separation strings, replay protection via sender_seq in AAD, the deterministic personal-room key K_pm via ECDH.", href: "https://github.com/shchuchkin-pkims/fear/wiki/Security-Cryptography", }, { t: "Threat model", d: "Formal description of adversary categories ranging from a passive network observer to an adversary having compromised the correspondent's identity. Tabulated guarantees of the application for each category; an explicit list of situations falling outside the threat model.", href: "https://github.com/shchuchkin-pkims/fear/wiki/Security-Threat-Model", }, { t: "Known limitations and mitigations", d: "Open list of weaknesses in the current version with severity ratings, user impact, mitigations, and a remediation plan. Among the most significant: absence of forward secrecy, plaintext room name on the wire, absence of transport-layer encryption by default.", href: "https://github.com/shchuchkin-pkims/fear/wiki/Security-Known-Issues", }, { t: "Architecture and wire protocol", d: "Logical components of the system and the data flow. Codebase: shared C identity library, command-line client and server in C, graphical Desktop client in Qt, Android client in Kotlin. Complete byte-level format of all frame types.", href: "https://github.com/shchuchkin-pkims/fear/wiki/Architecture", }, { t: "Roadmap", d: "Completed phases 0, A and B. Planned phases C (two-tier key hierarchy with automatic rotation for forward secrecy), D (opaque on-the-wire room identifiers), E (server-side inbox for offline delivery and push notifications), F (stable release).", href: "https://github.com/shchuchkin-pkims/fear/wiki/Roadmap", }, { t: "Participating in development", d: "Repository structure, build instructions for all components, code style for C, C++ and Kotlin, the procedure for opening a pull request, verification of release-artifact signatures with minisign.", href: "https://github.com/shchuchkin-pkims/fear/wiki/For-Contributors", }, { t: "Frequently asked questions", d: "Comparison with Signal and Matrix, answers to common questions on security and privacy, on installation and server operation, on day-to-day use of the application.", href: "https://github.com/shchuchkin-pkims/fear/wiki/FAQ", }, ], }, foot: { slogan: "Being afraid is normal.", sec: "evgenii@fear-project.ru", secLabel: "Support", lic: "AGPLv3", }, a11y: { langSwitch: "Switch language", menu: "Open menu", copyHash: "Copy hash", external: "External link", }, }, }; /* Server roster — static metadata (region labels, host). Live status (online/ping) is fetched at runtime from /api/status.json. */ const SERVERS = [ { id: "nl-meppel", regionRu: "Меппел, Нидерланды", regionEn: "Meppel, Netherlands", host: "77.221.145.132:8888" }, { id: "ru-msk", regionRu: "Москва, Россия", regionEn: "Moscow, Russia", host: "fear-project.ru:8888" }, ]; /* Latest release pulled from GitHub Releases. Update on every release together with bumping versionCode/PROGRAM_VERSION. */ const RELEASE_VERSION = "0.5.0"; const DESKTOP_RELEASES = "https://github.com/shchuchkin-pkims/fear/releases"; const MOBILE_RELEASES = "https://github.com/shchuchkin-pkims/fear-mobile/releases"; const ARTIFACTS = { win: { file: `fear-windows-x64-v${RELEASE_VERSION}.zip`, url: `${DESKTOP_RELEASES}/download/v${RELEASE_VERSION}/fear-windows-x64-v${RELEASE_VERSION}.zip`, sha: "be541ba2c1c909c4730d8b19c85fb2b26eaaa1b6f67c3ea0e02022fbbeb02e3b", sig: null, }, lin: { file: `fear-linux-x86_64-v${RELEASE_VERSION}.zip`, url: `${DESKTOP_RELEASES}/download/v${RELEASE_VERSION}/fear-linux-x86_64-v${RELEASE_VERSION}.zip`, sha: "367114c1bbf0373279c104f72b63c7affdc4fbba7ca33c07bec474148a34ef52", sig: null, }, and: { file: `fear-android-v${RELEASE_VERSION}.apk`, url: `${MOBILE_RELEASES}/download/v${RELEASE_VERSION}/fear-android-v${RELEASE_VERSION}.apk`, sha: "2982cbe81668dbe82ebdcef1dfa20936f973e94c4dfeee17a11b2d99334b8dee", sig: null, }, }; const VERIFY_CMDS = { win: `:: Verify SHA-256 (PowerShell)\r\nGet-FileHash fear-windows-x64-v${RELEASE_VERSION}.zip -Algorithm SHA256\r\n:: Expected:\r\n:: be541ba2c1c909c4730d8b19c85fb2b26eaaa1b6f67c3ea0e02022fbbeb02e3b\r\n:: Распакуйте архив и запустите fear_gui.exe`, lin: `# Verify SHA-256\nsha256sum fear-linux-x86_64-v${RELEASE_VERSION}.zip\n# Expected:\n# 367114c1bbf0373279c104f72b63c7affdc4fbba7ca33c07bec474148a34ef52 fear-linux-x86_64-v${RELEASE_VERSION}.zip\nunzip fear-linux-x86_64-v${RELEASE_VERSION}.zip\ncd fear && ./fear_gui`, and: `# Verify SHA-256 + APK signature\nsha256sum fear-android-v${RELEASE_VERSION}.apk\n# Expected:\n# 2982cbe81668dbe82ebdcef1dfa20936f973e94c4dfeee17a11b2d99334b8dee fear-android-v${RELEASE_VERSION}.apk\napksigner verify --print-certs fear-android-v${RELEASE_VERSION}.apk`, }; window.I18N = I18N; window.SERVERS = SERVERS; window.ARTIFACTS = ARTIFACTS; window.VERIFY_CMDS = VERIFY_CMDS;