Slashing covenants

Slashing covenants
2025-03-24 13:41 ` [bitcoindev] " Hunter Beast
  
From: Ethan Heilman @ 2024-11-24 21:13 UTC ( / )
  To: Bitcoin Development Mailing List

Slashing covenants is a protocol for covenants in Bitcoin via
incentives. A covenant is a set of rules about what transactions can
spend a Bitcoin output which is encumbered by that covenant. Typically
a covenant is enforced by preventing someone from spending that
output. In this protocol we instead allow the spending of the output
and then punish the spender by a loss of funds, i.e. we slash them, if
they do not follow the rules of the covenant. This is less secure than
a covenant enforced by an opcode, FE or ColliderScript, because it
relies on incentives over enforcement. The advantage of this approach
is that it is efficient, does not add new cryptographic assumptions
and is possible on Bitcoin today.

This protocol uses very similar mechanisms to BitVM, originally I
thought this was how BitVM worked, which is why I didn’t publish it.
After talking to many people it appears this technique is not used in
BitVM.


Notation
====
By <x>32 we denote a value, x, in Bitcoin Script which is encoded as a
list of 32-bit stack elements. We can perform arbitrary computation on
such values using Bitcoin’s math opcodes, a.k.a., Small Script.

Protocol
====
The essential problem for enforcing covenants in Bitcoin outputs is
showing that a signature s1 that will pass CHECKSIGVERIFY is equal to
a signature s2 encoded for Small Script. This is because once we get a
signature into Small Script, we extract the sighash and do transaction
introspection. ColliderScript gets us covenants by using hash
collisions to check equality between s1 and <s2>32. CAT gets us
covenants by simply concatenating all the <s2>32 and then comparing
against s1 using EQUAL:

s2 = CAT(<s2>32 [0], <s2>32 [1],  <s2>32 [2], … <s2>32 [15])
EQUAL s1, s2

Slashing covenants works by removing the requirement for this equality
check, but instead providing a fraud proof ifs1!=s2, and posting that
fraud proof to punish the spending party. To do this we construct a
Bitcoin script output which takes as input:

s1 - the spending signature.
<s2>32 - the spending signature encoded in small script. An honest
spender will set s1 = s2.
L - a Lamport signature on <s2>32.
<txn data>32 - data about the spending transaction that we use to open
the sighash

The Bitcoin script covenant output then:
1. checks s1 is a valid spending signature.
2. Checks that <s2>32 is validly signed by the Lamport signature L
3. Supplies <s2>32 and <txn data>32 to Small Script which enforces the
covenant under the assumption that s1=s2.

Covenant output (s1, <s2>32, L, <txn data>32):
  CHECKSIGVERIFY s1
  Lamport-Verify <s2>32, L
  SmallScript Enforce-Cov <s2>32, <txn data>32

As long as s1=s2 the covenant is enforced. However if s1!=s2 the
covenant can be broken. To punish spenders who set s1!=s2, we create
an output that allows anyone to burn/slash the coins of the rule
breaker if and only if they spent a covenant and supplied s1 and s2
such that  s1!=s2.

The Bitcoin script slash output takes as input: <s1>32, <s2>32, and L.

Slashing output (<s1>32, <s2>32, L):
  SmallScript CHECKSIGVERIFY <s1>32
  Lamport-Verify <s2>32, L
  IF <s1>32 != <s2>32: Verify

Thus the slashing output can only be spent if the rule breaker spent
the covenant with s1!=s2. SmallScript CHECKSIGVERIFY is used to prove
the rule breaker signed s1, the lamport signature is used to prove the
rule breaker signed s2. Thus, we have a fraud proof that the rule
breaker signed s1!=s2.  The Lamport signature is only used here to
avoid having to do ECC math in Small Script in the covenant.

Note that because we are doing CHECKSIGVERIFY in Small Script, the
spending transaction will be massive. The slashing occurs because of
the fees incurred by spending the slashing transaction. Note that such
a slashing output could also be done on ethereum. This would simplify
the construction.

For the purposes of explanation, we assumed the spender is also the
party who is slashed. In actual practice it is more likely you could
have a set of N slashable cosigners who could attest to a spend not
violating the covenant. Using pre-signed transactions you could
recover an output if all n slashable cosigners were indefinitely
offline. If you could fit a SNARKS in Small Script, you could have
people join and leave the cosigner set dynamically for already posted
covenant outputs by simply proving they have posted slash outputs and
that the value in covenants < value in slash outputs.

-- 
You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bitcoindev+unsubscribe@googlegroups•com.
To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/CAEM%3Dy%2BV_jUoupVRBPqwzOQaUVNdJj5uJy3LK9JjD7ixuCYEt-A%40mail.gmail.com.
2024-11-24 21:13 [bitcoindev] Slashing covenants Ethan Heilman

  2025-03-24 21:51   ` Ethan Heilman
  
