cipherstash-client 0.34.1-alpha.1

The official CipherStash SDK
Documentation
use super::{EncryptedSteVecTerm, TokenizedSelector};
use crate::zerokms::{encrypted_record, EncryptedRecord};
use serde::{Deserialize, Serialize};

#[cfg_attr(test, derive(PartialEq, Eq))]
#[derive(Debug, Serialize, Deserialize)]
pub struct EncryptedEntry<const N: usize> {
    #[serde(rename = "s")]
    pub tokenized_selector: TokenizedSelector<N>,
    #[serde(flatten)]
    pub term: EncryptedSteVecTerm,
    #[serde(rename = "c", with = "encrypted_record::formats::mp_base85")]
    pub record: EncryptedRecord,
    pub parent_is_array: bool,
}

impl<const N: usize> EncryptedEntry<N> {
    pub(crate) fn new(
        tokenized_selector: TokenizedSelector<N>,
        term: EncryptedSteVecTerm,
        record: EncryptedRecord,
        parent_is_array: bool,
    ) -> Self {
        Self {
            tokenized_selector,
            term,
            record,
            parent_is_array,
        }
    }
}

#[cfg(test)]
use super::QueryEntry;

impl<const N: usize> EncryptedEntry<N> {
    #[cfg(test)]
    pub fn contains(&self, q: &QueryEntry<N>) -> bool {
        self.tokenized_selector == q.0 && self.term == q.1
    }
}

#[cfg(test)]
mod tests {
    use crate::encryption::{
        json_indexer::ste_vec::encrypted_term::{EncryptedSteVecTerm, Mac},
        EncryptedEntry, TokenizedSelector,
    };
    use crate::zerokms::EncryptedRecord;
    use serde_json::json;
    use std::vec;

    fn make_encrypted_entry(term: EncryptedSteVecTerm) -> EncryptedEntry<16> {
        let ciphertext = EncryptedRecord {
            iv: Default::default(),
            ciphertext: vec![1, 2, 3],
            tag: vec![1, 16],
            descriptor: Default::default(),
            keyset_id: Default::default(),
        };

        EncryptedEntry::new(TokenizedSelector([0; 16]), term, ciphertext, false)
    }

    mod mac {
        use super::*;

        fn expected() -> serde_json::Value {
            json!({
                "parent_is_array": false,
                // Hex-encoded tokenized_selector
                "s": "00000000000000000000000000000000",
                // Hex encoded MAC term
                "b": "01010101010101010101010101010101",
                // Base85-encoded ciphertext
                "c": "mBbJL0000000000000000002Q0|5d9!~y{jpuh"
            })
        }

        #[test]
        fn serialize_shape() {
            let entry = make_encrypted_entry(EncryptedSteVecTerm::Mac(Mac::new(vec![1; 16])));
            let serialized = serde_json::to_string(&entry).unwrap();

            assert_eq!(
                serde_json::from_str::<serde_json::Value>(&serialized).unwrap(),
                expected()
            );
        }

        #[test]
        fn deserialize_shape() {
            let serialized = expected();
            let entry: Result<EncryptedEntry<16>, _> = serde_json::from_value(serialized);
            assert!(entry.is_ok());
        }
    }

    mod ore_fixed {
        use super::*;
        use cllw_ore::OreCllw8V1;

        fn expected() -> serde_json::Value {
            json!({
                "parent_is_array": false,
                // Hex-encoded tokenized_selector
                "s": "00000000000000000000000000000000",
                // Hex encoded 64-byte ORE term
                "ocf": "09090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909",
                // Base85-encoded ciphertext
                "c": "mBbJL0000000000000000002Q0|5d9!~y{jpuh"
            })
        }

        #[test]
        fn serialize_shape() {
            let bytes = vec![9; 64];
            let entry = make_encrypted_entry(EncryptedSteVecTerm::OreFixed(
                OreCllw8V1::try_from(bytes.as_ref()).unwrap(),
            ));
            let serialized = serde_json::to_string(&entry).unwrap();

            assert_eq!(
                serde_json::from_str::<serde_json::Value>(&serialized).unwrap(),
                expected()
            );
        }

        #[test]
        fn deserialize_shape() {
            let serialized = expected();
            let entry: Result<EncryptedEntry<16>, _> = serde_json::from_value(serialized);
            assert!(entry.is_ok());
        }
    }

    mod ore_variable {
        use super::*;
        use cllw_ore::OreCllw8VariableV1;

        fn expected() -> serde_json::Value {
            json!({
                "parent_is_array": false,
                // Hex-encoded tokenized_selector
                "s": "00000000000000000000000000000000",
                // Hex encoded 17-byte ORE term (0x02 header byte)
                "ocv": "0404040404040404040404040404040404",
                // Base85-encoded ciphertext
                "c": "mBbJL0000000000000000002Q0|5d9!~y{jpuh"
            })
        }

        #[test]
        fn serialize_shape() {
            let bytes = vec![4; 17];
            let entry = make_encrypted_entry(EncryptedSteVecTerm::OreVariable(
                OreCllw8VariableV1::from(bytes),
            ));

            let serialized = serde_json::to_string(&entry).unwrap();

            assert_eq!(
                serde_json::from_str::<serde_json::Value>(&serialized).unwrap(),
                expected()
            );
        }

        #[test]
        fn deserialize_shape() {
            let serialized = expected();
            let entry: Result<EncryptedEntry<16>, _> = serde_json::from_value(serialized);
            assert!(entry.is_ok());
        }
    }
}