<p>I've done some searches and research, and I also got input on #elements channel on bitcoincore slack, so I feel that I can answer these now (EDIT: At first I got confused about CODESEPARATOR method, but after some more time, I asked Anthony Towns and he provided the links to his messages in lighting-dev list explaining it.)</p>

<ul>
<li><p>I think that the size 57 is chosen for increased guarantee against the possibility that other small-size R value would be found, that is larger than 21 bytes, but small enough that grinding for smaller S could enable to overcome the size limit. I've also seen other example of how this technique might be used (<a href="https://gist.github.com/nothingmuch/683042343c48a4ef07efd3d438e7ee56" rel="nofollow noreferrer">https://gist.github.com/nothingmuch/683042343c48a4ef07efd3d438e7ee56</a>), but it sets 60 for the size limit. It might be assuming that R value that starts with 72 zero bits is not feasible to be found either. It also may be that 57 byte limit is unnecessary small. Note that grinding for len(S) &lt;= 29 is feasible on general-purpose computer. This could be done by changing other inputs/outputs of the transaction so that sighash changes. Relevant: <a href="https://lists.linuxfoundation.org/pipermail/lightning-dev/2015-November/000344.html" rel="nofollow noreferrer">https://lists.linuxfoundation.org/pipermail/lightning-dev/2015-November/000344.html</a></p></li>
<li><p>The second way to achieve this on unmodified bitcoin may somehow involve the use of OP_CODESEPARATOR. There would be two signatures of one pubkey, but the second signature would use different sighash because this signature is checked after CODESEPARATOR is executed, and sighash will be calculated using only the part of the script after CODESEPARATOR. But while you can have two different signatures (on different messages) for one pubkey, it is not clear to me how to force nonce reuse here, if not with the same size-trick as described before, or using the disabled opcodes.</p>

<p>EDIT: Asked Anthony Towns about this, got reply. There is a tecnique using two codeseparators and three checkmultisigs, in such a way that forces reuse of R. See <a href="https://lists.linuxfoundation.org/pipermail/lightning-dev/2015-November/000344.html" rel="nofollow noreferrer">https://lists.linuxfoundation.org/pipermail/lightning-dev/2015-November/000344.html</a> and <a href="https://lists.linuxfoundation.org/pipermail/lightning-dev/2015-November/000363.html" rel="nofollow noreferrer">https://lists.linuxfoundation.org/pipermail/lightning-dev/2015-November/000363.html</a></p>

<p>Other relevant links: <a href="https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-December/016594.html" rel="nofollow noreferrer">https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-December/016594.html</a> <a href="https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-December/016592.html" rel="nofollow noreferrer">https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-December/016592.html</a> My experimental scripts: <a href="https://gist.github.com/dgpv/7818a4009f4e90868c0920cc1e238653" rel="nofollow noreferrer">https://gist.github.com/dgpv/7818a4009f4e90868c0920cc1e238653</a></p>

<p>Note that CODESEPARATOR is non-standard for non-segwit inputs in Bitcoin, but should be OK for segwit inputs. But still not without some controvesy: <a href="https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-March/016732.html" rel="nofollow noreferrer">https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-March/016732.html</a> (there was a proposal to remove CODESEPARATOR altogether, or to calculate sighash always using initial script, disregarding effects of CODESEPARATOR)</p></li>
<li><p>HTLC is simpler to implement, and the program that creates HTLCs does not need to be able to work with bignums, along with having the function that implements modular inverse on bignums. HTLCs would also generally be smaller in size. They are also more 'known' and thus popular.</p></li>
</ul>

CC BY-SA 4.0
2019-06-06T12:50:24.460Z
It turns out I made a mistake thinking that CODESEPARATOR can be used alone for this purpose - if there are two signatures for one pubkey and two different sighashes, the side that creates the signatures is not restricted in the choice of nonces - no way for script to check that sigs have the same r. So there need to be a way to force these signatures to reuse the nonce - and the only trick so far known to me on umodified bitcoin is the size trick. So unfortunately, the second question remains unanswered.
Dmitry Petukhov
CC BY-SA 4.0
2019-06-07T16:44:03.630Z
Asked Anthony Towns about this, got reply. There are a tecnique using two codeseparators and three checkmultisigs, in such a way that forces reuse of R. See https://lists.linuxfoundation.org/pipermail/lightning-dev/2015-November/000344.html and https://lists.linuxfoundation.org/pipermail/lightning-dev/2015-November/000363.html
Dmitry Petukhov
CC BY-SA 4.0
2019-04-12T17:34:55.350Z
2019-06-08T06:18:14.297Z
2019-06-08T06:18:14.297Z
Dmitry Petukhov
<p>Context: I am creating an example code that would demonstrate an atomic swap between Elements and Bitcoin, with the aim that the swap transactions cannot be trivially linked, as it would be with <em>simple</em> HTLC, where you can look for the same hash/preimage in both chains. This is because the key to disclose is actually a sum of keys, (A+B), and to claim the other side of the swap, another sum key, (A+C) is used. A, B, and C are only known to (one or both) participants.</p>

