Class: Melos::Crypto

Inherits:
Object
  • Object
show all
Defined in:
lib/melos/crypto.rb

Defined Under Namespace

Modules: Util Classes: CipherSuite

Class Method Summary collapse

Class Method Details

.aead_decrypt(suite, key, nonce, aad, ciphertext) ⇒ Object



265
266
267
# File 'lib/melos/crypto.rb', line 265

def self.aead_decrypt(suite, key, nonce, aad, ciphertext)
  suite.hpke.aead_decrypt(key, nonce, aad, ciphertext)
end

.aead_encrypt(suite, key, nonce, aad, plaintext) ⇒ Object



261
262
263
# File 'lib/melos/crypto.rb', line 261

def self.aead_encrypt(suite, key, nonce, aad, plaintext)
  suite.hpke.aead_encrypt(key, nonce, aad, plaintext)
end

.decrypt_with_label(suite, private_key, label, context, kem_output, ciphertext) ⇒ Object



235
236
237
238
239
# File 'lib/melos/crypto.rb', line 235

def self.decrypt_with_label(suite, private_key, label, context, kem_output, ciphertext)
  encrypt_context = Melos::Vec.from_string("MLS 1.0 " + label) + Melos::Vec.from_string(context)
  pkey = suite.pkey.deserialize_private_encapsulation_key(private_key)
  open_base(suite, kem_output, pkey, encrypt_context, "", ciphertext)
end

.derive_key_pair(suite, secret) ⇒ Object



205
206
207
208
209
210
211
212
213
214
# File 'lib/melos/crypto.rb', line 205

def self.derive_key_pair(suite, secret)
  pkey = suite.hpke.kem.derive_key_pair(secret)
  if suite.pkey.equal?(Melos::Crypto::CipherSuite::X25519) || suite.pkey.equal?(Melos::Crypto::CipherSuite::X448)
    # is an Edwards curve
    [pkey.raw_private_key, pkey.raw_public_key]
  else
    # is an EC
    [pkey.private_key.to_s(2), pkey.public_key.to_bn.to_s(2)]
  end
end

.derive_secret(suite, secret, label) ⇒ Object



196
197
198
# File 'lib/melos/crypto.rb', line 196

def self.derive_secret(suite, secret, label)
  expand_with_label(suite, secret, label, "", suite.kdf.n_h)
end

.derive_tree_secret(suite, secret, label, generation, length) ⇒ Object



200
201
202
203
# File 'lib/melos/crypto.rb', line 200

def self.derive_tree_secret(suite, secret, label, generation, length)
  generation_in_uint32 = [generation].pack('L>')
  expand_with_label(suite, secret, label, generation_in_uint32, length)
end

.encapsulation_key_pair_corresponds?(suite, private_key, public_key) ⇒ Boolean

Returns:

  • (Boolean)


279
280
281
282
283
284
285
286
287
288
289
# File 'lib/melos/crypto.rb', line 279

def self.encapsulation_key_pair_corresponds?(suite, private_key, public_key)
  private_pkey = suite.pkey.deserialize_private_encapsulation_key(private_key)
  public_pkey  = suite.pkey.deserialize_public_encapsulation_key(public_key)
  if suite.pkey.equal?(Melos::Crypto::CipherSuite::X25519) || suite.pkey.equal?(Melos::Crypto::CipherSuite::X448)
    # is an Edwards curve; check equality of the raw public key
    private_pkey.raw_public_key == public_pkey.raw_public_key
  else
    # is an EC; check equality of the public key Point
    private_pkey.public_key == public_pkey.public_key
  end
end

.encrypt_with_label(suite, public_key, label, context, plaintext) ⇒ Object



229
230
231
232
233
# File 'lib/melos/crypto.rb', line 229

def self.encrypt_with_label(suite, public_key, label, context, plaintext)
  encrypt_context = Melos::Vec.from_string("MLS 1.0 " + label) + Melos::Vec.from_string(context)
  pkey = suite.pkey.deserialize_public_encapsulation_key(public_key)
  seal_base(suite, pkey, encrypt_context, "", plaintext)
end

.expand_with_label(suite, secret, label, context, length) ⇒ Object



191
192
193
194
# File 'lib/melos/crypto.rb', line 191

def self.expand_with_label(suite, secret, label, context, length)
  kdf_label = [length].pack('S>') + Melos::Vec.from_string("MLS 1.0 " + label) + Melos::Vec.from_string(context)
  suite.kdf.expand(secret, kdf_label, length)
end

.hash(suite, data) ⇒ Object



257
258
259
# File 'lib/melos/crypto.rb', line 257

def self.hash(suite, data)
  suite.digest.digest(data)
end

.kdf_extract(suite, salt, ikm) ⇒ Object



187
188
189
# File 'lib/melos/crypto.rb', line 187

def self.kdf_extract(suite, salt, ikm)
  suite.kdf.extract(salt, ikm)
end

.mac(suite, key, data) ⇒ Object



