View tags
Один байт, который ускоряет сканирование кошелька в разы
С августа 2022 года (хардфорк v15) к каждому выходу прилагается 1 байт — view tag = первый байт Keccak("view_tag" ‖ 8rA ‖ i). Кошелёк сначала сверяет этот байт и только при совпадении (≈1 раз из 256) делает дорогую проверку. Сканирование ускоряется примерно на 40%.
Проблема
Чтобы проверить, наш ли выход, кошелёк делает две дорогие операции: 8·a·R (одна на транзакцию) и Hs(…)·G + B (одна на каждый выход). Вторая — умножение на базовую точку и сложение — заметная доля времени синхронизации. При этом в 99.99% случаев ответ «не наш».
Решение
Отправитель кладёт этот байт рядом с выходом. Получатель, вычислив общий секрет 8·a·R, считает тот же хеш (это быстро: хеш, а не операция на кривой) и сравнивает байт. Не совпал — выход точно не наш, дальше не считаем. Совпал — делаем полную проверку (иногда окажется, что это случайное совпадение: в 1/256 случаев).
Цена
Один дополнительный байт на выход. Приватность почти не страдает: view tag вычисляется из общего секрета, который знают только отправитель и получатель, поэтому для постороннего это случайный байт. Единственная утечка — для того, кто знает ключ просмотра (например, сервер light wallet): ему достаточно хеша, чтобы отсеять чужие выходы, — но он и так мог это сделать.
В Carrot view tag увеличится до 3 байт, а обмен ключами перейдёт на X25519 — сканирование станет ещё быстрее и ложных срабатываний станет в ~65 000 раз меньше.