1#![allow(non_snake_case)]
2
3use std::error::Error;
4use std::fmt::Display;
5use std::marker::PhantomData;
6
7use crate::backward_compatibility::{
8 SerializableAffineVersions, SerializableCubicExtFieldVersions, SerializableFpVersions,
9 SerializableGroupElementsVersions, SerializablePKEv1PublicParamsVersions,
10 SerializablePKEv2PublicParamsVersions, SerializableQuadExtFieldVersions,
11};
12use ark_ec::short_weierstrass::{Affine, SWCurveConfig};
13use ark_ec::AffineRepr;
14use ark_ff::{BigInt, Field, Fp, Fp2, Fp6, Fp6Config, FpConfig, QuadExtConfig, QuadExtField};
15use serde::{Deserialize, Serialize};
16use tfhe_versionable::Versionize;
17
18use crate::curve_api::{Curve, CurveGroupOps};
19use crate::proofs::pke::PublicParams as PKEv1PublicParams;
20use crate::proofs::pke_v2::{Bound, PublicParams as PKEv2PublicParams};
21use crate::proofs::GroupElements;
22
23#[derive(Debug)]
26pub struct InvalidArraySizeError {
27 expected_len: usize,
28 found_len: usize,
29}
30
31impl Display for InvalidArraySizeError {
32 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33 write!(
34 f,
35 "Invalid serialized array: found array of size {}, expected {}",
36 self.found_len, self.expected_len
37 )
38 }
39}
40
41impl Error for InvalidArraySizeError {}
42
43pub(crate) fn try_vec_to_array<T, const N: usize>(
46 vec: Vec<T>,
47) -> Result<[T; N], InvalidArraySizeError> {
48 let len = vec.len();
49
50 vec.try_into().map_err(|_| InvalidArraySizeError {
51 expected_len: len,
52 found_len: N,
53 })
54}
55
56#[derive(Serialize, Deserialize, Versionize)]
59#[versionize(SerializableFpVersions)]
60pub struct SerializableFp {
61 val: Vec<u64>, }
63
64impl<P: FpConfig<N>, const N: usize> From<Fp<P, N>> for SerializableFp {
65 fn from(value: Fp<P, N>) -> Self {
66 Self {
67 val: value.0 .0.to_vec(),
68 }
69 }
70}
71
72impl<P: FpConfig<N>, const N: usize> TryFrom<SerializableFp> for Fp<P, N> {
73 type Error = InvalidArraySizeError;
74
75 fn try_from(value: SerializableFp) -> Result<Self, Self::Error> {
76 Ok(Fp(BigInt(try_vec_to_array(value.val)?), PhantomData))
77 }
78}
79
80#[derive(Debug)]
81pub enum InvalidSerializedAffineError {
82 InvalidFp(InvalidArraySizeError),
83 InvalidCompressedXCoordinate,
84}
85
86impl Display for InvalidSerializedAffineError {
87 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88 match self {
89 InvalidSerializedAffineError::InvalidFp(fp_error) => {
90 write!(f, "Invalid fp element in affine: {fp_error}")
91 }
92 InvalidSerializedAffineError::InvalidCompressedXCoordinate => {
93 write!(
94 f,
95 "Cannot uncompress affine: X coordinate does not belong to the curve"
96 )
97 }
98 }
99 }
100}
101
102impl Error for InvalidSerializedAffineError {
103 fn source(&self) -> Option<&(dyn Error + 'static)> {
104 match self {
105 InvalidSerializedAffineError::InvalidFp(fp_error) => Some(fp_error),
106 InvalidSerializedAffineError::InvalidCompressedXCoordinate => None,
107 }
108 }
109}
110
111impl From<InvalidArraySizeError> for InvalidSerializedAffineError {
112 fn from(value: InvalidArraySizeError) -> Self {
113 Self::InvalidFp(value)
114 }
115}
116
117#[derive(Serialize, Deserialize, Versionize)]
120#[versionize(SerializableAffineVersions)]
121pub enum SerializableAffine<F> {
122 Infinity,
123 Compressed { x: F, take_largest_y: bool },
124 Uncompressed { x: F, y: F },
125}
126
127impl<F> SerializableAffine<F> {
128 #[allow(unused)]
129 pub fn uncompressed<BaseField: Into<F> + Field, C: SWCurveConfig<BaseField = BaseField>>(
130 value: Affine<C>,
131 ) -> Self {
132 if value.is_zero() {
133 Self::Infinity
134 } else {
135 Self::Uncompressed {
136 x: value.x.into(),
137 y: value.y.into(),
138 }
139 }
140 }
141
142 pub fn compressed<BaseField: Into<F> + Field, C: SWCurveConfig<BaseField = BaseField>>(
143 value: Affine<C>,
144 ) -> Self {
145 if value.is_zero() {
146 Self::Infinity
147 } else {
148 let take_largest_y = value.y > -value.y;
149 Self::Compressed {
150 x: value.x.into(),
151 take_largest_y,
152 }
153 }
154 }
155}
156
157impl<F, C: SWCurveConfig> TryFrom<SerializableAffine<F>> for Affine<C>
158where
159 F: TryInto<C::BaseField, Error = InvalidArraySizeError>,
160{
161 type Error = InvalidSerializedAffineError;
162
163 fn try_from(value: SerializableAffine<F>) -> Result<Self, Self::Error> {
164 match value {
165 SerializableAffine::Infinity => Ok(Self::zero()),
166 SerializableAffine::Compressed { x, take_largest_y } => {
167 Self::get_point_from_x_unchecked(x.try_into()?, take_largest_y)
168 .ok_or(InvalidSerializedAffineError::InvalidCompressedXCoordinate)
169 }
170 SerializableAffine::Uncompressed { x, y } => {
171 Ok(Self::new_unchecked(x.try_into()?, y.try_into()?))
172 }
173 }
174 }
175}
176
177pub(crate) type SerializableG1Affine = SerializableAffine<SerializableFp>;
178
179#[derive(Serialize, Deserialize, Versionize)]
180#[versionize(SerializableQuadExtFieldVersions)]
181pub struct SerializableQuadExtField<F> {
182 c0: F,
183 c1: F,
184}
185
186pub(crate) type SerializableFp2 = SerializableQuadExtField<SerializableFp>;
187pub type SerializableG2Affine = SerializableAffine<SerializableFp2>;
188
189impl<F, P: QuadExtConfig> From<QuadExtField<P>> for SerializableQuadExtField<F>
190where
191 F: From<P::BaseField>,
192{
193 fn from(value: QuadExtField<P>) -> Self {
194 Self {
195 c0: value.c0.into(),
196 c1: value.c1.into(),
197 }
198 }
199}
200
201impl<F, P: QuadExtConfig> TryFrom<SerializableQuadExtField<F>> for QuadExtField<P>
202where
203 F: TryInto<P::BaseField, Error = InvalidArraySizeError>,
204{
205 type Error = InvalidArraySizeError;
206
207 fn try_from(value: SerializableQuadExtField<F>) -> Result<Self, Self::Error> {
208 Ok(QuadExtField {
209 c0: value.c0.try_into()?,
210 c1: value.c1.try_into()?,
211 })
212 }
213}
214
215#[derive(Serialize, Deserialize, Versionize)]
216#[versionize(SerializableCubicExtFieldVersions)]
217pub struct SerializableCubicExtField<F> {
218 c0: F,
219 c1: F,
220 c2: F,
221}
222
223pub(crate) type SerializableFp6 = SerializableCubicExtField<SerializableFp2>;
224
225impl<F, P6: Fp6Config> From<Fp6<P6>> for SerializableCubicExtField<F>
226where
227 F: From<Fp2<P6::Fp2Config>>,
228{
229 fn from(value: Fp6<P6>) -> Self {
230 Self {
231 c0: value.c0.into(),
232 c1: value.c1.into(),
233 c2: value.c2.into(),
234 }
235 }
236}
237
238impl<F, P6: Fp6Config> TryFrom<SerializableCubicExtField<F>> for Fp6<P6>
239where
240 F: TryInto<Fp2<P6::Fp2Config>, Error = InvalidArraySizeError>,
241{
242 type Error = InvalidArraySizeError;
243
244 fn try_from(value: SerializableCubicExtField<F>) -> Result<Self, Self::Error> {
245 Ok(Fp6 {
246 c0: value.c0.try_into()?,
247 c1: value.c1.try_into()?,
248 c2: value.c2.try_into()?,
249 })
250 }
251}
252
253pub(crate) type SerializableFp12 = SerializableQuadExtField<SerializableFp6>;
254
255#[derive(Debug)]
256pub enum InvalidSerializedGroupElementsError {
257 InvalidAffine(InvalidSerializedAffineError),
258 InvalidGlistDimension(InvalidArraySizeError),
259 MissingPuncteredElement,
260}
261
262impl Display for InvalidSerializedGroupElementsError {
263 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
264 match self {
265 InvalidSerializedGroupElementsError::InvalidAffine(affine_error) => {
266 write!(f, "Invalid Affine in GroupElement: {affine_error}")
267 }
268 InvalidSerializedGroupElementsError::InvalidGlistDimension(arr_error) => {
269 write!(f, "invalid number of elements in g_list: {arr_error}")
270 }
271 InvalidSerializedGroupElementsError::MissingPuncteredElement => {
272 write!(f, "Element at index n in g_list should be 0")
273 }
274 }
275 }
276}
277
278impl Error for InvalidSerializedGroupElementsError {
279 fn source(&self) -> Option<&(dyn Error + 'static)> {
280 match self {
281 InvalidSerializedGroupElementsError::InvalidAffine(affine_error) => Some(affine_error),
282 InvalidSerializedGroupElementsError::InvalidGlistDimension(arr_error) => {
283 Some(arr_error)
284 }
285 InvalidSerializedGroupElementsError::MissingPuncteredElement => None,
286 }
287 }
288}
289
290impl From<InvalidSerializedAffineError> for InvalidSerializedGroupElementsError {
291 fn from(value: InvalidSerializedAffineError) -> Self {
292 Self::InvalidAffine(value)
293 }
294}
295
296#[derive(Serialize, Deserialize, Versionize)]
297#[versionize(SerializableGroupElementsVersions)]
298pub(crate) struct SerializableGroupElements {
299 pub(crate) g_list: Vec<SerializableG1Affine>,
300 pub(crate) g_hat_list: Vec<SerializableG2Affine>,
301}
302
303impl<G: Curve> From<GroupElements<G>> for SerializableGroupElements
304where
305 <G::G1 as CurveGroupOps<G::Zp>>::Affine: Into<SerializableG1Affine>,
306 <G::G2 as CurveGroupOps<G::Zp>>::Affine: Into<SerializableG2Affine>,
307{
308 fn from(value: GroupElements<G>) -> Self {
309 let mut g_list = Vec::new();
310 let mut g_hat_list = Vec::new();
311 for idx in 0..value.message_len {
312 g_list.push(value.g_list[(idx * 2) + 1].into());
313 g_list.push(value.g_list[(idx * 2) + 2].into());
314 g_hat_list.push(value.g_hat_list[idx + 1].into())
315 }
316
317 Self { g_list, g_hat_list }
318 }
319}
320
321impl<G: Curve> TryFrom<SerializableGroupElements> for GroupElements<G>
322where
323 <G::G1 as CurveGroupOps<G::Zp>>::Affine:
324 TryFrom<SerializableG1Affine, Error = InvalidSerializedAffineError>,
325 <G::G2 as CurveGroupOps<G::Zp>>::Affine:
326 TryFrom<SerializableG2Affine, Error = InvalidSerializedAffineError>,
327{
328 type Error = InvalidSerializedGroupElementsError;
329
330 fn try_from(value: SerializableGroupElements) -> Result<Self, Self::Error> {
331 if value.g_list.len() != value.g_hat_list.len() * 2 {
332 return Err(InvalidSerializedGroupElementsError::InvalidGlistDimension(
333 InvalidArraySizeError {
334 expected_len: value.g_hat_list.len() * 2,
335 found_len: value.g_list.len(),
336 },
337 ));
338 }
339
340 let g_list = value
341 .g_list
342 .into_iter()
343 .map(<G::G1 as CurveGroupOps<G::Zp>>::Affine::try_from)
344 .collect::<Result<_, InvalidSerializedAffineError>>()?;
345 let g_hat_list = value
346 .g_hat_list
347 .into_iter()
348 .map(<G::G2 as CurveGroupOps<G::Zp>>::Affine::try_from)
349 .collect::<Result<_, InvalidSerializedAffineError>>()?;
350
351 Ok(Self::from_vec(g_list, g_hat_list))
352 }
353}
354
355#[derive(Debug)]
356pub enum InvalidSerializedPublicParamsError {
357 InvalidGroupElements(InvalidSerializedGroupElementsError),
358 InvalidHashDimension(InvalidArraySizeError),
359}
360
361impl Display for InvalidSerializedPublicParamsError {
362 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
363 match self {
364 InvalidSerializedPublicParamsError::InvalidGroupElements(group_error) => {
365 write!(f, "Invalid PublicParams: {group_error}")
366 }
367 InvalidSerializedPublicParamsError::InvalidHashDimension(arr_error) => {
368 write!(f, "invalid size of hash: {arr_error}")
369 }
370 }
371 }
372}
373
374impl Error for InvalidSerializedPublicParamsError {
375 fn source(&self) -> Option<&(dyn Error + 'static)> {
376 match self {
377 InvalidSerializedPublicParamsError::InvalidGroupElements(group_error) => {
378 Some(group_error)
379 }
380 InvalidSerializedPublicParamsError::InvalidHashDimension(arr_error) => Some(arr_error),
381 }
382 }
383}
384
385impl From<InvalidSerializedGroupElementsError> for InvalidSerializedPublicParamsError {
386 fn from(value: InvalidSerializedGroupElementsError) -> Self {
387 Self::InvalidGroupElements(value)
388 }
389}
390
391impl From<InvalidArraySizeError> for InvalidSerializedPublicParamsError {
392 fn from(value: InvalidArraySizeError) -> Self {
393 Self::InvalidHashDimension(value)
394 }
395}
396
397#[derive(serde::Serialize, serde::Deserialize, Versionize)]
398#[versionize(SerializablePKEv2PublicParamsVersions)]
399pub struct SerializablePKEv2PublicParams {
400 pub(crate) g_lists: SerializableGroupElements,
401 pub(crate) D: usize,
402 pub n: usize,
403 pub d: usize,
404 pub k: usize,
405 pub B_bound_squared: u128,
406 pub B_inf: u64,
407 pub q: u64,
408 pub t: u64,
409 pub msbs_zero_padding_bit_count: u64,
410 pub bound_type: Bound,
411 pub(crate) hash: Vec<u8>,
413 pub(crate) hash_R: Vec<u8>,
414 pub(crate) hash_t: Vec<u8>,
415 pub(crate) hash_w: Vec<u8>,
416 pub(crate) hash_agg: Vec<u8>,
417 pub(crate) hash_lmap: Vec<u8>,
418 pub(crate) hash_phi: Vec<u8>,
419 pub(crate) hash_xi: Vec<u8>,
420 pub(crate) hash_z: Vec<u8>,
421 pub(crate) hash_chi: Vec<u8>,
422}
423
424impl<G: Curve> From<PKEv2PublicParams<G>> for SerializablePKEv2PublicParams
425where
426 GroupElements<G>: Into<SerializableGroupElements>,
427{
428 fn from(value: PKEv2PublicParams<G>) -> Self {
429 let PKEv2PublicParams {
430 g_lists,
431 D,
432 n,
433 d,
434 k,
435 B_bound_squared,
436 B_inf,
437 q,
438 t,
439 msbs_zero_padding_bit_count,
440 bound_type,
441 hash,
442 hash_R,
443 hash_t,
444 hash_w,
445 hash_agg,
446 hash_lmap,
447 hash_phi,
448 hash_xi,
449 hash_z,
450 hash_chi,
451 } = value;
452 Self {
453 g_lists: g_lists.into(),
454 D,
455 n,
456 d,
457 k,
458 B_bound_squared,
459 B_inf,
460 q,
461 t,
462 msbs_zero_padding_bit_count,
463 bound_type,
464 hash: hash.to_vec(),
465 hash_R: hash_R.to_vec(),
466 hash_t: hash_t.to_vec(),
467 hash_w: hash_w.to_vec(),
468 hash_agg: hash_agg.to_vec(),
469 hash_lmap: hash_lmap.to_vec(),
470 hash_phi: hash_phi.to_vec(),
471 hash_xi: hash_xi.to_vec(),
472 hash_z: hash_z.to_vec(),
473 hash_chi: hash_chi.to_vec(),
474 }
475 }
476}
477
478impl<G: Curve> TryFrom<SerializablePKEv2PublicParams> for PKEv2PublicParams<G>
479where
480 GroupElements<G>:
481 TryFrom<SerializableGroupElements, Error = InvalidSerializedGroupElementsError>,
482{
483 type Error = InvalidSerializedPublicParamsError;
484
485 fn try_from(value: SerializablePKEv2PublicParams) -> Result<Self, Self::Error> {
486 let SerializablePKEv2PublicParams {
487 g_lists,
488 D,
489 n,
490 d,
491 k,
492 B_bound_squared,
493 B_inf,
494 q,
495 t,
496 msbs_zero_padding_bit_count,
497 bound_type,
498 hash,
499 hash_R,
500 hash_t,
501 hash_w,
502 hash_agg,
503 hash_lmap,
504 hash_phi,
505 hash_xi,
506 hash_z,
507 hash_chi,
508 } = value;
509 Ok(Self {
510 g_lists: g_lists.try_into()?,
511 D,
512 n,
513 d,
514 k,
515 B_bound_squared,
516 B_inf,
517 q,
518 t,
519 msbs_zero_padding_bit_count,
520 bound_type,
521 hash: try_vec_to_array(hash)?,
522 hash_R: try_vec_to_array(hash_R)?,
523 hash_t: try_vec_to_array(hash_t)?,
524 hash_w: try_vec_to_array(hash_w)?,
525 hash_agg: try_vec_to_array(hash_agg)?,
526 hash_lmap: try_vec_to_array(hash_lmap)?,
527 hash_phi: try_vec_to_array(hash_phi)?,
528 hash_xi: try_vec_to_array(hash_xi)?,
529 hash_z: try_vec_to_array(hash_z)?,
530 hash_chi: try_vec_to_array(hash_chi)?,
531 })
532 }
533}
534
535#[derive(serde::Serialize, serde::Deserialize, Versionize)]
536#[versionize(SerializablePKEv1PublicParamsVersions)]
537pub struct SerializablePKEv1PublicParams {
538 pub(crate) g_lists: SerializableGroupElements,
539 pub(crate) big_d: usize,
540 pub n: usize,
541 pub d: usize,
542 pub k: usize,
543 pub b: u64,
544 pub b_r: u64,
545 pub q: u64,
546 pub t: u64,
547 pub msbs_zero_padding_bit_count: u64,
548 pub(crate) hash: Vec<u8>,
550 pub(crate) hash_t: Vec<u8>,
551 pub(crate) hash_agg: Vec<u8>,
552 pub(crate) hash_lmap: Vec<u8>,
553 pub(crate) hash_z: Vec<u8>,
554 pub(crate) hash_w: Vec<u8>,
555}
556
557impl<G: Curve> From<PKEv1PublicParams<G>> for SerializablePKEv1PublicParams
558where
559 GroupElements<G>: Into<SerializableGroupElements>,
560{
561 fn from(value: PKEv1PublicParams<G>) -> Self {
562 let PKEv1PublicParams {
563 g_lists,
564 big_d,
565 n,
566 d,
567 k,
568 b,
569 b_r,
570 q,
571 t,
572 msbs_zero_padding_bit_count,
573 hash,
574 hash_t,
575 hash_agg,
576 hash_lmap,
577 hash_z,
578 hash_w,
579 } = value;
580 Self {
581 g_lists: g_lists.into(),
582 big_d,
583 n,
584 d,
585 k,
586 b,
587 b_r,
588 q,
589 t,
590 msbs_zero_padding_bit_count,
591 hash: hash.to_vec(),
592 hash_t: hash_t.to_vec(),
593 hash_agg: hash_agg.to_vec(),
594 hash_lmap: hash_lmap.to_vec(),
595 hash_z: hash_z.to_vec(),
596 hash_w: hash_w.to_vec(),
597 }
598 }
599}
600
601impl<G: Curve> TryFrom<SerializablePKEv1PublicParams> for PKEv1PublicParams<G>
602where
603 GroupElements<G>:
604 TryFrom<SerializableGroupElements, Error = InvalidSerializedGroupElementsError>,
605{
606 type Error = InvalidSerializedPublicParamsError;
607
608 fn try_from(value: SerializablePKEv1PublicParams) -> Result<Self, Self::Error> {
609 let SerializablePKEv1PublicParams {
610 g_lists,
611 big_d,
612 n,
613 d,
614 k,
615 b,
616 b_r,
617 q,
618 t,
619 msbs_zero_padding_bit_count,
620 hash,
621 hash_t,
622 hash_agg,
623 hash_lmap,
624 hash_z,
625 hash_w,
626 } = value;
627 Ok(Self {
628 g_lists: g_lists.try_into()?,
629 big_d,
630 n,
631 d,
632 k,
633 b,
634 b_r,
635 q,
636 t,
637 msbs_zero_padding_bit_count,
638 hash: try_vec_to_array(hash)?,
639 hash_t: try_vec_to_array(hash_t)?,
640 hash_agg: try_vec_to_array(hash_agg)?,
641 hash_lmap: try_vec_to_array(hash_lmap)?,
642 hash_z: try_vec_to_array(hash_z)?,
643 hash_w: try_vec_to_array(hash_w)?,
644 })
645 }
646}