class Ethereum::PublicKey

Attributes

raw[R]

Public Class Methods

new(raw) click to toggle source
# File lib/ethereum/public_key.rb, line 7
def initialize(raw)
  @raw = raw
end

Public Instance Methods

decode(fmt=nil) click to toggle source
# File lib/ethereum/public_key.rb, line 32
def decode(fmt=nil)
  fmt ||= format

  case fmt
  when :decimal
    raw
  when :bin
    [BaseConvert.decode(raw[1,32], 256), BaseConvert.decode(raw[33,32], 256)]
  when :bin_compressed
    x = BaseConvert.decode raw[1,32], 256
    m = x*x*x + Secp256k1::A*x + Secp256k1::B
    n = Utils.mod_exp(m, (Secp256k1::P+1)/4, Secp256k1::P)
    q = (n + raw[0].ord) % 2
    y = q == 1 ? (Secp256k1::P - n) : n
    [x, y]
  when :hex
    [BaseConvert.decode(raw[2,64], 16), BaseConvert.decode(raw[66,64], 16)]
  when :hex_compressed
    PublicKey.new(Utils.decode_hex(raw)).decode :bin_compressed
  when :bin_electrum
    [BaseConvert.decode(raw[0,32], 256), BaseConvert.decode(raw[32,32], 256)]
  when :hex_electrum
    [BaseConvert.decode(raw[0,64], 16), BaseConvert.decode(raw[64,128], 16)]
  else
    raise FormatError, "Invalid format!"
  end
end
encode(fmt) click to toggle source
# File lib/ethereum/public_key.rb, line 11
def encode(fmt)
  case fmt
  when :decimal
    value
  when :bin
    "\x04#{BaseConvert.encode(value[0], 256, 32)}#{BaseConvert.encode(value[1], 256, 32)}"
  when :bin_compressed
    "#{(2+(value[1]%2)).chr}#{BaseConvert.encode(value[0], 256, 32)}"
  when :hex
    "04#{BaseConvert.encode(value[0], 16, 64)}#{BaseConvert.encode(value[1], 16, 64)}"
  when :hex_compressed
    "0#{2+(value[1]%2)}#{BaseConvert.encode(value[0], 16, 64)}"
  when :bin_electrum
    "#{BaseConvert.encode(value[0], 256, 32)}#{BaseConvert.encode(value[1], 256, 32)}"
  when :hex_electrum
    "#{BaseConvert.encode(value[0], 16, 64)}#{BaseConvert.encode(value[1], 16, 64)}"
  else
    raise FormatError, "Invalid format!"
  end
end
format() click to toggle source
# File lib/ethereum/public_key.rb, line 64
def format
  return :decimal if raw.is_a?(Array)
  return :bin if raw.size == 65 && raw[0] == "\x04"
  return :hex if raw.size == 130 && raw[0, 2] == '04'
  return :bin_compressed if raw.size == 33 && "\x02\x03".include?(raw[0])
  return :hex_compressed if raw.size == 66 && %w(02 03).include?(raw[0,2])
  return :bin_electrum if raw.size == 64
  return :hex_electrum if raw.size == 128

  raise FormatError, "Pubkey is not in recognized format"
end
to_address(extended=false) click to toggle source
# File lib/ethereum/public_key.rb, line 81
def to_address(extended=false)
  bytes = Utils.keccak256(encode(:bin)[1..-1])[-20..-1]
  Address.new(bytes).to_bytes(extended)
end
to_bitcoin_address(magicbyte=0) click to toggle source
# File lib/ethereum/public_key.rb, line 76
def to_bitcoin_address(magicbyte=0)
  bytes = encode(:bin)
  Utils.bytes_to_base58_check Utils.hash160(bytes), magicbyte
end
value() click to toggle source
# File lib/ethereum/public_key.rb, line 60
def value
  @value ||= decode
end