sonobe_primitives/algebra/field/
mod.rs1use ark_ff::{BigInteger, Fp, FpConfig, PrimeField};
5use ark_r1cs_std::{
6 GR1CSVar,
7 alloc::AllocVar,
8 eq::EqGadget,
9 fields::{FieldVar, fp::FpVar},
10};
11use ark_relations::gr1cs::SynthesisError;
12use ark_std::{
13 any::TypeId,
14 mem::transmute_copy,
15 ops::{Add, Mul},
16};
17
18use crate::{
19 algebra::{Val, field::emulated::EmulatedFieldVar},
20 circuits::WitnessToPublic,
21 traits::{Inputize, InputizeEmulated},
22 transcripts::{Absorbable, AbsorbableVar},
23};
24
25pub mod emulated;
26
27pub trait SonobeField:
30 PrimeField<BasePrimeField = Self>
31 + Absorbable
32 + Inputize<Self>
33 + Val<
34 Var: FieldVar<Self, Self> + WitnessToPublic,
35 EmulatedVar<Self> = EmulatedFieldVar<Self, Self>,
36 >
37{
38 const BITS_PER_LIMB: usize;
43}
44
45impl<P: FpConfig<N>, const N: usize> SonobeField for Fp<P, N> {
46 const BITS_PER_LIMB: usize = 32;
47}
48
49impl<P: FpConfig<N>, const N: usize> Val for Fp<P, N> {
50 type PreferredConstraintField = Self;
51 type Var = FpVar<Self>;
52
53 type EmulatedVar<F: SonobeField> = EmulatedFieldVar<F, Self>;
54}
55
56impl<P: FpConfig<N>, const N: usize> Absorbable for Fp<P, N> {
57 fn absorb_into<F: PrimeField>(&self, dest: &mut Vec<F>) {
58 if TypeId::of::<F>() == TypeId::of::<Self>() {
59 dest.push(unsafe { transmute_copy::<Self, F>(self) });
62 } else {
63 let bits_per_limb = F::MODULUS_BIT_SIZE - 1;
64 let num_limbs = Self::MODULUS_BIT_SIZE.div_ceil(bits_per_limb);
65
66 let mut limbs = self
67 .into_bigint()
68 .to_bits_le()
69 .chunks(bits_per_limb as usize)
70 .map(|chunk| F::from(F::BigInt::from_bits_le(chunk)))
71 .collect::<Vec<F>>();
72 limbs.resize(num_limbs as usize, F::zero());
73
74 dest.extend(&limbs)
75 }
76 }
77}
78
79impl<F: PrimeField> AbsorbableVar<F> for FpVar<F> {
80 fn absorb_into(&self, dest: &mut Vec<FpVar<F>>) -> Result<(), SynthesisError> {
81 dest.push(self.clone());
82 Ok(())
83 }
84}
85
86impl<P: FpConfig<N>, const N: usize> Inputize<Self> for Fp<P, N> {
87 fn inputize(&self) -> Vec<Self> {
88 vec![*self]
89 }
90}
91
92impl<F: SonobeField, P: SonobeField> InputizeEmulated<F> for P {
93 fn inputize_emulated(&self) -> Vec<F> {
94 self.into_bigint()
95 .to_bits_le()
96 .chunks(F::BITS_PER_LIMB)
97 .map(|chunk| F::from(F::BigInt::from_bits_le(chunk)))
98 .collect()
99 }
100}
101
102impl<F: PrimeField> WitnessToPublic for FpVar<F> {
103 fn mark_as_public(&self) -> Result<(), SynthesisError> {
104 self.enforce_equal(&FpVar::new_input(self.cs(), || self.value())?)
115 }
116}
117
118pub trait TwoStageFieldVar:
130 Clone
131 + Add<Output = Self::Intermediate>
132 + for<'a> Add<&'a Self, Output = Self::Intermediate>
133 + Mul<Output = Self::Intermediate>
134 + for<'a> Mul<&'a Self, Output = Self::Intermediate>
135{
136 type Intermediate: Clone
145 + From<Self>
146 + TryInto<Self>
147 + Add<Output = Self::Intermediate>
148 + for<'a> Add<&'a Self::Intermediate, Output = Self::Intermediate>
149 + Mul<Output = Self::Intermediate>
150 + for<'a> Mul<&'a Self::Intermediate, Output = Self::Intermediate>
151 + Add<Self, Output = Self::Intermediate>
152 + for<'a> Add<&'a Self, Output = Self::Intermediate>
153 + Mul<Self, Output = Self::Intermediate>
154 + for<'a> Mul<&'a Self, Output = Self::Intermediate>;
155}
156
157impl<F: PrimeField> TwoStageFieldVar for FpVar<F> {
159 type Intermediate = Self;
160}