This is the second entry in a series thoroughly exploring individual covenant proposals that have achieved a level of development warranting a detailed analysis.
CHECKSIGFROMSTACK (CSFS), introduced by Brandon Black and Jeremy Rubin through BIP 348, is not categorized as a covenant. As mentioned in the introductory piece of this series, some of the proposals I will discuss are not covenants themselves, but they collaborate or connect with them in certain aspects. CSFS serves as the primary illustration of that concept.
CSFS is an exceptionally straightforward opcode, but before diving into its operation, let’s review the fundamentals of how a Bitcoin script functions.
Script is structured as a stack-based language. This signifies that data is “stacked” atop one another in the stack, and manipulated by removing an item from the stack’s peak to execute operations based on an opcode, either yielding the data or a resulting value which is then placed back at the top of the stack.
When a script is ultimately executed and authenticated, it comprises two segments, the “witness” provided to unlock the script, and the script embedded in the output being utilized. The witness/unlocking script is “appended” to the left side of the locking script, and subsequently, each element is added to (or processes on) the stack sequentially from left to right. Consider this example (the “|” signifies the division between the witness and the script):
1 2 | OP_ADD 3 OP_EQUAL
This example script contributes the value “1” to the stack, followed by the value “2” stacked on top. OP_ADD takes the two uppermost elements of the stack and adds them, returning the result back onto the stack (thus resulting in “3”). A further “3” is then added to the stack. The final command, OP_EQUAL, takes the top two items from the stack and returns a “1” (where 1 and 0 can denote True or False as well as numerical values).
A script must conclude with the last item on the stack being True; otherwise, the script (and the transaction executing it) fails and is deemed consensus invalid.
This is a foundational instance of a pay-to-pubkey-hash (P2PKH) script, i.e., the legacy addresses beginning with a “1”:
Initially, the signature and the public key are pushed onto the stack. Then DUP is invoked, which takes the top stack item and duplicates it, placing it back at the top of the stack. HASH160 processes the top stack item (the duplicated public key), hashes it, and then returns it to the top of the stack. The public key hash from the script is positioned at the uppermost part of the stack. EQUALVERIFY operates similarly to EQUAL, capturing the two top stack items and yielding a 1 or 0 depending on the result. The only distinction is that EQUALVERIFY also executes VERIFY following EQUAL, which invalidates the transaction if the top stack item is not 1, as well as removing this upper item. Finally, CHECKSIG is executed, which retrieves the two top elements of the stack, presuming them to be a signature and a public key, and validates the signature implicitly against the hash of the transaction being authenticated. If valid, it places a 1 on the stack.
How CSFS Operates
CHECKSIG is among the most frequently utilized opcodes in Bitcoin. Almost every transaction uses this opcode at some stage in its scripts. Signature verification is a crucial element of the Bitcoin protocol. The challenge is that there exists minimal flexibility regarding what message the signature is being verified against. CHECKSIG will exclusively authenticate a signature corresponding to the transaction being validated. There is some flexibility, meaning you can select with a certain degree of freedom which sections of the transaction the signature pertains to, but that’s the extent of it.
CSFS intends to alter this by allowing a signature to be verified against any arbitrary message directly pushed onto the stack, rather than being restricted to signature validations against the transaction itself. The opcode adheres to a straightforward operational framework:
The signature and message are placed on the stack, succeeded by the public key on top, and finally, CSFS retrieves the three top items from the stack, treating them as the public key, message, and signature from top to bottom, verifying the signature against the message. If the signature checks out, a 1 is pushed onto the stack.
That’s all. A simplistic variation of CHECKSIG that enables users to define arbitrary messages rather than being limited to just the spending transaction.
What Is CSFS Beneficial For
So, what precisely is the advantage? What is the purpose of verifying a signature against a random message on the stack instead of the spending transaction?
First and foremost, when combined with CTV, it can yield features equivalent to what Lightning developers have aspired to since the very onset, floating signatures that can link to different transactions. This was initially proposed as a new sighash flag for signatures (the component that determines which parts of a transaction a signature pertains to). This necessity arose because a transaction signature encompasses the transaction ID of the transaction that executed the output being spent. Consequently, the signature remains valid solely for a transaction that spends that exact output.
This functionality is sought after in Lightning as it would eliminate channel penalties. Each prior state of Lightning requires a penalty key and transaction to ensure that your channel counterpart does not use any of them to attempt to claim funds that are not theirs. If they attempt to do so, you can reclaim all their funds. An enhanced feature would be one that permits you to simply “attach” the current state transaction to any previous ones, thereby preventing theft attempts through proper fund distribution instead of just confiscation.
This can be realized with a basic script that utilizes a CTV hash and a signature over it, which is validated using CSFS. This would enable any transaction hash endorsed by that CSFS key to spend any output created using this script.
Another significant feature is the delegation of control over a UTXO. Similar to how any CTV hash signed by a CSFS key can authentically spend a UTXO structured for that purpose, other parameters can be incorporated into the script for verification, such as a new public key. A script could be designed enabling a CSFS key to authorize any public key, which could then be authenticated using CSFS before being employed for a conventional CHECKSIG validation. This capability would allow you to assign the authority to spend a UTXO to another user without requiring on-chain movement.
Lastly, alongside CAT, CSFS can be utilized to construct significantly more advanced introspection functionalities. However, as we will explore later in the series, CSFS is not inherently necessary to replicate any of this more sophisticated behavior since CAT can accomplish it independently.
Final Thoughts
CSFS is a remarkably fundamental opcode that, apart from providing straightforward yet valuable functionality on its own, integrates seamlessly with even the simplest covenant opcodes to yield highly useful capabilities. While the previous example relating to floating signatures specifically pertains to the Lightning Network, floating signatures represent a broadly beneficial primitive applicable to any protocol constructed on Bitcoin which utilizes pre-signed transactions.
Beyond floating signatures, script delegation emerges as a highly advantageous primitive that extends far beyond the delegation of control over a UTXO to a new public key. This fundamental ability to “sideload” parameters into a script validation flow can be relevant to anything, not merely public keys. Timelock values, hashlock preimages, and so on. Any script that encodes a variable for verification can now have those values dynamically incorporated afterward.
Moreover, CSFS stands as a thoroughly developed proposal. Its implementation has been operational on the Liquid Network and Elements (the codebase powering Liquid) since 2016. Additionally, Bitcoin Cash has had a version available since 2018.
CSFS is a well-established proposal that conceptually dates back almost as long as my involvement in this domain, featuring various robust implementations and distinctly clear applicable use cases.