#![cfg(feature = "ztier")]
use crate::{constants::SCHEME_MARKER_SIZE, error::Error, Format, Scheme};
#[cfg(feature = "zmock")]
use crate::decrypt_zmock1;
#[cfg(feature = "zrbcx")]
use crate::decrypt_zrbcx;
#[inline(always)]
pub(crate) fn dec_from_format_ztier(
obtext: &str,
format: Format,
secret: &[u8; 32],
) -> Result<String, Error> {
let mut buffer = crate::dec::decode_obtext_to_payload(obtext, format.encoding())?;
if buffer.len() < SCHEME_MARKER_SIZE {
return Err(Error::PayloadTooShort);
}
let len = buffer.len();
let first_byte = buffer[0];
let scheme_marker = [buffer[len - 2] ^ first_byte, buffer[len - 1] ^ first_byte];
if scheme_marker != format.scheme().marker() {
return Err(Error::SchemeMarkerMismatch);
}
buffer.truncate(len - SCHEME_MARKER_SIZE);
let plaintext_bytes = match format.scheme() {
#[cfg(feature = "zrbcx")]
Scheme::Zrbcx => decrypt_zrbcx(secret, &buffer)?,
#[cfg(feature = "zmock")]
Scheme::Zmock1 => decrypt_zmock1(secret, &buffer)?,
#[cfg(feature = "legacy")]
Scheme::Legacy => unreachable!("legacy uses separate path"),
_ => return Err(Error::InvalidScheme),
};
#[cfg(feature = "unchecked-utf8")]
{
Ok(unsafe { String::from_utf8_unchecked(plaintext_bytes) })
}
#[cfg(not(feature = "unchecked-utf8"))]
{
String::from_utf8(plaintext_bytes).map_err(|_| Error::InvalidUtf8)
}
}