253
254
255
# File 'lib/melos/crypto.rb', line 253

def self.mac(suite, key, data)
  OpenSSL::HMAC.digest(suite.digest, key, data)
end

.make_keypackage_ref(suite, value) ⇒ Object



179
180
181
# File 'lib/melos/crypto.rb', line 179

def self.make_keypackage_ref(suite, value)
  self.ref_hash(suite, "MLS 1.0 KeyPackage Reference", value)
end

.make_proposal_ref(suite, value) ⇒ Object



183
184
185
# File 'lib/melos/crypto.rb', line 183

def self.make_proposal_ref(suite, value)
  self.ref_hash(suite, "MLS 1.0 Proposal Reference", value)
end

.open_base(suite, enc, skr, info, aad, ct) ⇒ Object



224
225
226
227
# File 'lib/melos/crypto.rb', line 224

def self.open_base(suite, enc, skr, info, aad, ct)
  ctx = suite.hpke.setup_base_r(enc, skr, info)
  ctx.open(aad, ct)
end

.parent_hash(suite, encryption_key, ph_of_parent, sibling_hash) ⇒ Object



303
304
305
306
# File 'lib/melos/crypto.rb', line 303

def self.parent_hash(suite, encryption_key, ph_of_parent, sibling_hash)
  parent_hash_input = Melos::Vec.from_string(encryption_key) + Melos::Vec.from_string(ph_of_parent) + Melos::Vec.from_string(sibling_hash)
  Melos::Crypto.hash(suite, parent_hash_input)
end

.ref_hash(suite, label, value) ⇒ Object



174
175
176
177
# File 'lib/melos/crypto.rb', line 174

def self.ref_hash(suite, label, value)
  ref_hash_input = Melos::Vec.from_string(label) + Melos::Vec.from_string(value)
  suite.digest.digest(ref_hash_input)
end

.seal_base(suite, pkr, info, aad, pt) ⇒ Object



216
217
218
219
220
221
222
# File 'lib/melos/crypto.rb', line 216

def self.seal_base(suite, pkr, info, aad, pt)
  context = suite.hpke.setup_base_s(pkr, info)
  enc = context[:enc]
  ctx = context[:context_s]
  ct = ctx.seal(aad, pt)
  [enc, ct]
end

.sender_data_key(suite, sender_data_secret, ciphertext) ⇒ Object



269
270
271
272
# File 'lib/melos/crypto.rb', line 269

def self.sender_data_key(suite, sender_data_secret, ciphertext)
  ciphertext_sample = ciphertext[0..(suite.kdf.n_h - 1)]
  expand_with_label(suite, sender_data_secret, "key", ciphertext_sample, suite.hpke.n_k)
end

.sender_data_nonce(suite, sender_data_secret, ciphertext) ⇒ Object



274
275
276
277
# File 'lib/melos/crypto.rb', line 274

def self.sender_data_nonce(suite, sender_data_secret, ciphertext)
  ciphertext_sample = ciphertext[0..(suite.kdf.n_h - 1)]
  expand_with_label(suite, sender_data_secret, "nonce", ciphertext_sample, suite.hpke.n_n)
end

.sign_with_label(suite, signature_key, label, content) ⇒ Object



241
242
243
244
245
# File 'lib/melos/crypto.rb', line 241

def self.sign_with_label(suite, signature_key, label, content)
  skey = suite.pkey.deserialize_private_signature_key(signature_key)
  sign_content = Melos::Vec.from_string("MLS 1.0 " + label) + Melos::Vec.from_string(content)
  skey.sign(suite.pkey.hash_algorithm, sign_content)
end

.signature_key_pair_corresponds?(suite, private_key, public_key) ⇒ Boolean

Returns:

  • (Boolean)


291
292
293
294
295
296
297
298
299
300
301
# File 'lib/melos/crypto.rb', line 291

def self.signature_key_pair_corresponds?(suite, private_key, public_key)
  private_pkey = suite.pkey.deserialize_private_signature_key(private_key)
  public_pkey  = suite.pkey.deserialize_public_signature_key(public_key)
  if suite.pkey.equal?(Melos::Crypto::CipherSuite::X25519) || suite.pkey.equal?(Melos::Crypto::CipherSuite::X448)
    # is an Edwards curve; check equality of the raw public key
    private_pkey.raw_public_key == public_pkey.raw_public_key
  else
    # is an EC; check equality of the public key Point
    private_pkey.public_key == public_pkey.public_key
  end
end

.verify_with_label(suite, verification_key, label, content, signature_value) ⇒ Object



247
248
249
250
251
# File 'lib/melos/crypto.rb', line 247

def self.verify_with_label(suite, verification_key, label, content, signature_value)
  vkey = suite.pkey.deserialize_public_signature_key(verification_key)
  sign_content = Melos::Vec.from_string("MLS 1.0 " + label) + Melos::Vec.from_string(content)
  vkey.verify(suite.pkey.hash_algorithm, signature_value, sign_content)
end