lilium_transcript/
messages.rs1use 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
45pub(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
58pub 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}