mirror of
https://github.com/arnaucube/testudo.git
synced 2026-01-12 16:51:28 +01:00
fix transcript inconsistency
This commit is contained in:
6
.github/workflows/testudo.yml
vendored
6
.github/workflows/testudo.yml
vendored
@@ -21,8 +21,8 @@ jobs:
|
|||||||
run: rustup default nightly
|
run: rustup default nightly
|
||||||
- name: Install rustfmt Components
|
- name: Install rustfmt Components
|
||||||
run: rustup component add rustfmt
|
run: rustup component add rustfmt
|
||||||
- name: Install clippy
|
# - name: Install clippy
|
||||||
run: rustup component add clippy
|
# run: rustup component add clippy
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cargo build --verbose
|
run: cargo build --verbose
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
@@ -32,6 +32,6 @@ jobs:
|
|||||||
- name: Check Rustfmt Code Style
|
- name: Check Rustfmt Code Style
|
||||||
run: cargo fmt --all -- --check
|
run: cargo fmt --all -- --check
|
||||||
# cargo clippy uses cargo check which returns an error when asm is emitted
|
# cargo clippy uses cargo check which returns an error when asm is emitted
|
||||||
# we want to emit asm for ff operations so we avoid using clippy for now
|
# we want to emit asm for ark-ff operations so we avoid using clippy for # now
|
||||||
# - name: Check clippy warnings
|
# - name: Check clippy warnings
|
||||||
# run: cargo clippy --all-targets --all-features
|
# run: cargo clippy --all-targets --all-features
|
||||||
|
|||||||
@@ -255,6 +255,7 @@ pub struct R1CSVerificationCircuit {
|
|||||||
pub sc_phase2: SumcheckVerificationCircuit,
|
pub sc_phase2: SumcheckVerificationCircuit,
|
||||||
// The point on which the polynomial was evaluated by the prover.
|
// The point on which the polynomial was evaluated by the prover.
|
||||||
pub claimed_ry: Vec<Scalar>,
|
pub claimed_ry: Vec<Scalar>,
|
||||||
|
pub claimed_transcript_sat_state: Scalar,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl R1CSVerificationCircuit {
|
impl R1CSVerificationCircuit {
|
||||||
@@ -276,6 +277,7 @@ impl R1CSVerificationCircuit {
|
|||||||
polys: config.polys_sc2.clone(),
|
polys: config.polys_sc2.clone(),
|
||||||
},
|
},
|
||||||
claimed_ry: config.ry.clone(),
|
claimed_ry: config.ry.clone(),
|
||||||
|
claimed_transcript_sat_state: config.transcript_sat_state,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -386,13 +388,21 @@ impl ConstraintSynthesizer<Fr> for R1CSVerificationCircuit {
|
|||||||
|
|
||||||
let eval_A_r_var = FpVar::<Fr>::new_witness(cs.clone(), || Ok(eval_A_r))?;
|
let eval_A_r_var = FpVar::<Fr>::new_witness(cs.clone(), || Ok(eval_A_r))?;
|
||||||
let eval_B_r_var = FpVar::<Fr>::new_witness(cs.clone(), || Ok(eval_B_r))?;
|
let eval_B_r_var = FpVar::<Fr>::new_witness(cs.clone(), || Ok(eval_B_r))?;
|
||||||
let eval_C_r_var = FpVar::<Fr>::new_witness(cs, || Ok(eval_C_r))?;
|
let eval_C_r_var = FpVar::<Fr>::new_witness(cs.clone(), || Ok(eval_C_r))?;
|
||||||
|
|
||||||
let scalar_var = &r_A_var * &eval_A_r_var + &r_B_var * &eval_B_r_var + &r_C_var * &eval_C_r_var;
|
let scalar_var = &r_A_var * &eval_A_r_var + &r_B_var * &eval_B_r_var + &r_C_var * &eval_C_r_var;
|
||||||
|
|
||||||
let expected_claim_post_phase2_var = eval_Z_at_ry_var * scalar_var;
|
let expected_claim_post_phase2_var = eval_Z_at_ry_var * scalar_var;
|
||||||
claim_post_phase2_var.enforce_equal(&expected_claim_post_phase2_var)?;
|
claim_post_phase2_var.enforce_equal(&expected_claim_post_phase2_var)?;
|
||||||
|
|
||||||
|
let expected_transcript_state_var = transcript_var.challenge()?;
|
||||||
|
let claimed_transcript_state_var =
|
||||||
|
FpVar::<Fr>::new_input(cs, || Ok(self.claimed_transcript_sat_state))?;
|
||||||
|
|
||||||
|
// Ensure that the prover and verifier transcipt views are consistent at
|
||||||
|
// the end of the satisfiability proof.
|
||||||
|
expected_transcript_state_var.enforce_equal(&claimed_transcript_state_var)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -411,6 +421,7 @@ pub struct VerifierConfig {
|
|||||||
pub polys_sc1: Vec<UniPoly>,
|
pub polys_sc1: Vec<UniPoly>,
|
||||||
pub polys_sc2: Vec<UniPoly>,
|
pub polys_sc2: Vec<UniPoly>,
|
||||||
pub ry: Vec<Scalar>,
|
pub ry: Vec<Scalar>,
|
||||||
|
pub transcript_sat_state: Scalar,
|
||||||
}
|
}
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct VerifierCircuit {
|
pub struct VerifierCircuit {
|
||||||
@@ -420,6 +431,7 @@ pub struct VerifierCircuit {
|
|||||||
pub eval_vars_at_ry: Fr,
|
pub eval_vars_at_ry: Fr,
|
||||||
pub claims_phase2: (Fr, Fr, Fr, Fr),
|
pub claims_phase2: (Fr, Fr, Fr, Fr),
|
||||||
pub ry: Vec<Fr>,
|
pub ry: Vec<Fr>,
|
||||||
|
pub transcript_sat_state: Scalar,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VerifierCircuit {
|
impl VerifierCircuit {
|
||||||
@@ -438,6 +450,7 @@ impl VerifierCircuit {
|
|||||||
eval_vars_at_ry: config.eval_vars_at_ry,
|
eval_vars_at_ry: config.eval_vars_at_ry,
|
||||||
claims_phase2: config.claims_phase2,
|
claims_phase2: config.claims_phase2,
|
||||||
ry: config.ry.clone(),
|
ry: config.ry.clone(),
|
||||||
|
transcript_sat_state: config.transcript_sat_state,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -449,7 +462,8 @@ impl ConstraintSynthesizer<Fq> for VerifierCircuit {
|
|||||||
let mut pubs = vec![];
|
let mut pubs = vec![];
|
||||||
pubs.extend(self.ry);
|
pubs.extend(self.ry);
|
||||||
pubs.extend(vec![v_A, v_B, v_C, v_AB]);
|
pubs.extend(vec![v_A, v_B, v_C, v_AB]);
|
||||||
pubs.extend(vec![self.eval_vars_at_ry]);
|
pubs.extend(vec![self.eval_vars_at_ry, self.transcript_sat_state]);
|
||||||
|
|
||||||
let bits = pubs
|
let bits = pubs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|c| {
|
.map(|c| {
|
||||||
|
|||||||
35
src/lib.rs
35
src/lib.rs
@@ -42,6 +42,7 @@ mod constraints;
|
|||||||
pub mod poseidon_transcript;
|
pub mod poseidon_transcript;
|
||||||
|
|
||||||
use ark_ff::Field;
|
use ark_ff::Field;
|
||||||
|
use ark_relations::r1cs;
|
||||||
use ark_serialize::*;
|
use ark_serialize::*;
|
||||||
use ark_std::Zero;
|
use ark_std::Zero;
|
||||||
use core::cmp::max;
|
use core::cmp::max;
|
||||||
@@ -400,6 +401,13 @@ impl SNARK {
|
|||||||
(proof, rx, ry)
|
(proof, rx, ry)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// We need to reset the transcript state before starting the evaluation
|
||||||
|
// proof and share this state with the verifier because, on the verifier's
|
||||||
|
// side all the previous updates are done on the transcript
|
||||||
|
// circuit variable and the transcript outside the circuit will be
|
||||||
|
// inconsistent wrt to the prover's.
|
||||||
|
transcript.new_from_state(&r1cs_sat_proof.transcript_sat_state);
|
||||||
|
|
||||||
// We send evaluations of A, B, C at r = (rx, ry) as claims
|
// We send evaluations of A, B, C at r = (rx, ry) as claims
|
||||||
// to enable the verifier complete the first sum-check
|
// to enable the verifier complete the first sum-check
|
||||||
let timer_eval = Timer::new("eval_sparse_polys");
|
let timer_eval = Timer::new("eval_sparse_polys");
|
||||||
@@ -466,24 +474,27 @@ impl SNARK {
|
|||||||
)?;
|
)?;
|
||||||
timer_sat_proof.stop();
|
timer_sat_proof.stop();
|
||||||
|
|
||||||
// let timer_eval_proof = Timer::new("verify_eval_proof");
|
let timer_eval_proof = Timer::new("verify_eval_proof");
|
||||||
|
// Reset the transcript using the state sent by the prover.
|
||||||
|
// TODO: find a way to retrieve this state from the circuit. Currently
|
||||||
|
// the API for generating constraints doesn't support returning values
|
||||||
|
// computed inside the circuit.
|
||||||
|
transcript.new_from_state(&self.r1cs_sat_proof.transcript_sat_state);
|
||||||
|
|
||||||
let (Ar, Br, Cr) = &self.inst_evals;
|
let (Ar, Br, Cr) = &self.inst_evals;
|
||||||
transcript.append_scalar(&Ar);
|
transcript.append_scalar(&Ar);
|
||||||
transcript.append_scalar(&Br);
|
transcript.append_scalar(&Br);
|
||||||
transcript.append_scalar(&Cr);
|
transcript.append_scalar(&Cr);
|
||||||
|
|
||||||
// TODO: debug this
|
self.r1cs_eval_proof.verify(
|
||||||
// https://github.com/maramihali/Spartan/issues/6
|
&comm.comm,
|
||||||
// self.r1cs_eval_proof.verify(
|
&self.rx,
|
||||||
// &comm.comm,
|
&self.ry,
|
||||||
// &self.rx,
|
&self.inst_evals,
|
||||||
// &self.ry,
|
&gens.gens_r1cs_eval,
|
||||||
// &self.inst_evals,
|
transcript,
|
||||||
// &gens.gens_r1cs_eval,
|
)?;
|
||||||
// transcript,
|
timer_eval_proof.stop();
|
||||||
// )?;
|
|
||||||
// timer_eval_proof.stop();
|
|
||||||
timer_verify.stop();
|
timer_verify.stop();
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ pub struct R1CSProof {
|
|||||||
proof_eval_vars_at_ry: Proof<I>,
|
proof_eval_vars_at_ry: Proof<I>,
|
||||||
rx: Vec<Scalar>,
|
rx: Vec<Scalar>,
|
||||||
ry: Vec<Scalar>,
|
ry: Vec<Scalar>,
|
||||||
|
// The transcript state after the satisfiability proof was computed.
|
||||||
|
pub transcript_sat_state: Scalar,
|
||||||
}
|
}
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct R1CSSumcheckGens {
|
pub struct R1CSSumcheckGens {
|
||||||
@@ -245,6 +247,8 @@ impl R1CSProof {
|
|||||||
|
|
||||||
timer_prove.stop();
|
timer_prove.stop();
|
||||||
|
|
||||||
|
let c = transcript.challenge_scalar();
|
||||||
|
|
||||||
(
|
(
|
||||||
R1CSProof {
|
R1CSProof {
|
||||||
comm,
|
comm,
|
||||||
@@ -255,6 +259,7 @@ impl R1CSProof {
|
|||||||
proof_eval_vars_at_ry,
|
proof_eval_vars_at_ry,
|
||||||
rx: rx.clone(),
|
rx: rx.clone(),
|
||||||
ry: ry.clone(),
|
ry: ry.clone(),
|
||||||
|
transcript_sat_state: c,
|
||||||
},
|
},
|
||||||
rx,
|
rx,
|
||||||
ry,
|
ry,
|
||||||
@@ -300,6 +305,7 @@ impl R1CSProof {
|
|||||||
input_as_sparse_poly,
|
input_as_sparse_poly,
|
||||||
// rx: self.rx.clone(),
|
// rx: self.rx.clone(),
|
||||||
ry: self.ry.clone(),
|
ry: self.ry.clone(),
|
||||||
|
transcript_sat_state: self.transcript_sat_state,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut rng = ark_std::test_rng();
|
let mut rng = ark_std::test_rng();
|
||||||
@@ -389,6 +395,7 @@ impl R1CSProof {
|
|||||||
input_as_sparse_poly,
|
input_as_sparse_poly,
|
||||||
// rx: self.rx.clone(),
|
// rx: self.rx.clone(),
|
||||||
ry: self.ry.clone(),
|
ry: self.ry.clone(),
|
||||||
|
transcript_sat_state: self.transcript_sat_state,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut rng = ark_std::test_rng();
|
let mut rng = ark_std::test_rng();
|
||||||
|
|||||||
Reference in New Issue
Block a user