Aller au contenu
ecdsa.com

Signatures ECDSA vs Schnorr : ce que Taproot a changé

Schnorr est la conception la plus ancienne, la plus simple et celle dont la sécurité se démontre le mieux ; ECDSA existe en grande partie à cause d’un brevet. BIP-340 a apporté Schnorr à Bitcoin en 2021, et EdDSA l’a apporté partout ailleurs.

ECDSA vs Schnorr est aujourd’hui surtout une question propre à Bitcoin, car Taproot (BIP 340 à 342, activé en novembre 2021) a ajouté les signatures Schnorr à côté d’ECDSA sur la même courbe, secp256k1. Les deux schémas utilisent les mêmes clés et reposent sur le même problème difficile, mais la structure linéaire de Schnorr rend naturelles les multisignatures, la signature à seuil et la vérification par lots, alors que la structure d’ECDSA les rend malaisées.

Vue d’ensemble

ECDSA (secp256k1)Schnorr (BIP-340, secp256k1)
Équation de signatures = k⁻¹·(z + r·d) mod ns = k + e·d mod n, e = H(R ‖ P ‖ m)
Clé publique33 octets en forme compressée (65 en forme non compressée)32 octets, coordonnée x seule (x-only)
Signature64 octets en forme compacte ; 70–72 octets en DER dans les scripts Bitcoin64 octets
Malléabilité(r, n − s) également valide ; Bitcoin impose low-SAucune avec la vérification BIP-340
Récupération de la clé publiquePossible (ecrecover d’Ethereum)Impossible
Agrégation de clésNécessite des protocoles de calcul multipartiteNative (MuSig2, BIP-327)
Signature à seuilProtocoles complexes (GG18/20, CGGMP)FROST (RFC 9591)
Vérification par lotsNonOui
Preuve de sécuritéUniquement dans le modèle du groupe génériqueModèle de l’oracle aléatoire, logarithme discret
NormesFIPS 186-5, SEC 1BIP-340 ; EdDSA (RFC 8032) est une variante de Schnorr
Utilisé parBitcoin historique et SegWit v0, Ethereum, la plupart des chaînes EVMBitcoin Taproot, Nostr, déploiements FROST

Ce qui les distingue

Les deux signent avec un nonce k secret et son point R = k·G. ECDSA combine le condensat z, la clé privée d et r (la coordonnée x de R) au moyen d’un inverse modulaire de k. Schnorr, lui, hache l’engagement, la clé publique et le message pour obtenir un challenge e et répond par s = k + e·d, que le vérificateur contrôle sous la forme s·G = R + e·P.

Ce seul choix de conception détermine tout le reste :

  • Linéarité. Les signatures Schnorr s’additionnent. Plusieurs signataires peuvent combiner leurs nonces et leurs réponses partielles en une seule signature, qui se vérifie avec la somme de leurs clés. MuSig2 (BIP-327) le fait en deux tours pour une signature n parmi n ; FROST (RFC 9591) réalise une signature à seuil t parmi n. Avec ECDSA, l’inverse de k rompt la linéarité : l’ECDSA à seuil exige donc de lourds protocoles multipartites, que les portefeuilles et les dépositaires utilisent, mais qui ont connu de graves bugs.
  • Vérification par lots. De nombreuses signatures Schnorr peuvent être vérifiées ensemble plus vite qu’une par une, ce qui compte pour la validation des blocs. ECDSA n’offre aucun raccourci de ce genre.
  • Engagement sur la clé. Comme e intègre la clé publique dans le hachage, une signature Schnorr ne peut pas être réutilisée avec une autre clé, et la clé ne peut pas être retrouvée à partir de la signature. ECDSA permet la récupération de la clé publique, dont Ethereum dépend pour économiser des octets ; avec Schnorr, vous devez transmettre ou connaître la clé.
  • Malléabilité. Avec ECDSA, (r, s) et (r, n − s) se vérifient tous deux : Bitcoin impose donc low-S et un DER strict. BIP-340 fixe un encodage unique, si bien que des tiers ne peuvent pas modifier une signature valide.
  • Historique. Le schéma de Claus Schnorr de 1989 était breveté, et DSA (puis ECDSA) a été conçu pour contourner ce brevet ; celui-ci a expiré en 2008, alors qu’ECDSA était déjà solidement implanté. EdDSA (2011) est une variante déterministe de Schnorr sur courbes d’Edwards.

Ce que Taproot a changé en pratique