<p>I use CHECKSIGFROMSTACK on Elements side to force the counterparty to create a signature with fixed R value (the k would be known, and thus the other party can recover the key)</p>

<p>I was pointed to <a href="https://bitcointalk.org/index.php?topic=321228.msg13072047#msg13072047" rel="nofollow noreferrer">https://bitcointalk.org/index.php?topic=321228.msg13072047#msg13072047</a>, where gmaxwell tells that you can achieve the same effect of forcing privkey disclosure on unmodified Bitcoin.</p>

<p>He says that he is aware of two ways to achieve this on unmodified Bitcoin, one of them is:</p>

<p><code>OP_SIZE 57 OP_LESSTHANOREQUAL OP_VERIFY &lt;P&gt; OP_CHECKSIGVERIFY</code></p>

<p>My questions:</p>

<ul>
<li><p>in the script listed above, the signature is forced to be of the length less than or equal 57. This seems to rely on known small R value, and assumption that other R values of equal or smaller size for some known k is not computationally possible to find.</p>

<p>in this post <a href="https://crypto.stackexchange.com/questions/60420/what-does-the-special-form-of-the-base-point-of-secp256k1-allow">https://crypto.stackexchange.com/questions/60420/what-does-the-special-form-of-the-base-point-of-secp256k1-allow</a> an R value with 90 leading zero bits is given. S would need to be &lt;= 29 bytes in size with R length of 21 bytes (166 bit), for signature to fit into 57 byte limit (29+21+6+1=57). To satisfy this script using this known small R, the creator of the signature would need to search for the message to sign that would result in a signature with len(S) &lt;= 29. Is this tight limit chosen to reduce 'wiggle room' for bruteforcing R ?</p></li>
<li><p>What is the second method to achieve this on unmodified Bitcoin ?</p></li>
<li><p>If these methods work, why they have not been widely used instead of HTLC constructs, given that these methods (or at least the presented one) are not much more complex implementation-wise, but are more private (because there is no public shared hash/preimage) ? What are the downsides of these methods, versus HTLC ?</p></li>
</ul>

