10 KiB
Преобразование Ed25519 в X25519
Назначение
Этот документ фиксирует единое правило проекта SHiNE:
- публичная идентичность пользователя задаётся одним
clientKeyв форматеEd25519; - подпись пользовательских сообщений и команд выполняется ключом
Ed25519; - шифрование личных сообщений использует ключ
X25519, получаемый детерминированно из того же ключевого материала; - для преобразования используется только стандартное преобразование
Ed25519 <-> X25519; - самодельные формулы, альтернативные хэши и нестандартные схемы преобразования в проекте не допускаются.
Цель документа: исключить путаницу между ключом подписи и ключом шифрования и зафиксировать один общий способ преобразования для клиента, сервера и будущих реализаций.
Краткое правило
Если у пользователя есть:
- приватный ключ
Ed25519 private; - публичный ключ
Ed25519 public(clientKey);
то для шифрования личных сообщений из них получаются:
X25519 privateдля расшифровки своих копий;X25519 publicдля шифрования сообщений на этого пользователя.
При этом:
- в профиле пользователя по-прежнему публикуется только
clientKey; - отдельный публичный
dmEncKeyне требуется; - владелец устройства локально может использовать один и тот же исходный секрет и для подписи, и для вывода ключа шифрования.
Что считается стандартным преобразованием
Под "стандартным преобразованием" в проекте понимается совместимое с общепринятой практикой libsodium/NaCl преобразование:
- из
Ed25519 privateполучаетсяX25519 privateчерез стандартную процедуру на основе SHA-512 и clamping; - из
Ed25519 publicполучаетсяX25519 publicчерез стандартное преобразование точки Edwards в точку Montgomery.
Иными словами:
- приватный ключ шифрования должен получаться из приватного ключа подписи стандартным способом;
- публичный ключ шифрования должен получаться из публичного
clientKeyстандартным способом; - обе стороны должны получать одинаковый
X25519 publicпо одному и тому жеclientKey.
Преобразование приватного ключа
Исходные данные:
Ed25519 privateв SHiNE рассматривается как 32-байтный seed приватного ключа.
Стандартная процедура:
- Вычислить
SHA-512(seed32). - Взять первые 32 байта результата.
- Применить стандартный clamping для
X25519 private. - Полученный результат использовать как
X25519 private.
Замечания:
- нельзя использовать для
X25519 privateпросто исходный 32-байтныйEd25519 seedбез преобразования; - нельзя заменять
SHA-512наSHA-256,HMAC,HKDFили произвольную пользовательскую формулу; - clamping обязателен.
Преобразование публичного ключа
Исходные данные:
clientKeyпользователя в форматеEd25519 public(32 байта).
Стандартная процедура:
- Декодировать публичную точку Edwards из
Ed25519 public. - Выполнить стандартное преобразование Edwards -> Montgomery.
- Полученное значение использовать как
X25519 public.
На уровне математики используется стандартное отображение:
u = (1 + y) / (1 - y)
где y берётся из публичной точки Ed25519, а результат u кодируется как публичный ключ X25519.
Замечания:
- нельзя получать
X25519 publicпростым хэшированиемclientKey; - нельзя получать
X25519 public"через приватный ключ на сервере"; - любой клиент должен уметь вывести
X25519 publicдругого пользователя, имея только егоclientKey.
Что хранится в проекте
На текущем архитектурном уровне:
- в публичном профиле пользователя хранится только
clientKey(Ed25519 public); - приватная часть
clientKeyхранится только у владельца устройства; X25519 privateиX25519 publicсчитаются производными величинами и могут вычисляться по мере необходимости;- отдельный
keyIdдля DM пока не вводится.
Это означает:
- если в будущем пользователь сменит
clientKey, старые DM должны будут быть перешифрованы; - массовая перешифровка истории рассматривается как отдельная функция более позднего этапа;
- текущая архитектура должна оставлять возможность такой перешифровки, но не обязана реализовывать её прямо сейчас.
Как это применяется в DM
Для личных сообщений SHiNE:
- входящая копия сообщения шифруется на
X25519 public, полученный изclientKeyполучателя; - исходящая копия сообщения шифруется на
X25519 public, полученный изclientKeyотправителя; - расшифровать входящую копию может только владелец приватного ключа получателя;
- расшифровать исходящую копию может только владелец приватного ключа отправителя.
Следствия:
encryptedBodyу входящей и исходящей копии одного логического сообщения обычно разный;- сервер не должен требовать побайтного совпадения ciphertext у пары;
- сервер не должен уметь расшифровывать содержимое DM;
- подпись и шифрование используют один корневой секрет пользователя, но разные стандартно выведенные представления ключа.
Ограничения и компромиссы
Эта архитектура осознанно имеет следующие свойства:
- компрометация приватного
clientKeyодновременно даёт злоумышленнику возможность и подписывать от имени пользователя, и расшифровывать его личные сообщения; - отдельное разделение ключа подписи и ключа шифрования пока не используется;
- простота пользовательской модели и минимизация числа публичных ключей считаются в проекте более важными, чем разделение этих ролей на текущем этапе.
Если позже проекту понадобится более строгая модель безопасности, допускается переход на отдельный публичный ключ шифрования, но только как отдельная версия протокола.
Что запрещено
В проекте запрещено:
- придумывать собственное "детерминированное преобразование"
Ed25519 -> X25519; - хэшировать
clientKeyпроизвольным образом и считать результатX25519 public; - использовать
Ed25519 publicнапрямую как ключ ECDH; - использовать сырой
Ed25519 seedкакX25519 privateбез стандартной процедуры; - смешивать разные способы преобразования в разных клиентах.
Требование к реализациям
Любая реализация SHiNE, которая:
- подписывает DM;
- шифрует DM;
- расшифровывает DM;
- проверяет совместимость личных сообщений между устройствами;
обязана использовать именно этот подход.
Если библиотека уже предоставляет готовые совместимые функции преобразования Ed25519 -> X25519, нужно использовать их вместо самодельной реализации.