Дайджесты новостей
Натюрморт рабочего места разработчика с деревянным столом, смартфоном с открытым защищённым чатом соцсети Flora, блокнотом со схемой шифрования FSCP v1 и запечатанным бумажным конвертом.

Архитектура соцсети Flora: E2E-шифрование сообщений и открытая формула ленты

Когда мы заходим в современные социальные сети — будь то X, Telegram, Bluesky или платформы Meta, — мы неизбежно принимаем негласный общественный договор. Серверные операторы видят практически всё: историю переписки, круг общения, время активности и каждое движение пальца по экрану. А так называемая «лента рекомендаций» управляется закрытыми алгоритмическими моделями, чья единственная цель — максимизировать экранное время любой ценой, подмешивая кликбейт, поляризацию и оплаченный рекламодателями контент.

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

Независимый разработчик с ником effka11 представил комплексный ответ на этот вызов — открытую социальную платформу Flora Ecosystem (лицензия AGPL-3.0, портал social.flora-s.net). Проект объединил бескомпромиссные криптографические гарантии приватности личных чатов с кристально прозрачной математической формулой формирования публичной ленты.

Давай погрузимся в исходный код Flora и разберем ее инженерную анатомию: от сетевых конвертов на Rust до формулы алгоритма ранжирования.

Модульный монолит на Rust и клиенты нового поколения

Вместо модной, но прожорливой микросервисной архитектуры бэкенд Flora спроектирован как высокопроизводительный модульный монолит на языке Rust (flora-api). В качестве хранилища используется PostgreSQL 16+.

Выбор Rust позволил добиться предсказуемой задержки при параллельной обработке десятков тысяч WebSocket-соединений без сборщика мусора. Монолит строго разделен на независимые доменные модули: авторизация, профили, доставка шифрованных конвертов и конвейер ранжирования. Любопытно, что управление зависимостями и тулчейном Rust на платформе напоминает архитектурные практики, описанные в материале pnpm 12.11.0: управление тулчейном Rust, навыки для ИИ-агентов и гранулярные права.

Клиентская часть представлена двумя приложениями:

  1. Веб-интерфейс на Next.js 16 и TypeScript с поддержкой серверного рендеринга и локального выполнения криптографических примитивов через Web Crypto API и WASM-модули;
  2. Кроссплатформенное мобильное приложение на Expo (React Native) для iOS и Android.

Криптографический протокол FSCP v1: математика приватности

Сердце защищенного общения во Flora — собственный протокол FSCP v1 (Flora Secure Communication Protocol).

В отличие от многих корпоративных мессенджеров, где E2E-шифрование либо отключено по умолчанию, либо использует устаревший стандарт AES-GCM, архитектура FSCP v1 опирается на современный стек шифров:

  1. Симметричное шифрование сообщений: алгоритм XChaCha20-Poly1305. Использование 24-байтного случайного nonce полностью устраняет катастрофический риск повторного использования nonce (nonce reuse), который часто приводит к взлому при стандартном 12-байтном AES-GCM в распределенных системах. Длина сессионного ключа сообщения (messageKey) составляет 32 байта.
  2. Асимметричное согласование ключей: протокол Диффи-Хеллмана на эллиптических кривых X25519 для генерации эфемерных ключевых пар с деривацией сессионного секрета через HKDF-SHA-256.
  3. Цифровые подписи идентичности: алгоритм Ed25519. Каждое сообщение подписывается приватным ключом отправителя, исключая атаку «человек посередине» (MitM).

Взгляни на базовую структуру зашифрованного конверта на Rust:

// Пакет зашифрованного конверта FSCP v1 в рантайме flora-api
pub struct EncryptedEnvelope {
    pub protocol_version: u8,           // Версия протокола (v1)
    pub ephemeral_public_key: [u8; 32], // Эфемерный открытый ключ X25519
    pub recipient_key_id: [u8; 16],     // Идентификатор ключа получателя
    pub nonce: [u8; 24],                // Случайный 24-байтный nonce XChaCha20
    pub ciphertext: Vec<u8>,            // Зашифрованное тело сообщения
    pub signature: [u8; 64],            // Цифровая подпись отправителя Ed25519
}

Сервер Flora выступает исключительно «слепым почтальоном». В базу данных сохраняются только байты EncryptedEnvelope и открытые метаданные маршрутизации. Физически сервер не имеет ключей для расшифровки текста, картинок или голосовых файлов.

Резервное копирование ключей по принципу Zero-Knowledge

Что происходит, если пользователь теряет смартфон? В большинстве систем приходится жертвовать либо безопасностью (хранить ключи на сервере в открытом виде), либо историей переписки.

Во Flora реализован элегантный протокол Zero-Knowledge Key Backup:

  • При регистрации клиент генерирует мнемоническую фразу из 12 слов;
  • Мастер-пароль пользователя проходит через стойкую функцию деривации ключа Argon2id (параметры: 64 МиБ оперативной памяти, 3 итерации, 1 поток);
  • Сгенерированным ключом шифруется локальное хранилище закрытых ключей;
  • На сервер отправляется только наглухо зашифрованный контейнер. Без мастер-пароля даже обладатель полного дампа базы данных не сможет подобрать ключи.

Алгоритм FIRA: открытая и честная рекомендательная лента

Вторая революционная часть экосистемы Flora — полный отказ от манипулятивных непрозрачных алгоритмов в пользу открытого рекомендательного движка FIRA (Flora Intelligent Ranking Algorithm).

Инфографический чертёж и математическая модель алгоритма FIRA соцсети Flora с балансом глобального охвата 70% и социальной близости 30%.

Вместо «черного ящика» машинного обучения ранжирование публикаций в публичной ленте рассчитывается по детерминированной математической формуле:

Score=0.70×GlobalRelevance+0.30×SocialProximity\text{Score} = 0.70 \times \text{GlobalRelevance} + 0.30 \times \text{SocialProximity}

Формула гармонично сочетает два фактора:

  1. Глобальный интерес (GlobalRelevance, вес 70%): рассчитывается логарифмически по формуле log2(1 + likes + 2 * reposts + 3 * comments). Это предотвращает экспоненциальный отрыв вирусных тем от полезных постов. При этом действует штраф экспоненциального затухания по возрасту: exp(-0.05 * age_hours), благодаря чему лента непрерывно обновляется, а вчерашние публикации плавно уступают место новым.
  2. Социальная близость (SocialProximity, вес 30%): умножает скор публикации на коэффициент взаимных связей с автором, гарантируя, что посты людей из твоего круга общения не теряются в общем потоке.

Посмотрим на эталонную реализацию формулы FIRA:

import math
import time

def compute_fira_score(post, current_time):
    # Логарифмический учет вовлеченности с весами действий
    engagement = math.log2(1 + post.likes + 2 * post.reposts + 3 * post.comments)
    
    # Экспоненциальное затухание по возрасту публикации (в часах)
    age_hours = (current_time - post.created_at) / 3600.0
    decay = math.exp(-0.05 * age_hours)
    
    global_relevance = engagement * decay
    
    # Социальная близость на основе взаимных связей
    social_proximity = post.author_mutual_connections_count * 1.5
    
    return 0.70 * global_relevance + 0.30 * social_proximity

Любой пользователь Flora может открыть настройки и точно увидеть, почему конкретная публикация оказалась на первом месте в его ленте.

Flora Ecosystem наглядно демонстрирует, что социальные сети могут существовать без шпионажа за пользователями и непрозрачных алгоритмов, опираясь на честный открытый код и надежную математику.