Skip to content

Commit b497e47

Browse files
committed
Ran fmt
1 parent 2ce913b commit b497e47

File tree

18 files changed

+761
-115
lines changed

18 files changed

+761
-115
lines changed

src/lib/client/batch.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Batch operations for encryption and decryption.
22
3-
use crate::data::traits::{Encryptable, Encrypted};
3+
use crate::data::traits::{BatchEncryptable, Encryptable, Encrypted};
44
use crate::transcryptor::batch::BatchError;
55
use rand_core::{CryptoRng, Rng};
66

@@ -17,6 +17,23 @@ pub fn encrypt_batch<M, R>(
1717
public_key: &M::PublicKeyType,
1818
rng: &mut R,
1919
) -> Result<Vec<M::EncryptedType>, BatchError>
20+
where
21+
M: BatchEncryptable,
22+
R: Rng + CryptoRng,
23+
{
24+
let preprocessed = M::preprocess_batch(messages)?;
25+
Ok(preprocessed
26+
.iter()
27+
.map(|x| x.encrypt(public_key, rng))
28+
.collect())
29+
}
30+
31+
#[cfg(feature = "insecure")]
32+
pub fn encrypt_batch_raw<M, R>(
33+
messages: &[M],
34+
public_key: &M::PublicKeyType,
35+
rng: &mut R,
36+
) -> Result<Vec<M::EncryptedType>, BatchError>
2037
where
2138
M: Encryptable,
2239
R: Rng + CryptoRng,

src/lib/client/functions.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ where
4040
/// # Examples
4141
/// ```rust,ignore
4242
/// let pseudonym = decrypt(&encrypted_pseudonym, &pseudonym_key);
43-
/// let attribute = decrypt(&encrypted_attribute, &attribute_key);
43+
/// let attribute = decrypt(&encrypted_attribute,
44+
/// &attribute_key);
4445
/// ```
4546
#[cfg(not(feature = "elgamal3"))]
4647
pub fn decrypt<E>(encrypted: &E, secret_key: &E::SecretKeyType) -> E::UnencryptedType

src/lib/client/py/batch.rs

Lines changed: 206 additions & 95 deletions
Large diffs are not rendered by default.

src/lib/client/py/distributed.rs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,21 @@ impl PyClient {
370370
return py_result.into_py_any(py);
371371
}
372372

373+
// Try Vec<PEPJSONValue> - uses SessionKeys directly
374+
#[cfg(feature = "json")]
375+
if let Ok(las) = messages.extract::<Vec<PyPEPJSONValue>>() {
376+
let msgs: Vec<_> = las.into_iter().map(|a| a.0).collect();
377+
let result = self
378+
.0
379+
.encrypt_batch(&msgs, &mut rng)
380+
.map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))?;
381+
let py_result: Vec<PyEncryptedPEPJSONValue> =
382+
result.into_iter().map(PyEncryptedPEPJSONValue).collect();
383+
return py_result.into_py_any(py);
384+
}
385+
373386
Err(PyTypeError::new_err(
374-
"encrypt_batch() requires Vec[Pseudonym], Vec[Attribute], Vec[LongPseudonym], or Vec[LongAttribute]",
387+
"encrypt_batch() requires Vec[Pseudonym], Vec[Attribute], Vec[LongPseudonym], or Vec[LongAttribute], or Vec[PEPJSONValue]",
375388
))
376389
}
377390

@@ -427,8 +440,19 @@ impl PyClient {
427440
return py_result.into_py_any(py);
428441
}
429442

443+
// Try Vec<EncryptedPEPJSONValue> - uses SessionKeys directly
444+
#[cfg(feature = "json")]
445+
if let Ok(leas) = encrypted.extract::<Vec<PyEncryptedPEPJSONValue>>() {
446+
let enc: Vec<_> = leas.into_iter().map(|e| e.0).collect();
447+
let result = self .0
448+
.decrypt_batch(&enc)
449+
.map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))?;
450+
let py_result: Vec<PyPEPJSONValue> = result.into_iter().map(PyPEPJSONValue).collect();
451+
return py_result.into_py_any(py);
452+
}
453+
430454
Err(PyTypeError::new_err(
431-
"decrypt_batch() requires Vec[EncryptedPseudonym], Vec[EncryptedAttribute], Vec[LongEncryptedPseudonym], or Vec[LongEncryptedAttribute]",
455+
"decrypt_batch() requires Vec[EncryptedPseudonym], Vec[EncryptedAttribute], Vec[LongEncryptedPseudonym], or Vec[LongEncryptedAttribute], or Vec[EncryptedPEPJSONValue]",
432456
))
433457
}
434458

