1use crate::high_level::secrets::{
6 make_attribute_rekey_factor, make_pseudonym_rekey_factor, make_pseudonymisation_factor,
7 EncryptionSecret, PseudonymizationSecret,
8};
9use crate::internal::arithmetic::ScalarNonZero;
10use derive_more::{Deref, From};
11use serde::{Deserialize, Serialize};
12
13#[derive(Clone, Eq, Hash, PartialEq, Debug, Deref, Serialize, Deserialize)]
18#[cfg(feature = "legacy-pep-repo-compatible")]
19pub struct PseudonymizationDomain {
20 #[deref]
21 pub payload: String,
22 pub audience_type: u32,
23}
24#[derive(Clone, Eq, Hash, PartialEq, Debug, Deref, Serialize, Deserialize)]
29#[cfg(feature = "legacy-pep-repo-compatible")]
30pub struct EncryptionContext {
31 #[deref]
32 pub payload: String,
33 pub audience_type: u32,
34}
35
36#[derive(Clone, Eq, Hash, PartialEq, Debug, Deref, Serialize, Deserialize)]
39#[cfg(not(feature = "legacy-pep-repo-compatible"))]
40pub struct PseudonymizationDomain(pub String);
41#[derive(Clone, Eq, Hash, PartialEq, Debug, Deref, Serialize, Deserialize)]
44#[cfg(not(feature = "legacy-pep-repo-compatible"))]
45pub struct EncryptionContext(pub String);
46
47impl PseudonymizationDomain {
48 #[cfg(feature = "legacy-pep-repo-compatible")]
49 pub fn from(payload: &str) -> Self {
50 PseudonymizationDomain {
51 payload: payload.to_string(),
52 audience_type: 0,
53 }
54 }
55 #[cfg(not(feature = "legacy-pep-repo-compatible"))]
56 pub fn from(payload: &str) -> Self {
57 PseudonymizationDomain(payload.to_string())
58 }
59
60 #[cfg(feature = "legacy-pep-repo-compatible")]
61 pub fn from_audience(payload: &str, audience_type: u32) -> Self {
62 PseudonymizationDomain {
63 payload: payload.to_string(),
64 audience_type,
65 }
66 }
67}
68impl EncryptionContext {
69 #[cfg(feature = "legacy-pep-repo-compatible")]
70 pub fn from(payload: &str) -> Self {
71 EncryptionContext {
72 payload: payload.to_string(),
73 audience_type: 0,
74 }
75 }
76 #[cfg(not(feature = "legacy-pep-repo-compatible"))]
77 pub fn from(payload: &str) -> Self {
78 EncryptionContext(payload.to_string())
79 }
80
81 #[cfg(feature = "legacy-pep-repo-compatible")]
82 pub fn from_audience(payload: &str, audience_type: u32) -> Self {
83 EncryptionContext {
84 payload: payload.to_string(),
85 audience_type,
86 }
87 }
88}
89
90#[derive(Copy, Clone, Eq, PartialEq, Debug, From)]
92pub struct RerandomizeFactor(pub(crate) ScalarNonZero);
93#[derive(Copy, Clone, Eq, PartialEq, Debug, From)]
95pub struct ReshuffleFactor(pub ScalarNonZero);
96pub trait RekeyFactor {
98 fn scalar(&self) -> ScalarNonZero;
99}
100
101#[derive(Copy, Clone, Eq, PartialEq, Debug, From)]
103pub struct PseudonymRekeyFactor(pub(crate) ScalarNonZero);
104
105impl RekeyFactor for PseudonymRekeyFactor {
106 fn scalar(&self) -> ScalarNonZero {
107 self.0
108 }
109}
110
111#[derive(Copy, Clone, Eq, PartialEq, Debug, From)]
113pub struct AttributeRekeyFactor(pub(crate) ScalarNonZero);
114
115impl RekeyFactor for AttributeRekeyFactor {
116 fn scalar(&self) -> ScalarNonZero {
117 self.0
118 }
119}
120
121#[derive(Eq, PartialEq, Clone, Copy, Debug, From)]
124pub struct PseudonymRSKFactors {
125 pub s: ReshuffleFactor,
127 pub k: PseudonymRekeyFactor,
129}
130
131pub type PseudonymizationInfo = PseudonymRSKFactors;
136
137pub type PseudonymRekeyInfo = PseudonymRekeyFactor;
141
142pub type AttributeRekeyInfo = AttributeRekeyFactor;
146impl PseudonymizationInfo {
147 pub fn new(
149 domain_from: &PseudonymizationDomain,
150 domain_to: &PseudonymizationDomain,
151 session_from: Option<&EncryptionContext>,
152 session_to: Option<&EncryptionContext>,
153 pseudonymization_secret: &PseudonymizationSecret,
154 encryption_secret: &EncryptionSecret,
155 ) -> Self {
156 let s_from = make_pseudonymisation_factor(pseudonymization_secret, domain_from);
157 let s_to = make_pseudonymisation_factor(pseudonymization_secret, domain_to);
158 let reshuffle_factor = ReshuffleFactor::from(s_from.0.invert() * s_to.0);
159 let rekey_factor = PseudonymRekeyInfo::new(session_from, session_to, encryption_secret);
160 Self {
161 s: reshuffle_factor,
162 k: rekey_factor,
163 }
164 }
165
166 pub fn reverse(&self) -> Self {
168 Self {
169 s: ReshuffleFactor::from(self.s.0.invert()),
170 k: PseudonymRekeyFactor::from(self.k.0.invert()),
171 }
172 }
173}
174impl PseudonymRekeyInfo {
175 pub fn new(
177 session_from: Option<&EncryptionContext>,
178 session_to: Option<&EncryptionContext>,
179 encryption_secret: &EncryptionSecret,
180 ) -> Self {
181 let k_from = session_from
182 .map(|ctx| make_pseudonym_rekey_factor(encryption_secret, ctx))
183 .unwrap_or_else(|| PseudonymRekeyFactor(ScalarNonZero::one()));
184
185 let k_to = session_to
186 .map(|ctx| make_pseudonym_rekey_factor(encryption_secret, ctx))
187 .unwrap_or_else(|| PseudonymRekeyFactor(ScalarNonZero::one()));
188
189 Self::from(k_from.0.invert() * k_to.0)
190 }
191
192 pub fn reverse(&self) -> Self {
194 Self::from(self.0.invert())
195 }
196}
197
198impl AttributeRekeyInfo {
199 pub fn new(
201 session_from: Option<&EncryptionContext>,
202 session_to: Option<&EncryptionContext>,
203 encryption_secret: &EncryptionSecret,
204 ) -> Self {
205 let k_from = session_from
206 .map(|ctx| make_attribute_rekey_factor(encryption_secret, ctx))
207 .unwrap_or_else(|| AttributeRekeyFactor(ScalarNonZero::one()));
208
209 let k_to = session_to
210 .map(|ctx| make_attribute_rekey_factor(encryption_secret, ctx))
211 .unwrap_or_else(|| AttributeRekeyFactor(ScalarNonZero::one()));
212
213 Self::from(k_from.0.invert() * k_to.0)
214 }
215
216 pub fn reverse(&self) -> Self {
218 Self::from(self.0.invert())
219 }
220}
221impl From<PseudonymizationInfo> for PseudonymRekeyInfo {
222 fn from(x: PseudonymizationInfo) -> Self {
223 x.k
224 }
225}
226
227#[derive(Eq, PartialEq, Clone, Copy, Debug)]
229pub struct TranscryptionInfo {
230 pub pseudonym: PseudonymizationInfo,
231 pub attribute: AttributeRekeyInfo,
232}
233
234impl TranscryptionInfo {
235 pub fn new(
237 domain_from: &PseudonymizationDomain,
238 domain_to: &PseudonymizationDomain,
239 session_from: Option<&EncryptionContext>,
240 session_to: Option<&EncryptionContext>,
241 pseudonymization_secret: &PseudonymizationSecret,
242 encryption_secret: &EncryptionSecret,
243 ) -> Self {
244 Self {
245 pseudonym: PseudonymizationInfo::new(
246 domain_from,
247 domain_to,
248 session_from,
249 session_to,
250 pseudonymization_secret,
251 encryption_secret,
252 ),
253 attribute: AttributeRekeyInfo::new(session_from, session_to, encryption_secret),
254 }
255 }
256
257 pub fn reverse(&self) -> Self {
259 Self {
260 pseudonym: self.pseudonym.reverse(),
261 attribute: self.attribute.reverse(),
262 }
263 }
264}