Class: IcAgent::Identity

Inherits:
Object
  • Object
show all
Defined in:
lib/ic_agent/identity.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(privkey = '', type = 'ed25519', anonymous = false) ⇒ Identity

Returns a new instance of Identity.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/ic_agent/identity.rb', line 14

def initialize(privkey = '', type = 'ed25519', anonymous = false)
  privkey = [privkey].pack('H*')
  @anonymous = anonymous
  if @anonymous
    return
  end
  @key_type = type
  if type == 'secp256k1'
    data = privkey.length > 0 ? privkey : Random.new.bytes(32)
    @sk = Secp256k1::PrivateKey.from_data(data)
    @privkey = @sk.data.str2hex
    context = Secp256k1::Context.create
    @vk = context.key_pair_from_private_key(data)
    @pubkey = @vk.public_key.uncompressed.str2hex
    @der_pubkey = "#{IcAgent::IC_PUBKEY_SECP_DER_HERD}#{@pubkey}".hex2str
  elsif type == 'ed25519'
    @sk = privkey.length > 0 ? Ed25519::SigningKey.new(privkey) : Ed25519::SigningKey.generate
    @privkey = @sk.keypair.unpack1('H*')[0..63]
    @vk = @sk.verify_key
    @pubkey = @vk.to_bytes.unpack1('H*')
    @der_pubkey = "#{IcAgent::IC_PUBKEY_ED_DER_HEAD}#{@vk.to_bytes.unpack1('H*')}".hex2str
  else
    raise 'unsupported identity type'
  end
end

Instance Attribute Details

#der_pubkeyObject (readonly)

Returns the value of attribute der_pubkey.



12
13
14
# File 'lib/ic_agent/identity.rb', line 12

def der_pubkey
  @der_pubkey
end

#key_typeObject (readonly)

Returns the value of attribute key_type.



12
13
14
# File 'lib/ic_agent/identity.rb', line 12

def key_type
  @key_type
end

#privkeyObject (readonly)

Returns the value of attribute privkey.



12
13
14
# File 'lib/ic_agent/identity.rb', line 12

def privkey
  @privkey
end

#pubkeyObject (readonly)

Returns the value of attribute pubkey.



12
13
14
# File 'lib/ic_agent/identity.rb', line 12

def pubkey
  @pubkey
end

#skObject (readonly)

Returns the value of attribute sk.



12
13
14
# File 'lib/ic_agent/identity.rb', line 12

def sk
  @sk
end

#vkObject (readonly)

Returns the value of attribute vk.



12
13
14
# File 'lib/ic_agent/identity.rb', line 12

def vk
  @vk
end

Class Method Details

.from_seed(mnemonic) ⇒ Object



40
41
42
43
44
45
# File 'lib/ic_agent/identity.rb', line 40

def self.from_seed(mnemonic)
  seed = Bitcoin::Trezor::Mnemonic.to_seed(mnemonic)
  privkey = seed[0..63]
  key_type = 'ed25519'
  Identity.new(privkey = privkey, type = key_type)
end

Instance Method Details

#senderObject



47
48
49
50
51
52
53
# File 'lib/ic_agent/identity.rb', line 47

def sender
  if @anonymous
    IcAgent::Principal.anonymous
  else
    IcAgent::Principal.self_authenticating(@der_pubkey)
  end
end

#sign(msg) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/ic_agent/identity.rb', line 55

def sign(msg)
  if @anonymous
    [nil, nil]
  elsif @key_type == 'ed25519'
    sig = @sk.sign(msg)
    [@der_pubkey, sig]
  elsif @key_type == 'secp256k1'
    context = Secp256k1::Context.create
    sig = context.sign(@sk, Digest::SHA256.digest(msg)).compact
    [@der_pubkey, sig]
  end
end

#to_pemObject



76
77
78
79
80
81
82
83
# File 'lib/ic_agent/identity.rb', line 76

def to_pem
  der = @key_type == 'secp256k1' ? "#{IcAgent::IC_PUBKEY_SECP_DER_HERD}#{@sk.data.unpack1('H*')}".hex2str : "#{IcAgent::IC_PUBKEY_ED_DER_HEAD}#{@sk.to_bytes.unpack1('H*')}".hex2str
  b64 = Base64.strict_encode64(der)
  lines = ["-----BEGIN PRIVATE KEY-----\n"]
  lines.concat(b64.chars.each_slice(64).map(&:join).map { |line| "#{line}\n" })
  lines << "-----END PRIVATE KEY-----\n"
  lines.join
end

#to_sObject Also known as: inspect



85
86
87
# File 'lib/ic_agent/identity.rb', line 85

def to_s
  "(#{@key_type}, #{@privkey}, #{@pubkey})"
end

#verify(msg, sig) ⇒ Object



68
69
70
71
72
73
74
# File 'lib/ic_agent/identity.rb', line 68

def verify(msg, sig)
  if @anonymous
    false
  else
    @vk.verify(sig, msg)
  end
end