@@ -484,8 +508,19 @@ impl PyClient {
484508
return py_result.into_py_any(py);
485509
}
486510

511+
// Try Vec<EncryptedPEPJSONValue> - uses SessionKeys directly
512+
#[cfg(feature = "json")]
513+
if let Ok(leas) = encrypted.extract::<Vec<PyEncryptedPEPJSONValue>>() {
514+
let enc: Vec<_> = leas.into_iter().map(|e| e.0).collect();
515+
let result = self .0
516+
.decrypt_batch(&enc)
517+
.map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))?;
518+
let py_result: Vec<PyPEPJSONValue> = result.into_iter().map(PyPEPJSONValue).collect();
519+
return py_result.into_py_any(py);
520+
}
521+
487522
Err(PyTypeError::new_err(
488-
"decrypt_batch() requires Vec[EncryptedPseudonym], Vec[EncryptedAttribute], Vec[LongEncryptedPseudonym], or Vec[LongEncryptedAttribute]",
523+
"decrypt_batch() requires Vec[EncryptedPseudonym], Vec[EncryptedAttribute], Vec[LongEncryptedPseudonym], or Vec[LongEncryptedAttribute], or Vec[EncryptedPEPJSONValue]",
489524
))
490525
}
491526

src/lib/client/py/functions.rs

Lines changed: 115 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::data::py::simple::{
1818
PyAttribute, PyEncryptedAttribute, PyEncryptedPseudonym, PyPseudonym,
1919
};
2020
#[cfg(feature = "offline")]
21-
use crate::keys::py::types::{PyAttributeGlobalPublicKey, PyPseudonymGlobalPublicKey};
21+
use crate::keys::py::types::{PyAttributeGlobalPublicKey, PyPseudonymGlobalPublicKey, PyGlobalPublicKeys};
2222
#[cfg(all(feature = "offline", feature = "insecure"))]
2323
use crate::keys::py::types::{PyAttributeGlobalSecretKey, PyPseudonymGlobalSecretKey};
2424
use crate::keys::py::PySessionKeys;
@@ -30,10 +30,7 @@ use crate::keys::py::{
3030
use crate::keys::{AttributeGlobalPublicKey, PseudonymGlobalPublicKey};
3131
#[cfg(all(feature = "offline", feature = "insecure"))]
3232
use crate::keys::{AttributeGlobalSecretKey, PseudonymGlobalSecretKey};
33-
use crate::keys::{
34-
AttributeSessionPublicKey, AttributeSessionSecretKey, PseudonymSessionPublicKey,
35-
PseudonymSessionSecretKey, SessionKeys,
36-
};
33+
use crate::keys::{AttributeSessionPublicKey, AttributeSessionSecretKey, GlobalPublicKeys, PseudonymSessionPublicKey, PseudonymSessionSecretKey, SessionKeys};
3734
use pyo3::exceptions::PyTypeError;
3835
use pyo3::prelude::*;
3936
use pyo3::types::PyAny;
@@ -367,6 +364,19 @@ pub fn py_encrypt_global(message: &Bound<PyAny>, public_key: &Bound<PyAny>) -> P
367364
}
368365
}
369366

367+
// Try PEPJSONValue with SessionKeys
368+
#[cfg(feature = "json")]
369+
if let Ok(json) = message.extract::<PyPEPJSONValue>() {
370+
if let Ok(pk) = public_key.extract::<PyGlobalPublicKeys>() {
371+
let keys = GlobalPublicKeys {
372+
pseudonym: PseudonymGlobalPublicKey(*pk.pseudonym.0),
373+
attribute: AttributeGlobalPublicKey(*pk.attribute.0)
374+
};
375+
let result = encrypt_global(&json.0, &keys, &mut rng);
376+
return Ok(Py::new(py, PyEncryptedPEPJSONValue(result))?.into_any());
377+
}
378+
}
379+
370380
Err(PyTypeError::new_err(
371381
"encrypt_global() requires (unencrypted_type, matching_global_public_key)",
372382
))
@@ -430,6 +440,18 @@ pub fn py_decrypt_global(
430440
}
431441
}
432442

