Fa un temps, vam proposar un mecanisme per abordar un problema persistent en Bitcoin: la vulnerabilitat de les transaccions sense confirmacions (zero-confirmation o 0-conf) als atacs de doble despesa. Les transaccions 0-conf són aquelles que comerciants o serveis accepten abans que siguin confirmades en un bloc, sovint per motius pràctics com millorar l’experiència d’usuari i reduir els temps d’espera. El nostre objectiu era oferir una solució lleugera i compatible amb els incentius per dissuadir la doble despesa, sense necessitat de modificar les regles de consens de Bitcoin ni de confiar en terceres parts.

La solució que vam dissenyar, malauradament, va arribar abans d’hora (o potser massa tard?). El mecanisme depenia d’un opcode concret (OP_AND) que havia existit en el llenguatge de scripting de Bitcoin en els seus inicis, però que havia estat desactivat. Sense aquest opcode, la nostra construcció no es podia desplegar directament a Bitcoin. Tot i el seu potencial, la proposta va romandre teòrica.

Avançant fins avui, el panorama del scripting de Bitcoin ha revifat amb noves possibilitats. La comunitat està immersa en un debat intens sobre la reactivació de OP_CAT, un altre opcode dels primers dies de Bitcoin que es va eliminar per preocupacions relacionades amb la complexitat dels scripts. L’emoció al voltant de OP_CAT prové de les noves primitives potents que permet per als scripts de Bitcoin: covenants, smart contracts composables… i el nostre mecanisme de prevenció de doble despesa! Resulta que OP_CAT es pot utilitzar per implementar el nostre mecanisme de prevenció sense necessitat de OP_AND, mitjançant una construcció proposada per CremaLabs). En altres paraules, el renovat interès per l’extensibilitat dels scripts de Bitcoin podria, finalment, obrir la porta al desplegament de la nostra solució a la mainnet de Bitcoin.

En aquest article, primer resumirem les idees clau del nostre article original: com funciona el protocol, què pretén evitar i per què és útil. A continuació, explicarem com es pot implementar una variant del protocol utilitzant OP_CAT, proporcionant un exemple concret de com petits canvis en el llenguatge de scripting de Bitcoin poden desbloquejar millores significatives en la seguretat de les transaccions.

Double-spending prevention: The Original Version

La doble despesa (intentar gastar el mateix token digital més d’una vegada) és un dels desafiaments fonamentals que han d’afrontar les monedes digitals. A diferència dels diners físics, que són intrínsecament resistents a la duplicació i canvien de mans de manera tangible, els tokens digitals es poden copiar i reutilitzar fàcilment si no hi ha mecanismes de seguretat forts.

Bitcoin resol aquest problema mantenint un llibre de comptes només appendable, la cadena de blocs, que es replica a tots els nodes complets de la xarxa. Les transaccions es consideren finals un cop estan confirmades i incrustades a la cadena de blocs, fent que sigui computacionalment inviable revertir-les o duplicar-les sense un esforç considerable.

Tanmateix, per permetre pagaments més ràpids, molts usuaris i serveis de Bitcoin confien en les transaccions sense confirmació (zero-confirmation o 0-conf) — aquelles que han estat difoses a la xarxa però encara no han estat incloses en un bloc. Aquestes transaccions permeten pagaments instantanis en casos on la latència és crítica: comprar snacks a una màquina expenedora, pagar en un restaurant de menjar ràpid o retirar diners en un caixer compatible amb Bitcoin. Ara bé, aquesta comoditat té un preu: com que encara no han estat confirmades, aquestes transaccions no gaudeixen de la protecció de la cadena de blocs i són vulnerables a atacs de doble despesa.

En el nostre article, vam proposar un mecanisme per reduir aquesta vulnerabilitat i dissuadir la doble despesa en escenaris 0-conf. La idea consisteix a aprofitar la potència expressiva del llenguatge de scripting de Bitcoin juntament amb una propietat subtil i coneguda (una vulnerabilitat?) de l’algorisme de signatures ECDSA. Combinant aquests dos elements, la nostra construcció actua com un desincentiu per als atacants, fent que els intents de doble despesa siguin més arriscats i menys atractius en la pràctica.

Vulnerabilitat d’ECDSA

Originalment, Bitcoin utilitzava l’algorisme de signatura digital de corba el·líptica (ECDSA) per a l’autenticació de les transaccions. Tot i que l’actualització Taproot ha introduït les signatures Schnorr com a alternativa, la nostra proposta original es va desenvolupar dins del context d’ECDSA.

Una característica important d’ECDSA és que és probabilístic. Això vol dir que, per a un mateix missatge i una mateixa clau privada, no hi ha una única signatura possible. La signatura exacta generada depèn de l’elecció d’un enter aleatori, habitualment denotat com a k, que es selecciona de nou per a cada signatura. Aquesta aleatorietat és essencial per a la seguretat de l’algorisme.

Resum ràpid de com es calcula una signatura ECDSA:

  1. Es tria un enter aleatori k.
  2. Es calcula un punt (x, y) en la corba el·líptica multiplicant k pel punt generador G.
  3. Es defineix r = x mod q, que forma part de la signatura.
  4. El segon component, s, es calcula com s = k⁻¹ (m + r·d) mod q, on d és la clau privada i q és l’ordre de la corba.
  5. La signatura resultant consta de dos components, r i s.

