snark_verifier/loader/
native.rs

1//! `Loader` implementation in native rust.
2
3use crate::{
4    loader::{EcPointLoader, LoadedEcPoint, LoadedScalar, Loader, ScalarLoader},
5    util::arithmetic::{fe_to_big, Curve, CurveAffine, FieldOps, PrimeField},
6    Error,
7};
8use lazy_static::lazy_static;
9use std::fmt::Debug;
10
11lazy_static! {
12    /// NativeLoader instance for [`LoadedEcPoint::loader`] and
13    /// [`LoadedScalar::loader`] referencing.
14    pub static ref LOADER: NativeLoader = NativeLoader;
15}
16
17/// `Loader` implementation in native rust.
18#[derive(Clone, Debug)]
19pub struct NativeLoader;
20
21impl<C: CurveAffine> LoadedEcPoint<C> for C {
22    type Loader = NativeLoader;
23
24    fn loader(&self) -> &NativeLoader {
25        &LOADER
26    }
27}
28
29impl<F: PrimeField> FieldOps for F {
30    fn invert(&self) -> Option<F> {
31        self.invert().into()
32    }
33}
34
35impl<F: PrimeField> LoadedScalar<F> for F {
36    type Loader = NativeLoader;
37
38    fn loader(&self) -> &NativeLoader {
39        &LOADER
40    }
41
42    fn pow_var(&self, exp: &Self, _: usize) -> Self {
43        let exp = fe_to_big(*exp).to_u64_digits();
44        self.pow_vartime(exp)
45    }
46}
47
48impl<C: CurveAffine> EcPointLoader<C> for NativeLoader {
49    type LoadedEcPoint = C;
50
51    fn ec_point_load_const(&self, value: &C) -> Self::LoadedEcPoint {
52        *value
53    }
54
55    fn ec_point_assert_eq(
56        &self,
57        annotation: &str,
58        lhs: &Self::LoadedEcPoint,
59        rhs: &Self::LoadedEcPoint,
60    ) {
61        lhs.eq(rhs)
62            .then_some(())
63            .unwrap_or_else(|| panic!("{:?}", Error::AssertionFailure(annotation.to_string())))
64    }
65
66    fn multi_scalar_multiplication(
67        pairs: &[(&<Self as ScalarLoader<C::Scalar>>::LoadedScalar, &C)],
68    ) -> C {
69        pairs
70            .iter()
71            .cloned()
72            .map(|(scalar, base)| *base * scalar)
73            .reduce(|acc, value| acc + value)
74            .expect("pairs should not be empty")
75            .to_affine()
76    }
77}
78
79impl<F: PrimeField> ScalarLoader<F> for NativeLoader {
80    type LoadedScalar = F;
81
82    fn load_const(&self, value: &F) -> Self::LoadedScalar {
83        *value
84    }
85
86    fn assert_eq(&self, annotation: &str, lhs: &Self::LoadedScalar, rhs: &Self::LoadedScalar) {
87        lhs.eq(rhs)
88            .then_some(())
89            .unwrap_or_else(|| panic!("{:?}", Error::AssertionFailure(annotation.to_string())))
90    }
91}
92
93impl<C: CurveAffine> Loader<C> for NativeLoader {}