Une sortie Taproot s’engage sur une seule clé x-only de 32 octets. Une dépense par le chemin de clé (key path) n’exige qu’une signature Schnorr de 64 octets, que cette clé appartienne à une seule personne ou soit un agrégat MuSig2 de plusieurs clés : une dépense multisig 2 parmi 2 ou 3 parmi 3 ressemble donc, sur la chaîne, à n’importe quelle dépense à signature unique. Les conditions de dépense alternatives se trouvent dans un arbre de Merkle de scripts, qui n’est révélé qu’au moment de son utilisation. L’équivalent SegWit v0 d’une dépense à clé unique transporte dans le témoin une signature ECDSA DER d’au plus 72 octets, plus un octet de sighash et une clé publique de 33 octets.

Le script ci-dessous, exécuté avec @noble/curves 2.3.0 sous Node.js 26.10, montre la différence de taille pour une même clé secrète.

@noble/curves : ECDSA et Schnorr BIP-340 avec une seule clé 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));
Sortie
ECDSA   public key: 33 bytes, signature: 64 bytes, valid: true
Schnorr public key: 32 bytes, signature: 64 bytes, valid: true

La forme compacte d’ECDSA fait elle aussi 64 octets, mais les scripts Bitcoin transportent ECDSA en DER et Ethereum ajoute un octet de récupération ; la forme Schnorr est celle qui est inscrite telle quelle sur la chaîne.

Pièges communs

Aucun des deux schémas ne pardonne un mauvais nonce : réutiliser k pour deux messages, ou en laisser fuiter quelques bits de façon répétée, révèle la clé privée dans les deux cas. BIP-340 recommande de dériver le nonce de la clé et du message, mélangés à 32 octets d’aléa auxiliaire frais. La signature Schnorr multipartite ajoute une nouvelle règle : les nonces MuSig2 ne doivent jamais être dérivés de façon déterministe à partir du seul message, car un attaquant qui contrôle un autre participant peut faire signer deux challenges agrégés différents avec le même nonce. Utilisez des implémentations auditées, comme le module MuSig2 de libsecp256k1, plutôt que d’assembler vous-même des primitives.

Quand choisir l’un ou l’autre

  • Nouveaux portefeuilles et nouvelles sorties Bitcoin : dépenses Taproot par le chemin de clé avec Schnorr ; MuSig2 pour les clés multipartites lorsque les participants peuvent se coordonner, chemins de script pour les solutions de repli.
  • Signature de messages Bitcoin : BIP-322 pour les adresses Taproot, car l’ancien format BIP-137 ne connaît qu’ECDSA.
  • Ethereum et chaînes EVM : ECDSA, car les transactions, ecrecover et les portefeuilles l’attendent ; les comptes intelligents peuvent vérifier d’autres schémas dans le code du contrat.
  • Nostr : Schnorr BIP-340, comme l’exige NIP-01.
  • Conservation des fonds par signature à seuil : FROST lorsque les vérificateurs acceptent les signatures Schnorr ou EdDSA ; ECDSA à seuil uniquement lorsque la chaîne cible exige ECDSA.
  • Systèmes hors blockchain : Ed25519 vous offre la conception Schnorr avec une norme (RFC 8032), la prise en charge des bibliothèques et des nonces déterministes.

Notes de migration

Sur Bitcoin, la même clé secrète peut produire les deux types de signature, mais ce sont les sorties qui déterminent ce qui est exigé : la migration consiste à déplacer les fonds de sorties P2WPKH ou P2PKH vers des sorties P2TR.

  1. Mettez à jour les logiciels et le matériel de portefeuille vers des versions qui prennent en charge Taproot (chemin de dérivation BIP-86 m/86'/0'/0') et les champs Taproot des PSBT.
  2. Utilisez correctement les clés x-only : les clés BIP-340 omettent l’octet de parité, et les clés sont ajustées (tweaked) avec l’engagement sur l’arbre de scripts ; ne réutilisez pas les encodages de clé publique ECDSA.
  3. Passez à BIP-322 pour la signature de messages afin de pouvoir prouver la propriété d’adresses Taproot.
  4. Pour le multisig, choisissez entre l’agrégation MuSig2 par le chemin de clé (la plus confidentielle et la moins coûteuse, mais interactive) et les chemins de script Tapscript avec OP_CHECKSIGADD (non interactifs, ils révèlent la politique lors de leur utilisation).
  5. Continuez à vérifier ECDSA pour les sorties plus anciennes ; les règles de consensus prennent en charge les deux indéfiniment.

Références

Tous les comparatifs