cipherstash-client 0.34.1-alpha.1

The official CipherStash SDK
Documentation
use cllw_ore::{OreCllw8V1, OreCllw8VariableV1};
use hex::{FromHex, FromHexError};
use serde::{Deserialize, Serialize};

/// Represents an encrypted term in a STE vector.
/// It can be a MAC, a fixed-length ORE term, or a variable-length ORE term.
#[derive(Debug, PartialEq, Eq, PartialOrd, Serialize, Deserialize)]
#[non_exhaustive]
pub enum EncryptedSteVecTerm {
    #[serde(with = "hex::serde", rename = "b")]
    Mac(Mac),
    /// An ORE term with a fixed length of 64 bytes.
    /// Because JSON number are always represented as f64, the ORE term is fixed at 64 bytes.
    #[serde(with = "hex::serde", rename = "ocf")]
    OreFixed(OreCllw8V1<64>),
    #[serde(with = "hex::serde", rename = "ocv")]
    OreVariable(OreCllw8VariableV1),
}

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Mac(Vec<u8>);

impl AsRef<[u8]> for Mac {
    fn as_ref(&self) -> &[u8] {
        self.0.as_ref()
    }
}

impl FromHex for Mac {
    type Error = FromHexError;

    fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
        Ok(Self(Vec::from_hex(hex.as_ref())?))
    }
}

impl Mac {
    pub(crate) fn new(bytes: Vec<u8>) -> Self {
        Self(bytes)
    }
}

#[cfg(test)]
mod tests {
    use serde_json::json;

    use super::*;

    #[test]
    fn test_encrypted_ste_vec_term_mac_serde() {
        let term = EncryptedSteVecTerm::Mac(Mac::new(vec![1, 2, 3, 4]));
        let serialized = serde_json::to_value(&term).unwrap();
        assert_eq!(serialized, json!({"b": "01020304"}));
        let deserialized: EncryptedSteVecTerm = serde_json::from_value(serialized).unwrap();
        assert_eq!(term, deserialized);
    }

    #[test]
    fn test_encrypted_ste_vec_term_ore_fixed_serde() {
        let bytes: Vec<u8> = vec![2; 64];
        let term =
            EncryptedSteVecTerm::OreFixed(OreCllw8V1::<64>::try_from(bytes.as_ref()).unwrap());
        let serialized = serde_json::to_value(&term).unwrap();
        assert_eq!(
            serialized,
            json!({ "ocf": "02020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202" })
        );
        let deserialized: EncryptedSteVecTerm = serde_json::from_value(serialized).unwrap();
        assert_eq!(term, deserialized);
    }

    #[test]
    fn test_encrypted_ste_vec_term_ore_variable_serde() {
        let bytes: Vec<u8> = vec![5; 17];
        let term = EncryptedSteVecTerm::OreVariable(OreCllw8VariableV1::from(bytes));
        let serialized = serde_json::to_value(&term).unwrap();
        assert_eq!(
            serialized,
            json!({"ocv": "0505050505050505050505050505050505"})
        );
        let deserialized: EncryptedSteVecTerm = serde_json::from_value(serialized).unwrap();
        assert_eq!(term, deserialized);
    }
}