pasta_curves-source/src/plonk/srs.rs

152 lines
4.7 KiB
Rust
Raw Normal View History

2020-08-22 20:15:39 +00:00
use super::{
circuit::{AdviceWire, Circuit, ConstraintSystem, FixedWire, MetaCircuit, Variable, Wire},
2020-08-22 20:15:39 +00:00
domain::EvaluationDomain,
Error, GATE_DEGREE, SRS,
};
use crate::arithmetic::{Curve, CurveAffine, Field};
use crate::polycommit::Params;
impl<C: CurveAffine> SRS<C> {
/// This generates a structured reference string for the provided `circuit`
/// and `params`.
pub fn generate<ConcreteCircuit: Circuit<C::Scalar>>(
params: &Params<C>,
circuit: &ConcreteCircuit,
) -> Result<Self, Error> {
struct Assembly<F: Field> {
sa: Vec<F>,
sb: Vec<F>,
sc: Vec<F>,
sd: Vec<F>,
sm: Vec<F>,
fixed: Vec<Vec<F>>,
2020-08-22 20:15:39 +00:00
}
impl<F: Field> ConstraintSystem<F> for Assembly<F> {
fn assign_advice(
&mut self,
_: AdviceWire,
_: usize,
_: impl FnOnce() -> Result<F, Error>,
) -> Result<(), Error> {
// We only care about fixed wires here
Ok(())
}
fn assign_fixed(
&mut self,
wire: FixedWire,
row: usize,
to: impl FnOnce() -> Result<F, Error>,
) -> Result<(), Error> {
*self
.fixed
.get_mut(wire.0)
.and_then(|v| v.get_mut(row))
.ok_or(Error::BoundsFailure)? = to()?;
Ok(())
}
2020-08-22 20:15:39 +00:00
fn create_gate(
&mut self,
sa: F,
sb: F,
sc: F,
sd: F,
sm: F,
_: impl Fn() -> Result<(F, F, F, F), Error>,
2020-08-22 21:15:39 +00:00
) -> Result<(Variable, Variable, Variable, Variable), Error> {
2020-08-22 20:15:39 +00:00
let tmp = Ok((
2020-08-22 21:15:39 +00:00
Variable(Wire::A, self.sa.len()),
Variable(Wire::B, self.sa.len()),
Variable(Wire::C, self.sa.len()),
Variable(Wire::D, self.sa.len()),
2020-08-22 20:15:39 +00:00
));
self.sa.push(sa);
self.sb.push(sb);
self.sc.push(sc);
self.sd.push(sd);
self.sm.push(sm);
tmp
}
}
let mut meta = MetaCircuit::default();
let config = ConcreteCircuit::configure(&mut meta);
2020-08-22 20:15:39 +00:00
let mut assembly: Assembly<C::Scalar> = Assembly {
sa: vec![],
sb: vec![],
sc: vec![],
sd: vec![],
sm: vec![],
fixed: vec![vec![C::Scalar::zero(); params.n as usize]; meta.num_fixed_wires],
2020-08-22 20:15:39 +00:00
};
// Synthesize the circuit to obtain SRS
2020-08-22 21:09:47 +00:00
circuit.synthesize(&mut assembly, config)?;
2020-08-22 20:15:39 +00:00
assembly.sa.resize(params.n as usize, C::Scalar::zero());
assembly.sb.resize(params.n as usize, C::Scalar::zero());
assembly.sc.resize(params.n as usize, C::Scalar::zero());
assembly.sd.resize(params.n as usize, C::Scalar::zero());
assembly.sm.resize(params.n as usize, C::Scalar::zero());
// Compute commitments to the fixed wire values
let sa_commitment = params
.commit_lagrange(&assembly.sa, C::Scalar::one())
.to_affine();
let sb_commitment = params
.commit_lagrange(&assembly.sb, C::Scalar::one())
.to_affine();
let sc_commitment = params
.commit_lagrange(&assembly.sc, C::Scalar::one())
.to_affine();
let sd_commitment = params
.commit_lagrange(&assembly.sd, C::Scalar::one())
.to_affine();
let sm_commitment = params
.commit_lagrange(&assembly.sm, C::Scalar::one())
.to_affine();
let fixed_commitments = assembly
.fixed
.iter()
.map(|poly| params.commit_lagrange(poly, C::Scalar::one()).to_affine())
.collect();
2020-08-22 20:15:39 +00:00
let domain = EvaluationDomain::new(GATE_DEGREE, params.k);
let sa = domain.obtain_coset(assembly.sa);
let sb = domain.obtain_coset(assembly.sb);
let sc = domain.obtain_coset(assembly.sc);
let sd = domain.obtain_coset(assembly.sd);
let sm = domain.obtain_coset(assembly.sm);
let fixed_polys = assembly
.fixed
.into_iter()
.map(|poly| domain.obtain_coset(poly))
.collect();
2020-08-22 20:15:39 +00:00
Ok(SRS {
sa,
sb,
sc,
sd,
sm,
sa_commitment,
sb_commitment,
sc_commitment,
sd_commitment,
sm_commitment,
domain,
fixed_commitments,
fixed_polys,
meta,
2020-08-22 20:15:39 +00:00
})
}
}