El punt clau és que mai s’hauria de reutilitzar el mateix valor de k per a missatges diferents (amb la mateixa clau privada). Si això passa, i un atacant pot observar dues signatures amb el mateix r, pot recuperar la clau privada.

Aquesta vulnerabilitat està ben documentada i ha provocat fugues de claus en el món real, especialment en casos on hi havia mala generació d’aleatorietat o reutilització del k (com va passar en algunes implementacions de wallets de Bitcoin). En la nostra proposta, convertim aquesta vulnerabilitat en una funcionalitat, creant una mena de trampa d’incentius: si un atacant intenta fer una doble despesa, es juga la possibilitat de filtrar la seva pròpia clau privada.

Fixed-r Pay-to-Pubkey (FR-P2PK)

Per implementar la nostra defensa contra la doble despesa, introduïm un script personalitzat de Bitcoin que anomenem Fixed-r Pay-to-Pubkey (FR-P2PK). Aquesta construcció és una variant del conegut Pay-to-Pubkey (P2PK), que requereix una signatura vàlida per gastar una sortida. La innovació clau de FR-P2PK és que no n’hi ha prou amb que la signatura sigui vàlida: el valor r de la signatura ha de ser exactament un de concret i preestablert.

Aquest petit canvi té grans conseqüències. Degut a la vulnerabilitat d’ECDSA descrita abans, si un atacant intenta fer una doble despesa d’una sortida FR-P2PK transmetent dues transaccions diferents signades amb el mateix r, posa en risc la seva clau privada. Qualsevol node que vegi ambdues transaccions pot explotar la reutilització de r per recuperar la clau privada — i, amb ella, reclamar tots els fons de l’atacant.

L’estructura de l’script és la següent:


ScriptPubKey:  OP_DUP <pubKey> OP_CHECKSIGVERIFY
               OP_SIZE <0x47> OP_EQUALVERIFY
               <sigmask> OP_AND <r> OP_EQUAL

ScriptSig:     <sig>

Per gastar una sortida FR-P2PK, l’usuari ha de proporcionar una única signatura ECDSA. Aquesta signatura ha de verificar-se correctament contra la clau pública proporcionada i ha de contenir un valor r específic quan s’analitza. Si la signatura és malformada o si el valor de r no coincideix amb el requerit, l’script fallarà i la transacció serà invàlida.

En imposar un r fix, creem efectivament una trampa per a atacants. Els usuaris honestos no necessiten mai reutilitzar r (només signen una vegada, amb els paràmetres correctes). Però un actor maliciós que intenti fer una doble despesa de la mateixa sortida s’enfronta a un dilema perillós: signar dues vegades amb el mateix r obre la porta a una compromissió total de la clau privada.

Prevenció de la doble despesa amb OP_CAT i Schnorr

Una nova proposta de CremaLabs, anomenada PurrSettle , es basa en aquesta idea. Tot i que la nostra construcció original es recolzava en ECDSA i l’opcode OP_AND, PurrSettle adapta l’enfocament a les signatures Schnorr i a la reactivació proposada de OP_CAT.

En lloc d’encodar el valor r directament a l’scriptPubKey de la sortida, PurrSettle incrusta el valor r dins la sortida mitjançant un Taproot tweak, el qual compromet un script que conté r. El witness llavors proporciona s, i l’script el concatena amb r mitjançant OP_CAT per reconstruir la signatura completa. Aquesta signatura reconstruïda es verifica posteriorment amb OP_CHECKSIG.

L’estructura de l’script és la següent:


ScriptPubKey:  OP_1 <Q>
Witness:       <s> <OP_PUSHBYTES_32 R OP_SWAP OP_CAT OP_PUSHBYTES_32 P OP_CHECKSIG> <controlblock>

on <Q> és la clau de sortida Taproot, que compromet un arbre d’scripts que inclou un compromís amb R.

L’avaluació de la pila (stack evaluation) de l’script proposat s’explica al blog de PurrSettle blog, i es pot veure una transacció d’exemple que gasta una sortida FR-P2PK basada en Taproot al signet de StarkWare.

Tot i que la nostra proposta original per prevenir la doble despesa en transaccions sense confirmació (0-conf) a Bitcoin va assentar les bases per desincentivar aquest tipus d’atacs en pagaments ràpids, l’evolució de les capacitats de scripting de Bitcoin ha obert noves vies de millora. PurrSettle aprofita aquests avenços, utilitzant signatures Schnorr i l’opcode OP_CAT per refinar i enfortir el concepte. Dividint la signatura en dues parts (una compromesa a l’script i l’altra proporcionada durant la transacció), ofereix una manera d’implementar la vulnerabilitat de reutilització de k com a mecanisme preventiu contra la doble despesa.

A mesura que Bitcoin continua evolucionant, mecanismes com PurrSettle representen una direcció prometedora per a aplicacions pràctiques de seguretat criptogràfica en transaccions quotidianes.

Deixa un comentari