2021-02-17 05:13:25 -08:00
|
|
|
use super::circuit::{Any, Column};
|
2020-11-30 18:09:03 -08:00
|
|
|
use crate::{
|
|
|
|
arithmetic::CurveAffine,
|
2021-09-30 15:05:15 -07:00
|
|
|
helpers::CurveRead,
|
2020-11-30 18:09:03 -08:00
|
|
|
poly::{Coeff, ExtendedLagrangeCoeff, LagrangeCoeff, Polynomial},
|
|
|
|
};
|
2020-11-24 16:49:52 -08:00
|
|
|
|
2020-11-30 18:09:03 -08:00
|
|
|
pub(crate) mod keygen;
|
2021-01-20 05:47:55 -08:00
|
|
|
pub(crate) mod prover;
|
|
|
|
pub(crate) mod verifier;
|
2020-11-24 16:49:52 -08:00
|
|
|
|
2021-01-12 07:28:35 -08:00
|
|
|
use std::io;
|
|
|
|
|
2020-11-30 18:09:03 -08:00
|
|
|
/// A permutation argument.
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub(crate) struct Argument {
|
|
|
|
/// A sequence of columns involved in the argument.
|
2021-02-17 05:13:25 -08:00
|
|
|
columns: Vec<Column<Any>>,
|
2020-11-30 18:09:03 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Argument {
|
2021-07-02 15:20:36 -07:00
|
|
|
pub(crate) fn new() -> Self {
|
|
|
|
Argument { columns: vec![] }
|
2020-11-30 18:09:03 -08:00
|
|
|
}
|
|
|
|
|
2021-07-10 06:52:42 -07:00
|
|
|
/// Returns the minimum circuit degree required by the permutation argument.
|
|
|
|
/// The argument may use larger degree gates depending on the actual
|
|
|
|
/// circuit's degree and how many columns are involved in the permutation.
|
2020-11-30 18:09:03 -08:00
|
|
|
pub(crate) fn required_degree(&self) -> usize {
|
2020-12-22 07:54:41 -08:00
|
|
|
// degree 2:
|
|
|
|
// l_0(X) * (1 - z(X)) = 0
|
|
|
|
//
|
2021-07-02 15:20:36 -07:00
|
|
|
// We will fit as many polynomials p_i(X) as possible
|
|
|
|
// into the required degree of the circuit, so the
|
|
|
|
// following will not affect the required degree of
|
|
|
|
// this middleware.
|
|
|
|
//
|
2021-07-13 15:30:52 -07:00
|
|
|
// (1 - (l_last(X) + l_blind(X))) * (
|
2021-07-02 15:20:36 -07:00
|
|
|
// z(\omega X) \prod (p(X) + \beta s_i(X) + \gamma)
|
2021-03-04 09:34:56 -08:00
|
|
|
// - z(X) \prod (p(X) + \delta^i \beta X + \gamma)
|
2021-07-02 15:20:36 -07:00
|
|
|
// )
|
|
|
|
//
|
|
|
|
// On the first sets of columns, except the first
|
2021-07-14 08:46:29 -07:00
|
|
|
// set, we will do
|
2021-07-02 15:20:36 -07:00
|
|
|
//
|
|
|
|
// l_0(X) * (z(X) - z'(\omega^(last) X)) = 0
|
|
|
|
//
|
2021-07-14 08:46:29 -07:00
|
|
|
// where z'(X) is the permutation for the previous set
|
2021-07-02 15:20:36 -07:00
|
|
|
// of columns.
|
|
|
|
//
|
|
|
|
// On the final set of columns, we will do
|
|
|
|
//
|
|
|
|
// degree 3:
|
|
|
|
// l_last(X) * (z'(X)^2 - z'(X)) = 0
|
|
|
|
//
|
|
|
|
// which will allow the last value to be zero to
|
|
|
|
// ensure the argument is perfectly complete.
|
|
|
|
|
|
|
|
// There are constraints of degree 3 regardless of the
|
|
|
|
// number of columns involved.
|
|
|
|
3
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn add_column(&mut self, column: Column<Any>) {
|
|
|
|
if !self.columns.contains(&column) {
|
|
|
|
self.columns.push(column);
|
|
|
|
}
|
2020-11-30 18:09:03 -08:00
|
|
|
}
|
2020-12-21 21:56:30 -08:00
|
|
|
|
2021-02-17 05:13:25 -08:00
|
|
|
pub(crate) fn get_columns(&self) -> Vec<Column<Any>> {
|
2020-12-21 21:56:30 -08:00
|
|
|
self.columns.clone()
|
|
|
|
}
|
2020-11-30 18:09:03 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// The verifying key for a single permutation argument.
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub(crate) struct VerifyingKey<C: CurveAffine> {
|
|
|
|
commitments: Vec<C>,
|
|
|
|
}
|
|
|
|
|
2021-01-12 07:28:35 -08:00
|
|
|
impl<C: CurveAffine> VerifyingKey<C> {
|
|
|
|
pub(crate) fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
|
|
|
|
for commitment in &self.commitments {
|
2021-09-30 15:05:15 -07:00
|
|
|
writer.write_all(commitment.to_bytes().as_ref())?;
|
2021-01-12 07:28:35 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn read<R: io::Read>(reader: &mut R, argument: &Argument) -> io::Result<Self> {
|
2021-01-21 15:40:25 -08:00
|
|
|
let commitments = (0..argument.columns.len())
|
|
|
|
.map(|_| C::read(reader))
|
|
|
|
.collect::<Result<Vec<_>, _>>()?;
|
2021-01-12 07:28:35 -08:00
|
|
|
Ok(VerifyingKey { commitments })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-30 18:09:03 -08:00
|
|
|
/// The proving key for a single permutation argument.
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub(crate) struct ProvingKey<C: CurveAffine> {
|
|
|
|
permutations: Vec<Polynomial<C::Scalar, LagrangeCoeff>>,
|
|
|
|
polys: Vec<Polynomial<C::Scalar, Coeff>>,
|
|
|
|
cosets: Vec<Polynomial<C::Scalar, ExtendedLagrangeCoeff>>,
|
|
|
|
}
|