ark_r1cs_std/groups/
mod.rsuse crate::{
convert::{ToBitsGadget, ToBytesGadget, ToConstraintFieldGadget},
fields::emulated_fp::EmulatedFpVar,
prelude::*,
};
use ark_ff::PrimeField;
use ark_relations::r1cs::{Namespace, SynthesisError};
use core::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign};
use ark_ec::CurveGroup;
use core::{borrow::Borrow, fmt::Debug};
pub mod curves;
pub use self::curves::short_weierstrass::{bls12, mnt4, mnt6};
pub trait GroupOpsBounds<'a, G, T: 'a>:
Sized
+ Add<&'a T, Output = T>
+ Sub<&'a T, Output = T>
+ Add<T, Output = T>
+ Sub<T, Output = T>
+ Add<G, Output = T>
+ Sub<G, Output = T>
{
}
pub trait CurveVar<C: CurveGroup, ConstraintF: PrimeField>:
'static
+ Sized
+ Clone
+ Debug
+ R1CSVar<ConstraintF, Value = C>
+ ToBitsGadget<ConstraintF>
+ ToBytesGadget<ConstraintF>
+ EqGadget<ConstraintF>
+ CondSelectGadget<ConstraintF>
+ AllocVar<C, ConstraintF>
+ AllocVar<C::Affine, ConstraintF>
+ ToConstraintFieldGadget<ConstraintF>
+ for<'a> GroupOpsBounds<'a, C, Self>
+ for<'a> AddAssign<&'a Self>
+ for<'a> SubAssign<&'a Self>
+ AddAssign<C>
+ SubAssign<C>
+ AddAssign<Self>
+ SubAssign<Self>
+ Mul<EmulatedFpVar<C::ScalarField, ConstraintF>, Output = Self>
+ for<'a> Mul<&'a EmulatedFpVar<C::ScalarField, ConstraintF>, Output = Self>
+ MulAssign<EmulatedFpVar<C::ScalarField, ConstraintF>>
{
fn zero() -> Self;
#[tracing::instrument(target = "r1cs")]
fn is_zero(&self) -> Result<Boolean<ConstraintF>, SynthesisError> {
self.is_eq(&Self::zero())
}
fn constant(other: C) -> Self;
fn new_variable_omit_prime_order_check(
cs: impl Into<Namespace<ConstraintF>>,
f: impl FnOnce() -> Result<C, SynthesisError>,
mode: AllocationMode,
) -> Result<Self, SynthesisError>;
fn enforce_prime_order(&self) -> Result<(), SynthesisError>;
#[tracing::instrument(target = "r1cs")]
fn double(&self) -> Result<Self, SynthesisError> {
let mut result = self.clone();
result.double_in_place()?;
Ok(result)
}
fn double_in_place(&mut self) -> Result<(), SynthesisError>;
fn negate(&self) -> Result<Self, SynthesisError>;
#[tracing::instrument(target = "r1cs", skip(bits))]
fn scalar_mul_le<'a>(
&self,
bits: impl Iterator<Item = &'a Boolean<ConstraintF>>,
) -> Result<Self, SynthesisError> {
let mut res = Self::zero();
let mut multiple = self.clone();
for bit in bits {
let tmp = res.clone() + &multiple;
res = bit.select(&tmp, &res)?;
multiple.double_in_place()?;
}
Ok(res)
}
#[tracing::instrument(target = "r1cs", skip(scalar_bits_with_bases))]
fn precomputed_base_scalar_mul_le<'a, I, B>(
&mut self,
scalar_bits_with_bases: I,
) -> Result<(), SynthesisError>
where
I: Iterator<Item = (B, &'a C)>,
B: Borrow<Boolean<ConstraintF>>,
C: 'a,
{
let mut result = Self::zero();
for (bit, base) in scalar_bits_with_bases {
let self_plus_base = result.clone() + *base;
result = bit.borrow().select(&self_plus_base, &result)?;
}
*self += result;
Ok(())
}
#[tracing::instrument(target = "r1cs", skip(bases, scalars))]
fn precomputed_base_multiscalar_mul_le<'a, T, I, B>(
bases: &[B],
scalars: I,
) -> Result<Self, SynthesisError>
where
T: 'a + ToBitsGadget<ConstraintF> + ?Sized,
I: Iterator<Item = &'a T>,
B: Borrow<[C]>,
{
let mut result = Self::zero();
for (bits, bases) in scalars.zip(bases) {
let bases = bases.borrow();
let bits = bits.to_bits_le()?;
result.precomputed_base_scalar_mul_le(bits.iter().zip(bases))?;
}
Ok(result)
}
}