primitives/sharing/authenticated/
curve_key.rs1use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
2
3use serde::{Deserialize, Serialize};
4use subtle::{Choice, ConstantTimeEq};
5
6use super::{GlobalFieldKey, ScalarKey};
7use crate::{
8 algebra::elliptic_curve::{Curve, Point, Scalar, ScalarAsExtension, ScalarField},
9 errors::PrimitiveError,
10 random::{CryptoRngCore, Random, RandomWith},
11 sharing::OpenPointShare,
12 types::ConditionallySelectable,
13};
14
15pub type GlobalCurveKey<C> = GlobalFieldKey<ScalarField<C>>;
16
17#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
20#[serde(bound = "C: Curve")]
21pub struct CurveKey<C: Curve> {
22 pub(crate) alpha: GlobalCurveKey<C>,
23 pub(crate) beta: Point<C>,
24}
25
26impl<C: Curve> CurveKey<C> {
27 pub fn new(alpha: GlobalCurveKey<C>, beta: Point<C>) -> Self {
28 CurveKey { alpha, beta }
29 }
30
31 pub fn compute_mac(&self, value: &Point<C>) -> Point<C> {
32 self.beta + value * *self.alpha
33 }
34
35 #[inline]
36 pub fn verify_mac(&self, open_share: &OpenPointShare<C>) -> Result<(), PrimitiveError> {
37 let expected_mac = self.compute_mac(&open_share.value);
38 if expected_mac == open_share.mac {
39 Ok(())
40 } else {
41 Err(PrimitiveError::WrongMAC(
42 serde_json::to_string(&expected_mac).unwrap(),
43 serde_json::to_string(&open_share.mac).unwrap(),
44 ))
45 }
46 }
47
48 pub fn get_alpha(&self) -> GlobalCurveKey<C> {
49 self.alpha.clone()
50 }
51
52 pub fn get_alpha_value(&self) -> ScalarAsExtension<C> {
53 *self.alpha
54 }
55
56 pub fn get_beta(&self) -> Point<C> {
57 self.beta
58 }
59
60 pub fn zero_batch(alphas: Vec<GlobalCurveKey<C>>) -> Vec<CurveKey<C>> {
61 alphas
62 .iter()
63 .map(|alpha| CurveKey::new(alpha.clone(), Point::<C>::identity()))
64 .collect()
65 }
66}
67
68impl<C: Curve> ConditionallySelectable for CurveKey<C> {
69 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
70 CurveKey {
71 alpha: GlobalCurveKey::<C>::conditional_select(&a.alpha, &b.alpha, choice),
72 beta: Point::conditional_select(&a.beta, &b.beta, choice),
73 }
74 }
75}
76
77impl<C: Curve> Random for CurveKey<C> {
82 fn random(mut rng: impl CryptoRngCore) -> Self {
83 let alpha = GlobalCurveKey::<C>::random(&mut rng);
84 let beta = Point::<C>::random(&mut rng);
85 CurveKey { alpha, beta }
86 }
87}
88
89impl<C: Curve> RandomWith<GlobalCurveKey<C>> for CurveKey<C> {
90 fn random_with(mut rng: impl CryptoRngCore, alpha: GlobalCurveKey<C>) -> Self {
91 CurveKey {
92 alpha,
93 beta: Point::random(&mut rng),
94 }
95 }
96}
97
98#[macros::op_variants(owned, borrowed, flipped_commutative)]
104impl<'a, C: Curve> Add<&'a CurveKey<C>> for CurveKey<C> {
105 type Output = CurveKey<C>;
106
107 #[inline]
108 fn add(self, other: &'a CurveKey<C>) -> Self::Output {
109 debug_assert_eq!(self.alpha, other.alpha);
110 CurveKey {
111 beta: self.beta + other.beta,
112 ..self
113 }
114 }
115}
116
117#[macros::op_variants(owned)]
118impl<'a, C: Curve> AddAssign<&'a CurveKey<C>> for CurveKey<C> {
119 #[inline]
120 fn add_assign(&mut self, rhs: &'a CurveKey<C>) {
121 self.beta += rhs.beta;
122 }
123}
124
125#[macros::op_variants(owned, borrowed, flipped)]
128impl<'a, C: Curve> Sub<&'a CurveKey<C>> for CurveKey<C> {
129 type Output = CurveKey<C>;
130
131 #[inline]
132 fn sub(self, other: &'a CurveKey<C>) -> Self::Output {
133 debug_assert_eq!(self.alpha, other.alpha);
134 CurveKey {
135 beta: self.beta - other.beta,
136 ..self
137 }
138 }
139}
140
141#[macros::op_variants(owned)]
144impl<'a, C: Curve> SubAssign<&'a CurveKey<C>> for CurveKey<C> {
145 #[inline]
146 fn sub_assign(&mut self, rhs: &'a CurveKey<C>) {
147 self.beta -= rhs.beta;
148 }
149}
150
151#[macros::op_variants(owned, borrowed, flipped)]
154impl<'a, C: Curve> Mul<&'a ScalarAsExtension<C>> for CurveKey<C> {
155 type Output = CurveKey<C>;
156
157 #[inline]
158 fn mul(self, other: &'a ScalarAsExtension<C>) -> Self::Output {
159 CurveKey {
160 beta: self.beta * other,
161 ..self
162 }
163 }
164}
165
166#[macros::op_variants(owned, borrowed, flipped)]
167impl<'a, C: Curve> Mul<&'a Scalar<C>> for CurveKey<C> {
168 type Output = CurveKey<C>;
169
170 #[inline]
171 fn mul(self, other: &'a Scalar<C>) -> Self::Output {
172 CurveKey {
173 beta: self.beta * other,
174 ..self
175 }
176 }
177}
178
179#[macros::op_variants(owned)]
182impl<'a, C: Curve> MulAssign<&'a ScalarAsExtension<C>> for CurveKey<C> {
183 #[inline]
184 fn mul_assign(&mut self, rhs: &'a ScalarAsExtension<C>) {
185 self.beta *= rhs;
186 }
187}
188
189#[macros::op_variants(owned)]
190impl<'a, C: Curve> MulAssign<&'a Scalar<C>> for CurveKey<C> {
191 #[inline]
192 fn mul_assign(&mut self, rhs: &'a Scalar<C>) {
193 self.beta *= rhs;
194 }
195}
196
197#[macros::op_variants(borrowed)]
200impl<C: Curve> Neg for CurveKey<C> {
201 type Output = CurveKey<C>;
202
203 #[inline]
204 fn neg(self) -> Self::Output {
205 CurveKey {
206 alpha: self.alpha,
207 beta: -self.beta,
208 }
209 }
210}
211
212impl<C: Curve> ConstantTimeEq for CurveKey<C> {
215 #[inline]
216 fn ct_eq(&self, other: &Self) -> Choice {
217 self.alpha.ct_eq(&other.alpha) & self.beta.ct_eq(&other.beta)
218 }
219}
220
221impl<C: Curve> From<ScalarKey<C>> for CurveKey<C> {
224 #[inline]
225 fn from(scalar_key: ScalarKey<C>) -> Self {
226 CurveKey {
227 alpha: scalar_key.alpha,
228 beta: scalar_key.beta * Point::<C>::generator(),
229 }
230 }
231}
232
233#[cfg(test)]
234mod tests {
235 use super::*;
236 use crate::algebra::elliptic_curve::Curve25519Ristretto as C;
237
238 pub type FrExt = ScalarAsExtension<C>;
239 pub type P = Point<C>;
240
241 #[test]
242 fn test_addition() {
243 let mut rng = rand::thread_rng();
244 let alpha = GlobalCurveKey::<C>::new(FrExt::random(&mut rng));
245 let beta1 = P::random(&mut rng);
246 let beta2 = P::random(&mut rng);
247
248 let key1 = CurveKey {
249 alpha: alpha.clone(),
250 beta: beta1,
251 };
252 let key2 = CurveKey {
253 alpha: alpha.clone(),
254 beta: beta2,
255 };
256 let expected_result = CurveKey {
257 alpha,
258 beta: beta1 + beta2,
259 };
260 assert_eq!(key1 + key2, expected_result);
261 }
262
263 #[test]
264 fn test_subtraction() {
265 let mut rng = rand::thread_rng();
266 let alpha = GlobalCurveKey::<C>::new(FrExt::random(&mut rng));
267 let beta1 = P::random(&mut rng);
268 let beta2 = P::random(&mut rng);
269
270 let key1 = CurveKey {
271 alpha: alpha.clone(),
272 beta: beta1,
273 };
274 let key2 = CurveKey {
275 alpha: alpha.clone(),
276 beta: beta2,
277 };
278 let expected_result = CurveKey {
279 alpha,
280 beta: beta1 - beta2,
281 };
282 assert_eq!(key1 - key2, expected_result);
283 }
284
285 #[test]
286 fn test_multiplication() {
287 let mut rng = rand::thread_rng();
288 let alpha = GlobalCurveKey::<C>::new(FrExt::random(&mut rng));
289 let beta1 = P::random(&mut rng);
290
291 let key = CurveKey {
292 alpha: alpha.clone(),
293 beta: beta1,
294 };
295 let scalar = FrExt::from(3u32);
296 let expected_result = CurveKey {
297 alpha,
298 beta: beta1 * scalar,
299 };
300 assert_eq!(key * scalar, expected_result);
301 }
302
303 #[test]
304 fn test_negation() {
305 let mut rng = rand::thread_rng();
306 let alpha = GlobalCurveKey::<C>::new(FrExt::random(&mut rng));
307 let beta1 = P::random(&mut rng);
308
309 let key = CurveKey {
310 alpha: alpha.clone(),
311 beta: beta1,
312 };
313 let expected_result = CurveKey {
314 alpha,
315 beta: -beta1,
316 };
317 assert_eq!(-key, expected_result);
318 }
319}