Когда мы заходим в современные социальные сети — будь то 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, навыки для ИИ-агентов и гранулярные права.
Клиентская часть представлена двумя приложениями:
- Веб-интерфейс на Next.js 16 и TypeScript с поддержкой серверного рендеринга и локального выполнения криптографических примитивов через Web Crypto API и WASM-модули;
- Кроссплатформенное мобильное приложение на Expo (React Native) для iOS и Android.
Криптографический протокол FSCP v1: математика приватности
Сердце защищенного общения во Flora — собственный протокол FSCP v1 (Flora Secure Communication Protocol).
В отличие от многих корпоративных мессенджеров, где E2E-шифрование либо отключено по умолчанию, либо использует устаревший стандарт AES-GCM, архитектура FSCP v1 опирается на современный стек шифров:
- Симметричное шифрование сообщений: алгоритм XChaCha20-Poly1305. Использование 24-байтного случайного nonce полностью устраняет катастрофический риск повторного использования nonce (nonce reuse), который часто приводит к взлому при стандартном 12-байтном AES-GCM в распределенных системах. Длина сессионного ключа сообщения (
messageKey) составляет 32 байта. - Асимметричное согласование ключей: протокол Диффи-Хеллмана на эллиптических кривых X25519 для генерации эфемерных ключевых пар с деривацией сессионного секрета через HKDF-SHA-256.
- Цифровые подписи идентичности: алгоритм 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).

Вместо «черного ящика» машинного обучения ранжирование публикаций в публичной ленте рассчитывается по детерминированной математической формуле:
Формула гармонично сочетает два фактора:
- Глобальный интерес (GlobalRelevance, вес 70%): рассчитывается логарифмически по формуле
log2(1 + likes + 2 * reposts + 3 * comments). Это предотвращает экспоненциальный отрыв вирусных тем от полезных постов. При этом действует штраф экспоненциального затухания по возрасту:exp(-0.05 * age_hours), благодаря чему лента непрерывно обновляется, а вчерашние публикации плавно уступают место новым. - Социальная близость (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 может открыть настройки и точно увидеть, почему конкретная публикация оказалась на первом месте в его ленте.
В текущей спецификации v1 используется асимметричный обмен X25519 с симметричным ключом сессии. Полноценный храповик Double Ratchet с гарантией Post-Compromise Security запланирован к реализации в спецификации FSCP v2.
Да, для доставки сообщений сервер обязан знать идентификаторы отправителя и получателя, а также размер зашифрованного пакета. Однако текст сообщений и вложения защищены сквозным шифрованием.
Flora Ecosystem наглядно демонстрирует, что социальные сети могут существовать без шпионажа за пользователями и непрозрачных алгоритмов, опираясь на честный открытый код и надежную математику.
