mod encrypt;
mod fhe;
mod key;
mod plain;
mod sbox;
#[cfg(test)]
mod test;
pub use fhe::AesFheState;
pub use key::AesFheRoundKeys;
pub use plain::AesPlainState;
use crate::named::Named;
use crate::shortint::oprf::OprfSeed;
use crate::shortint::{Ciphertext, ClientKey, ServerKey};
use crate::transciphering::backward_compatibility::{
AesIvVersions, AesPlainKeyVersions, SerializableAesFheKeyVersions,
};
use crate::transciphering::ciphers::*;
use crate::transciphering::TranscipheringServerKey;
use serde::{Deserialize, Serialize};
use tfhe_versionable::Versionize;
#[derive(Clone, Copy, Serialize, Deserialize, Versionize)]
#[versionize(AesPlainKeyVersions)]
pub struct AesPlainKey([u8; 16]);
impl Named for AesPlainKey {
const NAME: &'static str = "transciphering::AesPlainKey";
}
impl AesPlainKey {
pub fn expand(self) -> [bool; 128] {
let mut out = [false; 128];
unpack_bits_lsb_first(&self.0, &mut out);
out
}
pub fn encrypt(&self, client_key: &ClientKey) -> AesFheKey {
AesFheKey {
key: self.expand().map(|b| client_key.encrypt_bool(b)),
}
}
pub(crate) fn to_csprng_key_u128(self) -> u128 {
u128::from_ne_bytes(self.0)
}
}
impl From<u128> for AesPlainKey {
fn from(value: u128) -> Self {
value.to_be_bytes().into()
}
}
impl From<[u8; 16]> for AesPlainKey {
fn from(value: [u8; 16]) -> Self {
Self(value)
}
}
impl From<[bool; 128]> for AesPlainKey {
fn from(value: [bool; 128]) -> Self {
let mut bits = [0u8; 16];
pack_bits_lsb_first(&value, &mut bits);
bits.into()
}
}
#[derive(Clone, Serialize, Deserialize, Versionize)]
#[serde(into = "SerializableAesFheKey", try_from = "SerializableAesFheKey")]
#[versionize(into = "SerializableAesFheKey", try_from = "SerializableAesFheKey")]
pub struct AesFheKey {
key: [Ciphertext; 128],
}
impl AesFheKey {
pub fn ciphertexts(&self) -> &[Ciphertext; 128] {
&self.key
}
pub fn new_random(
seed: impl OprfSeed,
transciphering_key: &TranscipheringServerKey,
sks: &ServerKey,
) -> Self {
let encrypted_bits = transciphering_key
.oprf_key()
.generate_random_boolean_sequence(seed, 128, sks);
let key: [Ciphertext; 128] = encrypted_bits.try_into().expect("the vec has 128 elements");
Self { key }
}
pub fn decrypt(&self, client_key: &ClientKey) -> AesPlainKey {
let mut decrypted_bits = [false; 128];
for (ct, out) in self.key.iter().zip(decrypted_bits.iter_mut()) {
*out = client_key.decrypt(ct) != 0;
}
AesPlainKey::from(decrypted_bits)
}
}
#[derive(Clone, Serialize, Deserialize, Versionize)]
#[versionize(SerializableAesFheKeyVersions)]
pub struct SerializableAesFheKey {
key: Vec<Ciphertext>,
}
impl From<AesFheKey> for SerializableAesFheKey {
fn from(value: AesFheKey) -> Self {
Self {
key: value.key.into(),
}
}
}
impl TryFrom<SerializableAesFheKey> for AesFheKey {
type Error = crate::Error;
fn try_from(value: SerializableAesFheKey) -> Result<Self, Self::Error> {
let len = value.key.len();
let key: [Ciphertext; 128] = value.key.try_into().map_err(|_| {
crate::error!("an AES key must hold exactly 128 ciphertexts, got {len}")
})?;
Ok(Self { key })
}
}
#[derive(Clone, Copy, Serialize, Deserialize, Versionize)]
#[versionize(AesIvVersions)]
pub struct AesIv(u128);
impl AesIv {
pub fn to_u128(self) -> u128 {
self.0
}
}
impl From<u128> for AesIv {
fn from(value: u128) -> Self {
Self(value)
}
}
impl From<[u8; 16]> for AesIv {
fn from(value: [u8; 16]) -> Self {
u128::from_be_bytes(value).into()
}
}
impl From<[bool; 128]> for AesIv {
fn from(value: [bool; 128]) -> Self {
let mut bits = [0u8; 16];
pack_bits_lsb_first(&value, &mut bits);
bits.into()
}
}
impl Named for AesIv {
const NAME: &'static str = "transciphering::AesIv";
}