Skip to content
This repository has been archived by the owner on Oct 11, 2024. It is now read-only.

Autogen Bug Fixes to Rust Code #706

Merged
merged 14 commits into from
Jun 8, 2020
75 changes: 75 additions & 0 deletions crypto/stark/examples/claim_polynomial.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use zkp_macros_decl::field_element;
use zkp_primefield::FieldElement;
use zkp_stark::{
generate, proof_serialize, prove, Constraints, DensePolynomial, Provable, RationalExpression,
TraceTable, Verifiable,
};
use zkp_u256::U256;

#[derive(Clone, Debug)]
struct Claim(FieldElement);

#[derive(Clone, Debug)]
struct Witness(FieldElement);

impl Verifiable for Claim {
fn constraints(&self) -> Constraints {
use RationalExpression::*;
Constraints::from_expressions((2, 1), self.0.as_montgomery().to_bytes_be().to_vec(), vec![
(Trace(0, 0) - ClaimPolynomial(0, 0, Box::new(X))) / (X - 1),
])
.unwrap()
}
}

impl Provable<&Witness> for Claim {
fn trace(&self, witness: &Witness) -> TraceTable {
let mut trace = TraceTable::new(2, 1);
trace[(0, 0)] = witness.0.clone();
trace[(1, 0)] = witness.0.clone() + FieldElement::from(100);
trace
}
}

impl Claim {
fn concrete_system(&self) -> Constraints {
let claim_polynomials = vec![DensePolynomial::new(&[self.0.clone()])];
let expressions = self
.constraints()
.expressions()
.iter()
.map(|x| x.substitute_claim(&claim_polynomials))
.collect();

Constraints::from_expressions(
(2, 1),
self.0.as_montgomery().to_bytes_be().to_vec(),
expressions,
)
.unwrap()
}
}

fn main() {
let claim = Claim(field_element!("1325123410"));
let witness = Witness(claim.0.clone());

println!("claim: 0x{}", claim.0.as_montgomery());

let concrete_system = claim.concrete_system();
let trace = claim.trace(&witness);
let proof = prove(&concrete_system, &trace).unwrap();

let mut proof_string = "".to_string();
proof_serialize(&concrete_system, &proof, &mut proof_string).unwrap();
println!("{}", proof_string);

let system = claim.constraints();
let _ = generate(
system.trace_nrows(),
&system.expressions(),
system.trace_ncolumns(),
16,
"../stark-verifier-ethereum/contracts/claim_polynomial",
);
}
65 changes: 65 additions & 0 deletions crypto/stark/examples/constant.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use zkp_macros_decl::field_element;
use zkp_primefield::FieldElement;
use zkp_stark::{
generate, proof_serialize, prove, Constraints, Provable, RationalExpression, TraceTable,
Verifiable,
};
use zkp_u256::U256;

#[derive(Clone, Debug)]
struct Claim(FieldElement);

#[derive(Clone, Debug)]
struct Witness(FieldElement);

impl Verifiable for Claim {
fn constraints(&self) -> Constraints {
use RationalExpression::*;
Constraints::from_expressions((2, 1), self.0.as_montgomery().to_bytes_be().to_vec(), vec![
(Trace(0, 0) - Constant(self.0.clone())) / (X - 1),
])
.unwrap()
}
}

impl Provable<&Witness> for Claim {
fn trace(&self, witness: &Witness) -> TraceTable {
let mut trace = TraceTable::new(2, 1);
trace[(0, 0)] = witness.0.clone();
trace[(1, 0)] = witness.0.clone() + FieldElement::from(100);
trace
}
}

fn main() {
let claim = Claim(field_element!("1325123410"));
let witness = Witness(claim.0.clone());

let mut constraints = claim.constraints();
constraints.num_queries = 2;
constraints.pow_bits = 10;

let trace = claim.trace(&witness);

println!("claim: 0x{}", claim.0.as_montgomery());

let mut proof_string = "".to_string();
proof_serialize(
&constraints,
&prove(&constraints, &trace).unwrap(),
&mut proof_string,
)
.unwrap();
println!("{}", proof_string);

let system = claim.constraints();

let _ = generate(
system.trace_nrows(),
// &[&Constant(claim.0.clone())],
&system.expressions(),
system.trace_ncolumns(),
16,
"../stark-verifier-ethereum/contracts/constant",
);
}
33 changes: 32 additions & 1 deletion crypto/stark/src/constraints.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::rational_expression::RationalExpression;
use crate::{polynomial::DensePolynomial, rational_expression::RationalExpression};
use itertools::Itertools;
use std::{collections::BTreeSet, fmt, prelude::v1::*};
use zkp_primefield::{FieldElement, Root};
Expand Down Expand Up @@ -60,6 +60,13 @@ pub struct Constraints {
/// After `fri_layout.sum()` reductions are done, the remaining polynomial
/// is written explicitly in coefficient form.
pub fri_layout: Vec<usize>,

/// To make autogeneration easier we have included a 'ClaimPolynomial'
/// these claim polynomials need to be taken out of the expressions before
/// they can be evaluated
/// The following Vec of dense polys can be used to substitute claim
/// polynomials inside of the prover.
pub claim_polynomials: Vec<DensePolynomial>,
}

