How to sign a transaction hash in ruby? I'm trying to sign (using secp256k1) a transaction as explained here. I'm using my own private key and an unsigned transaction as the input. 

I'm able to sign it using the JSON-RPC client, but when I sign it with my own ruby script and try to submit it using blockchain.info/pushTx it returns "Invalid signature".

@secret = PRIVATE_KEY_IN_HEX
@keypair_array = Bitcoin::OpenSSL_EC.regenerate_key(@secret)
@pubkey =  @keypair_array[1]

@keypair = OpenSSL::PKey::EC.new("secp256k1")
@keypair.private_key = @keypair_array[0].hex
@keypair.public_key = ::OpenSSL::PKey::EC::Point.from_hex(@keypair.group, @pubkey)

sha_little_endian = SHA_256_HEX_STRING.rjust(64,"0").scan(/(..)/).reverse.join()
signature_binary = @keypair.dsa_sign_asn1([sha_little_endian].pack("H*"))

# Alternative (as in bitcoin-ruby)
# signature_binary = @keypair.dsa_sign_asn1([SHA_256_HEX_STRING].pack("H*"))

signature = signature_binary.unpack("H*").first


First I take the SHA hash, e.g. ABCD...001124 and convert it from big endian to little endian: 241100....CDAB. I do this because in the BitcoinQT client the hash is represented as an uint256 which is cast to a char array used as an input for signing. The result is just stored as a var so I assume I don't have to reverse it.

You'll need to download this OpenSSL_EC file and add the following code to reproduce the above steps.

require 'openssl'
require 'ffi'

module Bitcoin
  def self.require_dependency(dummy1, dummy2)
  end  
autoload :OpenSSL_EC, "./openssl"
end  

module ::OpenSSL
  class BN
    def self.from_hex(hex); new(hex, 16); end
    end
  class PKey::EC::Point
    def self.from_hex(group, hex)
      new(group, BN.from_hex(hex))
    end
  end
end


What am I missing?
The binary encoding of the signature cannot be used to determine if you've performed the steps correctly - it will differ for each signature (even with the same private key).

So the signature of a hash signed with the same private key will be different every time. A random number is included in the formula that calculates the signature, so the resulting signature will be different each time. If a random number was not used in the formula, signing two different hashes with the same private key would make it possible to calculate the private key from the two signatures (which is the reason the security of the Sony PlayStation 3 was breached). You can read more about that here: http://www.johannes-bauer.com/compsci/ecc/

If you want to test whether you've made a valid transaction, then feed it to bitcoind using the sendrawtransaction command. It will spit out an error if the transaction is invalid, and if it's valid you will see the transaction going through.