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 }