Мотивация
Некоторым людям не нравятся EdDSA или RedDSA. Мы должны предложить некоторые альтернативы и позволить им заслеплять подписи ECDSA.
Обзор
Это предложение описывает заслепление ключей для типов подписей ECDSA 1, 2, 3.
Предложение
Работает так же, как RedDSA, но все в формате Big Endian. Разрешены только одинаковые типы подписей, например, 1->1, 2->2, 3->3.
Определения
B Базовая точка кривой
L Порядок группы эллиптической кривой. Свойство кривой.
DERIVE_PUBLIC(a) Преобразование закрытого ключа в открытый путем умножения B на эллиптической кривой
alpha 32-байтовое случайное число, известное тем, кто знает пункт назначения.
GENERATE_ALPHA(destination, date, secret) Генерация alpha на текущую дату для тех, кто знает пункт назначения и секрет.
a Незаслепленный 32-байтовый закрытый ключ подписания, используемый для подписи пункта назначения
A Незаслепленный 32-байтовый открытый ключ подписания в пункте назначения, = DERIVE_PUBLIC(a), как на соответствующей кривой
a' Заслепленный 32-байтовый закрытый ключ подписания, используемый для подписи зашифрованного leaseset. Это действительный закрытый ключ ECDSA.
A' Заслепленный 32-байтовый открытый ключ подписания ECDSA в пункте назначения, может быть сгенерирован с помощью DERIVE_PUBLIC(a’), или из A и alpha. Это действительный открытый ключ ECDSA на кривой.
H(p, d) Функция хеширования SHA-256, которая принимает персонализированную строку p и данные d, и выдает результат длиной 32 байта.
Используйте SHA-256 следующим образом::
H(p, d) := SHA-256(p || d)
HKDF(salt, ikm, info, n) Криптографическая функция деривации ключей, которая принимает некоторый исходный материал ключа ikm (который должен иметь хорошую энтропию, но не обязательно быть равномерно случайной строкой), соль длиной 32 байта и значение ‘info’ специфичное для контекста, и выдает результат длиной n байт, пригодный для использования в качестве ключевого материала.
Используйте HKDF, как указано в [RFC-5869](https://tools.ietf.org/html/rfc5869), с использованием функции хеширования HMAC SHA-256
как указано в [RFC-2104](https://tools.ietf.org/html/rfc2104). Это означает, что SALT_LEN составляет 32 байта максимум.
Расчеты заслепления
Каждый день (UTC) должен генерироваться новый секрет alpha и заслепленные ключи. Секрет alpha и заслепленные ключи вычисляются следующим образом.
GENERATE_ALPHA(destination, date, secret), для всех участников:
// GENERATE_ALPHA(destination, date, secret)
// секрет является необязательным, иначе нулевой длины
A = открытый ключ подписания пункта назначения
stA = тип подписи A, 2 байта в big endian (0x0001, 0x0002 или 0x0003)
stA' = тип подписи заслепленного открытого ключа A', 2 байта в big endian, всегда такой же, как у stA
keydata = A || stA || stA'
datestring = 8 байт ASCII YYYYMMDD из текущей даты UTC
secret = строка в кодировке UTF-8
seed = HKDF(H("I2PGenerateAlpha", keydata), datestring || secret, "i2pblinding1", 64)
// рассматривайте seed как 64-байтовое значение в формате big-endian
alpha = seed mod L
BLIND_PRIVKEY(), для владельца, публикующего leaseset:
// BLIND_PRIVKEY()
alpha = GENERATE_ALPHA(destination, date, secret)
a = закрытый ключ подписания пункта назначения
// Сложение с использованием скалярной арифметики
заслепленный закрытый ключ подписания = a' = BLIND_PRIVKEY(a, alpha) = (a + alpha) mod L
заслепленный открытый ключ подписания = A' = DERIVE_PUBLIC(a')
BLIND_PUBKEY(), для клиентов, получающих доступ к leaseset:
// BLIND_PUBKEY()
alpha = GENERATE_ALPHA(destination, date, secret)
A = открытый ключ подписания пункта назначения
// Сложение с использованием элементов группы (точек на кривой)
заслепленный открытый ключ = A' = BLIND_PUBKEY(A, alpha) = A + DERIVE_PUBLIC(alpha)
Оба метода вычисления A’ дают одинаковый результат, как и требуется.
b33 адрес
Публичный ключ ECDSA представляет собой пару (X,Y), поэтому, например, для P256 он состоит из 64 байт, а не 32, как для RedDSA. Адрес b33 будет длиннее, или открытый ключ может быть сохранен в сжатом формате, как в кошельках Bitcoin.