add ML-KEM as an option for base OT#48
Conversation
robinhundt
left a comment
There was a problem hiding this comment.
Hi, thank you so much for your interest in my crate and this PR!
I've had a preliminary look at the paper and the code and left a few comments. I also enabled the pipelines to run for you.
- the lint and docs checks are currently failing. Note that I'm using nightly rustfmt (see CI here) so that I can enable some extra options.
- What is really weird, is that on macos, the silent_ot::tests::random_silent_ot test consistently fails. It doesn't fail on Ubuntu and doesn't fail on the main branch. I think this failure has something to do with the mlkem-ot implementation, as the tests are run with
--all-featuresso it will be used, but I'm really stumped why exactly this test fails with a communication error in the PPRF phase and only on macos 🤔
Regarding security:
When used in an OT extension protocol, semi-honest base OT is sufficient for the whole protocol to have malicious security
I'm not sure this holds. E.g. if an actively malicious adversary is able to recover information about the choice bits used for the base OTs of the KOS15 protocol, the whole protocol should be broken.
I'm also a bit unsure about the security of the ML-KEM OT. On the one hand, it offers stronger security by being PQ secure, on other hand, it only offers endemic security whereas the current implementation of Simplest OT offers uniform message security (I think). While the uniform security is currently not documented, it could still be a hazard if the ML-KEM OT offers weaker message security.
I think this is a good opportunity to better document the actual security guarantees of the OT implementations and I like the definitions of the MR19 paper. But I'll need to look a bit closer into that.
I haven't yet looked in-depth into the code itself and potential differences to the libOTe implementation. I'll do that in the coming days.
|
Thanks for looking the PR! I will fix the small things. Re malicious security, I was coming from what libOTe + Kyber is doing, but I cannot prove it is secure myself, at least not yet. Even if it isn't, I guess there is still value in using ML-KEM, right? I agree it would be good to document the requirements and what the extensions end up with given what base OT is used, but I'd need more time. But more importantly, maybe I am not the right person for that as I am not a cryptographer, I hope you can help 🙂 |
|
Re MacOS and Linux, maybe could be endianness (ARM vs AMD64) and not the OS. Or maybe OS-related - socket buffers when using much bigger ciphertexts. Just speculating, will have a look. |
cb1f971 to
c73a47b
Compare
robinhundt
left a comment
There was a problem hiding this comment.
Thanks for the changes! It seems that limiting the threads on macos "fixed" the issue. I think there is likely an issue with my network library which caused this issue in the test and also the spurious benchmarking failures. It's annoying that I can't seem to replicate it locally.
I've had a closer look at the implementation now and it does not seem to correctly implement the MR19 protocol, see the comment below.
| let (dk, ek) = MlKem::generate(&mut RngCompat(&mut self.rng)); | ||
| let real_ek = EncapKeyBytes( | ||
| ek.as_bytes() | ||
| .as_slice() | ||
| .try_into() | ||
| .expect("incorrect encapsulation key size"), | ||
| ); | ||
| let fake_ek = EncapKeyBytes(self.rng.random()); | ||
|
|
||
| let ek0 = EncapKeyBytes::conditional_select(&real_ek, &fake_ek, *choice); | ||
| let ek1 = EncapKeyBytes::conditional_select(&fake_ek, &real_ek, *choice); | ||
|
|
||
| decap_keys.push(dk); | ||
| eks0.push(ek0); | ||
| eks1.push(ek1); | ||
| } | ||
|
|
||
| let receiver_msg = EncapsulationKeysMessage { eks0, eks1 }; | ||
| { | ||
| let mut send_stream = send.as_stream(); | ||
| send_stream.send(receiver_msg).await?; | ||
| } |
There was a problem hiding this comment.
This does not follow the MR19 protocol Figure 8. One message needs to be a real ek corresponding to the dk, and the other one needs to be the real ek minus a hash of the random ek. See the libOTe implementation here.
Crucially, both messages need to look like actual group elements of the UKA protocol. In the current version, ek_c is an actual key generated by the MlKem library, whereas the other one are just random bytes. The problem is, that the actual ek is distinguishable from the fake_ek as it has a specific structure which the random bytes do not have with high likelihood.
Sadly, it seems the ml-kem crate does not directly expose the necessary internals required to implement the MR19 protocol (e.g. adding/subtracting of group elements, hashing to the group)... Ohh, I just saw that the ML-KEM crate uses the module-lattice crate for the arithmetic. Maybe that can be used.
There was a problem hiding this comment.
Thank you, let me look into that!
And maybe a dumb question - should the reference be the MR19 paper if we are using ML-KEM and not Kyber?
Also, what about the receiver being able to keep the fake key? I will dig into that more, but have you had a chance to look?
There was a problem hiding this comment.
Actually, ignore these questions. I've realized I've misunderstood the endemic thing and assumed quite a lot. Sorry for wasting your time on that. Let me get back at it and will try to make it correctly in this PR. Thank you!
There was a problem hiding this comment.
No worries, the MR19 paper is actually very interesting and clarified some relations between key exchange and OT for me. It is quite long though and I initially also had some trouble understanding how the generic OT protocol presented in the paper can be used with ML-KEM.
|
I've had a closer look at the ml-kem and module-lattice crate and I think they can be used to implement the endemic OT protocol. The module-lattice crate has the This leaves hashing to the group which I'm about unsure how to implement. It seems libOTe hashes the pk to a 32-byte seed and then from that seed samples a new random pk (see here). I think this operation is described section D.3 of the MR19 paper but it is a bit hard for me to understand. |
|
As it seems that the module lattice crate was recently extracted from ML-KEM, it probably makes sense to use the newest pre-release of ml-kem which uses the module-lattice crate to hopefully reduce the amount of duplicated code. |
Based on the discussion in #48 this clarifies the message security of the CO15 base OT implementation using the terminology of MR19.
Based on the discussion in #48 this clarifies the message security of the CO15 base OT implementation using the terminology of MR19.
Based on the discussion in #48 this clarifies the message security of the CO15 base OT implementation using the terminology of MR19.
c73a47b to
11dc9aa
Compare
|
I am back to it and looking at how to implement. |
|
I've pushed something, but please don't review it yet, I am still working on it. I put the PR as a draft for now. Will ping you once ready to review. |
Based on the discussion in robinhundt#48 this clarifies the message security of the CO15 base OT implementation using the terminology of MR19.
7070fff to
22cda7a
Compare
|
Hey @robinhundt, could you please have a look? I now generate the encapsulation keys as you mentioned in the comments above, following libOTe's implementation. I also put an .md file that describes the approach - essentially, I've tried to stick to what you suggested. |
This makes the base OT post-quantum secure by utilizing ML-KEM key encapsulation via https://crates.io/crates/ml-kem. We keep the Simplest OT as default base OT and make ML-KEM optional by adding compile-time features for different variants (k = 512/768/1024). References: MR19: https://eprint.iacr.org/2019/706 FIPS 203: https://csrc.nist.gov/pubs/fips/203/final libOTe: https://github.com/osu-crypto/libOTe/blob/d0e499206d1d4d16c6b4ca6c0e712490e0632f80/thirdparty/KyberOT/KyberOT.c#L40-L41 ML-KEM implementation: https://github.com/RustCrypto/KEMs/blob/5a7f3ab7af5420cacca9befc9212532e4c7f6ca1/ml-kem/src/ ml-kem crate: https://crates.io/crates/ml-kem module-lattice crate: https://crates.io/crates/module-lattice
22cda7a to
4db029c
Compare
This makes the base OT post-quantum secure by utilizing ML-KEM key encapsulation via https://crates.io/crates/ml-kem.
We keep the Simplest OT as default base OT and make ML-KEM optional by adding compile-time features for different variants (k = 512/768/1024).
References: