1

I currently try to sign a tx using OpenSSL. After some tinkering I think I got most of the tx right but Electrum complains with mandatory-script-verify-flag-failed (Non-canonical signature: S value is unnecessarily high) which is probably because of BIP62.

Is there a way to create proper signatures with OpenSSL except trying and hoping to get a small s value?

The rest of my code is in Golang and I couldn't find a proper packages for the used ECDSA curve and so wrapped around OpenSSL.

4

Alternatively, you could use libsecp256k1. This is the code used by Bitcoin Core for signing, and will automatically create low-S signatures (disclaimer: I'm the main author of that library). Perhaps a Go wrapper exists.

If you stick to OpenSSL, it is possible to manually adjust the S value after signing. This is what Bitcoin Core used to do before v0.10. Here is what it used to do: https://github.com/bitcoin/bitcoin/blob/v0.9.0/src/key.cpp#L204L224

  • Such a disclaimer though. – sr-gi Sep 22 '17 at 18:42
1

Open SSL won't force it, you will have to do it yourself. From BIP 62:

The value S in signatures must be between 0x1 and 0x7FFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 5D576E73 57A4501D DFE92F46 681B20A0 (inclusive). If S is too high, simply replace it by S' = 0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141 - S.

Source

  • The question then is: How can I set that s value using OpenSSL? I couldn't find a parameter to set it – soupdiver Sep 22 '17 at 6:57
  • @soupdiver: those numbers are, not coincidentally, the order of the group for secp256k1 and one-half the order (rounded down). If you have an EC_GROUP for secp25k1 use EC_GROUP_get[0]_order; if you have an EC_KEY use EC_KEY_get0_group first. Once you have the order BN_dup BN_rshift1 BN_cmp and BN_sub on the value from the ECDSA_SIG should be sufficient. – dave_thompson_085 Sep 22 '17 at 11:45
  • I don't really understand the last comment – soupdiver Sep 22 '17 at 11:46
  • @soupdiver you don't need to 'set it in OpenSSL', you just use it, the s value is a component of the final signature. – MeshCollider Sep 22 '17 at 11:52
  • yeah I understand this. I'm wondering if there is a way to set this value if it's too big and therefor rejected by the network – soupdiver Sep 22 '17 at 13:02
0

Is there a way to create proper signatures with OpenSSL except trying and hoping to get a small s value?

If the speed is not significant - this is not bad idea.

update: take some pseudocode:

while ( true )
{
  signature = createOpenSslSignature ( params );
  if ( !signature.toHex ( ).contains ( "022100" ) )
    return signature;
}
  • I would prefer to create "proper" signatures directly and not having to brute force it :) – soupdiver Sep 22 '17 at 6:58
  • answer updated. this in not brute-forcing. and this is not best solution. but this is simplest implementation :) – amaclin Sep 22 '17 at 16:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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