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

Initializes a new instance of the Identity class.

Parameters:

  • privkey: The private key of the identity in hexadecimal format. Defaults to an empty string.

  • type: The key type of the identity. Defaults to ‘ed25519’.

  • anonymous: A flag indicating whether the identity is anonymous. Defaults to false.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/ic_agent/identity.rb', line 20

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

Creates a new Identity instance from a seed phrase (mnemonic).

Parameters:

  • mnemonic: The seed phrase (mnemonic) used to generate the identity.

Returns: The Identity instance.



52
53
54
55
56
57
# File 'lib/ic_agent/identity.rb', line 52

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

Returns the sender Principal associated with the Identity.

Returns: The sender Principal.



62
63
64
65
66
67
68
# File 'lib/ic_agent/identity.rb', line 62

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

#sign(msg) ⇒ Object

Signs a message using the Identity.

Parameters:

  • msg: The message to sign.

Returns: An array containing the DER-encoded public key and the signature.



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

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

Returns the PEM-encoded private key of the Identity.

Returns: The PEM-encoded private key.



107
108
109
110
111
112
113
114
# File 'lib/ic_agent/identity.rb', line 107

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



116
117
118
# File 'lib/ic_agent/identity.rb', line 116

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

#verify(msg, sig) ⇒ Object

Verifies a message signature using the Identity.

Parameters:

  • msg: The message to verify.

  • sig: The signature to verify.

Returns: ‘true` if the signature is valid, otherwise `false`.



96
97
98
99
100
101
102
# File 'lib/ic_agent/identity.rb', line 96

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