Skip to content

Instantly share code, notes, and snippets.

@icostan
Created November 14, 2018 08:09
Show Gist options
  • Save icostan/1d8b61f89ba6d392686e87651174fa74 to your computer and use it in GitHub Desktop.
Save icostan/1d8b61f89ba6d392686e87651174fa74 to your computer and use it in GitHub Desktop.
def ecdsa_sign(private_key, digest, temp_key = nil)
temp_key ||= 1 + SecureRandom.random_number(EC_n - 1)
rx, _ry = ec_multiply(temp_key, EC_Gx, EC_Gy, EC_p)
r = rx % EC_n
r > 0 || raise('r is zero, try again new temp key')
i_tk = inverse temp_key, EC_n
m = bytes_to_bignum digest
s = (i_tk * (m + r * private_key)) % EC_n
s > 0 || raise('s is zero, try again new temp key')
[r, s]
end
def ecdsa_verify?(px, py, digest, signature)
r, s = signature
i_s = inverse s, EC_n
m = bytes_to_bignum digest
u1 = i_s * m % EC_n
u2 = i_s * r % EC_n
u1Gx, u1Gy = ec_multiply u1, EC_Gx, EC_Gy, EC_p
u2Px, u2Py = ec_multiply u2, px, py, EC_p
rx, _ry = ec_add u1Gx, u1Gy, u2Px, u2Py, EC_p
r == rx
end
Der = Struct.new :der, :length, :ri, :rl, :r, :si, :sl, :s, :sighash_type do
def initialize(der: 0x30, length: 0x45, ri: 0x02, rl: 0x21, r: nil, si: 0x02, sl: 0x20, s: nil, sighash_type: 0x01)
super der, length, ri, rl, r, si, sl, s, sighash_type
end
def serialize
byte_to_hex(der) + byte_to_hex(length) +
byte_to_hex(ri) + byte_to_hex(rl) + to_hex(bignum_to_bytes(r, 33)) +
byte_to_hex(si) + byte_to_hex(sl) + to_hex(bignum_to_bytes(s, 32)) +
byte_to_hex(sighash_type)
end
def self.parse(signature)
fields = *[signature].pack('H*').unpack('CCCCH66CCH64C')
Der.new r: fields[4], s: fields[7], sighash_type: fields[8]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment