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:


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)


1 Answer 1


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.)

  • 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. Jun 6, 2019 at 12:50
  • 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 lists.linuxfoundation.org/pipermail/lightning-dev/2015-November/… and lists.linuxfoundation.org/pipermail/lightning-dev/2015-November/… Jun 7, 2019 at 16:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.