443+
// Try EncryptedPEPJSONValue with SessionKeys
444+
#[cfg(feature = "json")]
445+
if let Ok(ej) = encrypted.extract::<PyEncryptedPEPJSONValue>() {
446+
if let Ok(sk) = secret_key.extract::<PySessionKeys>() {
447+
let keys: SessionKeys = sk.clone().into();
448+
if let Some(result) = decrypt_global(&ej.0, &keys) {
449+
return Ok(Py::new(py, PyPEPJSONValue(result))?.into_any());
450+
}
451+
return Err(pyo3::exceptions::PyValueError::new_err("Decryption failed"));
452+
}
453+
}
454+
433455
Err(PyTypeError::new_err(
434456
"decrypt_global() requires (encrypted_type, matching_global_secret_key)",
435457
))
@@ -484,6 +506,16 @@ pub fn py_decrypt_global(
484506
}
485507
}
486508

509+
// Try EncryptedPEPJSONValue with SessionKeys
510+
#[cfg(feature = "json")]
511+
if let Ok(ej) = encrypted.extract::<PyEncryptedPEPJSONValue>() {
512+
if let Ok(sk) = secret_key.extract::<PySessionKeys>() {
513+
let keys: SessionKeys = sk.clone().into();
514+
let result = decrypt_global(&ej.0, &keys);
515+
return Ok(Py::new(py, PyPEPJSONValue(result))?.into_any());
516+
}
517+
}
518+
487519
Err(PyTypeError::new_err(
488520
"decrypt_global() requires (encrypted_type, matching_global_secret_key)",
489521
))
@@ -628,6 +660,32 @@ pub fn py_encrypt_batch(
628660
}
629661
}
630662

663+
// Try PEPJSONValue + SessionKeys
664+
#[cfg(feature = "json")]
665+
if let Ok(sk) = key.extract::<PySessionKeys>() {
666+
if messages[0].extract::<PyPEPJSONValue>().is_ok() {
667+
let rust_msgs: Vec<_> = messages
668+
.iter()
669+
.map(|m| {
670+
m.extract::<PyPEPJSONValue>()
671+
.expect("type already validated")
672+
.0
673+
})
674+
.collect();
675+
let keys: SessionKeys = sk.clone().into();
676+
let encrypted = encrypt_batch(&rust_msgs, &keys, &mut rng)
677+
.map_err(|e| pyo3::exceptions::PyValueError::new_err(format!("{}", e)))?;
678+
return Ok(encrypted
679+
.into_iter()
680+
.map(|e| {
681+
Py::new(py, PyEncryptedPEPJSONValue(e))
682+
.expect("PyO3 allocation failed")
683+
.into_any()
684+
})
685+
.collect());
686+
}
687+
}
688+
631689
Err(PyTypeError::new_err(
632690
"encrypt_batch() requires list of (Pseudonym|Attribute|LongPseudonym|LongAttribute) and matching key",
633691
))
@@ -748,6 +806,32 @@ pub fn py_decrypt_batch(
748806
}
749807
}
750808

809+
// Try EncryptedPEPJSONValue + SessionKeys
810+
#[cfg(feature = "json")]
811+
if let Ok(sk) = key.extract::<PySessionKeys>() {
812+
if encrypted[0].extract::<PyEncryptedPEPJSONValue>().is_ok() {
813+
let rust_encs: Vec<_> = encrypted
814+
.iter()
815+
.map(|e| {
816+
e.extract::<PyEncryptedPEPJSONValue>()
817+
.expect("type already validated")
818+
.0
819+
})
820+
.collect();
821+
let keys: SessionKeys = sk.clone().into();
822+
let decrypted = decrypt_batch(&rust_encs, &keys)
823+
.map_err(|e| pyo3::exceptions::PyValueError::new_err(format!("{}", e)))?;
824+
return Ok(decrypted
825+
.into_iter()
826+
.map(|d| {
827+
Py::new(py, PyPEPJSONValue(d))
828+
.expect("PyO3 allocation failed")
829+
.into_any()
830+
})
831+
.collect());
832+
}
833+
}
834+
751835
Err(PyTypeError::new_err(
752836
"decrypt_batch() requires list of encrypted types and matching key",
753837
))
@@ -868,6 +952,32 @@ pub fn py_decrypt_batch(
868952
}
869953
}
870954

