Argyle-Software / kyber

A rust implementation of the Kyber post-quantum KEM
https://docs.rs/pqc_kyber/
Apache License 2.0
164 stars 37 forks source link

Could you provide PKE API? #56

Closed oilel closed 9 months ago

oilel commented 1 year ago

Could you provide application programming interface for PKE (public key encryption scheme)? Which is lower level and more customizable.

bwesterb commented 1 year ago

You should not use the inner PKE. Instead, you should use HPKE with Kyber. We're working on standardising that.

mberry commented 9 months ago

Stand-alone or hybrid PKE is out of scope for this crate, so closing this issue after much discussion.

Bas is certainly right, you should not be using Kyber alone, though I'm interested in why he doesn't hash or xor the shared secrets in that IETF draft?

tarcieri commented 9 months ago

FWIW, the @RustCrypto project is planning on implementing the X25519Kyber768 draft using the kem crate API.

You can follow along at https://github.com/RustCrypto/KEMs

mberry commented 9 months ago

For future note, in this crate the AuthEncapsulator trait probably needs some work to fit in using the kex module. Encapsulator seems good to go, though I'd prefer traits behind a feature gate.

bwesterb commented 9 months ago

Bas is certainly right, you should not be using Kyber alone, though I'm interested in why he doesn't hash or xor the shared secrets in that IETF draft?

It's explained in the security considerations section: the combined secret is hashed a layer up in HPKE.

mberry commented 9 months ago

By "a layer up" you mean in the protocols themselves? I am talking about here:

Nsecret: 64

The shared secret is calculated as the concatenation of the X25519 shared secret (32 bytes) and the Kyber768Draft00 shared secret (32 bytes). The resulting shared secret value is 64 bytes in length.

Prior-hashing or not, that's 32 bytes more on the wire than ever needs to be sent? Why not hash then send rather than concat then send? Wondering about the reasoning behind that.

bwesterb commented 9 months ago

Prior-hashing or not, that's 32 bytes more on the wire than ever needs to be sent? Why not hash then send rather than concat then send? Wondering about the reasoning behind that.

The draft defines an HPKE KEM. An HPKE KEM is only meant to be used in HPKE — not elsewhere. The "layer up" is HPKE itself. Let me quote the security considerations for you:

We aim for IND-CCA2 robustness: that means that if either constituent KEM is not IND-CCA2 secure, but the other is, the combined hybrid remains IND-CCA2 secure.

In general [GHP18] [COMBINERS] this requires a combiner that mixes in the cipher texts, such as, assuming fixed-length cipher texts and shared secrets:

HKDF(concat(ss1, ss2, enc1, enc2)).

In the present case, DHKEM(X25519, -) and Kyber768Draft00 already mix in the respective cipher texts into their shared secrets. Thus we can forgo mixing in the cipher texts a second time.

Furthermore, in HPKE, the shared secret is never used directly, but passed through HKDF (via KeySchedule), and thus we can forgo the call to HKDF as well.