done as a principal part, now should add public API

This commit is contained in:
Alex Vlasov 2019-06-17 19:55:05 +03:00
parent fafa64749e
commit 2e53ffc97f
8 changed files with 67 additions and 118 deletions

@ -33,6 +33,8 @@ use crate::{
const MIMC_ROUNDS: usize = 322;
// const MIMC_ROUNDS: usize = 1000000;
fn mimc<E: Engine>(
mut xl: E::Fr,
mut xr: E::Fr,

@ -39,6 +39,7 @@ use std::marker::PhantomData;
pub struct RollingHashTranscript<H: Hasher> {
buffer: Vec<u8>,
last_finalized_value: Vec<u8>,
repeated_request_nonce: u32,
_marker: PhantomData<H>
}
@ -50,6 +51,7 @@ impl<H: Hasher> RollingHashTranscript<H> {
Self {
buffer: buffer,
last_finalized_value: vec![],
repeated_request_nonce: 0u32,
_marker: PhantomData
}
}
@ -86,6 +88,7 @@ impl<H:Hasher> TranscriptProtocol for RollingHashTranscript<H> {
fn commit_point<G: CurveAffine>(&mut self, point: &G) {
self.commit_bytes(b"point", point.into_uncompressed().as_ref());
// self.commit_bytes(b"point", point.into_compressed().as_ref());
self.repeated_request_nonce = 0u32;
}
fn commit_scalar<F: PrimeField>(&mut self, scalar: &F) {
@ -94,11 +97,12 @@ impl<H:Hasher> TranscriptProtocol for RollingHashTranscript<H> {
// scalar.into_repr().write_le(&mut v).unwrap();
self.commit_bytes(b"scalar", &v);
self.repeated_request_nonce = 0u32;
}
fn get_challenge_scalar<F: PrimeField>(&mut self) -> F {
use byteorder::ByteOrder;
let mut nonce = 0u32;
let mut nonce = self.repeated_request_nonce;
loop {
let mut nonce_bytes = vec![0u8; 4];
byteorder::BigEndian::write_u32(&mut nonce_bytes, nonce);
@ -108,6 +112,7 @@ impl<H:Hasher> TranscriptProtocol for RollingHashTranscript<H> {
if let Ok(result) = F::from_repr(repr) {
// println!("Got a challenge {} for nonce = {}", result, nonce);
self.repeated_request_nonce = nonce + 1u32;
return result;
}
if nonce == (0xffffffff as u32) {

@ -74,11 +74,13 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
circuit: &C,
inputs: &[(Proof<E>, SxyAdvice<E>)],
srs: &SRS<E>,
specialized_srs: &SpecializedSRS<E>,
_specialized_srs: &SpecializedSRS<E>,
n: usize,
q: usize,
) -> SuccinctAggregate<E>
{
use std::time::Instant;
let start = Instant::now();
// take few proofs that are to be evaluated at some y_i and make an aggregate from them
let mut transcript = Transcript::new(&[]);
let mut y_values: Vec<E::Fr> = Vec::with_capacity(inputs.len());
@ -148,10 +150,11 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
permutations,
w,
z,
&srs,
&specialized_srs
&srs,
);
println!("Succinct signature for s(z, Y) taken {:?}", start.elapsed());
// Let's open up C to every y.
fn compute_value<E: Engine>(y: &E::Fr, poly_positive: &[E::Fr], poly_negative: &[E::Fr]) -> E::Fr {
let mut value = E::Fr::zero();
@ -165,7 +168,6 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
value
}
use std::time::Instant;
let start = Instant::now();
// we still need to re-open previous commitments at the same new z
@ -190,7 +192,7 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
c_openings.push((opening, value));
}
println!("Evaluation of s(z, Y) taken {:?}", start.elapsed());
println!("Re-Evaluation and re-opening of s(z, Y) taken {:?}", start.elapsed());
// Okay, great. Now we need to open up each S at the same point z to the same value.
// Since we're opening up all the S's at the same point, we create a bunch of random

@ -31,12 +31,9 @@ pub struct GrandProductProof<E: Engine> {
#[derive(Clone)]
pub struct GrandProductSignature<E: Engine> {
pub a_commitments: Vec<E::G1Affine>,
pub b_commitments: Vec<E::G1Affine>,
pub c_commitments: Vec<(E::G1Affine, E::Fr)>,
pub t_commitment: E::G1Affine,
pub grand_product_openings: Vec<(E::Fr, E::G1Affine)>,
// pub a_zy: Vec<E::Fr>,
pub proof: GrandProductProof<E>,
pub wellformedness_signature: WellformednessSignature<E>,
}
@ -49,18 +46,8 @@ impl<E: Engine> GrandProductArgument<E> {
z: E::Fr,
srs: &SRS<E>,
) -> GrandProductSignature<E> {
let mut a_commitments = vec![];
let mut b_commitments = vec![];
let mut grand_product_challenges = vec![];
// TODO: Remove
for (a, b) in grand_products.iter() {
let (c_a, c_b) = GrandProductArgument::commit_for_individual_products(& a[..], & b[..], &srs);
a_commitments.push(c_a);
b_commitments.push(c_b);
}
for _ in 0..grand_products.len() {
let c = transcript.get_challenge_scalar();
grand_product_challenges.push(c);
@ -85,19 +72,6 @@ impl<E: Engine> GrandProductArgument<E> {
&srs
);
// sanity check
for (j, (a, b)) in a_commitments.iter()
.zip(b_commitments.iter())
.enumerate()
{
let a_corr = wellformedness_signature.commitments[2*j];
let b_corr = wellformedness_signature.commitments[2*j + 1];
assert!(a_corr == *a);
assert!(b_corr == *b);
}
let mut grand_product_argument = GrandProductArgument::new(grand_products);
let c_commitments = grand_product_argument.commit_to_individual_c_polynomials(&srs);
let t_commitment = grand_product_argument.commit_to_t_polynomial(&grand_product_challenges, y, &srs);
@ -106,8 +80,6 @@ impl<E: Engine> GrandProductArgument<E> {
let proof = grand_product_argument.make_argument(&a_zy, &grand_product_challenges, y, z, &srs);
GrandProductSignature {
a_commitments,
b_commitments,
c_commitments,
t_commitment,
grand_product_openings,

@ -412,7 +412,7 @@ impl<E: Engine> PermutationArgument<E> {
let proof = wellformed_argument.make_argument(wellformed_challenges.clone(), &srs);
let valid = WellformednessArgument::verify(n, &wellformed_challenges, &commitments, &proof, &srs);
// assert!(valid, "wellformedness argument must be valid");
assert!(valid, "wellformedness argument must be valid");
}
let mut grand_product_argument = GrandProductArgument::new(grand_products);
@ -590,7 +590,6 @@ impl<E: Engine> PermutationArgument<E> {
y: E::Fr,
z: E::Fr,
srs: &SRS<E>,
specialized_srs: &SpecializedSRS<E>,
) -> SignatureOfCorrectComputation<E> {
let mut argument = PermutationArgument::new(coefficients, permutations);
let commitments = argument.commit(y, &srs);
@ -599,61 +598,35 @@ impl<E: Engine> PermutationArgument<E> {
let mut s_commitments = vec![];
let mut s_prime_commitments = vec![];
let mut challenges = vec![];
let num_commitments = commitments.len();
for (s, s_prime) in commitments.into_iter() {
{
let mut transcript = Transcript::new(&[]);
transcript.commit_point(&s);
transcript.commit_point(&s_prime);
let challenge = transcript.get_challenge_scalar();
challenges.push(challenge);
}
transcript.commit_point(&s);
transcript.commit_point(&s_prime);
s_commitments.push(s);
s_prime_commitments.push(s_prime);
}
// get challenges for a full batch
for _ in 0..num_commitments {
let c: E::Fr = transcript.get_challenge_scalar();
challenges.push(c);
}
let z_prime = transcript.get_challenge_scalar();
let s_prime_commitments_opening = argument.open_commitments_to_s_prime(&challenges, y, z_prime, &srs);
let (proof, grand_product_signature, beta, gamma) = {
// TODO: create better way to get few distinct challenges from the transcript
let (proof, grand_product_signature, beta, gamma) = argument.make_argument_with_transcript(
let (proof, grand_product_signature) = {
let (proof, grand_product_signature) = argument.make_argument_with_transcript(
&mut transcript,
y,
z,
&srs
);
(proof, grand_product_signature, beta, gamma)
(proof, grand_product_signature)
};
// TODO: sanity check for now,
// later eliminate a and b commitments
for (j, (((a, b), s), s_prime)) in grand_product_signature.a_commitments.iter()
.zip(grand_product_signature.b_commitments.iter())
.zip(s_commitments.iter())
.zip(s_prime_commitments.iter())
.enumerate()
{
// Sj(P4j)β(P1j)γ
let mut lhs = s.into_projective();
lhs.add_assign(&specialized_srs.p_4[j].mul(beta.into_repr()));
lhs.add_assign(&specialized_srs.p_1.mul(gamma.into_repr()));
assert!(lhs.into_affine() == *a);
// Sj(P3j)β(P1j)γ
let mut rhs = s_prime.into_projective();
rhs.add_assign(&specialized_srs.p_3.mul(beta.into_repr()));
rhs.add_assign(&specialized_srs.p_1.mul(gamma.into_repr()));
assert!(rhs.into_affine() == *b);
}
SignatureOfCorrectComputation {
s_commitments,
s_prime_commitments,
@ -670,9 +643,18 @@ impl<E: Engine> PermutationArgument<E> {
y: E::Fr,
z: E::Fr,
srs: &SRS<E>
) -> (PermutationArgumentProof<E>, GrandProductSignature<E>, E::Fr, E::Fr) {
let beta: E::Fr = transcript.get_challenge_scalar();
let gamma: E::Fr = transcript.get_challenge_scalar();
) -> (PermutationArgumentProof<E>, GrandProductSignature<E>) {
// create random beta and gamma for every single permutation argument
let mut betas = vec![];
let mut gammas = vec![];
for _ in 0..self.permutations.len() {
let beta: E::Fr = transcript.get_challenge_scalar();
let gamma: E::Fr = transcript.get_challenge_scalar();
betas.push(beta);
gammas.push(gamma);
}
// Sj(P4j)β(P1j)γ is equal to the product of the coefficients of Sj(P3j)β(P1j)γ
// also open s = \sum self.permuted_coefficients(X, y) at z
@ -682,7 +664,6 @@ impl<E: Engine> PermutationArgument<E> {
let mut s_polynomial: Option<Vec<E::Fr>> = None;
// for c in self.permuted_at_y_coefficients.iter()
for c in self.inverse_permuted_at_y_coefficients.iter()
{
if s_polynomial.is_some() {
@ -721,11 +702,12 @@ impl<E: Engine> PermutationArgument<E> {
let mut grand_products = vec![];
// TODO: Check the validity!
for ((non_permuted, inv_permuted), permutation) in self.non_permuted_at_y_coefficients.into_iter()
for ((((non_permuted, inv_permuted), permutation), beta), gamma) in
self.non_permuted_at_y_coefficients.into_iter()
.zip(self.inverse_permuted_at_y_coefficients.into_iter())
.zip(self.permutations.into_iter())
// .zip(self.permuted_at_y_coefficients.into_iter())
.zip(betas.into_iter())
.zip(gammas.into_iter())
{
// in S combination at the place i there should be term coeff[sigma(i)] * Y^sigma(i), that we can take
@ -787,7 +769,7 @@ impl<E: Engine> PermutationArgument<E> {
s_zy: s_zy
};
(proof, grand_product_signature, beta, gamma)
(proof, grand_product_signature)
}
}

@ -475,11 +475,11 @@ impl<E: Engine> PermutationStructure<E> {
println!("Naive S contribution scaled = {}", s_contrib);
let specialized_srs = PermutationArgument::make_specialized_srs(
&non_permuted_coeffs,
&permutations,
&srs
);
// let specialized_srs = PermutationArgument::make_specialized_srs(
// &non_permuted_coeffs,
// &permutations,
// &srs
// );
let signature = PermutationArgument::make_signature(
non_permuted_coeffs,
@ -487,7 +487,6 @@ impl<E: Engine> PermutationStructure<E> {
y,
z,
&srs,
&specialized_srs
);
signature

@ -165,17 +165,15 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier
let mut challenges = vec![];
for (s, s_prime) in aggregate.signature.s_commitments.iter()
.zip(aggregate.signature.s_prime_commitments.iter()) {
{
let mut transcript = Transcript::new(&[]);
transcript.commit_point(s);
transcript.commit_point(s_prime);
let challenge = transcript.get_challenge_scalar();
challenges.push(challenge);
}
transcript.commit_point(s);
transcript.commit_point(s_prime);
}
for _ in 0..aggregate.signature.s_commitments.len() {
let challenge = transcript.get_challenge_scalar();
challenges.push(challenge);
}
let z_prime: E::Fr = transcript.get_challenge_scalar();
// we expect M permutation proofs, add them all into verification
@ -242,19 +240,29 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier
// for each of the grand product arguments create a corresponding commitment
// from already known elements
let beta: E::Fr = transcript.get_challenge_scalar();
let gamma: E::Fr = transcript.get_challenge_scalar();
let mut betas = vec![];
let mut gammas = vec![];
let mut a_commitments = vec![];
let mut b_commitments = vec![];
for _ in 0..aggregate.signature.s_commitments.len() {
let beta: E::Fr = transcript.get_challenge_scalar();
let gamma: E::Fr = transcript.get_challenge_scalar();
betas.push(beta);
gammas.push(gamma);
}
let mut wellformedness_argument_commitments = vec![];
use crate::pairing::CurveAffine;
use crate::pairing::ff::PrimeField;
for (j, (s, s_prime)) in aggregate.signature.s_commitments.iter()
for (j, (((s, s_prime), beta), gamma)) in aggregate.signature.s_commitments.iter()
.zip(aggregate.signature.s_prime_commitments.iter())
.zip(betas.iter())
.zip(gammas.iter())
.enumerate()
{
@ -272,12 +280,6 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier
b.add_assign(&self.s1_special_reference.p_1.mul(gamma.into_repr()));
let b = b.into_affine();
// let a_original = aggregate.signature.grand_product_signature.a_commitments[j];
// let b_original = aggregate.signature.grand_product_signature.b_commitments[j];
// assert!(a == a_original);
// assert!(b == b_original);
a_commitments.push(a);
b_commitments.push(b);
wellformedness_argument_commitments.push(a);

@ -22,7 +22,6 @@ pub struct WellformednessProof<E: Engine> {
#[derive(Clone)]
pub struct WellformednessSignature<E: Engine> {
pub commitments: Vec<E::G1Affine>,
pub proof: WellformednessProof<E>
}
@ -33,25 +32,11 @@ impl<E: Engine> WellformednessArgument<E> {
wellformed_challenges: Vec<E::Fr>,
srs: &SRS<E>
) -> WellformednessSignature<E> {
let j = all_polys.len();
let wellformed_argument = WellformednessArgument::new(all_polys);
// TODO: remove commitments
let commitments = wellformed_argument.commit(&srs);
// let mut wellformed_challenges = vec![];
// for c in commitments.iter() {
// transcript.commit_point(c);
// }
// // TODO
// for _ in 0..j {
// let challenge = transcript.get_challenge_scalar();
// wellformed_challenges.push(challenge);
// }
let proof = wellformed_argument.make_argument(wellformed_challenges, &srs);
WellformednessSignature {
commitments,
proof
}
}