o1_utils/
field_helpers.rs1use ark_ff::{BigInteger, Field, PrimeField};
4use num_bigint::{BigInt, BigUint, RandBigInt, Sign};
5use rand::rngs::StdRng;
6use std::ops::Neg;
7use thiserror::Error;
8
9#[allow(missing_docs)]
11#[derive(Error, Debug, Clone, PartialEq, Eq)]
12pub enum FieldHelpersError {
13 #[error("failed to deserialize field bytes")]
14 DeserializeBytes,
15 #[error("failed to deserialize field bits")]
16 DeserializeBits,
17 #[error("failed to decode hex")]
18 DecodeHex,
19 #[error("failed to convert BigUint into field element")]
20 FromBigToField,
21}
22
23pub type Result<T> = std::result::Result<T, FieldHelpersError>;
25
26pub trait RandomField<F> {
28 fn gen_field_with_bits(&mut self, bits: usize) -> F;
30
31 fn gen(&mut self, input: Option<F>, bits: Option<usize>) -> F;
33}
34
35impl<F: PrimeField> RandomField<F> for StdRng {
36 fn gen_field_with_bits(&mut self, bits: usize) -> F {
37 F::from_biguint(&self.gen_biguint_below(&BigUint::from(2u8).pow(bits as u32))).unwrap()
38 }
39
40 fn gen(&mut self, input: Option<F>, bits: Option<usize>) -> F {
41 if let Some(inp) = input {
42 inp
43 } else {
44 assert!(bits.is_some());
45 let bits = bits.unwrap();
46 self.gen_field_with_bits(bits)
47 }
48 }
49}
50
51pub trait Two<F> {
53 fn two() -> F;
55
56 fn two_pow(pow: u64) -> F;
58}
59
60impl<F: Field> Two<F> for F {
61 fn two() -> F {
62 F::from(2u8)
63 }
64
65 fn two_pow(pow: u64) -> F {
66 F::two().pow([pow])
67 }
68}
69
70pub trait FieldHelpers<F> {
73 fn from_bytes(bytes: &[u8]) -> Result<F>;
75
76 fn from_hex(hex: &str) -> Result<F>;
78
79 fn from_bits(bits: &[bool]) -> Result<F>;
81
82 fn from_biguint(big: &BigUint) -> Result<F>
84 where
85 F: PrimeField,
86 {
87 Ok(F::from(big.clone()))
88 }
89
90 fn to_bytes(&self) -> Vec<u8>;
92
93 fn to_hex(&self) -> String;
95
96 fn to_bits(&self) -> Vec<bool>;
98
99 fn to_biguint(&self) -> BigUint
101 where
102 F: PrimeField,
103 {
104 BigUint::from_bytes_le(&self.to_bytes())
105 }
106
107 fn to_bigint_positive(&self) -> BigInt
109 where
110 F: PrimeField,
111 {
112 use ark_ff::Zero;
113 let big_int = Self::to_biguint(self);
114
115 if big_int.is_zero() {
116 BigInt::zero()
117 } else {
118 BigInt::new(Sign::Plus, big_int.to_u32_digits())
119 }
120 }
121
122 fn bits_to_field(&self, start: usize, end: usize) -> Result<F>;
124
125 fn size_in_bytes() -> usize
127 where
128 F: PrimeField,
129 {
130 (F::MODULUS_BIT_SIZE / 8) as usize + (F::MODULUS_BIT_SIZE % 8 != 0) as usize
131 }
132
133 fn modulus_biguint() -> BigUint
135 where
136 F: PrimeField,
137 {
138 BigUint::from_bytes_le(&F::MODULUS.to_bytes_le())
139 }
140}
141
142impl<F: Field> FieldHelpers<F> for F {
143 fn from_bytes(bytes: &[u8]) -> Result<F> {
144 F::deserialize_uncompressed(&mut &*bytes).map_err(|_| FieldHelpersError::DeserializeBytes)
145 }
146
147 fn from_hex(hex: &str) -> Result<F> {
148 let bytes: Vec<u8> = hex::decode(hex).map_err(|_| FieldHelpersError::DecodeHex)?;
149 F::deserialize_uncompressed(&mut &bytes[..])
150 .map_err(|_| FieldHelpersError::DeserializeBytes)
151 }
152
153 fn from_bits(bits: &[bool]) -> Result<F> {
155 let bytes = bits
156 .iter()
157 .enumerate()
158 .fold(F::zero().to_bytes(), |mut bytes, (i, bit)| {
159 bytes[i / 8] |= (*bit as u8) << (i % 8);
160 bytes
161 });
162
163 F::deserialize_uncompressed(&mut &bytes[..])
164 .map_err(|_| FieldHelpersError::DeserializeBytes)
165 }
166
167 fn to_bytes(&self) -> Vec<u8> {
168 let mut bytes: Vec<u8> = vec![];
169 self.serialize_uncompressed(&mut bytes)
170 .expect("Failed to serialize field");
171
172 bytes
173 }
174
175 fn to_hex(&self) -> String {
176 hex::encode(self.to_bytes())
177 }
178
179 fn to_bits(&self) -> Vec<bool> {
181 self.to_bytes().iter().fold(vec![], |mut bits, byte| {
182 let mut byte = *byte;
183 for _ in 0..8 {
184 bits.push(byte & 0x01 == 0x01);
185 byte >>= 1;
186 }
187 bits
188 })
189 }
190
191 fn bits_to_field(&self, start: usize, end: usize) -> Result<F> {
192 F::from_bits(&self.to_bits()[start..end]).map_err(|_| FieldHelpersError::DeserializeBits)
193 }
194}
195
196pub trait BigUintFieldHelpers {
198 fn to_field<F: PrimeField>(self) -> Result<F>;
200}
201
202impl BigUintFieldHelpers for BigUint {
203 fn to_field<F: PrimeField>(self) -> Result<F> {
204 F::from_biguint(&self)
205 }
206}
207
208pub fn i32_to_field<F: From<u64> + Neg<Output = F>>(i: i32) -> F {
210 if i >= 0 {
211 F::from(i as u64)
212 } else {
213 -F::from(-i as u64)
214 }
215}
216
217pub fn pows<F: Field>(d: usize, x: F) -> Vec<F> {
220 let mut acc = F::one();
221 let mut res = Vec::with_capacity(d);
222 for _ in 1..=d {
223 res.push(acc);
224 acc *= x;
225 }
226 res
227}
228
229pub fn product<F: Field>(xs: impl Iterator<Item = F>) -> F {
231 let mut res = F::one();
232 for x in xs {
233 res *= &x;
234 }
235 res
236}
237
238pub fn inner_prod<F: Field>(xs: &[F], ys: &[F]) -> F {
240 let mut res = F::zero();
241 for (&x, y) in xs.iter().zip(ys) {
242 res += &(x * y);
243 }
244 res
245}