use core::borrow::Borrow;
use snarkvm_curves::PairingEngine;
use snarkvm_gadgets::traits::{alloc::AllocGadget, curves::PairingGadget};
use snarkvm_r1cs::{ConstraintSystem, SynthesisError};
use crate::{sonic_pc::PreparedCommitment, Vec};
pub struct PreparedCommitmentVar<
TargetCurve: PairingEngine,
BaseCurve: PairingEngine,
PG: PairingGadget<TargetCurve, <BaseCurve as PairingEngine>::Fr>,
> {
pub prepared_comm: Vec<PG::G1Gadget>,
}
impl<TargetCurve, BaseCurve, PG> Clone for PreparedCommitmentVar<TargetCurve, BaseCurve, PG>
where
TargetCurve: PairingEngine,
BaseCurve: PairingEngine,
PG: PairingGadget<TargetCurve, <BaseCurve as PairingEngine>::Fr>,
{
fn clone(&self) -> Self {
Self {
prepared_comm: self.prepared_comm.clone(),
}
}
}
impl<TargetCurve, BaseCurve, PG> AllocGadget<PreparedCommitment<TargetCurve>, <BaseCurve as PairingEngine>::Fr>
for PreparedCommitmentVar<TargetCurve, BaseCurve, PG>
where
TargetCurve: PairingEngine,
BaseCurve: PairingEngine,
PG: PairingGadget<TargetCurve, <BaseCurve as PairingEngine>::Fr>,
{
fn alloc_constant<
Fn: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<PreparedCommitment<TargetCurve>>,
CS: ConstraintSystem<<BaseCurve as PairingEngine>::Fr>,
>(
mut cs: CS,
value_gen: Fn,
) -> Result<Self, SynthesisError> {
let obj = value_gen()?.borrow().clone();
let mut prepared_comm = Vec::<PG::G1Gadget>::new();
for (i, comm_elem) in obj.0.iter().enumerate() {
prepared_comm.push(<PG::G1Gadget as AllocGadget<
<TargetCurve as PairingEngine>::G1Projective,
<BaseCurve as PairingEngine>::Fr,
>>::alloc_constant(
cs.ns(|| format!("comm_elem_{}", i)),
|| {
Ok(<<TargetCurve as PairingEngine>::G1Projective as From<
<TargetCurve as PairingEngine>::G1Affine,
>>::from(*comm_elem))
},
)?);
}
Ok(Self { prepared_comm })
}
fn alloc<
Fn: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<PreparedCommitment<TargetCurve>>,
CS: ConstraintSystem<<BaseCurve as PairingEngine>::Fr>,
>(
mut cs: CS,
value_gen: Fn,
) -> Result<Self, SynthesisError> {
let obj = value_gen()?.borrow().clone();
let mut prepared_comm = Vec::<PG::G1Gadget>::new();
for (i, comm_elem) in obj.0.iter().enumerate() {
prepared_comm.push(<PG::G1Gadget as AllocGadget<
<TargetCurve as PairingEngine>::G1Projective,
<BaseCurve as PairingEngine>::Fr,
>>::alloc(cs.ns(|| format!("comm_elem_{}", i)), || {
Ok(<<TargetCurve as PairingEngine>::G1Projective as From<
<TargetCurve as PairingEngine>::G1Affine,
>>::from(*comm_elem))
})?);
}
Ok(Self { prepared_comm })
}
fn alloc_input<
Fn: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<PreparedCommitment<TargetCurve>>,
CS: ConstraintSystem<<BaseCurve as PairingEngine>::Fr>,
>(
mut cs: CS,
value_gen: Fn,
) -> Result<Self, SynthesisError> {
let obj = value_gen()?.borrow().clone();
let mut prepared_comm = Vec::<PG::G1Gadget>::new();
for (i, comm_elem) in obj.0.iter().enumerate() {
prepared_comm.push(<PG::G1Gadget as AllocGadget<
<TargetCurve as PairingEngine>::G1Projective,
<BaseCurve as PairingEngine>::Fr,
>>::alloc_input(
cs.ns(|| format!("comm_elem_{}", i)),
|| {
Ok(<<TargetCurve as PairingEngine>::G1Projective as From<
<TargetCurve as PairingEngine>::G1Affine,
>>::from(*comm_elem))
},
)?);
}
Ok(Self { prepared_comm })
}
}