cosmian_kyber/api.rs
1use crate::{
2 error::KyberError,
3 kem::*,
4 kex::{Decapsulated, Encapsulated, PublicKey, SecretKey},
5 params::*,
6 CryptoRng, RngCore,
7};
8
9/// Keypair generation with a provided RNG.
10///
11/// ### Example
12/// ```
13/// # use cosmian_kyber::*;
14/// # fn main() -> Result<(), KyberError> {
15/// let mut rng = rand::thread_rng();
16/// let keys = keypair(&mut rng);
17/// # Ok(())}
18/// ```
19pub fn keypair<R>(rng: &mut R) -> Keypair
20where
21 R: RngCore + CryptoRng,
22{
23 let mut public = [0u8; KYBER_PUBLICKEYBYTES];
24 let mut secret = [0u8; KYBER_SECRETKEYBYTES];
25 crypto_kem_keypair(&mut public, &mut secret, rng, None);
26 Keypair { public, secret }
27}
28
29/// Encapsulates a public key returning the ciphertext to send
30/// and the shared secret
31///
32/// ### Example
33/// ```
34/// # use cosmian_kyber::*;
35/// # fn main() -> Result<(), KyberError> {
36/// let mut rng = rand::thread_rng();
37/// let keys = keypair(&mut rng);
38/// let (ciphertext, shared_secret) = encapsulate(&keys.public, &mut rng)?;
39/// # Ok(())}
40/// ```
41pub fn encapsulate<R>(pk: &[u8], rng: &mut R) -> Encapsulated
42where
43 R: CryptoRng + RngCore,
44{
45 if pk.len() != KYBER_PUBLICKEYBYTES {
46 return Err(KyberError::InvalidInput);
47 }
48 let mut ct = [0u8; KYBER_CIPHERTEXTBYTES];
49 let mut ss = [0u8; KYBER_SSBYTES];
50 crypto_kem_enc(&mut ct, &mut ss, pk, rng, None);
51 Ok((ct, ss))
52}
53
54/// Decapsulates ciphertext with a secret key, the result will contain
55/// a KyberError if decapsulation fails
56///
57/// ### Example
58/// ```
59/// # use cosmian_kyber::*;
60/// # fn main() -> Result<(), KyberError> {
61/// let mut rng = rand::thread_rng();
62/// let keys = keypair(&mut rng);
63/// let (ct, ss1) = encapsulate(&keys.public, &mut rng)?;
64/// let ss2 = decapsulate(&ct, &keys.secret)?;
65/// assert_eq!(ss1, ss2);
66/// # Ok(())}
67/// ```
68pub fn decapsulate(ct: &[u8], sk: &[u8]) -> Decapsulated {
69 if ct.len() != KYBER_CIPHERTEXTBYTES || sk.len() != KYBER_SECRETKEYBYTES {
70 return Err(KyberError::InvalidInput);
71 }
72 let mut ss = [0u8; KYBER_SSBYTES];
73 match crypto_kem_dec(&mut ss, ct, sk) {
74 Ok(_) => Ok(ss),
75 Err(e) => Err(e),
76 }
77}
78
79/// A public/secret keypair for use with Kyber.
80///
81/// Byte lengths of the keys are determined by the security level chosen.
82#[derive(Copy, Clone, Debug, Eq, PartialEq)]
83pub struct Keypair {
84 pub public: PublicKey,
85 pub secret: SecretKey,
86}
87
88impl Keypair {
89 /// Securely generates a new keypair`
90 /// ```
91 /// # use cosmian_kyber::*;
92 /// # fn main() -> Result<(), KyberError> {
93 /// let mut rng = rand::thread_rng();
94 /// let keys = Keypair::generate(&mut rng);
95 /// # let empty_keys = Keypair{
96 /// public: [0u8; KYBER_PUBLICKEYBYTES], secret: [0u8; KYBER_SECRETKEYBYTES]
97 /// };
98 /// # assert!(empty_keys != keys);
99 /// # Ok(()) }
100 /// ```
101 pub fn generate<R: CryptoRng + RngCore>(rng: &mut R) -> Keypair {
102 keypair(rng)
103 }
104}