Спецификация · для разработчиков

Как Umbera шифрует

Технический обзор для разработчиков и криптографов: на каких стандартах построена Umbera, как сложены слои и что гарантирует каждый из них. Открытое криптоядро и его тесты позволяют проверить примитивы самому.

Для Umbera 2.x (Android, iPhone) и Umbera для компьютера. Ноябрь 2026.
01

Модель угроз

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

Цели: конфиденциальность и целостность содержимого; прямая секретность и восстановление после взлома в переписке 1:1; анонимность отправителя для сервера; никакой незаметной подмены ключей; постквантовая конфиденциальность в каждом слое, который несёт ключи содержимого.

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

02

Примитивы и стандарты

Только стандартизованные примитивы из известных проверенных библиотек; своей криптографии нет. Одно общее ядро даёт одинаковый результат на Android, iPhone и компьютерах.

Алгоритмы и стандарты
ML-KEM-1024, ML-KEM-768 — FIPS 203
ML-DSA-65 — FIPS 204
X25519 — RFC 7748 · Ed25519 — RFC 8032 · secp256k1
X-Wing hybrid KEM (X25519 + ML-KEM-768)
HKDF-SHA-256 — RFC 5869 · AES-256-GCM · ChaCha20-Poly1305 — RFC 8439
Argon2id — RFC 9106
MLS — RFC 9420 · Merkle transparency log — RFC 6962
03

Личность, код безопасности и прозрачность ключей

У каждого аккаунта гибридная личность для подписи и гибридная — для шифрования. Открытый адрес выводится из постквантового ключа подписи. Код безопасности одинаков у обоих. Версия 2 покрывает все четыре ключа личности — secp256k1, X25519, ML-DSA-65 и ML-KEM-1024 — и используется, когда обе стороны объявили её внутри своих зашифрованных сообщений; со старой версией пара возвращается к версии 1, которая покрывает классические ключи, а постквантовые тогда покрывает журнал прозрачности. Объявленная версия 2 закрепляется: если она пропадёт, приложение предупредит, что ключ изменился, а не откатится молча.

Сервер ведёт журнал Меркла, куда ключи только дописываются. Приложение проверяет вершину, подписанную Ed25519 и ML-DSA-65, и доказательство включения, поэтому справочник не может отдать ключ, которого нет в журнале, — в том числе постквантовый ключ и версию протокола, что не даёт незаметно откатить защиту.

Ключи и проверки
signing identity = secp256k1 + ML-DSA-65 (both signatures required)
encryption identity = X25519 + ML-KEM-1024
safety number v2 = H( sorted fingerprints of secp256k1 ‖ X25519 ‖ ML-DSA-65 ‖ ML-KEM-1024 ) — identical on both sides
negotiated: v2 only if both sides announce it; otherwise v1 over the classical keys
transparency: tree head signed with Ed25519 ∧ ML-DSA-65, served keys = logged keys, inclusion proof
04

Запечатанный конверт

Каждый конверт 1:1 запечатывается получателю классическим обменом и постквантовой капсулой. Выработка ключа привязана к хешу транскрипта — разового ключа, шифртекста ML-KEM и ключей получателя, — как в X-Wing. Полный конверт несёт свежую капсулу; между ними короткие конверты берут ключи из подтверждённого обеими сторонами секрета пары, который сдвигается по односторонней цепочке, поэтому капсула не повторяется в каждом сообщении. Отправитель едет внутри, поэтому сервер не видит, кто написал, а по адресу — кто получает. Конверты дополняются до классов размера.

Гибридное запечатывание
ss_c = X25519(ephemeral, recipient)
ss_q = ML-KEM-1024.Encaps(recipient)
TH = H( ephemeral key ‖ ML-KEM ciphertext ‖ recipient keys )
K = HKDF( ss_c ‖ ss_q , salt = TH , context )
short envelope: key from a confirmed pair secret via a one-way chain; a fresh capsule regularly
envelope = AEAD_K( sender identity ‖ ratchet message ‖ hybrid signature ) → padded
05

Double Ratchet с постквантовым шагом

Внутри конверта сессия Double Ratchet меняет ключи с каждым сообщением. В корневой ключ периодически подмешивается постквантовый секрет, поэтому записанная сегодня переписка останется закрытой, даже если классическую часть сломают потом, а сессия восстанавливается после кражи ключей.

Расписание ключей
classical step: (rk′, ck) = KDF_RK( rk, DH )
post-quantum step: (rk′, ck) = KDF_RK( rk, DH ‖ ML-KEM-1024 secret ) — periodically
chain step: (ck′, mk) = KDF_CK( ck )
properties: forward secrecy, post-compromise security, bounded skipped keys
06

Гибридные подписи

Сообщения, наборы ключей и сертификаты устройств несут две подписи — secp256k1 и ML-DSA-65. Подпись принимается, только если проходят обе, поэтому для подделки нужно сломать обе схемы.

