Сегодня выбор между ECDSA и Schnorr касается в основном Bitcoin: Taproot (BIP 340–342, активирован в ноябре 2021 года) добавил подписи Schnorr наряду с ECDSA на той же кривой secp256k1. Обе схемы используют одни и те же ключи и опираются на одну и ту же трудную задачу, но линейная структура Schnorr делает мультиподписи, пороговое подписание и пакетную проверку естественными, а структура ECDSA превращает их в громоздкие конструкции.
Коротко о главном
| ECDSA (secp256k1) | Schnorr (BIP-340, secp256k1) | |
|---|---|---|
| Уравнение подписи | s = k⁻¹·(z + r·d) mod n | s = k + e·d mod n, e = H(R ‖ P ‖ m) |
| Открытый ключ | 33 байта в сжатой форме (65 в несжатой) | 32 байта, только координата x (x-only) |
| Подпись | 64 байта в компактной форме; 70–72 байта в DER в скриптах Bitcoin | 64 байта |
| Пластичность | (r, n − s) тоже верна; Bitcoin требует low-S | Отсутствует при проверке по BIP-340 |
| Восстановление открытого ключа | Возможно (ecrecover в Ethereum) | Невозможно |
| Агрегирование ключей | Нужны протоколы многосторонних вычислений | Встроено (MuSig2, BIP-327) |
| Пороговое подписание | Сложные протоколы (GG18/20, CGGMP) | FROST (RFC 9591) |
| Пакетная проверка | Нет | Да |
| Доказательство стойкости | Только в модели универсальной группы (generic group model) | В модели случайного оракула, через задачу дискретного логарифмирования |
| Стандарты | FIPS 186-5, SEC 1 | BIP-340; EdDSA (RFC 8032) — вариант Schnorr |
| Где используется | Устаревшие выходы Bitcoin и SegWit v0, Ethereum, большинство EVM-сетей | Bitcoin Taproot, Nostr, системы на FROST |
Чем они различаются
Обе схемы подписывают с помощью секретного одноразового числа nonce k и соответствующей ему точки R = k·G. ECDSA смешивает хеш z, закрытый ключ d и r (координату x точки R) через обратный по модулю элемент к k. Schnorr вместо этого хеширует обязательство (commitment), открытый ключ и сообщение в вызов (challenge) e и отвечает значением s = k + e·d, а проверяющая сторона сверяет его с равенством s·G = R + e·P.
Из этого единственного проектного решения следует всё остальное:
- Линейность. Подписи Schnorr складываются. Несколько подписантов могут объединить свои nonce и частичные ответы в одну подпись, которая проходит проверку по сумме их ключей. MuSig2 (BIP-327) делает это за два раунда для подписи n из n; FROST (RFC 9591) реализует пороговую подпись t из n. В ECDSA обращение
kнарушает линейность, поэтому пороговому ECDSA нужны тяжёлые многосторонние протоколы; кошельки и кастодиальные сервисы ими пользуются, но в этих протоколах уже находили серьёзные ошибки. - Пакетная проверка. Много подписей Schnorr можно проверить вместе быстрее, чем по одной, а это важно при проверке блоков. У ECDSA такого способа ускорения нет.
- Привязка к ключу. Поскольку в хеш
eвходит открытый ключ, подпись Schnorr нельзя использовать повторно с другим ключом, а сам ключ нельзя восстановить по подписи. ECDSA допускает восстановление открытого ключа, на которое Ethereum полагается, чтобы экономить байты; со Schnorr ключ нужно передать или знать заранее. - Пластичность. В ECDSA проверку проходят и
(r, s), и(r, n − s), поэтому Bitcoin требует low-S и строгий DER. BIP-340 фиксирует единственную кодировку, так что третьи лица не могут изменить верную подпись. - История. Схема Клауса Шнорра (Claus Schnorr) 1989 года была запатентована, и DSA (а позже ECDSA) разработали так, чтобы обойти этот патент; срок его действия истёк в 2008 году, когда ECDSA уже прочно укоренилась. EdDSA (2011) — детерминированный вариант Schnorr на кривых Эдвардса.
Что Taproot изменил на практике
Выход Taproot привязан к одному 32-байтному ключу x-only. Для траты по ключу (key path) нужна одна 64-байтная подпись Schnorr, независимо от того, принадлежит ли ключ одному человеку или это агрегат MuSig2 из ключей нескольких участников, поэтому трата с мультиподписью 2 из 2 или 3 из 3 выглядит в блокчейне как любая трата с одной подписью. Альтернативные условия траты хранятся в дереве Меркла из скриптов, которое раскрывается только при использовании. Эквивалентная трата с одним ключом в SegWit v0 несёт в witness подпись ECDSA в DER длиной до 72 байт, байт sighash и 33-байтный открытый ключ.
Скрипт ниже, запущенный с @noble/curves 2.3.0 на Node.js 26.10, показывает разницу в размерах для одного и того же секретного ключа.
import { secp256k1, schnorr } from "@noble/curves/secp256k1.js";
import { sha256 } from "@noble/hashes/sha2.js";
import { utf8ToBytes } from "@noble/hashes/utils.js";
const secretKey = secp256k1.utils.randomSecretKey();
const msg = sha256(utf8ToBytes("pay 0.01 BTC to bc1p..."));
// ECDSA: 33-byte compressed public key, 64-byte compact (r, s) signature.
const ecdsaPub = secp256k1.getPublicKey(secretKey, true);
const ecdsaSig = secp256k1.sign(msg, secretKey, { prehash: false });
// BIP-340 Schnorr: 32-byte x-only public key, 64-byte (R.x, s) signature.
const schnorrPub = schnorr.getPublicKey(secretKey);
const schnorrSig = schnorr.sign(msg, secretKey);
console.log("ECDSA public key:", ecdsaPub.length, "bytes, signature:", ecdsaSig.length, "bytes, valid:", secp256k1.verify(ecdsaSig, msg, ecdsaPub, { prehash: false }));
console.log("Schnorr public key:", schnorrPub.length, "bytes, signature:", schnorrSig.length, "bytes, valid:", schnorr.verify(schnorrSig, msg, schnorrPub));
ECDSA public key: 33 bytes, signature: 64 bytes, valid: true
Schnorr public key: 32 bytes, signature: 64 bytes, valid: true
Компактная форма ECDSA тоже занимает 64 байта, но в скриптах Bitcoin подпись ECDSA передаётся в DER, а Ethereum добавляет байт восстановления; подпись Schnorr попадает в блокчейн в исходном виде.
Общие подводные камни
Ни одна из схем не прощает плохого nonce: если использовать k повторно для двух сообщений или раз за разом допускать утечку нескольких его бит, закрытый ключ раскрывается в обеих схемах. BIP-340 рекомендует выводить nonce из ключа и сообщения, подмешивая 32 байта свежих вспомогательных случайных данных. Многосторонний Schnorr добавляет новое правило: nonce в MuSig2 никогда нельзя выводить детерминированно из одного только сообщения, потому что атакующий, который контролирует другого участника, может добиться, чтобы один и тот же nonce подписал два разных агрегированных вызова. Используйте реализации, прошедшие аудит, например модуль MuSig2 из libsecp256k1, а не собирайте схему из примитивов самостоятельно.
Что когда выбирать
- Новые кошельки и выходы Bitcoin: траты Taproot по ключу с подписью Schnorr; MuSig2 для ключей нескольких участников, если они могут координировать свои действия, и траты по скрипту (script path) как запасной вариант.
- Подпись сообщений Bitcoin: BIP-322 для адресов Taproot, поскольку более старый формат BIP-137 знает только ECDSA.
- Ethereum и EVM-сети: ECDSA, потому что на эту схему рассчитаны транзакции,
ecrecoverи кошельки; смарт-аккаунты могут проверять подписи других схем в коде контракта. - Nostr: Schnorr по BIP-340, как требует NIP-01.
- Пороговое хранение средств: FROST там, где проверяющие стороны принимают подписи Schnorr или EdDSA; пороговый ECDSA — только там, где целевая сеть требует ECDSA.
- Системы вне блокчейнов: Ed25519 даёт устройство Schnorr вместе со стандартом (RFC 8032), поддержкой в библиотеках и детерминированными nonce.
Заметки о миграции
В Bitcoin один и тот же секретный ключ может создавать подписи обоих видов, но какая подпись требуется, зависит от выходов: миграция и состоит в переводе средств с выходов P2WPKH или P2PKH на выходы P2TR.
- Обновите программные и аппаратные кошельки до версий, которые поддерживают Taproot (путь деривации BIP-86
m/86'/0'/0') и поля Taproot в PSBT. - Правильно используйте ключи x-only: в ключах BIP-340 нет байта чётности, а сами ключи модифицируются (tweak) обязательством дерева скриптов; не используйте повторно кодировки открытых ключей ECDSA.
- Переведите подпись сообщений на BIP-322, чтобы адреса Taproot могли подтверждать владение.
- Для мультиподписи выберите между агрегированием ключей MuSig2 для траты по ключу (самый конфиденциальный и дешёвый вариант, но подписание интерактивное) и тратами по скрипту Tapscript с
OP_CHECKSIGADD(подписание неинтерактивное, но при использовании политика раскрывается). - Продолжайте проверять ECDSA для старых выходов: правила консенсуса поддерживают обе схемы бессрочно.