use crate::{
base32::{BASE32_CROCKFORD, BASE32_RFC},
error::Error,
Encoding, Format, Scheme,
};
use data_encoding::{BASE64URL_NOPAD, HEXLOWER};
#[cfg(feature = "aags")]
use crate::encrypt_aags;
#[cfg(feature = "aasv")]
use crate::encrypt_aasv;
#[cfg(feature = "apgs")]
use crate::encrypt_apgs;
#[cfg(feature = "apsv")]
use crate::encrypt_apsv;
#[cfg(feature = "mock")]
use crate::encrypt_mock1;
#[cfg(feature = "mock")]
use crate::encrypt_mock2;
#[cfg(feature = "upbc")]
use crate::encrypt_upbc;
#[inline(always)]
pub(crate) fn enc_to_format(
plaintext: &str,
format: Format,
master_key: &[u8; 64],
) -> Result<String, Error> {
if plaintext.is_empty() {
return Err(Error::EmptyPlaintext);
}
let mut ciphertext: Vec<u8> = match format.scheme() {
#[cfg(feature = "aags")]
Scheme::Aags => encrypt_aags(master_key, plaintext.as_bytes())?,
#[cfg(feature = "apgs")]
Scheme::Apgs => encrypt_apgs(master_key, plaintext.as_bytes())?,
#[cfg(feature = "aasv")]
Scheme::Aasv => encrypt_aasv(master_key, plaintext.as_bytes())?,
#[cfg(feature = "apsv")]
Scheme::Apsv => encrypt_apsv(master_key, plaintext.as_bytes())?,
#[cfg(feature = "upbc")]
Scheme::Upbc => encrypt_upbc(master_key, plaintext.as_bytes())?,
#[cfg(feature = "mock")]
Scheme::Mock1 => encrypt_mock1(master_key, plaintext.as_bytes())?,
#[cfg(feature = "mock")]
Scheme::Mock2 => encrypt_mock2(master_key, plaintext.as_bytes())?,
#[cfg(feature = "zrbcx")]
Scheme::Zrbcx => unreachable!("ztier uses separate path"),
#[cfg(feature = "zmock")]
Scheme::Zmock1 => unreachable!("ztier uses separate path"),
#[cfg(feature = "legacy")]
Scheme::Legacy => unreachable!("legacy uses separate path"),
};
let marker = format.scheme().marker();
let first_byte = ciphertext[0];
ciphertext.push(marker[0] ^ first_byte);
ciphertext.push(marker[1] ^ first_byte);
Ok(match format.encoding() {
Encoding::C32 => BASE32_CROCKFORD.encode(&ciphertext),
Encoding::B32 => BASE32_RFC.encode(&ciphertext),
Encoding::B64 => BASE64URL_NOPAD.encode(&ciphertext),
Encoding::Hex => HEXLOWER.encode(&ciphertext),
})
}