07

Файлы

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

Ключи файлов
file = AEAD_fk( padded file ) fk — fresh random key per file
wrap = AEAD_W( fk ), W = HKDF( X25519 ‖ ML-KEM-1024 , salt = TH , file context )
08

Группы (MLS)

Группы работают на стандарте MLS с постквантовым набором X-Wing. Постквантовая защита покрывает каждую операцию раздачи ключей — приглашение, добавление и удаление участников и каждую смену эпохи, — а не только первый обмен. Существующие группы переводятся на месте вместе с историей.

Подписи участников MLS — Ed25519, как сегодня определяет стандарт. Поверх них каждый Commit, Proposal и Welcome несёт подпись ML-DSA-65 над кадром MLS и составом, а обычные сообщения каждого отправителя складываются в хеш-цепочку, которую регулярно закрывают контрольные подписи ML-DSA-65. Если участник объявил постквантовые подписи, изменение от его имени без такой подписи отвергается. Телефон подписывает ключом аккаунта, привязанный компьютер — своим ключом устройства, заверенным аккаунтом.

Каждый участник к тому же регулярно сам обновляет свой лист (Commit с UpdatePath), поэтому группа восстанавливается после кражи ключей, даже если никто не входит и не выходит. Участники со старой версией подпись ML-DSA-65 не ставят, их изменения принимаются по одной Ed25519.

Набор и охват
suite: MLS_256_XWING_CHACHA20POLY1305_SHA256_Ed25519
X-Wing protects every key distribution: Welcome, Commit / UpdatePath (add, remove, epoch change)
application messages: AEAD with keys from the epoch secret
PQ authentication: ML-DSA-65 over every Commit / Proposal / Welcome (MLS frame, member list)
+ regular ML-DSA-65 checkpoints over each sender’s message chain
post-compromise security: every member regularly refreshes its own leaf (Commit with UpdatePath)
migration: in place, same group, history kept; fallback for members without X-Wing
09

Звонки и показ экрана

Медиа шифруется DTLS-SRTP между устройствами, ретранслятор только пересылает шифр. Поскольку согласование ключей в DTLS классическое, каждый кадр звука, видео и экрана шифруется второй раз ключами из гибридного обмена, который едет внутри зашифрованной сквозным шифрованием настройки звонка. Звонок 1:1, перевод на другое устройство и каждая пара в конференции получают свои ключи.

Два слоя
layer 1: DTLS-SRTP between devices (relay forwards ciphertext)
layer 2: K_frames = HKDF( X25519 ‖ ML-KEM-1024 , transcript hash )
exchange carried inside the end-to-end encrypted call offer / answer
frame = AEAD_K_frames( frame ) inside SRTP — separate keys per direction and per connection
11

Сообщества

В каждом канале свой псевдоним со своими ключами, поэтому каналы нельзя связать ни друг с другом, ни с вашим аккаунтом. Вся асимметрия гибридная — Ed25519 + ML-DSA-65 для подписей, X25519 + ML-KEM-1024 для шифрования, — а приватные каналы шифруют посты, файлы и метаданные сквозным шифрованием.

12

Доставка и метаданные

Конверты идут на адреса доставки, которые могут вычислить только двое; они не связаны с аккаунтом, а когда новая версия у обеих сторон, выводятся ещё и из постквантового секрета конверта. С ближайшего выпуска адрес пары к тому же меняется каждую неделю; граница одна для всех, поэтому смена не выделяет отдельную переписку. Переход согласуется внутри зашифрованной переписки, а приложение слушает и соседние недели, поэтому на границе и пока устройство было не в сети ничего не теряется. С собеседником на старой версии и у связанных компьютеров адрес пока не меняется. Приложение опрашивает все свои ящики по одному соединению, поэтому сервер, наблюдая вживую, может сгруппировать адреса одного устройства. Пробуждающие уведомления идут на ящик пробуждения устройства, не связанный ни с одним адресом ящика; собеседники узнают его только из сообщений со сквозным шифрованием. Анонимные точки входа не несут токена аккаунта. Размеры дополняются, а сообщение в группу уходит отдельными конвертами в случайном порядке и с небольшой случайной задержкой. Соединение с сервером — TLS 1.3; с включённым Tor сервер не видит IP-адрес, без Tor — видит.

13

На устройстве

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

14

Почему это стойко

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

Независимого аудита пока нет. Заявки поданы, отчёт опубликуем целиком. Нашли проблему — пишите по контактам из SECURITY.md: исправим, выпустим исправление и расскажем, что было не так.

15

Проверьте сами

Криптоядро и его тесты открыты под Apache-2.0. Эталонные векторы закрепляют каждый примитив байт в байт. На странице «Доказательство» видно, как идут тесты и что ретранслятор записывает в Wireshark.

Запустить тесты
$ git clone https://github.com/UmberaAPP/UMBERA && cd UMBERA
$ cargo test