From: Hunter Beast @ 2025-03-24 13:41 UTC (permalink / raw)
  To: Bitcoin Development Mailing List


[-- Attachment #1.1: Type: text/plain, Size: 5723 bytes --]

I'm surprised nobody's noticed this. It's an interesting approach. I 
wouldn't discount it because it relies on incentives, since bitcoin mining 
itself is secure only through cryptoeconomic incentives, and yet that's 
good enough. Plenty of things on bitcoin aren't perfect, but they're good 
enough to do the job.

Some questions...
- What are some of the advantages of using slashing covenants instead of 
BitVM? Could this make the approach more practical?
- Does this absolutely require OP_CAT to work?
- What is the rough size of such a transaction?

On Sunday, November 24, 2024 at 2:26:20 PM UTC-7 Ethan Heilman wrote:

> Slashing covenants is a protocol for covenants in Bitcoin via
> incentives. A covenant is a set of rules about what transactions can
> spend a Bitcoin output which is encumbered by that covenant. Typically
> a covenant is enforced by preventing someone from spending that
> output. In this protocol we instead allow the spending of the output
> and then punish the spender by a loss of funds, i.e. we slash them, if
> they do not follow the rules of the covenant. This is less secure than
> a covenant enforced by an opcode, FE or ColliderScript, because it
> relies on incentives over enforcement. The advantage of this approach
> is that it is efficient, does not add new cryptographic assumptions
> and is possible on Bitcoin today.
>
> This protocol uses very similar mechanisms to BitVM, originally I
> thought this was how BitVM worked, which is why I didn’t publish it.
> After talking to many people it appears this technique is not used in
> BitVM.
>
>
> Notation
> ====
> By <x>32 we denote a value, x, in Bitcoin Script which is encoded as a
> list of 32-bit stack elements. We can perform arbitrary computation on
> such values using Bitcoin’s math opcodes, a.k.a., Small Script.
>
> Protocol
> ====
> The essential problem for enforcing covenants in Bitcoin outputs is
> showing that a signature s1 that will pass CHECKSIGVERIFY is equal to
> a signature s2 encoded for Small Script. This is because once we get a
> signature into Small Script, we extract the sighash and do transaction
> introspection. ColliderScript gets us covenants by using hash
> collisions to check equality between s1 and <s2>32. CAT gets us
> covenants by simply concatenating all the <s2>32 and then comparing
> against s1 using EQUAL:
>
> s2 = CAT(<s2>32 [0], <s2>32 [1], <s2>32 [2], … <s2>32 [15])
> EQUAL s1, s2
>
> Slashing covenants works by removing the requirement for this equality
> check, but instead providing a fraud proof ifs1!=s2, and posting that
> fraud proof to punish the spending party. To do this we construct a
> Bitcoin script output which takes as input:
>
> s1 - the spending signature.
> <s2>32 - the spending signature encoded in small script. An honest
> spender will set s1 = s2.
> L - a Lamport signature on <s2>32.
> <txn data>32 - data about the spending transaction that we use to open
> the sighash
>
> The Bitcoin script covenant output then:
> 1. checks s1 is a valid spending signature.
> 2. Checks that <s2>32 is validly signed by the Lamport signature L
> 3. Supplies <s2>32 and <txn data>32 to Small Script which enforces the
> covenant under the assumption that s1=s2.
>
> Covenant output (s1, <s2>32, L, <txn data>32):
> CHECKSIGVERIFY s1
> Lamport-Verify <s2>32, L
> SmallScript Enforce-Cov <s2>32, <txn data>32
>
> As long as s1=s2 the covenant is enforced. However if s1!=s2 the
> covenant can be broken. To punish spenders who set s1!=s2, we create
> an output that allows anyone to burn/slash the coins of the rule
> breaker if and only if they spent a covenant and supplied s1 and s2
> such that s1!=s2.
>
> The Bitcoin script slash output takes as input: <s1>32, <s2>32, and L.
>
> Slashing output (<s1>32, <s2>32, L):
> SmallScript CHECKSIGVERIFY <s1>32
> Lamport-Verify <s2>32, L
> IF <s1>32 != <s2>32: Verify
>
> Thus the slashing output can only be spent if the rule breaker spent
> the covenant with s1!=s2. SmallScript CHECKSIGVERIFY is used to prove
> the rule breaker signed s1, the lamport signature is used to prove the
> rule breaker signed s2. Thus, we have a fraud proof that the rule
> breaker signed s1!=s2. The Lamport signature is only used here to
> avoid having to do ECC math in Small Script in the covenant.
>
> Note that because we are doing CHECKSIGVERIFY in Small Script, the
> spending transaction will be massive. The slashing occurs because of
> the fees incurred by spending the slashing transaction. Note that such
> a slashing output could also be done on ethereum. This would simplify
> the construction.
>
> For the purposes of explanation, we assumed the spender is also the
> party who is slashed. In actual practice it is more likely you could
> have a set of N slashable cosigners who could attest to a spend not
> violating the covenant. Using pre-signed transactions you could
> recover an output if all n slashable cosigners were indefinitely
> offline. If you could fit a SNARKS in Small Script, you could have
> people join and leave the cosigner set dynamically for already posted
> covenant outputs by simply proving they have posted slash outputs and
> that the value in covenants < value in slash outputs.
>

-- 
You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bitcoindev+unsubscribe@googlegroups•com.
To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/da040025-3ddd-4333-9c64-b4aab483ebb2n%40googlegroups.com.

[-- Attachment #1.2: Type: text/html, Size: 6618 bytes --]

 permalink raw reply	[|nested]
2025-03-24 13:41 ` [bitcoindev] " Hunter Beast

  
From: Ethan Heilman @ 2025-03-24 21:51 UTC (permalink / raw)
  To: Hunter Beast;  Bitcoin Development Mailing List

> What are some of the advantages of using slashing covenants instead of BitVM? Could this make the approach more practical?

You could use this as a separate mechanism to get covenants and then
use those covenants in BitVM. Is that useful to BitVM, I don't know,
someone who is a BitVM expert can supply a better answer.

> Does this absolutely require OP_CAT to work?

This does not require OP_CAT to work at all. It works today.

> What is the rough size of such a transaction?

SHA256 costs about 211kb of small script per compression function call
[0]. I think, if you are clever, you might be able to get away with
only one compression function call rather than two. Not sure how big
the ECC math would be. We could merklize some of the computation via
tapleaf, but probably at least a few hundred kilobytes.

That said, this huge slash transaction is only postable if the party
who vouched for the covenant spend cheats. The large size is actually
a feature not a bug to ensure the stake is burned rather than
reclaimed.

[0]: https://github.com/TomerStarkware/BitVM/tree/tomer/main

On Mon, Mar 24, 2025 at 9:55 AM Hunter Beast <hunter@surmount•systems> wrote:
>
> I'm surprised nobody's noticed this. It's an interesting approach. I wouldn't discount it because it relies on incentives, since bitcoin mining itself is secure only through cryptoeconomic incentives, and yet that's good enough. Plenty of things on bitcoin aren't perfect, but they're good enough to do the job.
>
> Some questions...
> - What are some of the advantages of using slashing covenants instead of BitVM? Could this make the approach more practical?
> - Does this absolutely require OP_CAT to work?
> - What is the rough size of such a transaction?
>
> On Sunday, November 24, 2024 at 2:26:20 PM UTC-7 Ethan Heilman wrote:
>>
>> Slashing covenants is a protocol for covenants in Bitcoin via
>> incentives. A covenant is a set of rules about what transactions can
>> spend a Bitcoin output which is encumbered by that covenant. Typically
>> a covenant is enforced by preventing someone from spending that
>> output. In this protocol we instead allow the spending of the output
>> and then punish the spender by a loss of funds, i.e. we slash them, if
>> they do not follow the rules of the covenant. This is less secure than
>> a covenant enforced by an opcode, FE or ColliderScript, because it
>> relies on incentives over enforcement. The advantage of this approach
>> is that it is efficient, does not add new cryptographic assumptions
>> and is possible on Bitcoin today.
>>
>> This protocol uses very similar mechanisms to BitVM, originally I
>> thought this was how BitVM worked, which is why I didn’t publish it.
>> After talking to many people it appears this technique is not used in
>> BitVM.
>>
>>
>> Notation
>> ====
>> By <x>32 we denote a value, x, in Bitcoin Script which is encoded as a
>> list of 32-bit stack elements. We can perform arbitrary computation on
>> such values using Bitcoin’s math opcodes, a.k.a., Small Script.
>>
>> Protocol
>> ====
>> The essential problem for enforcing covenants in Bitcoin outputs is
>> showing that a signature s1 that will pass CHECKSIGVERIFY is equal to
>> a signature s2 encoded for Small Script. This is because once we get a
>> signature into Small Script, we extract the sighash and do transaction
>> introspection. ColliderScript gets us covenants by using hash
>> collisions to check equality between s1 and <s2>32. CAT gets us
>> covenants by simply concatenating all the <s2>32 and then comparing
>> against s1 using EQUAL:
>>
>> s2 = CAT(<s2>32 [0], <s2>32 [1], <s2>32 [2], … <s2>32 [15])
>> EQUAL s1, s2
>>
>> Slashing covenants works by removing the requirement for this equality
>> check, but instead providing a fraud proof ifs1!=s2, and posting that
>> fraud proof to punish the spending party. To do this we construct a
>> Bitcoin script output which takes as input:
>>
>> s1 - the spending signature.
>> <s2>32 - the spending signature encoded in small script. An honest
>> spender will set s1 = s2.
>> L - a Lamport signature on <s2>32.
>> <txn data>32 - data about the spending transaction that we use to open
>> the sighash
>>
>> The Bitcoin script covenant output then:
>> 1. checks s1 is a valid spending signature.
>> 2. Checks that <s2>32 is validly signed by the Lamport signature L
>> 3. Supplies <s2>32 and <txn data>32 to Small Script which enforces the
>> covenant under the assumption that s1=s2.
>>
>> Covenant output (s1, <s2>32, L, <txn data>32):
>> CHECKSIGVERIFY s1
>> Lamport-Verify <s2>32, L
>> SmallScript Enforce-Cov <s2>32, <txn data>32
>>
>> As long as s1=s2 the covenant is enforced. However if s1!=s2 the
>> covenant can be broken. To punish spenders who set s1!=s2, we create
>> an output that allows anyone to burn/slash the coins of the rule
>> breaker if and only if they spent a covenant and supplied s1 and s2
>> such that s1!=s2.
>>
>> The Bitcoin script slash output takes as input: <s1>32, <s2>32, and L.
>>
>> Slashing output (<s1>32, <s2>32, L):
>> SmallScript CHECKSIGVERIFY <s1>32
>> Lamport-Verify <s2>32, L
>> IF <s1>32 != <s2>32: Verify
>>
>> Thus the slashing output can only be spent if the rule breaker spent
>> the covenant with s1!=s2. SmallScript CHECKSIGVERIFY is used to prove
>> the rule breaker signed s1, the lamport signature is used to prove the
>> rule breaker signed s2. Thus, we have a fraud proof that the rule
>> breaker signed s1!=s2. The Lamport signature is only used here to
>> avoid having to do ECC math in Small Script in the covenant.
>>
>> Note that because we are doing CHECKSIGVERIFY in Small Script, the
>> spending transaction will be massive. The slashing occurs because of
>> the fees incurred by spending the slashing transaction. Note that such
>> a slashing output could also be done on ethereum. This would simplify
>> the construction.
>>
>> For the purposes of explanation, we assumed the spender is also the
>> party who is slashed. In actual practice it is more likely you could
>> have a set of N slashable cosigners who could attest to a spend not
>> violating the covenant. Using pre-signed transactions you could
>> recover an output if all n slashable cosigners were indefinitely
>> offline. If you could fit a SNARKS in Small Script, you could have
>> people join and leave the cosigner set dynamically for already posted
>> covenant outputs by simply proving they have posted slash outputs and
>> that the value in covenants < value in slash outputs.
>
> --
> You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to bitcoindev+unsubscribe@googlegroups•com.
> To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/da040025-3ddd-4333-9c64-b4aab483ebb2n%40googlegroups.com.

-- 
You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bitcoindev+unsubscribe@googlegroups•com.
To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/CAEM%3Dy%2BVqDLC_2nBUk%2BiDLiP%3DH3tc3tgSb1A-diAxw%3DAZch24Xw%40mail.gmail.com.


 permalink raw reply	[|nested]