use crate::client::{decrypt, encrypt};
#[cfg(feature = "long")]
use crate::data::py::long::{
PyLongAttribute, PyLongEncryptedAttribute, PyLongEncryptedPseudonym, PyLongPseudonym,
};
use crate::data::py::simple::{
PyAttribute, PyEncryptedAttribute, PyEncryptedPseudonym, PyPseudonym,
};
use crate::data::records::{EncryptedRecord, Record};
#[cfg(feature = "long")]
use crate::data::records::{LongEncryptedRecord, LongRecord, LongRecordStructure};
use crate::keys::py::PySessionKeys;
use crate::keys::types::SessionKeys;
use pyo3::prelude::*;
#[pyclass(name = "Record", from_py_object)]
#[derive(Clone)]
pub struct PyRecord(pub(crate) Record);
#[pymethods]
impl PyRecord {
#[new]
pub fn new(pseudonyms: Vec<PyPseudonym>, attributes: Vec<PyAttribute>) -> Self {
PyRecord(Record::new(
pseudonyms.into_iter().map(|p| p.0).collect(),
attributes.into_iter().map(|a| a.0).collect(),
))
}
#[getter]
pub fn pseudonyms(&self) -> Vec<PyPseudonym> {
self.0.pseudonyms.iter().map(|p| PyPseudonym(*p)).collect()
}
#[getter]
pub fn attributes(&self) -> Vec<PyAttribute> {
self.0.attributes.iter().map(|a| PyAttribute(*a)).collect()
}
fn __repr__(&self) -> String {
format!(
"Record(pseudonyms={}, attributes={})",
self.0.pseudonyms.len(),
self.0.attributes.len()
)
}
}
#[pyclass(name = "EncryptedRecord", from_py_object)]
#[derive(Clone)]
pub struct PyEncryptedRecord(pub(crate) EncryptedRecord);
#[pymethods]
impl PyEncryptedRecord {
#[new]
pub fn new(
pseudonyms: Vec<PyEncryptedPseudonym>,
attributes: Vec<PyEncryptedAttribute>,
) -> Self {
PyEncryptedRecord(EncryptedRecord::new(
pseudonyms.into_iter().map(|p| p.0).collect(),
attributes.into_iter().map(|a| a.0).collect(),
))
}
#[getter]
pub fn pseudonyms(&self) -> Vec<PyEncryptedPseudonym> {
self.0
.pseudonyms
.iter()
.map(|p| PyEncryptedPseudonym(*p))
.collect()
}
#[getter]
pub fn attributes(&self) -> Vec<PyEncryptedAttribute> {
self.0
.attributes
.iter()
.map(|a| PyEncryptedAttribute(*a))
.collect()
}
fn __repr__(&self) -> String {
format!(
"EncryptedRecord(pseudonyms={}, attributes={})",
self.0.pseudonyms.len(),
self.0.attributes.len()
)
}
}
#[pyfunction]
#[pyo3(name = "encrypt_record")]
pub fn py_encrypt_record(record: &PyRecord, session_keys: &PySessionKeys) -> PyEncryptedRecord {
let mut rng = rand::rng();
let keys: SessionKeys = session_keys.clone().into();
PyEncryptedRecord(encrypt(&record.0, &keys, &mut rng))
}
#[cfg(feature = "elgamal3")]
#[pyfunction]
#[pyo3(name = "decrypt_record")]
pub fn py_decrypt_record(
encrypted: &PyEncryptedRecord,
session_keys: &PySessionKeys,
) -> Option<PyRecord> {
let keys: SessionKeys = session_keys.clone().into();
decrypt(&encrypted.0, &keys).map(PyRecord)
}
#[cfg(not(feature = "elgamal3"))]
#[pyfunction]
#[pyo3(name = "decrypt_record")]
pub fn py_decrypt_record(encrypted: &PyEncryptedRecord, session_keys: &PySessionKeys) -> PyRecord {
let keys: SessionKeys = session_keys.clone().into();
PyRecord(decrypt(&encrypted.0, &keys))
}
#[cfg(feature = "long")]
#[pyclass(name = "LongRecord", from_py_object)]
#[derive(Clone)]
pub struct PyLongRecord(pub(crate) LongRecord);
#[cfg(feature = "long")]
#[pymethods]
impl PyLongRecord {
#[new]
pub fn new(pseudonyms: Vec<PyLongPseudonym>, attributes: Vec<PyLongAttribute>) -> Self {
PyLongRecord(LongRecord::new(
pseudonyms.into_iter().map(|p| p.0).collect(),
attributes.into_iter().map(|a| a.0).collect(),
))
}
#[getter]
pub fn pseudonyms(&self) -> Vec<PyLongPseudonym> {
self.0
.pseudonyms
.iter()
.map(|p| PyLongPseudonym(p.clone()))
.collect()
}
#[getter]
pub fn attributes(&self) -> Vec<PyLongAttribute> {
self.0
.attributes
.iter()
.map(|a| PyLongAttribute(a.clone()))
.collect()
}
fn __repr__(&self) -> String {
format!(
"LongRecord(pseudonyms={}, attributes={})",
self.0.pseudonyms.len(),
self.0.attributes.len()
)
}
#[pyo3(name = "structure")]
fn structure(&self) -> PyLongRecordStructure {
PyLongRecordStructure(self.0.structure())
}
#[pyo3(name = "pad_to")]
fn pad_to(&self, structure: &PyLongRecordStructure) -> PyResult<Self> {
self.0
.pad_to(&structure.0)
.map(Self)
.map_err(|e| pyo3::exceptions::PyValueError::new_err(format!("Padding failed: {e}")))
}
}
#[cfg(feature = "long")]
#[pyclass(name = "LongEncryptedRecord", from_py_object)]
#[derive(Clone)]
pub struct PyLongEncryptedRecord(pub(crate) LongEncryptedRecord);
#[cfg(feature = "long")]
#[pymethods]
impl PyLongEncryptedRecord {
#[new]
pub fn new(
pseudonyms: Vec<PyLongEncryptedPseudonym>,
attributes: Vec<PyLongEncryptedAttribute>,
) -> Self {
PyLongEncryptedRecord(LongEncryptedRecord::new(
pseudonyms.into_iter().map(|p| p.0).collect(),
attributes.into_iter().map(|a| a.0).collect(),
))
}
#[getter]
pub fn pseudonyms(&self) -> Vec<PyLongEncryptedPseudonym> {
self.0
.pseudonyms
.iter()
.map(|p| PyLongEncryptedPseudonym(p.clone()))
.collect()
}
#[getter]
pub fn attributes(&self) -> Vec<PyLongEncryptedAttribute> {
self.0
.attributes
.iter()
.map(|a| PyLongEncryptedAttribute(a.clone()))
.collect()
}
fn __repr__(&self) -> String {
format!(
"LongEncryptedRecord(pseudonyms={}, attributes={})",
self.0.pseudonyms.len(),
self.0.attributes.len()
)
}
}
#[cfg(feature = "long")]
#[pyfunction]
#[pyo3(name = "encrypt_long_record")]
pub fn py_encrypt_long_record(
record: &PyLongRecord,
session_keys: &PySessionKeys,
) -> PyLongEncryptedRecord {
let mut rng = rand::rng();
let keys: SessionKeys = session_keys.clone().into();
PyLongEncryptedRecord(encrypt(&record.0, &keys, &mut rng))
}
#[cfg(feature = "long")]
#[cfg(feature = "elgamal3")]
#[pyfunction]
#[pyo3(name = "decrypt_long_record")]
pub fn py_decrypt_long_record(
encrypted: &PyLongEncryptedRecord,
session_keys: &PySessionKeys,
) -> Option<PyLongRecord> {
let keys: SessionKeys = session_keys.clone().into();
decrypt(&encrypted.0, &keys).map(PyLongRecord)
}
#[cfg(feature = "long")]
#[cfg(not(feature = "elgamal3"))]
#[pyfunction]
#[pyo3(name = "decrypt_long_record")]
pub fn py_decrypt_long_record(
encrypted: &PyLongEncryptedRecord,
session_keys: &PySessionKeys,
) -> PyLongRecord {
let keys: SessionKeys = session_keys.clone().into();
PyLongRecord(decrypt(&encrypted.0, &keys))
}
#[cfg(feature = "long")]
#[pyclass(name = "LongRecordStructure", from_py_object)]
#[derive(Clone)]
pub struct PyLongRecordStructure(pub(crate) LongRecordStructure);
#[cfg(feature = "long")]
#[pymethods]
impl PyLongRecordStructure {
#[new]
pub fn new(pseudonym_blocks: Vec<usize>, attribute_blocks: Vec<usize>) -> Self {
PyLongRecordStructure(LongRecordStructure {
pseudonym_blocks,
attribute_blocks,
})
}
#[getter]
pub fn pseudonym_blocks(&self) -> Vec<usize> {
self.0.pseudonym_blocks.clone()
}
#[getter]
pub fn attribute_blocks(&self) -> Vec<usize> {
self.0.attribute_blocks.clone()
}
fn __repr__(&self) -> String {
format!(
"LongRecordStructure(pseudonym_blocks={:?}, attribute_blocks={:?})",
self.0.pseudonym_blocks, self.0.attribute_blocks
)
}
}
pub fn register(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_class::<PyRecord>()?;
m.add_class::<PyEncryptedRecord>()?;
#[cfg(feature = "long")]
{
m.add_class::<PyLongRecord>()?;
m.add_class::<PyLongEncryptedRecord>()?;
m.add_class::<PyLongRecordStructure>()?;
}
Ok(())
}