Blinded ID в Session и что с ними не так
Blinded ID (aka "слепые" айди и т.п) - алгоритм деривации публичного ключа (ID) пользователя для открытых групп в Session, для того чтобы скрыть настоящий ID пользователя, тем самым обеспечить некую приватность.
Всего существует две версии данного алгоритма:
На данный момент полностью реализованной является legacy версия, а поддержка новой версии есть только в libsession и вроде как планируется в pysogs.
Один ключ -> два ключа. Legacy версия.
Алгоритм
Для работы алгоритма нам понадобится:
- Генерируем так называемый "blinding factor": хэшируем с помощью Blake2B публичный ключ сервера и скалярно уменьшаем результат.
Обозначим, какk
. - Из ID юзера убираем префикс 05 и переводим его в ed25519.
Обозначим, какA
. - Перемножаем скаляр
k
наA
и получаем ключ ed25519, который является одним из возможных "слепых" id.
Обозначим, какkA
.
Сломанное условие
Как следует из заголовка, legacy версия генерирует 2 возможных "слепых" ID.
Второй возможный ID (kA2
) генерируется на основе kA
, только с изменённым (XOR на 128) MSB битом.
И для того чтобы выяснить какой из двух ключей следует использовать, pysogs предлагает следующий код:
if kA[31] & 0x80: return kA[0:31] + bytes([kA[31] & 0x80])
Однако это условие совершенно не работает, поэтому в реализации клиентов пошли другим путём - получение "слепого" id из приватного ключа, вместо того чтобы получать его из публичного ключа. Таким образом сервер не знает наверняка, какой ключ из двух следует использовать, и надеется на клиент в результате чего в теории может произойти раздвоение пользователя.
Обратимая необратимость
Так же немало важным является то, что legacy версия (а фактически единственная версия на момент написания статьи) является обратимой вопреки всем заявлениям.
Для этого достаточно скалярно инвертировать полученный ранее "blinding factor", перемножить его на слепой id, полученный ключ перевести в Curve25519 и в результате мы имеем ID пользователя.
Один ключ -> один ключ. Новая версия
На момент написания статьи эта версия реализована только в libsession, и поэтому может поменяться.
Самое главное отличие этой версии от legacy в том, что в процессе генерации "blinding factor" принимает участие ID пользователя вместе с публичным ключом сервера, что, в свою очередь, исключает возможность обратимости, как это было с legacy версией.
- Генерируем так называемый "blinding factor": хэшируем с помощью Blake2B ID пользователя (вместе с префиксом) и публичный ключ сервера и скалярно уменьшаем результат.
Обозначим, какk
. - Переводим ID юзера из Curve25519 в ed25519.
Обозначим, какA
. - Перемножаем скаляр
k
наA
На выходе получаем единственный Blinded ID для конкретного пользователя на конкретном сервере.