Skip to main content

lilium_transcript/
messages.rs

1use crate::{params::ParamResolver, Message};
2use ark_ff::PrimeField;
3use ark_ff::{BigInteger, Field};
4use std::marker::PhantomData;
5
6impl<F: Field> Message<F> for () {
7    fn len(_vars: usize, _param_resolver: &ParamResolver) -> usize {
8        0
9    }
10
11    fn to_field_elements(&self) -> Vec<F> {
12        vec![]
13    }
14}
15
16#[derive(Debug, Clone, Copy)]
17pub struct SingleElement<F>(pub F);
18
19impl<F> SingleElement<F> {
20    pub fn inner(self) -> F {
21        self.0
22    }
23}
24
25impl<F: Field> Message<F> for SingleElement<F> {
26    fn len(_vars: usize, _param_resolver: &ParamResolver) -> usize {
27        1
28    }
29
30    fn to_field_elements(&self) -> Vec<F> {
31        vec![self.0]
32    }
33}
34
35impl<F: Field, M: Message<F>, const N: usize> Message<F> for [M; N] {
36    fn len(vars: usize, param_resolver: &ParamResolver) -> usize {
37        M::len(vars, param_resolver) * N
38    }
39
40    fn to_field_elements(&self) -> Vec<F> {
41        self.iter().flat_map(|x| x.to_field_elements()).collect()
42    }
43}
44
45/// special type to generate points
46pub(crate) struct PointRound;
47
48impl<F: Field> Message<F> for PointRound {
49    fn len(_vars: usize, _param_resolver: &ParamResolver) -> usize {
50        0
51    }
52
53    fn to_field_elements(&self) -> Vec<F> {
54        vec![]
55    }
56}
57
58/// Element of F1 represented as 2 elements of F2
59pub struct ForeignElement<F1, F2> {
60    pub value: F1,
61    _f2: PhantomData<F2>,
62}
63
64impl<F1, F2> From<F1> for ForeignElement<F1, F2>
65where
66    F1: Field,
67    F2: Field,
68{
69    fn from(value: F1) -> Self {
70        let bit_diff = F2::BasePrimeField::MODULUS_BIT_SIZE as i32
71            - F1::BasePrimeField::MODULUS_BIT_SIZE as i32;
72        let bit_diff = bit_diff.unsigned_abs();
73        assert!(bit_diff < 8, "fields differ in size in more than a byte");
74
75        Self {
76            value,
77            _f2: PhantomData,
78        }
79    }
80}
81impl<F1, F2> Message<F2> for ForeignElement<F1, F2>
82where
83    F1: Field,
84    F2: Field,
85{
86    fn len(_vars: usize, _param_resolver: &ParamResolver) -> usize {
87        2
88    }
89
90    fn to_field_elements(&self) -> Vec<F2> {
91        let (low, high) = self
92            .value
93            .to_base_prime_field_elements()
94            .map(|x| {
95                let mut bytes = x.into_bigint().to_bytes_le();
96                let high_byte = bytes.pop().unwrap();
97                let low = F2::BasePrimeField::from_le_bytes_mod_order(&bytes);
98                let high = F2::BasePrimeField::from_le_bytes_mod_order(&[high_byte]);
99                (low, high)
100            })
101            .unzip::<_, _, Vec<_>, Vec<_>>();
102        let low = F2::from_base_prime_field_elems(&low).unwrap();
103        let high = F2::from_base_prime_field_elems(&high).unwrap();
104        vec![low, high]
105    }
106}
107
108impl<F: Field, A: Message<F>, B: Message<F>> Message<F> for (A, B) {
109    fn len(vars: usize, param_resolver: &ParamResolver) -> usize {
110        A::len(vars, param_resolver) + B::len(vars, param_resolver)
111    }
112
113    fn to_field_elements(&self) -> Vec<F> {
114        let a = self.0.to_field_elements();
115        let b = self.1.to_field_elements();
116        a.into_iter().chain(b).collect()
117    }
118}