Module: Legion::Crypt::Ed25519

Extended by:
Logging::Helper
Defined in:
lib/legion/crypt/ed25519.rb

Constant Summary

Constants included from Logging::Helper

Logging::Helper::CompatLogger

Class Method Summary collapse

Methods included from Logging::Helper

handle_exception, log

Class Method Details

.generate_keypairObject



12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/legion/crypt/ed25519.rb', line 12

def generate_keypair
  signing_key = ::Ed25519::SigningKey.generate
  log.info 'Ed25519 keypair generated'
  {
    private_key:    signing_key.to_bytes,
    public_key:     signing_key.verify_key.to_bytes,
    public_key_hex: signing_key.verify_key.to_bytes.unpack1('H*')
  }
rescue StandardError => e
  handle_exception(e, level: :error, operation: 'crypt.ed25519.generate_keypair')
  raise
end

.load_private_key(agent_id:) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/legion/crypt/ed25519.rb', line 67

def load_private_key(agent_id:)
  log.debug "Ed25519 loading private key for agent #{agent_id}"
  return nil unless Legion::Crypt.respond_to?(:get)

  data = Legion::Crypt.get(vault_key_path(agent_id))
  if data&.dig(:private_key)
    log.info "Ed25519 private key loaded for agent #{agent_id}"
    [data[:private_key]].pack('H*')
  else
    log.warn "Ed25519 private key missing for agent #{agent_id}"
    nil
  end
rescue StandardError => e
  handle_exception(e, level: :warn, operation: 'crypt.ed25519.load_private_key', agent_id: agent_id)
  nil
end

.sign(message, private_key_bytes) ⇒ Object



25
26
27
28
29
30
31
32
33
# File 'lib/legion/crypt/ed25519.rb', line 25

def sign(message, private_key_bytes)
  signing_key = ::Ed25519::SigningKey.new(private_key_bytes)
  result = signing_key.sign(message)
  log.debug 'Ed25519 sign complete'
  result
rescue StandardError => e
  handle_exception(e, level: :error, operation: 'crypt.ed25519.sign')
  raise
end

.store_keypair(agent_id:, keypair: nil) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/legion/crypt/ed25519.rb', line 49

def store_keypair(agent_id:, keypair: nil)
  keypair ||= generate_keypair
  if Legion::Crypt.respond_to?(:write)
    log.info "Ed25519 storing keypair for agent #{agent_id}"
    Legion::Crypt.write(
      vault_key_path(agent_id),
      private_key: keypair[:private_key].unpack1('H*'),
      public_key:  keypair[:public_key_hex]
    )
  else
    log.warn "Ed25519 keypair generated for agent #{agent_id} but Vault is unavailable"
  end
  keypair
rescue StandardError => e
  handle_exception(e, level: :error, operation: 'crypt.ed25519.store_keypair', agent_id: agent_id)
  raise
end

.verify(message, signature, public_key_bytes) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/legion/crypt/ed25519.rb', line 35

def verify(message, signature, public_key_bytes)
  verify_key = ::Ed25519::VerifyKey.new(public_key_bytes)
  verify_key.verify(signature, message)
  log.debug 'Ed25519 verify success'
  true
rescue ::Ed25519::VerifyError => e
  handle_exception(e, level: :debug, operation: 'crypt.ed25519.verify.signature_mismatch')
  log.warn 'Ed25519 signature verification failed'
  false
rescue StandardError => e
  handle_exception(e, level: :error, operation: 'crypt.ed25519.verify')
  raise
end