Pular para o conteúdo
ecdsa.com

ECDSA vs assinaturas Schnorr: o que o Taproot mudou

O Schnorr é o projeto mais antigo, mais simples e com prova de segurança mais sólida; o ECDSA existe em grande parte por causa de uma patente. A BIP-340 levou o Schnorr ao Bitcoin em 2021, e o EdDSA o levou a todo o resto.

ECDSA vs Schnorr hoje é sobretudo uma questão do Bitcoin, porque o Taproot (BIPs 340–342, ativadas em novembro de 2021) acrescentou assinaturas Schnorr ao lado do ECDSA na mesma curva, a secp256k1. Os dois esquemas usam as mesmas chaves e o mesmo problema difícil, mas a estrutura linear do Schnorr torna naturais as multiassinaturas, a assinatura de limiar e a verificação em lote, enquanto a estrutura do ECDSA as torna complicadas.

Visão geral

ECDSA (secp256k1)Schnorr (BIP-340, secp256k1)
Equação de assinaturas = k⁻¹·(z + r·d) mod ns = k + e·d mod n, e = H(R ‖ P ‖ m)
Chave pública33 bytes com compressão (65 sem compressão)32 bytes, só a coordenada x (x-only)
Assinatura64 bytes no formato compacto; 70–72 bytes em DER nos scripts do Bitcoin64 bytes
Maleabilidade(r, n − s) também é válida; o Bitcoin exige low-SNenhuma com a verificação da BIP-340
Recuperação da chave públicaPossível (ecrecover do Ethereum)Impossível
Agregação de chavesExige protocolos de computação multipartidáriaNativa (MuSig2, BIP-327)
Assinatura de limiarProtocolos complexos (GG18/20, CGGMP)FROST (RFC 9591)
Verificação em loteNãoSim
Prova de segurançaSó no modelo de grupo genéricoModelo do oráculo aleatório, logaritmo discreto
NormasFIPS 186-5, SEC 1BIP-340; o EdDSA (RFC 8032) é uma variante do Schnorr
Usado porBitcoin legado e SegWit v0, Ethereum, a maioria das cadeias EVMBitcoin Taproot, Nostr, implantações de FROST

Como eles diferem

Os dois assinam com um nonce secreto k e o ponto correspondente R = k·G. O ECDSA combina o hash z, a chave privada d e r (a coordenada x de R) por meio do inverso modular de k. Já o Schnorr calcula o hash do compromisso, da chave pública e da mensagem para obter um desafio e e responde com s = k + e·d, que o verificador confere como s·G = R + e·P.

Essa única escolha de projeto determina todo o resto:

  • Linearidade. Assinaturas Schnorr se somam. Vários signatários podem combinar nonces e respostas parciais em uma única assinatura, que passa na verificação com a soma das chaves deles. O MuSig2 (BIP-327) faz isso em duas rodadas para assinatura n de n; o FROST (RFC 9591) faz assinatura de limiar t de n. No ECDSA, o inverso de k quebra a linearidade, então o ECDSA de limiar exige protocolos multipartidários pesados, que carteiras e custodiantes usam, mas que já tiveram bugs graves.
  • Verificação em lote. Muitas assinaturas Schnorr podem ser verificadas juntas mais rápido do que uma a uma, o que importa na validação de blocos. O ECDSA não tem esse atalho.
  • Compromisso com a chave. Como e inclui o hash da chave pública, uma assinatura Schnorr não pode ser reaproveitada com outra chave, e a chave não pode ser recuperada a partir da assinatura. O ECDSA permite a recuperação da chave pública, da qual o Ethereum depende para economizar bytes; com Schnorr, é preciso transmitir a chave ou já conhecê-la.
  • Maleabilidade. No ECDSA, tanto (r, s) quanto (r, n − s) passam na verificação, então o Bitcoin exige low-S e DER estrito. A BIP-340 define uma única codificação, então terceiros não conseguem alterar uma assinatura válida.
  • Histórico. O esquema de Claus Schnorr, de 1989, foi patenteado, e o DSA (e depois o ECDSA) foi projetado para contornar a patente, que expirou em 2008, quando o ECDSA já estava consolidado. O EdDSA (2011) é uma variante determinística do Schnorr sobre curvas de Edwards.

