Class: EphemeralCalc::KeyPair

Inherits:
Object
  • Object
show all
Defined in:
lib/ephemeral_calc/key_pair.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(private_key = nil) ⇒ KeyPair

Returns a new instance of KeyPair.



8
9
10
# File 'lib/ephemeral_calc/key_pair.rb', line 8

def initialize(private_key = nil)
  self.private_key = private_key || KeyPair.generate_private_key
end

Instance Attribute Details

#private_keyObject

Returns the value of attribute private_key.



6
7
8
# File 'lib/ephemeral_calc/key_pair.rb', line 6

def private_key
  @private_key
end

Class Method Details

.generate_private_keyObject



51
52
53
54
55
56
57
58
59
# File 'lib/ephemeral_calc/key_pair.rb', line 51

def self.generate_private_key
  # reference: https://code.google.com/archive/p/curve25519-donna/
  # See section on "generating a private key"
  key = SecureRandom.random_bytes(32).bytes
  key[0] &= 248
  key[31] &= 127
  key[31] |= 64
  return key.pack("C*")
end

Instance Method Details

#convert_key(key_string) ⇒ Object



43
44
45
46
47
48
49
# File 'lib/ephemeral_calc/key_pair.rb', line 43

def convert_key(key_string)
  if key_string.size == 64
    [key_string].pack("H*")
  else
    key_string
  end
end

#hkdf(secret, salt) ⇒ Object



61
62
63
64
65
# File 'lib/ephemeral_calc/key_pair.rb', line 61

def hkdf(secret, salt)
  digest = OpenSSL::Digest.new("SHA256")
  prk = OpenSSL::HMAC.digest(digest, salt, secret)
  OpenSSL::HMAC.digest(digest, prk, "\x01")
end

#identity_key(opts) ⇒ Object

opts must contain the key :resolver_public_key or :beacon_public_key



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/ephemeral_calc/key_pair.rb', line 27

def identity_key(opts)
  if opts[:resolver_public_key]
    resolver_public_key = convert_key(opts[:resolver_public_key])
    beacon_public_key = self.public_key
    secret = shared_secret(resolver_public_key)
  elsif opts[:beacon_public_key]
    resolver_public_key = self.public_key
    beacon_public_key = convert_key(opts[:beacon_public_key])
    secret = shared_secret(beacon_public_key)
  else
    raise ArgumentError, "Must pass a resolver_public_key or a beacon_public_key"
  end
  salt = resolver_public_key + beacon_public_key
  hkdf(secret, salt)[0..15]
end

#public_keyObject



16
17
18
19
20
# File 'lib/ephemeral_calc/key_pair.rb', line 16

def public_key
  @public_key ||= begin
    Curve25519.mult(self.private_key, Curve25519::BASEPOINT)
  end
end

#shared_secret(other_public_key) ⇒ Object



22
23
24
# File 'lib/ephemeral_calc/key_pair.rb', line 22

def shared_secret(other_public_key)
  Curve25519.mult(self.private_key, other_public_key)
end