6

I'm trying to write a sign function in Ruby for Ethereum using secp256k1.

I have access to this sign_compact function which seems to be for Bitcoin:

https://github.com/lian/bitcoin-ruby/blob/master/lib/bitcoin/ffi/secp256k1.rb#L207-L232

I'm trying to use this to sign for Ethereum but there seems to be some steps missing. Specifically, something to do with the head, r-value and s-value. Someone seems to be doing this properly using OpenSSL instead of secp256k1 here:

https://github.com/se3000/ruby-eth/blob/master/lib/eth/open_ssl.rb#L58-L97

The lines that seem to be different are:

if signature.get_array_of_pointer(0, 2).all?{|i| BN_num_bits(i) <= 256 }
  4.times{|i|
    head = [ Eth.v_base + i ].pack("C")
    if public_key_hex == recover_public_key_from_signature(hash, [head, r, s].join, i, pubkey_compressed)
      rec_id = i; break
     end
  }
end

How would I go about using the secp256k1 sign_compact function to sign Ethereum messages? Is there something I need to change for the signature? Or is there somewhere to find the protocol for this?

1

I have never programmed Ruby but I know a little bit about Bitcoin and Ethereum signatures. I hope I can help you.

A bitcoin signature consists of two parts: (r,s). An Ethereum signature consists of three parts: (v,r,s).

The extra value v which is only one byte allows for the derivation of the public key from the signature. There are only four possible values of v so the code that you are pointing to goes through all four possible values to check which is the correct one. If the recovered public key matches the provided one (input to the sign_compact function) we have found the correct rec_id value and this one is then returned along with the signature. So the function ends up returning (v,r,s) instead of just (r,s),

Perhaps the Yellow Paper may provide some illumination to this problem as well: enter image description here

It looks to me like the header value in the sign_compact for Bitcoin actually is set to this recovery bit (assuming that the function call secp256k1_ecdsa_recoverable_signature_serialize_compact sets this value). So I believe the function sign_compact actually returns what you need.

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.