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}