<p>(Note: The questions above are more out of intellectual curiosity  than for concrete practical purpose, because when Schnorr signatures will be enabled on Bitcoin (I hope that won't be too long), adaptor signatures <a href="https://github.com/apoelstra/scriptless-scripts/blob/master/md/atomic-swap.md" rel="nofollow noreferrer">https://github.com/apoelstra/scriptless-scripts/blob/master/md/atomic-swap.md</a> would be much better way to create atomic swaps without trivial link between transactions)</p>

CC BY-SA 4.0
2020-04-08T14:04:56.933Z
In addition to adaptor sigatures via Schnorr signatures, there's now a more easy way (than it was before) to do adaptor signatures with ECDSA: https://joinmarket.me/blog/blog/schnorrless-scriptless-scripts/
Dmitry Petukhov
<script><ecdsa><secp256k1><atomic-swap>
Bitcoin scripts that force disclosure of the private key
Dmitry Petukhov
# Bitcoin scripts that force disclosure of the private key

(Asked by: username_0 on 2019-04-09)

Context: I am creating an example code that would demonstrate an atomic swap between Elements and Bitcoin, with the aim that the swap transactions cannot be trivially linked, as it would be with *simple* HTLC, where you can look for the same hash/preimage in both chains. This is because the key to disclose is actually a sum of keys, (A+B), and to claim the other side of the swap, another sum key, (A+C) is used. A, B, and C are only known to (one or both) participants.

I use CHECKSIGFROMSTACK on Elements side to force the counterparty to create a signature with fixed R value (the k would be known, and thus the other party can recover the key)

I was pointed to <https://bitcointalk.org/index.php?topic=321228.msg13072047#msg13072047>, where gmaxwell tells that you can achieve the same effect of forcing privkey disclosure on unmodified Bitcoin.

He says that he is aware of two ways to achieve this on unmodified Bitcoin, one of them is:

`OP_SIZE 57 OP_LESSTHANOREQUAL OP_VERIFY <P> OP_CHECKSIGVERIFY`

My questions:

* in the script listed above, the signature is forced to be of the length less than or equal 57. This seems to rely on known small R value, and assumption that other R values of equal or smaller size for some known k is not computationally possible to find.

  in this post <https://crypto.stackexchange.com/questions/60420/what-does-the-special-form-of-the-base-point-of-secp256k1-allow> an R value with 90 leading zero bits is given. S would need to be <= 29 bytes in size with R length of 21 bytes (166 bit), for signature to fit into 57 byte limit (29+21+6+1=57). To satisfy this script using this known small R, the creator of the signature would need to search for the message to sign that would result in a signature with len(S) <= 29. Is this tight limit chosen to reduce 'wiggle room' for bruteforcing R ?
* What is the second method to achieve this on unmodified Bitcoin ?
* If these methods work, why they have not been widely used instead of HTLC constructs, given that these methods (or at least the presented one) are not much more complex implementation-wise, but are more private (because there is no public shared hash/preimage) ? What are the downsides of these methods, versus HTLC ?

(Note: The questions above are more out of intellectual curiosity than for concrete practical purpose, because when Schnorr signatures will be enabled on Bitcoin (I hope that won't be too long), adaptor signatures <https://github.com/apoelstra/scriptless-scripts/blob/master/md/atomic-swap.md> would be much better way to create atomic swaps without trivial link between transactions)

**Tags:** script, ecdsa, secp256k1, atomic-swap

> **Comments:**
> **username_0**: In addition to adaptor sigatures via Schnorr signatures, there's now a more easy way (than it was before) to do adaptor signatures with ECDSA: https://joinmarket.me/blog/blog/schnorrless-scriptless-scripts/  

---

## 1 answers

### Answer by username_0 on 2019-04-12. Score: 1 | Accepted answer

I've done some searches and research, and I also got input on #elements channel on bitcoincore slack, so I feel that I can answer these now (EDIT: At first I got confused about CODESEPARATOR method, but after some more time, I asked Anthony Towns and he provided the links to his messages in lighting-dev list explaining it.)

* I think that the size 57 is chosen for increased guarantee against the possibility that other small-size R value would be found, that is larger than 21 bytes, but small enough that grinding for smaller S could enable to overcome the size limit. I've also seen other example of how this technique might be used (<https://gist.github.com/nothingmuch/683042343c48a4ef07efd3d438e7ee56>), but it sets 60 for the size limit. It might be assuming that R value that starts with 72 zero bits is not feasible to be found either. It also may be that 57 byte limit is unnecessary small. Note that grinding for len(S) <= 29 is feasible on general-purpose computer. This could be done by changing other inputs/outputs of the transaction so that sighash changes. Relevant: <https://lists.linuxfoundation.org/pipermail/lightning-dev/2015-November/000344.html>
* The second way to achieve this on unmodified bitcoin may somehow involve the use of OP\_CODESEPARATOR. There would be two signatures of one pubkey, but the second signature would use different sighash because this signature is checked after CODESEPARATOR is executed, and sighash will be calculated using only the part of the script after CODESEPARATOR. But while you can have two different signatures (on different messages) for one pubkey, it is not clear to me how to force nonce reuse here, if not with the same size-trick as described before, or using the disabled opcodes.

  EDIT: Asked Anthony Towns about this, got reply. There is a tecnique using two codeseparators and three checkmultisigs, in such a way that forces reuse of R. See <https://lists.linuxfoundation.org/pipermail/lightning-dev/2015-November/000344.html> and <https://lists.linuxfoundation.org/pipermail/lightning-dev/2015-November/000363.html>

  Other relevant links: <https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-December/016594.html> <https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-December/016592.html> My experimental scripts: <https://gist.github.com/dgpv/7818a4009f4e90868c0920cc1e238653>

  Note that CODESEPARATOR is non-standard for non-segwit inputs in Bitcoin, but should be OK for segwit inputs. But still not without some controvesy: <https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-March/016732.html> (there was a proposal to remove CODESEPARATOR altogether, or to calculate sighash always using initial script, disregarding effects of CODESEPARATOR)
* HTLC is simpler to implement, and the program that creates HTLCs does not need to be able to work with bignums, along with having the function that implements modular inverse on bignums. HTLCs would also generally be smaller in size. They are also more 'known' and thus popular.

> **Comments:**
> **username_0**: It turns out I made a mistake thinking that CODESEPARATOR can be used alone for this purpose - if there are two signatures for one pubkey and two different sighashes, the side that creates the signatures is not restricted in the choice of nonces - no way for script to check that sigs have the same r. So there need to be a way to force these signatures to reuse the nonce - and the only trick so far known to me on umodified bitcoin is the size trick. So unfortunately, the second question remains unanswered.  
> **username_0**: Asked Anthony Towns about this, got reply. There are a tecnique using two codeseparators and three checkmultisigs, in such a way that forces reuse of R. See https://lists.linuxfoundation.org/pipermail/lightning-dev/2015-November/000344.html and https://lists.linuxfoundation.org/pipermail/lightning-dev/2015-November/000363.html  

---

