Class: HPKE

Inherits:
Object
  • Object
show all
Includes:
Util
Defined in:
lib/hpke.rb,
lib/hpke/version.rb

Defined Under Namespace

Modules: Util Classes: Context, ContextR, ContextS, DHKEM, HKDF

Constant Summary collapse

MODES =
{
  base: 0x00,
  psk: 0x01,
  auth: 0x02,
  auth_psk: 0x03
}
CIPHERS =
{
  aes_128_gcm: {
    name: 'aes-128-gcm',
    aead_id: 0x0001,
    n_k: 16,
    n_n: 12,
    n_t: 16
  },
  aes_256_gcm: {
    name: 'aes-256-gcm',
    aead_id: 0x0002,
    n_k: 32,
    n_n: 12,
    n_t: 16
  },
  chacha20_poly1305: {
    name: 'chacha20-poly1305',
    aead_id: 0x0003,
    n_k: 32,
    n_n: 12,
    n_t: 16
  },
  export_only: {
    aead_id: 0xffff
  }
}
HASHES =
{
  sha256: {
    name: 'SHA256',
    kdf_id: 1
  },
  sha384: {
    name: 'SHA384',
    kdf_id: 2
  },
  sha512: {
    name: 'SHA512',
    kdf_id: 3
  }
}
KEM_CURVES =
{
  p_256: DHKEM::EC::P_256,
  p_384: DHKEM::EC::P_384,
  p_521: DHKEM::EC::P_521,
  x25519: DHKEM::X25519,
  x448: DHKEM::X448
}
VERSION =
"0.1.0"

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Util

#i2osp, #os2ip, #xor

Constructor Details

#initialize(kem_curve_name, kem_hash, kdf_hash, aead_cipher) ⇒ HPKE

Returns a new instance of HPKE.

Raises:

  • (Exception)


68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/hpke.rb', line 68

def initialize(kem_curve_name, kem_hash, kdf_hash, aead_cipher)
  raise Exception.new('Unsupported KEM curve name') if KEM_CURVES[kem_curve_name].nil?
  raise Exception.new('Unsupported AEAD cipher name') if CIPHERS[aead_cipher].nil?

  @kem = KEM_CURVES[kem_curve_name].new(kem_hash)
  @hkdf = HKDF.new(kdf_hash)
  @aead_name = CIPHERS[aead_cipher][:name]
  @aead_id = CIPHERS[aead_cipher][:aead_id]
  @n_k = CIPHERS[aead_cipher][:n_k]
  @n_n = CIPHERS[aead_cipher][:n_n]
  @n_t = CIPHERS[aead_cipher][:n_t]
end

Instance Attribute Details

#aead_nameObject (readonly)

Returns the value of attribute aead_name.



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

def aead_name
  @aead_name
end

#hkdfObject (readonly)

Returns the value of attribute hkdf.



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

def hkdf
  @hkdf
end

#kemObject (readonly)

Returns the value of attribute kem.



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

def kem
  @kem
end

#n_kObject (readonly)

Returns the value of attribute n_k.



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

def n_k
  @n_k
end

#n_nObject (readonly)

Returns the value of attribute n_n.



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

def n_n
  @n_n
end

#n_tObject (readonly)

Returns the value of attribute n_t.



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

def n_t
  @n_t
end

Instance Method Details

#export(exporter_secret, exporter_context, len) ⇒ Object



167
168
169
# File 'lib/hpke.rb', line 167

def export(exporter_secret, exporter_context, len)
  @hkdf.labeled_expand(exporter_secret, 'sec', exporter_context, len, suite_id)
end

#setup_auth_psk_r(enc, sk_r, info, psk, psk_id, pk_s) ⇒ Object



129
130
131
132
# File 'lib/hpke.rb', line 129

def setup_auth_psk_r(enc, sk_r, info, psk, psk_id, pk_s)
  shared_secret = @kem.auth_decap(enc, sk_r, pk_s)
  key_schedule_r(MODES[:auth_psk], shared_secret, info, psk, psk_id)
end

#setup_auth_psk_s(pk_r, info, psk, psk_id, sk_s) ⇒ Object



121
122
123
124
125
126
127
# File 'lib/hpke.rb', line 121

def setup_auth_psk_s(pk_r, info, psk, psk_id, sk_s)
  encap_result = @kem.auth_encap(pk_r, sk_s)
  {
    enc: encap_result[:enc],
    context_s: key_schedule_s(MODES[:auth_psk], encap_result[:shared_secret], info, psk, psk_id)
  }
end

