tfhe_zk_pok/
serialization.rs

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, SerializablePKEv1DomainSeparatorsVersions,
10    SerializablePKEv1PublicParamsVersions, SerializablePKEv2DomainSeparatorsVersions,
11    SerializablePKEv2PublicParamsVersions, SerializableQuadExtFieldVersions,
12};
13use ark_ec::short_weierstrass::{Affine, SWCurveConfig};
14use ark_ec::AffineRepr;
15use ark_ff::{
16    BigInt, Field, Fp, Fp2, Fp6, Fp6Config, FpConfig, PrimeField, QuadExtConfig, QuadExtField,
17};
18use serde::{Deserialize, Serialize};
19use tfhe_versionable::Versionize;
20
21use crate::curve_api::{Curve, CurveGroupOps};
22use crate::proofs::pke::{
23    LegacyPKEv1DomainSeparators, PKEv1DomainSeparators, PublicParams as PKEv1PublicParams,
24    ShortPKEv1DomainSeparators,
25};
26use crate::proofs::pke_v2::{
27    Bound, LegacyPKEv2DomainSeparators, PKEv2DomainSeparators, PublicParams as PKEv2PublicParams,
28    ShortPKEv2DomainSeparators,
29};
30use crate::proofs::{GroupElements, Sid, HASH_DS_LEN_BYTES, LEGACY_HASH_DS_LEN_BYTES};
31
32/// Error returned when a conversion from a vec to a fixed size array failed because the vec size is
33/// incorrect
34#[derive(Debug)]
35pub struct InvalidArraySizeError {
36    expected_len: usize,
37    found_len: usize,
38}
39
40impl Display for InvalidArraySizeError {
41    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42        write!(
43            f,
44            "Invalid serialized array: found array of size {}, expected {}",
45            self.found_len, self.expected_len
46        )
47    }
48}
49
50impl Error for InvalidArraySizeError {}
51
52#[derive(Debug)]
53pub enum InvalidFpError {
54    InvalidArraySizeError(InvalidArraySizeError),
55    GreaterThanModulus,
56}
57
58impl From<InvalidArraySizeError> for InvalidFpError {
59    fn from(value: InvalidArraySizeError) -> Self {
60        Self::InvalidArraySizeError(value)
61    }
62}
63
64impl Display for InvalidFpError {
65    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66        match self {
67            Self::InvalidArraySizeError(e) => e.fmt(f),
68            Self::GreaterThanModulus => {
69                write!(
70                    f,
71                    "The deserialized value was bigger than what its type modulus allowed"
72                )
73            }
74        }
75    }
76}
77
78impl Error for InvalidFpError {}
79
80/// Tries to convert a Vec into a constant size array, and returns an [`InvalidArraySizeError`] if
81/// the size does not match
82pub(crate) fn try_vec_to_array<T, const N: usize>(
83    vec: Vec<T>,
84) -> Result<[T; N], InvalidArraySizeError> {
85    let len = vec.len();
86
87    vec.try_into().map_err(|_| InvalidArraySizeError {
88        expected_len: len,
89        found_len: N,
90    })
91}
92
93/// Serialization equivalent of the [`Fp`] struct, where the bigint is split into
94/// multiple u64.
95#[derive(Serialize, Deserialize, Versionize)]
96#[versionize(SerializableFpVersions)]
97pub struct SerializableFp {
98    val: Vec<u64>, // Use a Vec<u64> since serde does not support fixed size arrays with a generic
99}
100
101impl<P: FpConfig<N>, const N: usize> From<Fp<P, N>> for SerializableFp {
102    fn from(value: Fp<P, N>) -> Self {
103        Self {
104            val: value.0 .0.to_vec(),
105        }
106    }
107}
108
109impl<P: FpConfig<N>, const N: usize> TryFrom<SerializableFp> for Fp<P, N> {
110    type Error = InvalidFpError;
111
112    fn try_from(value: SerializableFp) -> Result<Self, Self::Error> {
113        let fp = BigInt(try_vec_to_array(value.val)?);
114        if fp >= Fp::<P, N>::MODULUS {
115            return Err(InvalidFpError::GreaterThanModulus);
116        }
117        Ok(Fp(fp, PhantomData))
118    }
119}
120
121#[derive(Debug)]
122pub enum InvalidSerializedAffineError {
123    InvalidFp(InvalidFpError),
124    InvalidCompressedXCoordinate,
125}
126
127impl Display for InvalidSerializedAffineError {
128    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
129        match self {
130            InvalidSerializedAffineError::InvalidFp(fp_error) => {
131                write!(f, "Invalid fp element in affine: {fp_error}")
132            }
133            InvalidSerializedAffineError::InvalidCompressedXCoordinate => {
134                write!(
135                    f,
136                    "Cannot uncompress affine: X coordinate does not belong to the curve"
137                )
138            }
139        }
140    }
141}
142
143impl Error for InvalidSerializedAffineError {
144    fn source(&self) -> Option<&(dyn Error + 'static)> {
145        match self {
146            InvalidSerializedAffineError::InvalidFp(fp_error) => Some(fp_error),
147            InvalidSerializedAffineError::InvalidCompressedXCoordinate => None,
148        }
149    }
150}
151
152impl From<InvalidFpError> for InvalidSerializedAffineError {
153    fn from(value: InvalidFpError) -> Self {
154        Self::InvalidFp(value)
155    }
156}
157
158/// Serialization equivalent to the [`Affine`], which support an optional compression mode
159/// where only the `x` coordinate is stored, and the `y` is computed on load.
160#[derive(Serialize, Deserialize, Versionize)]
161#[versionize(SerializableAffineVersions)]
162pub enum SerializableAffine<F> {
163    Infinity,
164    Compressed { x: F, take_largest_y: bool },
165    Uncompressed { x: F, y: F },
166}
167
168impl<F> SerializableAffine<F> {
169    #[allow(unused)]
170    pub fn uncompressed<BaseField: Into<F> + Field, C: SWCurveConfig<BaseField = BaseField>>(
171        value: Affine<C>,
172    ) -> Self {
173        if value.is_zero() {
174            Self::Infinity
175        } else {
176            Self::Uncompressed {
177                x: value.x.into(),
178                y: value.y.into(),
179            }
180        }
181    }
182
183    pub fn compressed<BaseField: Into<F> + Field, C: SWCurveConfig<BaseField = BaseField>>(
184        value: Affine<C>,
185    ) -> Self {
186        if value.is_zero() {
187            Self::Infinity
188        } else {
189            let take_largest_y = value.y > -value.y;
190            Self::Compressed {
191                x: value.x.into(),
192                take_largest_y,
193            }
194        }
195    }
196}
197
198impl<F, C: SWCurveConfig> TryFrom<SerializableAffine<F>> for Affine<C>
199where
200    F: TryInto<C::BaseField, Error = InvalidFpError>,
201{
202    type Error = InvalidSerializedAffineError;
203
204    fn try_from(value: SerializableAffine<F>) -> Result<Self, Self::Error> {
205        match value {
206            SerializableAffine::Infinity => Ok(Self::zero()),
207            SerializableAffine::Compressed { x, take_largest_y } => {
208                Self::get_point_from_x_unchecked(x.try_into()?, take_largest_y)
209                    .ok_or(InvalidSerializedAffineError::InvalidCompressedXCoordinate)
210            }
211            SerializableAffine::Uncompressed { x, y } => {
212                Ok(Self::new_unchecked(x.try_into()?, y.try_into()?))
213            }
214        }
215    }
216}
217
218pub(crate) type SerializableG1Affine = SerializableAffine<SerializableFp>;
219
220#[derive(Serialize, Deserialize, Versionize)]
221#[versionize(SerializableQuadExtFieldVersions)]
222pub struct SerializableQuadExtField<F> {
223    c0: F,
224    c1: F,
225}
226
227pub(crate) type SerializableFp2 = SerializableQuadExtField<SerializableFp>;
228pub type SerializableG2Affine = SerializableAffine<SerializableFp2>;
229
230impl<F, P: QuadExtConfig> From<QuadExtField<P>> for SerializableQuadExtField<F>
231where
232    F: From<P::BaseField>,
233{
234    fn from(value: QuadExtField<P>) -> Self {
235        Self {
236            c0: value.c0.into(),
237            c1: value.c1.into(),
238        }
239    }
240}
241
242impl<F, P: QuadExtConfig> TryFrom<SerializableQuadExtField<F>> for QuadExtField<P>
243where
244    F: TryInto<P::BaseField, Error = InvalidFpError>,
245{
246    type Error = InvalidFpError;
247
248    fn try_from(value: SerializableQuadExtField<F>) -> Result<Self, Self::Error> {
249        Ok(QuadExtField {
250            c0: value.c0.try_into()?,
251            c1: value.c1.try_into()?,
252        })
253    }
254}
255
256#[derive(Serialize, Deserialize, Versionize)]
257#[versionize(SerializableCubicExtFieldVersions)]
258pub struct SerializableCubicExtField<F> {
259    c0: F,
260    c1: F,
261    c2: F,
262}
263
264pub(crate) type SerializableFp6 = SerializableCubicExtField<SerializableFp2>;
265
266impl<F, P6: Fp6Config> From<Fp6<P6>> for SerializableCubicExtField<F>
267where
268    F: From<Fp2<P6::Fp2Config>>,
269{
270    fn from(value: Fp6<P6>) -> Self {
271        Self {
272            c0: value.c0.into(),
273            c1: value.c1.into(),
274            c2: value.c2.into(),
275        }
276    }
277}
278
279impl<F, P6: Fp6Config> TryFrom<SerializableCubicExtField<F>> for Fp6<P6>
280where
281    F: TryInto<Fp2<P6::Fp2Config>, Error = InvalidFpError>,
282{
283    type Error = InvalidFpError;
284
285    fn try_from(value: SerializableCubicExtField<F>) -> Result<Self, Self::Error> {
286        Ok(Fp6 {
287            c0: value.c0.try_into()?,
288            c1: value.c1.try_into()?,
289            c2: value.c2.try_into()?,
290        })
291    }
292}
293
294pub(crate) type SerializableFp12 = SerializableQuadExtField<SerializableFp6>;
295
296#[derive(Debug)]
297pub enum InvalidSerializedGroupElementsError {
298    InvalidAffine(InvalidSerializedAffineError),
299    InvalidGlistDimension(InvalidArraySizeError),
300    MissingPuncteredElement,
301}
302
303impl Display for InvalidSerializedGroupElementsError {
304    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
305        match self {
306            InvalidSerializedGroupElementsError::InvalidAffine(affine_error) => {
307                write!(f, "Invalid Affine in GroupElement: {affine_error}")
308            }
309            InvalidSerializedGroupElementsError::InvalidGlistDimension(arr_error) => {
310                write!(f, "invalid number of elements in g_list: {arr_error}")
311            }
312            InvalidSerializedGroupElementsError::MissingPuncteredElement => {
313                write!(f, "Element at index n in g_list should be 0")
314            }
315        }
316    }
317}
318
319impl Error for InvalidSerializedGroupElementsError {
320    fn source(&self) -> Option<&(dyn Error + 'static)> {
321        match self {
322            InvalidSerializedGroupElementsError::InvalidAffine(affine_error) => Some(affine_error),
323            InvalidSerializedGroupElementsError::InvalidGlistDimension(arr_error) => {
324                Some(arr_error)
325            }
326            InvalidSerializedGroupElementsError::MissingPuncteredElement => None,
327        }
328    }
329}
330
331impl From<InvalidSerializedAffineError> for InvalidSerializedGroupElementsError {
332    fn from(value: InvalidSerializedAffineError) -> Self {
333        Self::InvalidAffine(value)
334    }
335}
336
337#[derive(Serialize, Deserialize, Versionize)]
338#[versionize(SerializableGroupElementsVersions)]
339pub(crate) struct SerializableGroupElements {
340    pub(crate) g_list: Vec<SerializableG1Affine>,
341    pub(crate) g_hat_list: Vec<SerializableG2Affine>,
342}
343
344impl<G: Curve> From<GroupElements<G>> for SerializableGroupElements
345where
346    <G::G1 as CurveGroupOps<G::Zp>>::Affine: Into<SerializableG1Affine>,
347    <G::G2 as CurveGroupOps<G::Zp>>::Affine: Into<SerializableG2Affine>,
348{
349    fn from(value: GroupElements<G>) -> Self {
350        let mut g_list = Vec::new();
351        let mut g_hat_list = Vec::new();
352        for idx in 0..value.message_len {
353            g_list.push(value.g_list[(idx * 2) + 1].into());
354            g_list.push(value.g_list[(idx * 2) + 2].into());
355            g_hat_list.push(value.g_hat_list[idx + 1].into())
356        }
357
358        Self { g_list, g_hat_list }
359    }
360}
361
362impl<G: Curve> TryFrom<SerializableGroupElements> for GroupElements<G>
363where
364    <G::G1 as CurveGroupOps<G::Zp>>::Affine:
365        TryFrom<SerializableG1Affine, Error = InvalidSerializedAffineError>,
366    <G::G2 as CurveGroupOps<G::Zp>>::Affine:
367        TryFrom<SerializableG2Affine, Error = InvalidSerializedAffineError>,
368{
369    type Error = InvalidSerializedGroupElementsError;
370
371    fn try_from(value: SerializableGroupElements) -> Result<Self, Self::Error> {
372        if value.g_list.len() != value.g_hat_list.len() * 2 {
373            return Err(InvalidSerializedGroupElementsError::InvalidGlistDimension(
374                InvalidArraySizeError {
375                    expected_len: value.g_hat_list.len() * 2,
376                    found_len: value.g_list.len(),
377                },
378            ));
379        }
380
381        let g_list = value
382            .g_list
383            .into_iter()
384            .map(<G::G1 as CurveGroupOps<G::Zp>>::Affine::try_from)
385            .collect::<Result<_, InvalidSerializedAffineError>>()?;
386        let g_hat_list = value
387            .g_hat_list
388            .into_iter()
389            .map(<G::G2 as CurveGroupOps<G::Zp>>::Affine::try_from)
390            .collect::<Result<_, InvalidSerializedAffineError>>()?;
391
392        Ok(Self::from_vec(g_list, g_hat_list))
393    }
394}
395
396#[derive(Debug)]
397pub enum InvalidSerializedPublicParamsError {
398    InvalidGroupElements(InvalidSerializedGroupElementsError),
399    InvalidHashDimension(InvalidArraySizeError),
400}
401
402impl Display for InvalidSerializedPublicParamsError {
403    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
404        match self {
405            InvalidSerializedPublicParamsError::InvalidGroupElements(group_error) => {
406                write!(f, "Invalid PublicParams: {group_error}")
407            }
408            InvalidSerializedPublicParamsError::InvalidHashDimension(arr_error) => {
409                write!(f, "invalid size of hash: {arr_error}")
410            }
411        }
412    }
413}
414
415impl Error for InvalidSerializedPublicParamsError {
416    fn source(&self) -> Option<&(dyn Error + 'static)> {
417        match self {
418            InvalidSerializedPublicParamsError::InvalidGroupElements(group_error) => {
419                Some(group_error)
420            }
421            InvalidSerializedPublicParamsError::InvalidHashDimension(arr_error) => Some(arr_error),
422        }
423    }
424}
425
426impl From<InvalidSerializedGroupElementsError> for InvalidSerializedPublicParamsError {
427    fn from(value: InvalidSerializedGroupElementsError) -> Self {
428        Self::InvalidGroupElements(value)
429    }
430}
431
432impl From<InvalidArraySizeError> for InvalidSerializedPublicParamsError {
433    fn from(value: InvalidArraySizeError) -> Self {
434        Self::InvalidHashDimension(value)
435    }
436}
437
438#[derive(serde::Serialize, serde::Deserialize, Versionize)]
439#[versionize(SerializablePKEv2PublicParamsVersions)]
440pub struct SerializablePKEv2PublicParams {
441    pub(crate) g_lists: SerializableGroupElements,
442    pub(crate) D: usize,
443    pub(crate) n: usize,
444    pub(crate) d: usize,
445    pub(crate) k: usize,
446    pub(crate) B_bound_squared: u128,
447    pub(crate) B_inf: u64,
448    pub(crate) q: u64,
449    pub(crate) t: u64,
450    pub(crate) msbs_zero_padding_bit_count: u64,
451    pub(crate) bound_type: Bound,
452    pub(crate) sid: Option<u128>,
453    pub(crate) domain_separators: SerializablePKEv2DomainSeparators,
454}
455
456impl<G: Curve> From<PKEv2PublicParams<G>> for SerializablePKEv2PublicParams
457where
458    GroupElements<G>: Into<SerializableGroupElements>,
459{
460    fn from(value: PKEv2PublicParams<G>) -> Self {
461        let PKEv2PublicParams {
462            g_lists,
463            D,
464            n,
465            d,
466            k,
467            B_bound_squared,
468            B_inf,
469            q,
470            t,
471            msbs_zero_padding_bit_count,
472            bound_type,
473            sid,
474            domain_separators,
475        } = value;
476        Self {
477            g_lists: g_lists.into(),
478            D,
479            n,
480            d,
481            k,
482            B_bound_squared,
483            B_inf,
484            q,
485            t,
486            msbs_zero_padding_bit_count,
487            bound_type,
488            sid: sid.0,
489            domain_separators: domain_separators.into(),
490        }
491    }
492}
493
494impl<G: Curve> TryFrom<SerializablePKEv2PublicParams> for PKEv2PublicParams<G>
495where
496    GroupElements<G>:
497        TryFrom<SerializableGroupElements, Error = InvalidSerializedGroupElementsError>,
498{
499    type Error = InvalidSerializedPublicParamsError;
500
501    fn try_from(value: SerializablePKEv2PublicParams) -> Result<Self, Self::Error> {
502        let SerializablePKEv2PublicParams {
503            g_lists,
504            D,
505            n,
506            d,
507            k,
508            B_bound_squared,
509            B_inf,
510            q,
511            t,
512            msbs_zero_padding_bit_count,
513            bound_type,
514            sid,
515            domain_separators,
516        } = value;
517        Ok(Self {
518            g_lists: g_lists.try_into()?,
519            D,
520            n,
521            d,
522            k,
523            B_bound_squared,
524            B_inf,
525            q,
526            t,
527            msbs_zero_padding_bit_count,
528            bound_type,
529            sid: Sid(sid),
530            domain_separators: domain_separators.try_into()?,
531        })
532    }
533}
534
535#[derive(serde::Serialize, serde::Deserialize, Versionize)]
536#[versionize(SerializablePKEv2DomainSeparatorsVersions)]
537pub struct SerializablePKEv2DomainSeparators {
538    // We use Vec<u8> since serde does not support fixed size arrays of 256 elements
539    pub(crate) hash: Vec<u8>,
540    pub(crate) hash_R: Vec<u8>,
541    pub(crate) hash_t: Vec<u8>,
542    pub(crate) hash_w: Vec<u8>,
543    pub(crate) hash_agg: Vec<u8>,
544    pub(crate) hash_lmap: Vec<u8>,
545    pub(crate) hash_phi: Vec<u8>,
546    pub(crate) hash_xi: Vec<u8>,
547    pub(crate) hash_z: Vec<u8>,
548    pub(crate) hash_chi: Vec<u8>,
549    pub(crate) hash_gamma: Vec<u8>,
550}
551
552impl From<PKEv2DomainSeparators> for SerializablePKEv2DomainSeparators {
553    fn from(value: PKEv2DomainSeparators) -> Self {
554        Self {
555            hash: value.hash().to_vec(),
556            hash_R: value.hash_R().to_vec(),
557            hash_t: value.hash_t().to_vec(),
558            hash_w: value.hash_w().to_vec(),
559            hash_agg: value.hash_agg().to_vec(),
560            hash_lmap: value.hash_lmap().to_vec(),
561            hash_phi: value.hash_phi().to_vec(),
562            hash_xi: value.hash_xi().to_vec(),
563            hash_z: value.hash_z().to_vec(),
564            hash_chi: value.hash_chi().to_vec(),
565            hash_gamma: value.hash_gamma().to_vec(),
566        }
567    }
568}
569
570impl TryFrom<SerializablePKEv2DomainSeparators> for LegacyPKEv2DomainSeparators {
571    type Error = InvalidArraySizeError;
572
573    fn try_from(value: SerializablePKEv2DomainSeparators) -> Result<Self, Self::Error> {
574        let SerializablePKEv2DomainSeparators {
575            hash,
576            hash_R,
577            hash_t,
578            hash_w,
579            hash_agg,
580            hash_lmap,
581            hash_phi,
582            hash_xi,
583            hash_z,
584            hash_chi,
585            hash_gamma,
586        } = value;
587
588        Ok(Self {
589            hash: try_vec_to_array(hash)?,
590            hash_R: try_vec_to_array(hash_R)?,
591            hash_t: try_vec_to_array(hash_t)?,
592            hash_w: try_vec_to_array(hash_w)?,
593            hash_agg: try_vec_to_array(hash_agg)?,
594            hash_lmap: try_vec_to_array(hash_lmap)?,
595            hash_phi: try_vec_to_array(hash_phi)?,
596            hash_xi: try_vec_to_array(hash_xi)?,
597            hash_z: try_vec_to_array(hash_z)?,
598            hash_chi: try_vec_to_array(hash_chi)?,
599            hash_gamma: try_vec_to_array(hash_gamma)?,
600        })
601    }
602}
603
604impl TryFrom<SerializablePKEv2DomainSeparators> for ShortPKEv2DomainSeparators {
605    type Error = InvalidArraySizeError;
606
607    fn try_from(value: SerializablePKEv2DomainSeparators) -> Result<Self, Self::Error> {
608        let SerializablePKEv2DomainSeparators {
609            hash,
610            hash_R,
611            hash_t,
612            hash_w,
613            hash_agg,
614            hash_lmap,
615            hash_phi,
616            hash_xi,
617            hash_z,
618            hash_chi,
619            hash_gamma,
620        } = value;
621
622        Ok(Self {
623            hash: try_vec_to_array(hash)?,
624            hash_R: try_vec_to_array(hash_R)?,
625            hash_t: try_vec_to_array(hash_t)?,
626            hash_w: try_vec_to_array(hash_w)?,
627            hash_agg: try_vec_to_array(hash_agg)?,
628            hash_lmap: try_vec_to_array(hash_lmap)?,
629            hash_phi: try_vec_to_array(hash_phi)?,
630            hash_xi: try_vec_to_array(hash_xi)?,
631            hash_z: try_vec_to_array(hash_z)?,
632            hash_chi: try_vec_to_array(hash_chi)?,
633            hash_gamma: try_vec_to_array(hash_gamma)?,
634        })
635    }
636}
637
638impl TryFrom<SerializablePKEv2DomainSeparators> for PKEv2DomainSeparators {
639    type Error = InvalidArraySizeError;
640
641    fn try_from(value: SerializablePKEv2DomainSeparators) -> Result<Self, Self::Error> {
642        let len = value.hash.len();
643
644        match len {
645            LEGACY_HASH_DS_LEN_BYTES => Ok(Self::Legacy(Box::new(value.try_into()?))),
646            HASH_DS_LEN_BYTES => Ok(Self::Short(value.try_into()?)),
647            _ => Err(InvalidArraySizeError {
648                expected_len: HASH_DS_LEN_BYTES,
649                found_len: len,
650            }),
651        }
652    }
653}
654
655#[derive(serde::Serialize, serde::Deserialize, Versionize)]
656#[versionize(SerializablePKEv1PublicParamsVersions)]
657pub struct SerializablePKEv1PublicParams {
658    pub(crate) g_lists: SerializableGroupElements,
659    pub(crate) big_d: usize,
660    pub(crate) n: usize,
661    pub(crate) d: usize,
662    pub(crate) k: usize,
663    pub(crate) b: u64,
664    pub(crate) b_r: u64,
665    pub(crate) q: u64,
666    pub(crate) t: u64,
667    pub(crate) msbs_zero_padding_bit_count: u64,
668    pub(crate) sid: Option<u128>,
669    pub(crate) domain_separators: SerializablePKEv1DomainSeparators,
670}
671
672impl<G: Curve> From<PKEv1PublicParams<G>> for SerializablePKEv1PublicParams
673where
674    GroupElements<G>: Into<SerializableGroupElements>,
675{
676    fn from(value: PKEv1PublicParams<G>) -> Self {
677        let PKEv1PublicParams {
678            g_lists,
679            big_d,
680            n,
681            d,
682            k,
683            b,
684            b_r,
685            q,
686            t,
687            msbs_zero_padding_bit_count,
688            sid,
689            domain_separators,
690        } = value;
691        Self {
692            g_lists: g_lists.into(),
693            big_d,
694            n,
695            d,
696            k,
697            b,
698            b_r,
699            q,
700            t,
701            msbs_zero_padding_bit_count,
702            sid: sid.0,
703            domain_separators: domain_separators.into(),
704        }
705    }
706}
707
708impl<G: Curve> TryFrom<SerializablePKEv1PublicParams> for PKEv1PublicParams<G>
709where
710    GroupElements<G>:
711        TryFrom<SerializableGroupElements, Error = InvalidSerializedGroupElementsError>,
712{
713    type Error = InvalidSerializedPublicParamsError;
714
715    fn try_from(value: SerializablePKEv1PublicParams) -> Result<Self, Self::Error> {
716        let SerializablePKEv1PublicParams {
717            g_lists,
718            big_d,
719            n,
720            d,
721            k,
722            b,
723            b_r,
724            q,
725            t,
726            msbs_zero_padding_bit_count,
727            sid,
728            domain_separators,
729        } = value;
730        Ok(Self {
731            g_lists: g_lists.try_into()?,
732            big_d,
733            n,
734            d,
735            k,
736            b,
737            b_r,
738            q,
739            t,
740            msbs_zero_padding_bit_count,
741            sid: Sid(sid),
742            domain_separators: domain_separators.try_into()?,
743        })
744    }
745}
746
747#[derive(serde::Serialize, serde::Deserialize, Versionize)]
748#[versionize(SerializablePKEv1DomainSeparatorsVersions)]
749pub struct SerializablePKEv1DomainSeparators {
750    // We use Vec<u8> since serde does not support fixed size arrays of 256 elements
751    pub(crate) hash: Vec<u8>,
752    pub(crate) hash_t: Vec<u8>,
753    pub(crate) hash_agg: Vec<u8>,
754    pub(crate) hash_lmap: Vec<u8>,
755    pub(crate) hash_w: Vec<u8>,
756    pub(crate) hash_z: Vec<u8>,
757    pub(crate) hash_gamma: Vec<u8>,
758}
759
760impl From<PKEv1DomainSeparators> for SerializablePKEv1DomainSeparators {
761    fn from(value: PKEv1DomainSeparators) -> Self {
762        Self {
763            hash: value.hash().to_vec(),
764            hash_t: value.hash_t().to_vec(),
765            hash_agg: value.hash_agg().to_vec(),
766            hash_lmap: value.hash_lmap().to_vec(),
767            hash_w: value.hash_w().to_vec(),
768            hash_z: value.hash_z().to_vec(),
769            hash_gamma: value.hash_gamma().to_vec(),
770        }
771    }
772}
773
774impl TryFrom<SerializablePKEv1DomainSeparators> for LegacyPKEv1DomainSeparators {
775    type Error = InvalidArraySizeError;
776
777    fn try_from(value: SerializablePKEv1DomainSeparators) -> Result<Self, Self::Error> {
778        let SerializablePKEv1DomainSeparators {
779            hash,
780            hash_t,
781            hash_agg,
782            hash_lmap,
783            hash_w,
784            hash_z,
785            hash_gamma,
786        } = value;
787
788        Ok(Self {
789            hash: try_vec_to_array(hash)?,
790            hash_t: try_vec_to_array(hash_t)?,
791            hash_agg: try_vec_to_array(hash_agg)?,
792            hash_lmap: try_vec_to_array(hash_lmap)?,
793            hash_w: try_vec_to_array(hash_w)?,
794            hash_z: try_vec_to_array(hash_z)?,
795            hash_gamma: try_vec_to_array(hash_gamma)?,
796        })
797    }
798}
799
800impl TryFrom<SerializablePKEv1DomainSeparators> for ShortPKEv1DomainSeparators {
801    type Error = InvalidArraySizeError;
802
803    fn try_from(value: SerializablePKEv1DomainSeparators) -> Result<Self, Self::Error> {
804        let SerializablePKEv1DomainSeparators {
805            hash,
806            hash_t,
807            hash_agg,
808            hash_lmap,
809            hash_w,
810            hash_z,
811            hash_gamma,
812        } = value;
813
814        Ok(Self {
815            hash: try_vec_to_array(hash)?,
816            hash_t: try_vec_to_array(hash_t)?,
817            hash_agg: try_vec_to_array(hash_agg)?,
818            hash_lmap: try_vec_to_array(hash_lmap)?,
819            hash_w: try_vec_to_array(hash_w)?,
820            hash_z: try_vec_to_array(hash_z)?,
821            hash_gamma: try_vec_to_array(hash_gamma)?,
822        })
823    }
824}
825
826impl TryFrom<SerializablePKEv1DomainSeparators> for PKEv1DomainSeparators {
827    type Error = InvalidArraySizeError;
828
829    fn try_from(value: SerializablePKEv1DomainSeparators) -> Result<Self, Self::Error> {
830        let len = value.hash.len();
831
832        match len {
833            LEGACY_HASH_DS_LEN_BYTES => Ok(Self::Legacy(Box::new(value.try_into()?))),
834            HASH_DS_LEN_BYTES => Ok(Self::Short(value.try_into()?)),
835            _ => Err(InvalidArraySizeError {
836                expected_len: HASH_DS_LEN_BYTES,
837                found_len: len,
838            }),
839        }
840    }
841}