tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

slice.rs (9681B)


      1 // Copyright 2023 Cryspen Sarl
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 
      9 //! This module contains the trait and related errors for a KEM that takes slices as
     10 //! arguments and writes the results to mutable slices..
     11 
     12 use super::arrayref;
     13 
     14 /// A Key Encapsulation Mechanismd (KEM). This trait takes slices as arguments.
     15 pub trait Kem {
     16    /// Generate a pair of encapsulation and decapsulation keys.
     17    /// It is the responsibility of the caller to ensure  that the `rand` argument is actually
     18    /// random.
     19    fn keygen(ek: &mut [u8], dk: &mut [u8], rand: &[u8]) -> Result<(), KeyGenError>;
     20 
     21    /// Encapsulate a shared secret towards a given encapsulation key.
     22    /// It is the responsibility of the caller to ensure  that the `rand` argument is actually
     23    /// random.
     24    fn encaps(ct: &mut [u8], ss: &mut [u8], ek: &[u8], rand: &[u8]) -> Result<(), EncapsError>;
     25 
     26    /// Decapsulate a shared secret.
     27    fn decaps(ss: &mut [u8], ct: &[u8], dk: &[u8]) -> Result<(), DecapsError>;
     28 }
     29 
     30 /// Error generating key with provided randomness
     31 #[derive(Debug)]
     32 pub enum KeyGenError {
     33    /// Error generating key with provided randomness
     34    InvalidRandomness,
     35    /// The provided randomness has the wrong length
     36    InvalidRandomnessLength,
     37    /// The provided encapsulation key has the wrong length
     38    InvalidEncapsKeyLength,
     39    /// The provided decapulation key has the wrong length
     40    InvalidDecapsKeyLength,
     41    /// An unknown error occurred
     42    Unknown,
     43 }
     44 
     45 /// Error indicating that encapsulating failed
     46 #[derive(Debug)]
     47 pub enum EncapsError {
     48    /// Encapsulation key is invalid
     49    InvalidEncapsKey,
     50    /// Error encapsulating key with provided randomness
     51    InvalidRandomness,
     52    /// The provided randomness has the wrong length
     53    InvalidRandomnessLength,
     54    /// The provided encapsulation key has the wrong length
     55    InvalidEncapsKeyLength,
     56    /// The provided ciphertext has the wrong length
     57    InvalidCiphertextLength,
     58    /// The provided shared secret has the wrong length
     59    InvalidSharedSecretLength,
     60    /// An unknown error occurred
     61    Unknown,
     62 }
     63 
     64 /// Error indicating that decapsulating failed
     65 #[derive(Debug)]
     66 pub enum DecapsError {
     67    /// Ciphertext key is invalid
     68    InvalidCiphertext,
     69    /// Decapsulation key is invalid
     70    InvalidDecapsKey,
     71    /// The provided decapulation key has the wrong length
     72    InvalidDecapsKeyLength,
     73    /// The provided ciphertext has the wrong length
     74    InvalidCiphertextLength,
     75    /// The provided shared secret has the wrong length
     76    InvalidSharedSecretLength,
     77    /// An unknown error occurred
     78    Unknown,
     79 }
     80 
     81 impl From<arrayref::KeyGenError> for KeyGenError {
     82    fn from(value: arrayref::KeyGenError) -> Self {
     83        match value {
     84            arrayref::KeyGenError::InvalidRandomness => KeyGenError::InvalidRandomness,
     85            arrayref::KeyGenError::Unknown => KeyGenError::Unknown,
     86        }
     87    }
     88 }
     89 
     90 impl From<arrayref::EncapsError> for EncapsError {
     91    fn from(value: arrayref::EncapsError) -> Self {
     92        match value {
     93            arrayref::EncapsError::InvalidEncapsKey => EncapsError::InvalidEncapsKey,
     94            arrayref::EncapsError::InvalidRandomness => EncapsError::InvalidRandomness,
     95            arrayref::EncapsError::Unknown => EncapsError::Unknown,
     96        }
     97    }
     98 }
     99 
    100 impl From<arrayref::DecapsError> for DecapsError {
    101    fn from(value: arrayref::DecapsError) -> Self {
    102        match value {
    103            arrayref::DecapsError::InvalidCiphertext => DecapsError::InvalidCiphertext,
    104            arrayref::DecapsError::InvalidDecapsKey => DecapsError::InvalidDecapsKey,
    105            arrayref::DecapsError::Unknown => DecapsError::Unknown,
    106        }
    107    }
    108 }
    109 
    110 #[macro_export]
    111 /// Implements [`Kem`] for any [`arrayref::Kem`]
    112 macro_rules! impl_trait {
    113    ($type:ty => $ek:expr, $dk:expr, $ct:expr, $ss:expr, $rand_kg:expr, $rand_encaps:expr) => {
    114        impl $crate::kem::slice::Kem for $type {
    115            fn keygen(ek: &mut [u8], dk: &mut [u8], rand: &[u8]) -> Result<(), $crate::kem::slice::KeyGenError> {
    116                let ek : &mut [u8; $ek] = ek
    117                    .try_into()
    118                    .map_err(|_| $crate::kem::slice::KeyGenError::InvalidEncapsKeyLength)?;
    119                let dk : &mut [u8; $dk] = dk
    120                    .try_into()
    121                    .map_err(|_| $crate::kem::slice::KeyGenError::InvalidDecapsKeyLength)?;
    122                let rand : &[u8; $rand_kg] = rand
    123                    .try_into()
    124                    .map_err(|_| $crate::kem::slice::KeyGenError::InvalidRandomnessLength)?;
    125 
    126                <$type as $crate::kem::arrayref::Kem<$ek, $dk, $ct, $ss, $rand_kg, $rand_encaps>>::keygen(ek, dk, rand).map_err($crate::kem::slice::KeyGenError::from)
    127            }
    128 
    129            fn encaps(ct: &mut [u8], ss: &mut [u8], ek: &[u8], rand: &[u8]) -> Result<(), $crate::kem::slice::EncapsError>{
    130                let ct : &mut [u8; $ct] = ct
    131                    .try_into()
    132                    .map_err(|_| $crate::kem::slice::EncapsError::InvalidCiphertextLength)?;
    133                let ss : &mut [u8; $ss] = ss
    134                    .try_into()
    135                    .map_err(|_| $crate::kem::slice::EncapsError::InvalidSharedSecretLength)?;
    136                let ek : & [u8; $ek] = ek
    137                    .try_into()
    138                    .map_err(|_| $crate::kem::slice::EncapsError::InvalidEncapsKeyLength)?;
    139                let rand : &[u8; $rand_encaps] = rand
    140                    .try_into()
    141                    .map_err(|_| $crate::kem::slice::EncapsError::InvalidRandomnessLength)?;
    142 
    143 
    144                <$type as $crate::kem::arrayref::Kem<$ek, $dk, $ct, $ss, $rand_kg, $rand_encaps>>::encaps(ct, ss, ek,rand).map_err($crate::kem::slice::EncapsError::from)
    145            }
    146 
    147            fn decaps(ss: &mut [u8], ct: &[u8], dk: &[u8]) -> Result<(), $crate::kem::slice::DecapsError> {
    148                let ss : &mut [u8; $ss] = ss
    149                    .try_into()
    150                    .map_err(|_| $crate::kem::slice::DecapsError::InvalidSharedSecretLength)?;
    151                let ct : &[u8; $ct] = ct
    152                    .try_into()
    153                    .map_err(|_| $crate::kem::slice::DecapsError::InvalidCiphertextLength)?;
    154                let dk : &[u8; $dk] = dk
    155                    .try_into()
    156                    .map_err(|_| $crate::kem::slice::DecapsError::InvalidDecapsKeyLength)?;
    157 
    158                <$type as $crate::kem::arrayref::Kem<$ek, $dk, $ct, $ss, $rand_kg, $rand_encaps>>::decaps(ss, ct, dk).map_err($crate::kem::slice::DecapsError::from)
    159            }
    160 
    161        }
    162 
    163        #[cfg(test)]
    164        #[test]
    165        fn simple_kem_test(){
    166            $crate::kem::tests::simple::<$ek, $dk, $ct, $ss, $rand_kg, $rand_encaps, $type>();
    167        }
    168    };
    169 
    170 }
    171 
    172 pub use impl_trait;
    173 
    174 impl core::fmt::Display for KeyGenError {
    175    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
    176        let text = match self {
    177            KeyGenError::InvalidRandomness => "error generating key with provided randomness",
    178            KeyGenError::Unknown => "an unknown error occurred",
    179            KeyGenError::InvalidRandomnessLength => "the provided randomness has the wrong length",
    180            KeyGenError::InvalidEncapsKeyLength => {
    181                "the provided encapsulation key has the wrong length"
    182            }
    183            KeyGenError::InvalidDecapsKeyLength => {
    184                "the provided decapsulation key has the wrong length"
    185            }
    186        };
    187 
    188        f.write_str(text)
    189    }
    190 }
    191 
    192 impl core::fmt::Display for EncapsError {
    193    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
    194        let text = match self {
    195            EncapsError::InvalidEncapsKey => "encapsulation key is invalid",
    196            EncapsError::InvalidRandomness => "error generating key with provided randomness",
    197            EncapsError::Unknown => "an unknown error occurred",
    198            EncapsError::InvalidRandomnessLength => "the provided randomness has the wrong length",
    199            EncapsError::InvalidEncapsKeyLength => {
    200                "the provided encapsulation key has the wrong length"
    201            }
    202            EncapsError::InvalidCiphertextLength => "the provided ciphertext has the wrong length",
    203            EncapsError::InvalidSharedSecretLength => {
    204                "the provided shared secret has the wrong length"
    205            }
    206        };
    207 
    208        f.write_str(text)
    209    }
    210 }
    211 
    212 impl core::fmt::Display for DecapsError {
    213    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
    214        let text = match self {
    215            DecapsError::InvalidDecapsKey => "encapsulation key is invalid",
    216            DecapsError::InvalidCiphertext => "ciphertext is invalid",
    217            DecapsError::Unknown => "an unknown error occurred",
    218            DecapsError::InvalidCiphertextLength => "the provided ciphertext has the wrong length",
    219            DecapsError::InvalidSharedSecretLength => {
    220                "the provided shared secret has the wrong length"
    221            }
    222            DecapsError::InvalidDecapsKeyLength => {
    223                "the provided decapsulation key has the wrong length"
    224            }
    225        };
    226 
    227        f.write_str(text)
    228    }
    229 }
    230 
    231 #[cfg(feature = "error-in-core")]
    232 /// Here we implement the Error trait. This has only been added to core relatively recently, so we
    233 /// are hiding that behind a feature.
    234 mod error_in_core {
    235    impl core::error::Error for super::KeyGenError {}
    236    impl core::error::Error for super::EncapsError {}
    237    impl core::error::Error for super::DecapsError {}
    238 }