class Eth::Key

def address

def address
  Utils.bin_to_hex(Utils.keccak256(public_bytes[1..-1])[-20..-1])
end

def initialize(priv: nil)

def initialize(priv: nil)
  @private_key = MoneyTree::PrivateKey.new key: priv
  @public_key = MoneyTree::PublicKey.new private_key, compressed: false
end

def message_hash(message)

def message_hash(message)
  Utils.keccak256 message
end

def private_hex

def private_hex
  private_key.to_hex
end

def public_bytes

def public_bytes
  public_key.to_bytes
end

def public_hex

def public_hex
  public_key.to_hex
end

def sign(message)

def sign(message)
  sign_hash message_hash(message)
end

def sign_hash(hash)

def sign_hash(hash)
  loop do
    signature = OpenSsl.sign_compact hash, private_hex, public_hex
    return signature if valid_s? signature
  end
end

def valid_s?(signature)

def valid_s?(signature)
  s_value = Utils.v_r_s_for(signature).last
  s_value <= Ethereum::Base::SECP256K1_N/2 && s_value != 0
end

def verify_signature(message, signature)

def verify_signature(message, signature)
  hash = message_hash(message)
  public_hex == OpenSsl.recover_compact(hash, signature)
end