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#[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}