O que o Taproot mudou na prática

Uma saída Taproot se vincula a uma única chave x-only de 32 bytes. O gasto pelo caminho da chave (key path) exige uma única assinatura Schnorr de 64 bytes, seja a chave de uma pessoa só, seja um agregado MuSig2 de várias, então um gasto multisig 2 de 2 ou 3 de 3 parece, na cadeia, um gasto comum com uma única assinatura. As condições alternativas de gasto ficam em uma árvore de Merkle de scripts, revelada apenas quando usada. O equivalente SegWit v0 de um gasto com uma única chave leva no witness uma assinatura ECDSA em DER de até 72 bytes, mais um byte de sighash e uma chave pública de 33 bytes.

O script abaixo, executado com a @noble/curves 2.3.0 no Node.js 26.10, mostra a diferença de tamanho para a mesma chave privada.

@noble/curves: ECDSA e Schnorr BIP-340 com uma única chave secp256k1
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));
Saída
ECDSA   public key: 33 bytes, signature: 64 bytes, valid: true
Schnorr public key: 32 bytes, signature: 64 bytes, valid: true

A forma compacta do ECDSA também tem 64 bytes, mas os scripts do Bitcoin carregam o ECDSA em DER, e o Ethereum acrescenta um byte de recuperação; a forma Schnorr é exatamente o que vai para a cadeia, sem alterações.

Armadilhas em comum

Nenhum dos dois esquemas perdoa um nonce ruim: reutilizar k em duas mensagens, ou vazar alguns bits dele repetidamente, revela a chave privada em ambos. A BIP-340 recomenda derivar o nonce da chave e da mensagem, misturadas com 32 bytes de aleatoriedade auxiliar nova. O Schnorr multipartidário acrescenta uma regra nova: os nonces do MuSig2 nunca devem ser derivados de forma determinística apenas a partir da mensagem, porque um atacante que controla outro participante consegue fazer o mesmo nonce assinar dois desafios agregados diferentes. Use implementações auditadas, como o módulo MuSig2 da libsecp256k1, em vez de combinar primitivas por conta própria.

Quando escolher cada um

  • Carteiras e saídas novas do Bitcoin: gastos Taproot pelo caminho da chave com Schnorr; MuSig2 para chaves multipartidárias quando os participantes conseguem se coordenar, e caminhos de script como alternativa de reserva.
  • Assinatura de mensagens no Bitcoin: BIP-322 para endereços Taproot, já que o formato mais antigo, o da BIP-137, só conhece ECDSA.
  • Ethereum e cadeias EVM: ECDSA, porque as transações, o ecrecover e as carteiras contam com ele; contas inteligentes podem verificar outros esquemas no código do contrato.
  • Nostr: Schnorr BIP-340, como exige a NIP-01.
  • Custódia com limiar: FROST quando os verificadores aceitam assinaturas Schnorr ou EdDSA; ECDSA de limiar apenas quando a cadeia de destino exige ECDSA.
  • Sistemas fora de blockchains: o Ed25519 oferece o projeto Schnorr com uma norma (RFC 8032), suporte nas bibliotecas e nonces determinísticos.

Notas de migração

No Bitcoin, a mesma chave privada pode produzir os dois tipos de assinatura, mas são as saídas que determinam o que é exigido: mover os fundos de saídas P2WPKH ou P2PKH para saídas P2TR é a migração.

  1. Atualize o software e o hardware das carteiras para versões com suporte ao Taproot (caminho de derivação BIP-86 m/86'/0'/0') e aos campos Taproot da PSBT.
  2. Use as chaves x-only corretamente: as chaves da BIP-340 descartam o byte de paridade e são ajustadas (tweaked) com o compromisso da árvore de scripts; não reutilize as codificações de chave pública do ECDSA.
  3. Passe a assinar mensagens com a BIP-322 para que seja possível provar o controle de endereços Taproot.
  4. Para multisig, escolha entre a agregação MuSig2 pelo caminho da chave (a mais privada e mais barata, mas interativa) e caminhos de script Tapscript com OP_CHECKSIGADD (não interativos, revelam a política quando usados).
  5. Continue verificando ECDSA nas saídas mais antigas; as regras de consenso aceitam os dois por tempo indeterminado.

Referências

Todas as comparações