955+
// Try EncryptedPEPJSONValue + SessionKeys
956+
#[cfg(feature = "json")]
957+
if let Ok(sk) = key.extract::<PySessionKeys>() {
958+
if encrypted[0].extract::<PyEncryptedPEPJSONValue>().is_ok() {
959+
let rust_encs: Vec<_> = encrypted
960+
.iter()
961+
.map(|e| {
962+
e.extract::<PyEncryptedPEPJSONValue>()
963+
.expect("type already validated")
964+
.0
965+
})
966+
.collect();
967+
let keys: SessionKeys = sk.clone().into();
968+
let decrypted = decrypt_batch(&rust_encs, &keys)
969+
.map_err(|e| pyo3::exceptions::PyValueError::new_err(format!("{}", e)))?;
970+
return Ok(decrypted
971+
.into_iter()
972+
.map(|d| {
973+
Py::new(py, PyPEPJSONValue(d))
974+
.expect("PyO3 allocation failed")
975+
.into_any()
976+
})
977+
.collect());
978+
}
979+
}
980+
871981
Err(PyTypeError::new_err(
872982
"decrypt_batch() requires list of encrypted types and matching key",
873983
))

src/lib/client/py/types.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl PyOfflineClient {
7272
}
7373

7474
Err(PyTypeError::new_err(
75-
"encrypt() requires Pseudonym, Attribute, LongPseudonym, or LongAttribute",
75+
"encrypt() requires Pseudonym, Attribute, LongPseudonym, or LongAttribute, or PEPJSONValue",
7676
))
7777
}
7878

@@ -133,8 +133,21 @@ impl PyOfflineClient {
133133
return py_result.into_py_any(py);
134134
}
135135

136+
// Try Vec<PEPJSONValue>
137+
#[cfg(feature = "json")]
138+
if let Ok(jsons) = messages.extract::<Vec<PyPEPJSONValue>>() {
139+
let msgs: Vec<_> = jsons.into_iter().map(|j| j.0).collect();
140+
let result = self
141+
.0
142+
.encrypt_batch(&msgs, &mut rng)
143+
.map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))?;
144+
let py_result: Vec<PyEncryptedPEPJSONValue> =
145+
result.into_iter().map(PyEncryptedPEPJSONValue).collect();
146+
return py_result.into_py_any(py);
147+
}
148+
136149
Err(PyTypeError::new_err(
137-
"encrypt_batch() requires Vec[Pseudonym], Vec[Attribute], Vec[LongPseudonym], or Vec[LongAttribute]",
150+
"encrypt_batch() requires Vec[Pseudonym], Vec[Attribute], Vec[LongPseudonym], or Vec[LongAttribute], or Vec[PEPJSONValue]",
138151
))
139152
}
140153

src/lib/client/types.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Client type definitions.
22
3-
use crate::data::traits::{Encryptable, Encrypted};
3+
use crate::data::traits::{BatchEncryptable, Encryptable, Encrypted};
44
#[cfg(feature = "offline")]
55
use crate::keys::GlobalPublicKeys;
66
use crate::keys::{KeyProvider, SessionKeys};
@@ -71,13 +71,28 @@ impl Client {
7171
rng: &mut R,
7272
) -> Result<Vec<M::EncryptedType>, crate::transcryptor::BatchError>
7373
where
74-
M: Encryptable,
74+
M: BatchEncryptable,
7575
SessionKeys: KeyProvider<M::PublicKeyType>,
7676
R: Rng + CryptoRng,
7777
{
7878
super::batch::encrypt_batch(messages, self.keys.get_key(), rng)
7979
}
8080

81+
/// Encrypt a batch of messages without padding or preprocessing.
82+
#[cfg(feature = "insecure")]
83+
pub fn encrypt_batch_raw<M, R>(
84+
&self,
85+
messages: &[M],
86+
rng: &mut R,
87+
) -> Result<Vec<M::EncryptedType>, crate::transcryptor::BatchError>
88+
where
89+
M: Encryptable,
90+
SessionKeys: KeyProvider<M::PublicKeyType>,
91+
R: Rng + CryptoRng,
92+
{
93+
super::batch::encrypt_batch_raw(messages, self.keys.get_key(), rng)
94+
}
95+
8196
/// Decrypt a batch of encrypted messages with the appropriate session secret key.
8297
/// Automatically selects the correct key (pseudonym or attribute) based on the encrypted type.
8398
/// With the `elgamal3` feature, returns an error if any decryption fails.

0 commit comments

Comments
 (0)