o1_utils/
field_helpers.rs1use ark_ff::{BigInteger, Field, PrimeField};
4use num_bigint::{BigInt, BigUint, RandBigInt, ToBigInt};
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 Self::to_biguint(self).to_bigint().unwrap()
113 }
114
115 fn bits_to_field(&self, start: usize, end: usize) -> Result<F>;
117
118 fn size_in_bytes() -> usize
120 where
121 F: PrimeField,
122 {
123 (F::MODULUS_BIT_SIZE / 8) as usize + (F::MODULUS_BIT_SIZE % 8 != 0) as usize
124 }
125
126 fn modulus_biguint() -> BigUint
128 where
129 F: PrimeField,
130 {
131 BigUint::from_bytes_le(&F::MODULUS.to_bytes_le())
132 }
133}
134
135impl<F: Field> FieldHelpers<F> for F {
136 fn from_bytes(bytes: &[u8]) -> Result<F> {
137 F::deserialize_uncompressed(&mut &*bytes).map_err(|_| FieldHelpersError::DeserializeBytes)
138 }
139
140 fn from_hex(hex: &str) -> Result<F> {
141 let bytes: Vec<u8> = hex::decode(hex).map_err(|_| FieldHelpersError::DecodeHex)?;
142 F::deserialize_uncompressed(&mut &bytes[..])
143 .map_err(|_| FieldHelpersError::DeserializeBytes)
144 }
145
146 fn from_bits(bits: &[bool]) -> Result<F> {
148 let bytes = bits
149 .iter()
150 .enumerate()
151 .fold(F::zero().to_bytes(), |mut bytes, (i, bit)| {
152 bytes[i / 8] |= (*bit as u8) << (i % 8);
153 bytes
154 });
155
156 F::deserialize_uncompressed(&mut &bytes[..])
157 .map_err(|_| FieldHelpersError::DeserializeBytes)
158 }
159
160 fn to_bytes(&self) -> Vec<u8> {
161 let mut bytes: Vec<u8> = vec![];
162 self.serialize_uncompressed(&mut bytes)
163 .expect("Failed to serialize field");
164
165 bytes
166 }
167
168 fn to_hex(&self) -> String {
169 hex::encode(self.to_bytes())
170 }
171
172 fn to_bits(&self) -> Vec<bool> {
174 self.to_bytes().iter().fold(vec![], |mut bits, byte| {
175 let mut byte = *byte;
176 for _ in 0..8 {
177 bits.push(byte & 0x01 == 0x01);
178 byte >>= 1;
179 }
180 bits
181 })
182 }
183
184 fn bits_to_field(&self, start: usize, end: usize) -> Result<F> {
185 F::from_bits(&self.to_bits()[start..end]).map_err(|_| FieldHelpersError::DeserializeBits)
186 }
187}
188
189pub trait BigUintFieldHelpers {
191 fn to_field<F: PrimeField>(self) -> Result<F>;
193}
194
195impl BigUintFieldHelpers for BigUint {
196 fn to_field<F: PrimeField>(self) -> Result<F> {
197 F::from_biguint(&self)
198 }
199}
200
201pub fn i32_to_field<F: From<u64> + Neg<Output = F>>(i: i32) -> F {
203 if i >= 0 {
204 F::from(i as u64)
205 } else {
206 -F::from(-i as u64)
207 }
208}
209
210pub fn pows<F: Field>(d: usize, x: F) -> Vec<F> {
213 let mut acc = F::one();
214 let mut res = Vec::with_capacity(d);
215 for _ in 1..=d {
216 res.push(acc);
217 acc *= x;
218 }
219 res
220}
221
222pub fn product<F: Field>(xs: impl Iterator<Item = F>) -> F {
224 let mut res = F::one();
225 for x in xs {
226 res *= &x;
227 }
228 res
229}
230
231pub fn inner_prod<F: Field>(xs: &[F], ys: &[F]) -> F {
233 let mut res = F::zero();
234 for (&x, y) in xs.iter().zip(ys) {
235 res += &(x * y);
236 }
237 res
238}