arnaucube
arnaucube/sonobePublic Self-hosted repository
sonobe/src/folding/circuits/nonnative.rs
src/folding/circuits/nonnative.rsRaw
 1use ark_ec::{AffineRepr, CurveGroup};
 2use ark_ff::PrimeField;
 3use ark_r1cs_std::fields::nonnative::{params::OptimizationType, AllocatedNonNativeFieldVar};
 4use ark_r1cs_std::{
 5    alloc::{AllocVar, AllocationMode},
 6    fields::nonnative::NonNativeFieldVar,
 7};
 8use ark_relations::r1cs::{Namespace, SynthesisError};
 9use core::borrow::Borrow;
10
11/// NonNativeAffineVar represents an elliptic curve point in Affine represenation in the non-native
12/// field. It is not intended to perform operations, but just to contain the affine coordinates in
13/// order to perform hash operations of the point.
14#[derive(Debug, Clone)]
15pub struct NonNativeAffineVar<F: PrimeField, CF: PrimeField> {
16    pub x: NonNativeFieldVar<F, CF>,
17    pub y: NonNativeFieldVar<F, CF>,
18}
19
20impl<C> AllocVar<C, C::ScalarField> for NonNativeAffineVar<C::BaseField, C::ScalarField>
21where
22    C: CurveGroup,
23    <C as ark_ec::CurveGroup>::BaseField: ark_ff::PrimeField,
24{
25    fn new_variable<T: Borrow<C>>(
26        cs: impl Into<Namespace<C::ScalarField>>,
27        f: impl FnOnce() -> Result<T, SynthesisError>,
28        mode: AllocationMode,
29    ) -> Result<Self, SynthesisError> {
30        f().and_then(|val| {
31            let cs = cs.into();
32
33            let affine = val.borrow().into_affine();
34            let xy = affine.xy().unwrap();
35            let x = NonNativeFieldVar::<C::BaseField, C::ScalarField>::new_variable(
36                cs.clone(),
37                || Ok(xy.0),
38                mode,
39            )?;
40            let y = NonNativeFieldVar::<C::BaseField, C::ScalarField>::new_variable(
41                cs.clone(),
42                || Ok(xy.1),
43                mode,
44            )?;
45
46            Ok(Self { x, y })
47        })
48    }
49}
50
51/// point_to_nonnative_limbs is used to return (outside the circuit) the limbs representation that
52/// matches the one used in-circuit.
53#[allow(clippy::type_complexity)]
54pub fn point_to_nonnative_limbs<C: CurveGroup>(
55    p: C,
56) -> Result<(Vec<C::ScalarField>, Vec<C::ScalarField>), SynthesisError>
57where
58    <C as ark_ec::CurveGroup>::BaseField: ark_ff::PrimeField,
59{
60    let affine = p.into_affine();
61    let (x, y) = affine.xy().unwrap();
62    let x = AllocatedNonNativeFieldVar::<C::BaseField, C::ScalarField>::get_limbs_representations(
63        x,
64        OptimizationType::Weight,
65    )?;
66    let y = AllocatedNonNativeFieldVar::<C::BaseField, C::ScalarField>::get_limbs_representations(
67        y,
68        OptimizationType::Weight,
69    )?;
70    Ok((x, y))
71}