halo2curves/derive/field/
common.rs

1#[macro_export]
2macro_rules! field_bits {
3    ($field:ident) => {
4        #[cfg(feature = "bits")]
5        #[cfg_attr(docsrs, doc(cfg(feature = "bits")))]
6        impl ff::PrimeFieldBits for $field {
7            #[cfg(target_pointer_width = "64")]
8            type ReprBits = [u64; Self::NUM_LIMBS];
9            #[cfg(not(target_pointer_width = "64"))]
10            type ReprBits = [u32; Self::NUM_LIMBS * 2];
11
12            fn to_le_bits(&self) -> ff::FieldBits<Self::ReprBits> {
13                use ff::PrimeField;
14                let bytes: [u8; Self::SIZE] = self.to_repr().into();
15
16                #[cfg(target_pointer_width = "64")]
17                const STEP: usize = 8;
18                #[cfg(not(target_pointer_width = "64"))]
19                const STEP: usize = 4;
20
21                let limbs = (0..Self::NUM_LIMBS * 8 / STEP)
22                    .map(|off| {
23                        #[cfg(target_pointer_width = "64")]
24                        let limb = u64::from_le_bytes(
25                            bytes[off * STEP..(off + 1) * STEP].try_into().unwrap(),
26                        );
27                        #[cfg(not(target_pointer_width = "64"))]
28                        let limb = u32::from_le_bytes(
29                            bytes[off * STEP..(off + 1) * STEP].try_into().unwrap(),
30                        );
31
32                        limb
33                    })
34                    .collect::<Vec<_>>();
35
36                ff::FieldBits::new(limbs.try_into().unwrap())
37            }
38
39            fn char_le_bits() -> ff::FieldBits<Self::ReprBits> {
40                #[cfg(target_pointer_width = "64")]
41                let bits = ff::FieldBits::new(Self::MODULUS_LIMBS);
42                #[cfg(not(target_pointer_width = "64"))]
43                let bits = ff::FieldBits::new(Self::MODULUS_LIMBS_32);
44
45                bits
46            }
47        }
48    };
49}
50
51#[macro_export]
52macro_rules! impl_from_u64 {
53    ($field:ident) => {
54        impl From<u64> for $field {
55            fn from(val: u64) -> $field {
56                let limbs = std::iter::once(val)
57                    .chain(std::iter::repeat(0))
58                    .take(Self::NUM_LIMBS)
59                    .collect::<Vec<_>>()
60                    .try_into()
61                    .unwrap();
62
63                $field(limbs) * Self::R2
64            }
65        }
66    };
67}
68
69#[macro_export]
70macro_rules! impl_from_bool {
71    ($field:ident) => {
72        impl From<bool> for $field {
73            fn from(val: bool) -> $field {
74                let limbs = std::iter::once(u64::from(val))
75                    .chain(std::iter::repeat(0))
76                    .take(Self::NUM_LIMBS)
77                    .collect::<Vec<_>>()
78                    .try_into()
79                    .unwrap();
80
81                $field(limbs) * Self::R2
82            }
83        }
84    };
85}
86
87/// A macro to help define serialization and deserialization for prime field
88/// implementations that use `$field::Repr`` representations. This assumes the
89/// concerned type implements PrimeField (for from_repr, to_repr).
90#[macro_export]
91macro_rules! serialize_deserialize_primefield {
92    ($field:ident) => {
93        #[cfg(feature = "derive_serde")]
94        impl<'de> ::serde::Deserialize<'de> for $field {
95            fn deserialize<D: ::serde::Deserializer<'de>>(
96                deserializer: D,
97            ) -> Result<Self, D::Error> {
98                use ::serde::de::Error as _;
99                let bytes = if deserializer.is_human_readable() {
100                    hex::serde::deserialize(deserializer)?
101                } else {
102                    ::serde_arrays::deserialize::<_, u8, { $field::SIZE }>(deserializer)?
103                };
104                use ff::PrimeField;
105                Option::from(Self::from_repr(bytes.into())).ok_or_else(|| {
106                    D::Error::custom("deserialized bytes don't encode a valid field element")
107                })
108            }
109        }
110        #[cfg(feature = "derive_serde")]
111        impl ::serde::Serialize for $field {
112            fn serialize<S: ::serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
113                use ff::PrimeField;
114                if serializer.is_human_readable() {
115                    hex::serde::serialize(self.to_repr().as_ref(), serializer)
116                } else {
117                    let bytes: [u8; $field::SIZE] = self.to_repr().into();
118                    ::serde_arrays::serialize(&bytes, serializer)
119                }
120            }
121        }
122    };
123}