Class: Melos::Crypto
- Inherits:
-
Object
show all
- Defined in:
- lib/melos/crypto.rb
Defined Under Namespace
Modules: Util
Classes: CipherSuite
Class Method Summary
collapse
-
.aead_decrypt(suite, key, nonce, aad, ciphertext) ⇒ Object
-
.aead_encrypt(suite, key, nonce, aad, plaintext) ⇒ Object
-
.decrypt_with_label(suite, private_key, label, context, kem_output, ciphertext) ⇒ Object
-
.derive_key_pair(suite, secret) ⇒ Object
-
.derive_secret(suite, secret, label) ⇒ Object
-
.derive_tree_secret(suite, secret, label, generation, length) ⇒ Object
-
.encapsulation_key_pair_corresponds?(suite, private_key, public_key) ⇒ Boolean
-
.encrypt_with_label(suite, public_key, label, context, plaintext) ⇒ Object
-
.expand_with_label(suite, secret, label, context, length) ⇒ Object
-
.hash(suite, data) ⇒ Object
-
.kdf_extract(suite, salt, ikm) ⇒ Object
-
.mac(suite, key, data) ⇒ Object
-
.make_keypackage_ref(suite, value) ⇒ Object
-
.make_proposal_ref(suite, value) ⇒ Object
-
.open_base(suite, enc, skr, info, aad, ct) ⇒ Object
-
.parent_hash(suite, encryption_key, ph_of_parent, sibling_hash) ⇒ Object
-
.ref_hash(suite, label, value) ⇒ Object
-
.seal_base(suite, pkr, info, aad, pt) ⇒ Object
-
.sender_data_key(suite, sender_data_secret, ciphertext) ⇒ Object
-
.sender_data_nonce(suite, sender_data_secret, ciphertext) ⇒ Object
-
.sign_with_label(suite, signature_key, label, content) ⇒ Object
-
.signature_key_pair_corresponds?(suite, private_key, public_key) ⇒ Boolean
-
.verify_with_label(suite, verification_key, label, content, signature_value) ⇒ Object
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)
[pkey.raw_private_key, pkey.raw_public_key]
else
[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
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)
private_pkey.raw_public_key == public_pkey.raw_public_key
else
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
|
187
188
189
|
# File 'lib/melos/crypto.rb', line 187
def self.(suite, salt, ikm)
suite.kdf.(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
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)
private_pkey.raw_public_key == public_pkey.raw_public_key
else
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
|