Технический › FCMP++

SA+L: право траты и key image

Обобщённый протокол Шнорра, который заменяет «подпись» в FCMP++

Коротко

SA+L (Spend Authorization + Linkability) — небольшое доказательство на Ed25519 для каждого входа. Оно показывает: «я знаю x и y для перерандомизированного ключа Õ, и опубликованный key image L равен x·I для того же выхода». Технически это обобщённый протокол Шнорра (GSP) — несколько уравнений Шнорра, связанных общими секретами.

Обобщённый Шнорр за одну минуту

Обычный Шнорр доказывает знание одного x в одном уравнении P = x·G. Обобщённый — знание вектора секретов (w₁, …, wₖ), удовлетворяющих нескольким линейным уравнениям над точками:

Y_j = Σ_k w_k · X_{j,k}    для каждого уравнения j

Протокол тот же, что и для одного ключа:

  1. выбрать случайные α_k и опубликовать A_j = Σ α_k·X_{j,k} для каждого уравнения;
  2. вызов c = Hs(всё опубликованное);
  3. ответы s_k = α_k + c·w_k;
  4. проверка: Σ s_k·X_{j,k} = A_j + c·Y_j для каждого j.

Ключевая деталь: один и тот же ответ s_k используется во всех уравнениях, где встречается w_k. Поэтому проверяющий убеждается не просто «знает какие-то секреты», а «знает одни и те же секреты для всех уравнений». Так и связываются право траты и key image.

Какие уравнения доказывает SA+L

Публично известны: Õ, Ĩ, R, L и генераторы G, T, U, V. Секреты тратящего: x, y (ключ выхода) и r_o, r_i, r_r_i (краска перерандомизации). Упрощённо SA+L доказывает систему:

Õ = x·G + (y + r_o)·T
R = r_i·V + r_r_i·T
L = x·Ĩ − (x·r_i)·U последнее — это L = x·(Ĩ − r_i·U) = x·I; произведение x·r_i вводится как отдельный секрет, а связь с R не даёт его подделать

Точная форма уравнений в спецификации немного другая (там аккуратно разбирается, какие произведения секретов нужны и как избежать утечек), но идея именно такая: одно доказательство, в котором x одновременно «открывает» Õ и «порождает» L.

Почему не просто подпись

В RingCT CLSAG делал три вещи одновременно: прятал вход в кольце, доказывал право траты и связывал key image. В FCMP++ первую задачу забирает membership proof. Остаются две — и они решаются гораздо более простым протоколом. Это даёт:

  • маленький размер — несколько точек и скаляров на вход;
  • разделение ролей — SA+L может посчитать устройство с ключом (аппаратный кошелёк), а тяжёлый membership proof — компьютер, у которого ключа нет;
  • forward secrecy — благодаря y·T в ключе (см. обзор);
  • заготовку для multisig — линейная структура GSP хорошо раскладывается между несколькими подписантами (FROST-подобные схемы).

Что подписывается

Вызов c включает хеш всей транзакции (префикс, выходы, обязательства), как и в CLSAG. Поэтому SA+L одновременно играет роль подписи: изменить хоть один байт транзакции после подписания — и доказательство перестанет сходиться.

Для любопытных

Формальные определения — в статье Люка Паркера о FCMP++ и в коде его реализации на Rust (проект monero-oxide). Протокол и реализация проходили внешние аудиты; ссылки на отчёты собираются в обсуждениях Monero Research Lab на GitHub.