#setup_auth_psk_s_fixed(pk_r, info, psk, psk_id, sk_s, ikm_e) ⇒ Object



159
160
161
162
163
164
165
# File 'lib/hpke.rb', line 159

def setup_auth_psk_s_fixed(pk_r, info, psk, psk_id, sk_s, ikm_e)
  encap_result = @kem.auth_encap_fixed(pk_r, sk_s, ikm_e)
  {
    enc: encap_result[:enc],
    context_s: key_schedule_s(MODES[:auth_psk], encap_result[:shared_secret], info, psk, psk_id)
  }
end

#setup_auth_r(enc, sk_r, info, pk_s) ⇒ Object



116
117
118
119
# File 'lib/hpke.rb', line 116

def setup_auth_r(enc, sk_r, info, pk_s)
  shared_secret = @kem.auth_decap(enc, sk_r, pk_s)
  key_schedule_r(MODES[:auth], shared_secret, info, DEFAULT_PSK, DEFAULT_PSK_ID)
end

#setup_auth_s(pk_r, info, sk_s) ⇒ Object



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

def setup_auth_s(pk_r, info, sk_s)
  encap_result = @kem.auth_encap(pk_r, sk_s)
  {
    enc: encap_result[:enc],
    context_s: key_schedule_s(MODES[:auth], encap_result[:shared_secret], info, DEFAULT_PSK, DEFAULT_PSK_ID)
  }
end

#setup_auth_s_fixed(pk_r, info, sk_s, ikm_e) ⇒ Object



151
152
153
154
155
156
157
# File 'lib/hpke.rb', line 151

def setup_auth_s_fixed(pk_r, info, sk_s, ikm_e)
  encap_result = @kem.auth_encap_fixed(pk_r, sk_s, ikm_e)
  {
    enc: encap_result[:enc],
    context_s: key_schedule_s(MODES[:auth], encap_result[:shared_secret], info, DEFAULT_PSK, DEFAULT_PSK_ID)
  }
end

#setup_base_r(enc, sk_r, info) ⇒ Object



90
91
92
93
# File 'lib/hpke.rb', line 90

def setup_base_r(enc, sk_r, info)
  shared_secret = @kem.decap(enc, sk_r)
  key_schedule_r(MODES[:base], shared_secret, info, DEFAULT_PSK, DEFAULT_PSK_ID)
end

#setup_base_s(pk_r, info) ⇒ Object

public facing APIs



82
83
84
85
86
87
88
# File 'lib/hpke.rb', line 82

def setup_base_s(pk_r, info)
  encap_result = @kem.encap(pk_r)
  {
    enc: encap_result[:enc],
    context_s: key_schedule_s(MODES[:base], encap_result[:shared_secret], info, DEFAULT_PSK, DEFAULT_PSK_ID)
  }
end

#setup_base_s_fixed(pk_r, info, ikm_e) ⇒ Object

for testing purposes



135
136
137
138
139
140
141
# File 'lib/hpke.rb', line 135

def setup_base_s_fixed(pk_r, info, ikm_e)
  encap_result = @kem.encap_fixed(pk_r, ikm_e)
  {
    enc: encap_result[:enc],
    context_s: key_schedule_s(MODES[:base], encap_result[:shared_secret], info, DEFAULT_PSK, DEFAULT_PSK_ID)
  }
end

#setup_psk_r(enc, sk_r, info, psk, psk_id) ⇒ Object



103
104
105
106
# File 'lib/hpke.rb', line 103

def setup_psk_r(enc, sk_r, info, psk, psk_id)
  shared_secret = @kem.decap(enc, sk_r)
  key_schedule_r(MODES[:psk], shared_secret, info, psk, psk_id)
end

#setup_psk_s(pk_r, info, psk, psk_id) ⇒ Object



95
96
97
98
99
100
101
# File 'lib/hpke.rb', line 95

def setup_psk_s(pk_r, info, psk, psk_id)
  encap_result = @kem.encap(pk_r)
  {
    enc: encap_result[:enc],
    context_s: key_schedule_s(MODES[:psk], encap_result[:shared_secret], info, psk, psk_id)
  }
end

#setup_psk_s_fixed(pk_r, info, psk, psk_id, ikm_e) ⇒ Object



143
144
145
146
147
148
149
# File 'lib/hpke.rb', line 143

def setup_psk_s_fixed(pk_r, info, psk, psk_id, ikm_e)
  encap_result = @kem.encap_fixed(pk_r, ikm_e)
  {
    enc: encap_result[:enc],
    context_s: key_schedule_s(MODES[:psk], encap_result[:shared_secret], info, psk, psk_id)
  }
end