impl Constraints {
Expand Down Expand Up @@ -111,6 +118,7 @@ impl Constraints {
pow_bits: 0,
num_queries: 45,
fri_layout: Self::default_fri_layout(trace_nrows),
claim_polynomials: vec![],
})
}

Expand Down Expand Up @@ -160,6 +168,7 @@ impl Constraints {
Some(x) => x,
None => Self::default_fri_layout(trace_nrows),
},
claim_polynomials: vec![],
})
}

Expand Down Expand Up @@ -264,6 +273,28 @@ impl Constraints {
.into_iter()
.collect()
}

// This sets a the claim polynomials field
// Note that since we didn't want to change the interface this is the
// only way to set or change the field
pub fn add_claim_polynomials(&mut self, polys: Vec<DensePolynomial>) {
self.claim_polynomials = polys;
}

// This function if called on a set of constraints which has both
// Rational Expression claim polynomials in the constraints
// and has set a claim_polynomials constraint field, will use the
// claim_polynomials constraint field to substitute out the
// Rational Expression claim polynomials
pub fn substitute(&mut self) {
if !self.claim_polynomials.is_empty() {
self.expressions = self
.expressions
.iter()
.map(|x| x.substitute_claim(&self.claim_polynomials))
.collect();
}
}
}

#[cfg(test)]
Expand Down
33 changes: 26 additions & 7 deletions crypto/stark/src/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,10 @@ impl VectorCommitment for FriLeaves {
// TODO: Split up
#[allow(clippy::too_many_lines)]
pub fn prove(constraints: &Constraints, trace: &TraceTable) -> Result<Proof> {
// This hack allows us to avoid changing the interface to mut for the
// claim polynomials but is ugly and should be removed.
let original_constraints = constraints.clone();
let mut constraints = constraints.clone();
// TODO: Verify input
// * Constraint trace length matches trace table length
// * Fri layout is less than trace length * blowup
Expand Down Expand Up @@ -405,7 +409,7 @@ pub fn prove(constraints: &Constraints, trace: &TraceTable) -> Result<Proof> {
info!("Compute constraint polynomials.");
let constraint_polynomials = get_constraint_polynomials(
&tree.leaves(),
&constraints,
&mut constraints,
&constraint_coefficients,
trace.num_rows(),
);
Expand Down Expand Up @@ -501,7 +505,7 @@ pub fn prove(constraints: &Constraints, trace: &TraceTable) -> Result<Proof> {
info!("Verify proof.");
// TODO: Rename channel / transcript object
let proof = Proof::from_bytes(proof.proof);
verify(constraints, &proof)?;
verify(&original_constraints, &proof)?;

trace!("END Stark proof");
Ok(proof)
Expand Down Expand Up @@ -541,7 +545,7 @@ fn get_indices(num: usize, bits: u32, proof: &mut ProverChannel) -> Vec<usize> {

fn get_constraint_polynomials(
trace_lde: &PolyLDE,
constraints: &Constraints,
constraints: &mut Constraints,
constraint_coefficients: &[FieldElement],
trace_length: usize,
) -> Vec<DensePolynomial> {
Expand All @@ -561,7 +565,16 @@ fn get_constraint_polynomials(
let trace_coset = extract_trace_coset(trace_lde, coset_size);

info!("Combine rational expressions");
let combined_constraints = constraints.combine(constraint_coefficients);
let mut combined_constraints = constraints.combine(constraint_coefficients);
// At this point the constraint's have had degrees assigned which
// match those where the claim polynomials aren't specified.
// TODO - This substitution lowers overall security and should be validated.
// TODO - Of particular concern is that by manipulating the degree of the
// claimed interpolating polynomial of the modifications modifications can
// unchecked in the proof.
combined_constraints = combined_constraints.substitute_claim(&constraints.claim_polynomials);
constraints.substitute();

let mut dag = AlgebraicGraph::new(
&FieldElement::generator(),
trace_coset.num_rows(),
Expand Down Expand Up @@ -642,6 +655,7 @@ fn oods_combine(
// Fetch the oods sampling point
let trace_length = trace_polynomials[0].len();
let oods_point: FieldElement = proof.get_random();
dbg!(oods_point.clone());
let g = FieldElement::root(trace_length).expect("No root for trace polynomial length.");

// Write point evaluations to proof
Expand All @@ -652,9 +666,14 @@ fn oods_combine(
}

let oods_point_pow = oods_point.pow(constraint_polynomials.len());
for constraint_polynomial in constraint_polynomials {
proof.write(&constraint_polynomial.evaluate(&oods_point_pow));
let mut oods_value = FieldElement::zero();
for (i, constraint_polynomial) in constraint_polynomials.iter().enumerate() {
let value = constraint_polynomial.evaluate(&oods_point_pow);
proof.write(&value);
// dbg!(oods_value);
oods_value += oods_point.pow(i) * value;
}
dbg!(oods_value);

// Divide out points and linear sum the polynomials
// OPT: Parallelization
Expand Down Expand Up @@ -1047,7 +1066,7 @@ mod tests {

let constraint_polynomials = get_constraint_polynomials(
&tree.leaves(),
&constraints,
&mut constraints,
&constraint_coefficients,
trace.num_rows(),
);
Expand Down
19 changes: 13 additions & 6 deletions crypto/stark/src/rational_expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,10 @@ impl RationalExpression {
X => x.clone(),
Constant(c) => c.clone(),
&Trace(i, j) => trace(i, j),
Polynomial(p, a) => p.evaluate(&a.evaluate(x, trace)),
Polynomial(p, a) => {
let inner = a.evaluate(x, trace);
p.evaluate(&inner)
}
ClaimPolynomial(..) => panic!("ClaimPolynomial should be substituted by Polynomial"),
Add(a, b) => a.evaluate(x, trace) + b.evaluate(x, trace),
Neg(a) => -&a.evaluate(x, trace),
Expand Down Expand Up @@ -343,14 +346,13 @@ impl Hash for RationalExpression {
i.hash(state);
j.hash(state);
}
Polynomial(p, _) => {
Polynomial(..) => {
"poly".hash(state);
let x = field_element!(
"754ed488ec9208d1c552bb254c0890042078a9e1f7e36072ebff1bf4e193d11b"
);
// Note - We don't hash in the a because we can deploy the same contract for
// identical dense poly, for true equality we need to hash a into it.
(p.evaluate(&x)).hash(state);
(self.evaluate(&x, &|_, _| panic!("Trace in polynomial not supported")))
.hash(state);
}
Add(a, b) => {
"add".hash(state);
Expand All @@ -375,7 +377,12 @@ impl Hash for RationalExpression {
a.hash(state);
e.hash(state);
}
ClaimPolynomial(..) => panic!("ClaimPolynomial should be substituted by Polynomial"),
ClaimPolynomial(i, n, a) => {
"claim_polynomial".hash(state);
i.hash(state);
n.hash(state);
a.hash(state);
}
}
}
}
Expand Down
18 changes: 5 additions & 13 deletions crypto/stark/src/solidity_seralizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,11 @@ pub fn proof_serialize(
// Get the oods information from the proof and random
let _: FieldElement = channel.get_random();

let trace_arguments = constraints.trace_arguments();
// This hack around claim polynomials is awful and should be removed
let mut parseable_constraints = constraints.clone();
parseable_constraints.substitute();

let trace_arguments = parseable_constraints.trace_arguments();
let trace_values: Vec<FieldElement> = channel.replay_many(trace_arguments.len());
result_string.push_str(&format!(
"\"trace_oods_values\": {}, \n",
Expand Down Expand Up @@ -278,27 +282,15 @@ mod tests {
constraints.num_queries = 20;
constraints.pow_bits = 10;

// autogen(
// constraints.trace_nrows(),
// &[&RationalExpression::Constant(150.into()),
// &RationalExpression::Constant((&public).value.clone())],
// constraints.expressions(),
// constraints.trace_nrows(),
// 16
// ).unwrap();

let trace = public.trace(&private);

let mut result_string = "".to_string();
// &prove(&constraints, &trace).unwrap();
proof_serialize(
&constraints,
&prove(&constraints, &trace).unwrap(),
&mut result_string,
)
.unwrap();
// println!("{}", result_string);
// assert!(false);
}

// Note this test is actually more like a binary which we want run so it
Expand Down
Loading