mirror of
https://github.com/arnaucube/testudo.git
synced 2026-01-12 16:51:28 +01:00
Merge pull request #18 from vmx/no-custom-fmt
chore: format Rust code the usual way
This commit is contained in:
@@ -37,7 +37,8 @@ fn nizk_prove_benchmark(c: &mut Criterion) {
|
|||||||
.measurement_time(Duration::from_secs(60))
|
.measurement_time(Duration::from_secs(60))
|
||||||
.bench_function(&name, move |b| {
|
.bench_function(&name, move |b| {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let mut prover_transcript = PoseidonTranscript::new(&POSEIDON_PARAMETERS_FR_377);
|
let mut prover_transcript =
|
||||||
|
PoseidonTranscript::new(&POSEIDON_PARAMETERS_FR_377);
|
||||||
NIZK::prove(
|
NIZK::prove(
|
||||||
black_box(&inst),
|
black_box(&inst),
|
||||||
black_box(vars.clone()),
|
black_box(vars.clone()),
|
||||||
@@ -78,7 +79,8 @@ fn nizk_verify_benchmark(c: &mut Criterion) {
|
|||||||
.measurement_time(Duration::from_secs(60))
|
.measurement_time(Duration::from_secs(60))
|
||||||
.bench_function(&name, move |b| {
|
.bench_function(&name, move |b| {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let mut verifier_transcript = PoseidonTranscript::new(&POSEIDON_PARAMETERS_FR_377);
|
let mut verifier_transcript =
|
||||||
|
PoseidonTranscript::new(&POSEIDON_PARAMETERS_FR_377);
|
||||||
assert!(proof
|
assert!(proof
|
||||||
.verify(
|
.verify(
|
||||||
black_box(&inst),
|
black_box(&inst),
|
||||||
@@ -120,7 +122,8 @@ fn nizk_verify_groth16_benchmark(c: &mut Criterion) {
|
|||||||
.measurement_time(Duration::from_secs(60))
|
.measurement_time(Duration::from_secs(60))
|
||||||
.bench_function(&name, move |b| {
|
.bench_function(&name, move |b| {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let mut verifier_transcript = PoseidonTranscript::new(&POSEIDON_PARAMETERS_FR_377);
|
let mut verifier_transcript =
|
||||||
|
PoseidonTranscript::new(&POSEIDON_PARAMETERS_FR_377);
|
||||||
assert!(proof
|
assert!(proof
|
||||||
.verify_groth16(
|
.verify_groth16(
|
||||||
black_box(&inst),
|
black_box(&inst),
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ extern crate libspartan;
|
|||||||
extern crate merlin;
|
extern crate merlin;
|
||||||
|
|
||||||
use libspartan::{
|
use libspartan::{
|
||||||
parameters::poseidon_params, poseidon_transcript::PoseidonTranscript, Instance, SNARKGens, SNARK,
|
parameters::poseidon_params, poseidon_transcript::PoseidonTranscript, Instance, SNARKGens,
|
||||||
|
SNARK,
|
||||||
};
|
};
|
||||||
|
|
||||||
use criterion::*;
|
use criterion::*;
|
||||||
@@ -16,7 +17,8 @@ fn snark_encode_benchmark(c: &mut Criterion) {
|
|||||||
let num_vars = (2_usize).pow(s as u32);
|
let num_vars = (2_usize).pow(s as u32);
|
||||||
let num_cons = num_vars;
|
let num_cons = num_vars;
|
||||||
let num_inputs = 10;
|
let num_inputs = 10;
|
||||||
let (inst, _vars, _inputs) = Instance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
let (inst, _vars, _inputs) =
|
||||||
|
Instance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
||||||
|
|
||||||
// produce public parameters
|
// produce public parameters
|
||||||
let gens = SNARKGens::new(num_cons, num_vars, num_inputs, num_cons);
|
let gens = SNARKGens::new(num_cons, num_vars, num_inputs, num_cons);
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ use ark_bls12_377::Fr as Scalar;
|
|||||||
use ark_ff::{BigInteger, PrimeField};
|
use ark_ff::{BigInteger, PrimeField};
|
||||||
use ark_std::{One, UniformRand, Zero};
|
use ark_std::{One, UniformRand, Zero};
|
||||||
use libspartan::{
|
use libspartan::{
|
||||||
parameters::poseidon_params, poseidon_transcript::PoseidonTranscript, InputsAssignment, Instance,
|
parameters::poseidon_params, poseidon_transcript::PoseidonTranscript, InputsAssignment,
|
||||||
SNARKGens, VarsAssignment, SNARK,
|
Instance, SNARKGens, VarsAssignment, SNARK,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
edition = "2018"
|
|
||||||
tab_spaces = 2
|
|
||||||
newline_style = "Unix"
|
|
||||||
use_try_shorthand = true
|
|
||||||
@@ -286,26 +286,34 @@ impl ConstraintSynthesizer<Fr> for R1CSVerificationCircuit {
|
|||||||
.sc_phase1
|
.sc_phase1
|
||||||
.polys
|
.polys
|
||||||
.iter()
|
.iter()
|
||||||
.map(|p| UniPolyVar::new_variable(cs.clone(), || Ok(p), AllocationMode::Witness).unwrap())
|
.map(|p| {
|
||||||
|
UniPolyVar::new_variable(cs.clone(), || Ok(p), AllocationMode::Witness).unwrap()
|
||||||
|
})
|
||||||
.collect::<Vec<UniPolyVar>>();
|
.collect::<Vec<UniPolyVar>>();
|
||||||
|
|
||||||
let poly_sc2_vars = self
|
let poly_sc2_vars = self
|
||||||
.sc_phase2
|
.sc_phase2
|
||||||
.polys
|
.polys
|
||||||
.iter()
|
.iter()
|
||||||
.map(|p| UniPolyVar::new_variable(cs.clone(), || Ok(p), AllocationMode::Witness).unwrap())
|
.map(|p| {
|
||||||
|
UniPolyVar::new_variable(cs.clone(), || Ok(p), AllocationMode::Witness).unwrap()
|
||||||
|
})
|
||||||
.collect::<Vec<UniPolyVar>>();
|
.collect::<Vec<UniPolyVar>>();
|
||||||
|
|
||||||
let input_vars = self
|
let input_vars = self
|
||||||
.input
|
.input
|
||||||
.iter()
|
.iter()
|
||||||
.map(|i| FpVar::<Fr>::new_variable(cs.clone(), || Ok(i), AllocationMode::Witness).unwrap())
|
.map(|i| {
|
||||||
|
FpVar::<Fr>::new_variable(cs.clone(), || Ok(i), AllocationMode::Witness).unwrap()
|
||||||
|
})
|
||||||
.collect::<Vec<FpVar<Fr>>>();
|
.collect::<Vec<FpVar<Fr>>>();
|
||||||
|
|
||||||
let claimed_ry_vars = self
|
let claimed_ry_vars = self
|
||||||
.claimed_ry
|
.claimed_ry
|
||||||
.iter()
|
.iter()
|
||||||
.map(|r| FpVar::<Fr>::new_variable(cs.clone(), || Ok(r), AllocationMode::Input).unwrap())
|
.map(|r| {
|
||||||
|
FpVar::<Fr>::new_variable(cs.clone(), || Ok(r), AllocationMode::Input).unwrap()
|
||||||
|
})
|
||||||
.collect::<Vec<FpVar<Fr>>>();
|
.collect::<Vec<FpVar<Fr>>>();
|
||||||
|
|
||||||
transcript_var.append_vector(&input_vars)?;
|
transcript_var.append_vector(&input_vars)?;
|
||||||
@@ -317,10 +325,11 @@ impl ConstraintSynthesizer<Fr> for R1CSVerificationCircuit {
|
|||||||
|
|
||||||
let claim_phase1_var = FpVar::<Fr>::new_witness(cs.clone(), || Ok(Fr::zero()))?;
|
let claim_phase1_var = FpVar::<Fr>::new_witness(cs.clone(), || Ok(Fr::zero()))?;
|
||||||
|
|
||||||
let (claim_post_phase1_var, rx_var) =
|
let (claim_post_phase1_var, rx_var) = self.sc_phase1.verifiy_sumcheck(
|
||||||
self
|
&poly_sc1_vars,
|
||||||
.sc_phase1
|
&claim_phase1_var,
|
||||||
.verifiy_sumcheck(&poly_sc1_vars, &claim_phase1_var, &mut transcript_var)?;
|
&mut transcript_var,
|
||||||
|
)?;
|
||||||
|
|
||||||
let (Az_claim, Bz_claim, Cz_claim, prod_Az_Bz_claims) = &self.claims_phase2;
|
let (Az_claim, Bz_claim, Cz_claim, prod_Az_Bz_claims) = &self.claims_phase2;
|
||||||
|
|
||||||
@@ -350,10 +359,11 @@ impl ConstraintSynthesizer<Fr> for R1CSVerificationCircuit {
|
|||||||
let claim_phase2_var =
|
let claim_phase2_var =
|
||||||
&r_A_var * &Az_claim_var + &r_B_var * &Bz_claim_var + &r_C_var * &Cz_claim_var;
|
&r_A_var * &Az_claim_var + &r_B_var * &Bz_claim_var + &r_C_var * &Cz_claim_var;
|
||||||
|
|
||||||
let (claim_post_phase2_var, ry_var) =
|
let (claim_post_phase2_var, ry_var) = self.sc_phase2.verifiy_sumcheck(
|
||||||
self
|
&poly_sc2_vars,
|
||||||
.sc_phase2
|
&claim_phase2_var,
|
||||||
.verifiy_sumcheck(&poly_sc2_vars, &claim_phase2_var, &mut transcript_var)?;
|
&mut transcript_var,
|
||||||
|
)?;
|
||||||
|
|
||||||
// Because the verifier checks the commitment opening on point ry outside
|
// Because the verifier checks the commitment opening on point ry outside
|
||||||
// the circuit, the prover needs to send ry to the verifier (making the
|
// the circuit, the prover needs to send ry to the verifier (making the
|
||||||
@@ -376,8 +386,8 @@ impl ConstraintSynthesizer<Fr> for R1CSVerificationCircuit {
|
|||||||
|
|
||||||
let eval_vars_at_ry_var = FpVar::<Fr>::new_input(cs.clone(), || Ok(&self.eval_vars_at_ry))?;
|
let eval_vars_at_ry_var = FpVar::<Fr>::new_input(cs.clone(), || Ok(&self.eval_vars_at_ry))?;
|
||||||
|
|
||||||
let eval_Z_at_ry_var =
|
let eval_Z_at_ry_var = (FpVar::<Fr>::one() - &ry_var[0]) * &eval_vars_at_ry_var
|
||||||
(FpVar::<Fr>::one() - &ry_var[0]) * &eval_vars_at_ry_var + &ry_var[0] * &poly_input_eval_var;
|
+ &ry_var[0] * &poly_input_eval_var;
|
||||||
|
|
||||||
let (eval_A_r, eval_B_r, eval_C_r) = self.evals;
|
let (eval_A_r, eval_B_r, eval_C_r) = self.evals;
|
||||||
|
|
||||||
@@ -385,7 +395,8 @@ impl ConstraintSynthesizer<Fr> for R1CSVerificationCircuit {
|
|||||||
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.clone(), || 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)?;
|
||||||
@@ -452,7 +463,8 @@ impl VerifierCircuit {
|
|||||||
|
|
||||||
impl ConstraintSynthesizer<Fq> for VerifierCircuit {
|
impl ConstraintSynthesizer<Fq> for VerifierCircuit {
|
||||||
fn generate_constraints(self, cs: ConstraintSystemRef<Fq>) -> ark_relations::r1cs::Result<()> {
|
fn generate_constraints(self, cs: ConstraintSystemRef<Fq>) -> ark_relations::r1cs::Result<()> {
|
||||||
let proof_var = ProofVar::<I, IV>::new_witness(cs.clone(), || Ok(self.inner_proof.clone()))?;
|
let proof_var =
|
||||||
|
ProofVar::<I, IV>::new_witness(cs.clone(), || Ok(self.inner_proof.clone()))?;
|
||||||
let (v_A, v_B, v_C, v_AB) = self.claims_phase2;
|
let (v_A, v_B, v_C, v_AB) = self.claims_phase2;
|
||||||
let mut pubs = vec![];
|
let mut pubs = vec![];
|
||||||
pubs.extend(self.ry);
|
pubs.extend(self.ry);
|
||||||
|
|||||||
@@ -377,7 +377,8 @@ impl DensePolynomial {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn bound(&self, L: &[Scalar]) -> Vec<Scalar> {
|
pub fn bound(&self, L: &[Scalar]) -> Vec<Scalar> {
|
||||||
let (left_num_vars, right_num_vars) = EqPolynomial::compute_factored_lens(self.get_num_vars());
|
let (left_num_vars, right_num_vars) =
|
||||||
|
EqPolynomial::compute_factored_lens(self.get_num_vars());
|
||||||
let L_size = left_num_vars.pow2();
|
let L_size = left_num_vars.pow2();
|
||||||
let R_size = right_num_vars.pow2();
|
let R_size = right_num_vars.pow2();
|
||||||
(0..R_size)
|
(0..R_size)
|
||||||
@@ -566,8 +567,7 @@ impl PolyEvalProof {
|
|||||||
|
|
||||||
let C_LZ = GroupElement::vartime_multiscalar_mul(&L, C_decompressed.as_slice()).compress();
|
let C_LZ = GroupElement::vartime_multiscalar_mul(&L, C_decompressed.as_slice()).compress();
|
||||||
|
|
||||||
self
|
self.proof
|
||||||
.proof
|
|
||||||
.verify(R.len(), &gens.gens, transcript, &R, &C_LZ, C_Zr)
|
.verify(R.len(), &gens.gens, transcript, &R, &C_LZ, C_Zr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
21
src/lib.rs
21
src/lib.rs
@@ -266,11 +266,9 @@ impl Instance {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(
|
Ok(self
|
||||||
self
|
|
||||||
.inst
|
.inst
|
||||||
.is_sat(&padded_vars.assignment, &inputs.assignment),
|
.is_sat(&padded_vars.assignment, &inputs.assignment))
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new synthetic R1CS `Instance` and an associated satisfying assignment
|
/// Constructs a new synthetic R1CS `Instance` and an associated satisfying assignment
|
||||||
@@ -279,7 +277,8 @@ impl Instance {
|
|||||||
num_vars: usize,
|
num_vars: usize,
|
||||||
num_inputs: usize,
|
num_inputs: usize,
|
||||||
) -> (Instance, VarsAssignment, InputsAssignment) {
|
) -> (Instance, VarsAssignment, InputsAssignment) {
|
||||||
let (inst, vars, inputs) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
let (inst, vars, inputs) =
|
||||||
|
R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
||||||
let digest = inst.get_digest();
|
let digest = inst.get_digest();
|
||||||
(
|
(
|
||||||
Instance { inst, digest },
|
Instance { inst, digest },
|
||||||
@@ -714,8 +713,8 @@ mod tests {
|
|||||||
let num_inputs = 1;
|
let num_inputs = 1;
|
||||||
|
|
||||||
let zero: [u8; 32] = [
|
let zero: [u8; 32] = [
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0,
|
0, 0, 0,
|
||||||
];
|
];
|
||||||
|
|
||||||
let A = vec![(0, 0, zero.to_vec())];
|
let A = vec![(0, 0, zero.to_vec())];
|
||||||
@@ -734,13 +733,13 @@ mod tests {
|
|||||||
let num_inputs = 1;
|
let num_inputs = 1;
|
||||||
|
|
||||||
let zero: [u8; 32] = [
|
let zero: [u8; 32] = [
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0,
|
0, 0, 0,
|
||||||
];
|
];
|
||||||
|
|
||||||
let larger_than_mod = [
|
let larger_than_mod = [
|
||||||
3, 0, 0, 0, 255, 255, 255, 255, 254, 91, 254, 255, 2, 164, 189, 83, 5, 216, 161, 9, 8, 216,
|
3, 0, 0, 0, 255, 255, 255, 255, 254, 91, 254, 255, 2, 164, 189, 83, 5, 216, 161, 9, 8,
|
||||||
57, 51, 72, 125, 157, 41, 83, 167, 237, 115,
|
216, 57, 51, 72, 125, 157, 41, 83, 167, 237, 115,
|
||||||
];
|
];
|
||||||
|
|
||||||
let A = vec![(0, 0, zero.to_vec())];
|
let A = vec![(0, 0, zero.to_vec())];
|
||||||
|
|||||||
@@ -87,15 +87,13 @@ impl BulletReductionProof {
|
|||||||
let (blind_L, blind_R) = blinds_iter.next().unwrap();
|
let (blind_L, blind_R) = blinds_iter.next().unwrap();
|
||||||
|
|
||||||
let L = GroupElement::vartime_multiscalar_mul(
|
let L = GroupElement::vartime_multiscalar_mul(
|
||||||
a_L
|
a_L.iter()
|
||||||
.iter()
|
|
||||||
.chain(iter::once(&c_L))
|
.chain(iter::once(&c_L))
|
||||||
.chain(iter::once(blind_L))
|
.chain(iter::once(blind_L))
|
||||||
.copied()
|
.copied()
|
||||||
.collect::<Vec<Scalar>>()
|
.collect::<Vec<Scalar>>()
|
||||||
.as_slice(),
|
.as_slice(),
|
||||||
G_R
|
G_R.iter()
|
||||||
.iter()
|
|
||||||
.chain(iter::once(Q))
|
.chain(iter::once(Q))
|
||||||
.chain(iter::once(H))
|
.chain(iter::once(H))
|
||||||
.copied()
|
.copied()
|
||||||
@@ -104,15 +102,13 @@ impl BulletReductionProof {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let R = GroupElement::vartime_multiscalar_mul(
|
let R = GroupElement::vartime_multiscalar_mul(
|
||||||
a_R
|
a_R.iter()
|
||||||
.iter()
|
|
||||||
.chain(iter::once(&c_R))
|
.chain(iter::once(&c_R))
|
||||||
.chain(iter::once(blind_R))
|
.chain(iter::once(blind_R))
|
||||||
.copied()
|
.copied()
|
||||||
.collect::<Vec<Scalar>>()
|
.collect::<Vec<Scalar>>()
|
||||||
.as_slice(),
|
.as_slice(),
|
||||||
G_L
|
G_L.iter()
|
||||||
.iter()
|
|
||||||
.chain(iter::once(Q))
|
.chain(iter::once(Q))
|
||||||
.chain(iter::once(H))
|
.chain(iter::once(H))
|
||||||
.copied()
|
.copied()
|
||||||
@@ -244,8 +240,7 @@ impl BulletReductionProof {
|
|||||||
let a_hat = inner_product(a, &s);
|
let a_hat = inner_product(a, &s);
|
||||||
|
|
||||||
let Gamma_hat = GroupElement::vartime_multiscalar_mul(
|
let Gamma_hat = GroupElement::vartime_multiscalar_mul(
|
||||||
u_sq
|
u_sq.iter()
|
||||||
.iter()
|
|
||||||
.chain(u_inv_sq.iter())
|
.chain(u_inv_sq.iter())
|
||||||
.chain(iter::once(&Scalar::one()))
|
.chain(iter::once(&Scalar::one()))
|
||||||
.copied()
|
.copied()
|
||||||
|
|||||||
@@ -555,8 +555,7 @@ impl DotProductProofLog {
|
|||||||
let Gamma = Cx.unpack()? + Cy.unpack()?;
|
let Gamma = Cx.unpack()? + Cy.unpack()?;
|
||||||
|
|
||||||
let (g_hat, Gamma_hat, a_hat) =
|
let (g_hat, Gamma_hat, a_hat) =
|
||||||
self
|
self.bullet_reduction_proof
|
||||||
.bullet_reduction_proof
|
|
||||||
.verify(n, a, transcript, &Gamma, &gens.gens_n.G)?;
|
.verify(n, a, transcript, &Gamma, &gens.gens_n.G)?;
|
||||||
// self.delta.append_to_poseidon( transcript);
|
// self.delta.append_to_poseidon( transcript);
|
||||||
// self.beta.append_to_poseidon( transcript);
|
// self.beta.append_to_poseidon( transcript);
|
||||||
@@ -573,8 +572,8 @@ impl DotProductProofLog {
|
|||||||
let z1_s = &self.z1;
|
let z1_s = &self.z1;
|
||||||
let z2_s = &self.z2;
|
let z2_s = &self.z2;
|
||||||
|
|
||||||
let lhs =
|
let lhs = ((Gamma_hat.mul(c_s.into_repr()) + beta_s).mul(a_hat_s.into_repr()) + delta_s)
|
||||||
((Gamma_hat.mul(c_s.into_repr()) + beta_s).mul(a_hat_s.into_repr()) + delta_s).compress();
|
.compress();
|
||||||
let rhs = ((g_hat + gens.gens_1.G[0].mul(a_hat_s.into_repr())).mul(z1_s.into_repr())
|
let rhs = ((g_hat + gens.gens_1.G[0].mul(a_hat_s.into_repr())).mul(z1_s.into_repr())
|
||||||
+ gens.gens_1.h.mul(z2_s.into_repr()))
|
+ gens.gens_1.h.mul(z2_s.into_repr()))
|
||||||
.compress();
|
.compress();
|
||||||
|
|||||||
@@ -149,8 +149,7 @@ pub fn poseidon_params() -> PoseidonParameters<Fr> {
|
|||||||
let arks = FR["ark"]
|
let arks = FR["ark"]
|
||||||
.members()
|
.members()
|
||||||
.map(|ark| {
|
.map(|ark| {
|
||||||
ark
|
ark.members()
|
||||||
.members()
|
|
||||||
.map(|v| Fr::from_str(v.as_str().unwrap()).unwrap())
|
.map(|v| Fr::from_str(v.as_str().unwrap()).unwrap())
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ impl ProductCircuit {
|
|||||||
right_vec.push(outp_right);
|
right_vec.push(outp_right);
|
||||||
|
|
||||||
for i in 0..num_layers - 1 {
|
for i in 0..num_layers - 1 {
|
||||||
let (outp_left, outp_right) = ProductCircuit::compute_layer(&left_vec[i], &right_vec[i]);
|
let (outp_left, outp_right) =
|
||||||
|
ProductCircuit::compute_layer(&left_vec[i], &right_vec[i]);
|
||||||
left_vec.push(outp_left);
|
left_vec.push(outp_left);
|
||||||
right_vec.push(outp_right);
|
right_vec.push(outp_right);
|
||||||
}
|
}
|
||||||
@@ -124,8 +125,7 @@ impl LayerProof {
|
|||||||
degree_bound: usize,
|
degree_bound: usize,
|
||||||
transcript: &mut PoseidonTranscript,
|
transcript: &mut PoseidonTranscript,
|
||||||
) -> (Scalar, Vec<Scalar>) {
|
) -> (Scalar, Vec<Scalar>) {
|
||||||
self
|
self.proof
|
||||||
.proof
|
|
||||||
.verify(claim, num_rounds, degree_bound, transcript)
|
.verify(claim, num_rounds, degree_bound, transcript)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
@@ -148,8 +148,7 @@ impl LayerProofBatched {
|
|||||||
degree_bound: usize,
|
degree_bound: usize,
|
||||||
transcript: &mut PoseidonTranscript,
|
transcript: &mut PoseidonTranscript,
|
||||||
) -> (Scalar, Vec<Scalar>) {
|
) -> (Scalar, Vec<Scalar>) {
|
||||||
self
|
self.proof
|
||||||
.proof
|
|
||||||
.verify(claim, num_rounds, degree_bound, transcript)
|
.verify(claim, num_rounds, degree_bound, transcript)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
@@ -184,10 +183,10 @@ impl ProductCircuitEvalProof {
|
|||||||
assert_eq!(poly_C.len(), len / 2);
|
assert_eq!(poly_C.len(), len / 2);
|
||||||
|
|
||||||
let num_rounds_prod = poly_C.len().log_2();
|
let num_rounds_prod = poly_C.len().log_2();
|
||||||
let comb_func_prod = |poly_A_comp: &Scalar,
|
let comb_func_prod =
|
||||||
poly_B_comp: &Scalar,
|
|poly_A_comp: &Scalar, poly_B_comp: &Scalar, poly_C_comp: &Scalar| -> Scalar {
|
||||||
poly_C_comp: &Scalar|
|
(*poly_A_comp) * poly_B_comp * poly_C_comp
|
||||||
-> Scalar { (*poly_A_comp) * poly_B_comp * poly_C_comp };
|
};
|
||||||
let (proof_prod, rand_prod, claims_prod) = SumcheckInstanceProof::prove_cubic(
|
let (proof_prod, rand_prod, claims_prod) = SumcheckInstanceProof::prove_cubic(
|
||||||
&claim,
|
&claim,
|
||||||
num_rounds_prod,
|
num_rounds_prod,
|
||||||
@@ -239,7 +238,8 @@ impl ProductCircuitEvalProof {
|
|||||||
assert_eq!(rand.len(), rand_prod.len());
|
assert_eq!(rand.len(), rand_prod.len());
|
||||||
let eq: Scalar = (0..rand.len())
|
let eq: Scalar = (0..rand.len())
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
rand[i] * rand_prod[i] + (Scalar::one() - rand[i]) * (Scalar::one() - rand_prod[i])
|
rand[i] * rand_prod[i]
|
||||||
|
+ (Scalar::one() - rand[i]) * (Scalar::one() - rand_prod[i])
|
||||||
})
|
})
|
||||||
.product();
|
.product();
|
||||||
assert_eq!(claims_prod[0] * claims_prod[1] * eq, claim_last);
|
assert_eq!(claims_prod[0] * claims_prod[1] * eq, claim_last);
|
||||||
@@ -281,10 +281,10 @@ impl ProductCircuitEvalProofBatched {
|
|||||||
assert_eq!(poly_C_par.len(), len / 2);
|
assert_eq!(poly_C_par.len(), len / 2);
|
||||||
|
|
||||||
let num_rounds_prod = poly_C_par.len().log_2();
|
let num_rounds_prod = poly_C_par.len().log_2();
|
||||||
let comb_func_prod = |poly_A_comp: &Scalar,
|
let comb_func_prod =
|
||||||
poly_B_comp: &Scalar,
|
|poly_A_comp: &Scalar, poly_B_comp: &Scalar, poly_C_comp: &Scalar| -> Scalar {
|
||||||
poly_C_comp: &Scalar|
|
(*poly_A_comp) * poly_B_comp * poly_C_comp
|
||||||
-> Scalar { (*poly_A_comp) * poly_B_comp * poly_C_comp };
|
};
|
||||||
|
|
||||||
let mut poly_A_batched_par: Vec<&mut DensePolynomial> = Vec::new();
|
let mut poly_A_batched_par: Vec<&mut DensePolynomial> = Vec::new();
|
||||||
let mut poly_B_batched_par: Vec<&mut DensePolynomial> = Vec::new();
|
let mut poly_B_batched_par: Vec<&mut DensePolynomial> = Vec::new();
|
||||||
@@ -329,7 +329,8 @@ impl ProductCircuitEvalProofBatched {
|
|||||||
.map(|i| claims_to_verify[i] * coeff_vec[i])
|
.map(|i| claims_to_verify[i] * coeff_vec[i])
|
||||||
.sum();
|
.sum();
|
||||||
|
|
||||||
let (proof, rand_prod, claims_prod, claims_dotp) = SumcheckInstanceProof::prove_cubic_batched(
|
let (proof, rand_prod, claims_prod, claims_dotp) =
|
||||||
|
SumcheckInstanceProof::prove_cubic_batched(
|
||||||
&claim,
|
&claim,
|
||||||
num_rounds_prod,
|
num_rounds_prod,
|
||||||
poly_vec_par,
|
poly_vec_par,
|
||||||
@@ -359,7 +360,9 @@ impl ProductCircuitEvalProofBatched {
|
|||||||
let r_layer = transcript.challenge_scalar();
|
let r_layer = transcript.challenge_scalar();
|
||||||
|
|
||||||
claims_to_verify = (0..prod_circuit_vec.len())
|
claims_to_verify = (0..prod_circuit_vec.len())
|
||||||
.map(|i| claims_prod_left[i] + r_layer * (claims_prod_right[i] - claims_prod_left[i]))
|
.map(|i| {
|
||||||
|
claims_prod_left[i] + r_layer * (claims_prod_right[i] - claims_prod_left[i])
|
||||||
|
})
|
||||||
.collect::<Vec<Scalar>>();
|
.collect::<Vec<Scalar>>();
|
||||||
|
|
||||||
let mut ext = vec![r_layer];
|
let mut ext = vec![r_layer];
|
||||||
@@ -424,7 +427,8 @@ impl ProductCircuitEvalProofBatched {
|
|||||||
assert_eq!(rand.len(), rand_prod.len());
|
assert_eq!(rand.len(), rand_prod.len());
|
||||||
let eq: Scalar = (0..rand.len())
|
let eq: Scalar = (0..rand.len())
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
rand[i] * rand_prod[i] + (Scalar::one() - rand[i]) * (Scalar::one() - rand_prod[i])
|
rand[i] * rand_prod[i]
|
||||||
|
+ (Scalar::one() - rand[i]) * (Scalar::one() - rand_prod[i])
|
||||||
})
|
})
|
||||||
.product();
|
.product();
|
||||||
let mut claim_expected: Scalar = (0..claims_prod_vec.len())
|
let mut claim_expected: Scalar = (0..claims_prod_vec.len())
|
||||||
@@ -453,7 +457,9 @@ impl ProductCircuitEvalProofBatched {
|
|||||||
let r_layer = transcript.challenge_scalar();
|
let r_layer = transcript.challenge_scalar();
|
||||||
|
|
||||||
claims_to_verify = (0..claims_prod_left.len())
|
claims_to_verify = (0..claims_prod_left.len())
|
||||||
.map(|i| claims_prod_left[i] + r_layer * (claims_prod_right[i] - claims_prod_left[i]))
|
.map(|i| {
|
||||||
|
claims_prod_left[i] + r_layer * (claims_prod_right[i] - claims_prod_left[i])
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// add claims to verify for dotp circuit
|
// add claims to verify for dotp circuit
|
||||||
|
|||||||
@@ -44,8 +44,13 @@ impl R1CSCommitmentGens {
|
|||||||
assert!(num_inputs < num_vars);
|
assert!(num_inputs < num_vars);
|
||||||
let num_poly_vars_x = num_cons.log_2();
|
let num_poly_vars_x = num_cons.log_2();
|
||||||
let num_poly_vars_y = (2 * num_vars).log_2();
|
let num_poly_vars_y = (2 * num_vars).log_2();
|
||||||
let gens =
|
let gens = SparseMatPolyCommitmentGens::new(
|
||||||
SparseMatPolyCommitmentGens::new(label, num_poly_vars_x, num_poly_vars_y, num_nz_entries, 3);
|
label,
|
||||||
|
num_poly_vars_x,
|
||||||
|
num_poly_vars_y,
|
||||||
|
num_nz_entries,
|
||||||
|
3,
|
||||||
|
);
|
||||||
R1CSCommitmentGens { gens }
|
R1CSCommitmentGens { gens }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -320,7 +325,8 @@ impl R1CSInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn commit(&self, gens: &R1CSCommitmentGens) -> (R1CSCommitment, R1CSDecommitment) {
|
pub fn commit(&self, gens: &R1CSCommitmentGens) -> (R1CSCommitment, R1CSDecommitment) {
|
||||||
let (comm, dense) = SparseMatPolynomial::multi_commit(&[&self.A, &self.B, &self.C], &gens.gens);
|
let (comm, dense) =
|
||||||
|
SparseMatPolynomial::multi_commit(&[&self.A, &self.B, &self.C], &gens.gens);
|
||||||
let r1cs_comm = R1CSCommitment {
|
let r1cs_comm = R1CSCommitment {
|
||||||
num_cons: self.num_cons,
|
num_cons: self.num_cons,
|
||||||
num_vars: self.num_vars,
|
num_vars: self.num_vars,
|
||||||
|
|||||||
@@ -89,12 +89,13 @@ impl R1CSProof {
|
|||||||
evals_Cz: &mut DensePolynomial,
|
evals_Cz: &mut DensePolynomial,
|
||||||
transcript: &mut PoseidonTranscript,
|
transcript: &mut PoseidonTranscript,
|
||||||
) -> (SumcheckInstanceProof, Vec<Scalar>, Vec<Scalar>) {
|
) -> (SumcheckInstanceProof, Vec<Scalar>, Vec<Scalar>) {
|
||||||
let comb_func =
|
let comb_func = |poly_tau_comp: &Scalar,
|
||||||
|poly_tau_comp: &Scalar,
|
|
||||||
poly_A_comp: &Scalar,
|
poly_A_comp: &Scalar,
|
||||||
poly_B_comp: &Scalar,
|
poly_B_comp: &Scalar,
|
||||||
poly_C_comp: &Scalar|
|
poly_C_comp: &Scalar|
|
||||||
-> Scalar { (*poly_tau_comp) * ((*poly_A_comp) * poly_B_comp - poly_C_comp) };
|
-> Scalar {
|
||||||
|
(*poly_tau_comp) * ((*poly_A_comp) * poly_B_comp - poly_C_comp)
|
||||||
|
};
|
||||||
|
|
||||||
let (sc_proof_phase_one, r, claims) = SumcheckInstanceProof::prove_cubic_with_additive_term(
|
let (sc_proof_phase_one, r, claims) = SumcheckInstanceProof::prove_cubic_with_additive_term(
|
||||||
&Scalar::zero(), // claim is zero
|
&Scalar::zero(), // claim is zero
|
||||||
@@ -509,7 +510,8 @@ mod tests {
|
|||||||
let num_vars = 1024;
|
let num_vars = 1024;
|
||||||
let num_cons = num_vars;
|
let num_cons = num_vars;
|
||||||
let num_inputs = 10;
|
let num_inputs = 10;
|
||||||
let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
let (inst, vars, input) =
|
||||||
|
R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
||||||
|
|
||||||
let gens = R1CSGens::new(b"test-m", num_cons, num_vars);
|
let gens = R1CSGens::new(b"test-m", num_cons, num_vars);
|
||||||
|
|
||||||
|
|||||||
@@ -306,15 +306,15 @@ impl SparseMatPolyCommitmentGens {
|
|||||||
num_nz_entries: usize,
|
num_nz_entries: usize,
|
||||||
batch_size: usize,
|
batch_size: usize,
|
||||||
) -> SparseMatPolyCommitmentGens {
|
) -> SparseMatPolyCommitmentGens {
|
||||||
let num_vars_ops =
|
let num_vars_ops = num_nz_entries.next_power_of_two().log_2()
|
||||||
num_nz_entries.next_power_of_two().log_2() + (batch_size * 5).next_power_of_two().log_2();
|
+ (batch_size * 5).next_power_of_two().log_2();
|
||||||
let num_vars_mem = if num_vars_x > num_vars_y {
|
let num_vars_mem = if num_vars_x > num_vars_y {
|
||||||
num_vars_x
|
num_vars_x
|
||||||
} else {
|
} else {
|
||||||
num_vars_y
|
num_vars_y
|
||||||
} + 1;
|
} + 1;
|
||||||
let num_vars_derefs =
|
let num_vars_derefs = num_nz_entries.next_power_of_two().log_2()
|
||||||
num_nz_entries.next_power_of_two().log_2() + (batch_size * 2).next_power_of_two().log_2();
|
+ (batch_size * 2).next_power_of_two().log_2();
|
||||||
|
|
||||||
let gens_ops = PolyCommitmentGens::new(num_vars_ops, label);
|
let gens_ops = PolyCommitmentGens::new(num_vars_ops, label);
|
||||||
let gens_mem = PolyCommitmentGens::new(num_vars_mem, label);
|
let gens_mem = PolyCommitmentGens::new(num_vars_mem, label);
|
||||||
@@ -341,11 +341,9 @@ impl AppendToTranscript for SparseMatPolyCommitment {
|
|||||||
transcript.append_u64(b"batch_size", self.batch_size as u64);
|
transcript.append_u64(b"batch_size", self.batch_size as u64);
|
||||||
transcript.append_u64(b"num_ops", self.num_ops as u64);
|
transcript.append_u64(b"num_ops", self.num_ops as u64);
|
||||||
transcript.append_u64(b"num_mem_cells", self.num_mem_cells as u64);
|
transcript.append_u64(b"num_mem_cells", self.num_mem_cells as u64);
|
||||||
self
|
self.comm_comb_ops
|
||||||
.comm_comb_ops
|
|
||||||
.append_to_transcript(b"comm_comb_ops", transcript);
|
.append_to_transcript(b"comm_comb_ops", transcript);
|
||||||
self
|
self.comm_comb_mem
|
||||||
.comm_comb_mem
|
|
||||||
.append_to_transcript(b"comm_comb_mem", transcript);
|
.append_to_transcript(b"comm_comb_mem", transcript);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -425,8 +423,7 @@ impl SparseMatPolynomial {
|
|||||||
|
|
||||||
// combine polynomials into a single polynomial for commitment purposes
|
// combine polynomials into a single polynomial for commitment purposes
|
||||||
let comb_ops = DensePolynomial::merge(
|
let comb_ops = DensePolynomial::merge(
|
||||||
row
|
row.ops_addr
|
||||||
.ops_addr
|
|
||||||
.iter()
|
.iter()
|
||||||
.chain(row.read_ts.iter())
|
.chain(row.read_ts.iter())
|
||||||
.chain(col.ops_addr.iter())
|
.chain(col.ops_addr.iter())
|
||||||
@@ -579,7 +576,8 @@ impl Layers {
|
|||||||
(0..num_mem_cells)
|
(0..num_mem_cells)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
// at init time, addr is given by i, init value is given by eval_table, and ts = 0
|
// at init time, addr is given by i, init value is given by eval_table, and ts = 0
|
||||||
hash_func(&Scalar::from(i as u64), &eval_table[i], &Scalar::zero()) - r_multiset_check
|
hash_func(&Scalar::from(i as u64), &eval_table[i], &Scalar::zero())
|
||||||
|
- r_multiset_check
|
||||||
})
|
})
|
||||||
.collect::<Vec<Scalar>>(),
|
.collect::<Vec<Scalar>>(),
|
||||||
);
|
);
|
||||||
@@ -587,7 +585,8 @@ impl Layers {
|
|||||||
(0..num_mem_cells)
|
(0..num_mem_cells)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
// at audit time, addr is given by i, value is given by eval_table, and ts is given by audit_ts
|
// at audit time, addr is given by i, value is given by eval_table, and ts is given by audit_ts
|
||||||
hash_func(&Scalar::from(i as u64), &eval_table[i], &audit_ts[i]) - r_multiset_check
|
hash_func(&Scalar::from(i as u64), &eval_table[i], &audit_ts[i])
|
||||||
|
- r_multiset_check
|
||||||
})
|
})
|
||||||
.collect::<Vec<Scalar>>(),
|
.collect::<Vec<Scalar>>(),
|
||||||
);
|
);
|
||||||
@@ -614,7 +613,8 @@ impl Layers {
|
|||||||
(0..num_ops)
|
(0..num_ops)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
// at write time, addr is given by addrs, value is given by derefs, and ts is given by write_ts = read_ts + 1
|
// at write time, addr is given by addrs, value is given by derefs, and ts is given by write_ts = read_ts + 1
|
||||||
hash_func(&addrs[i], &derefs[i], &(read_ts[i] + Scalar::one())) - r_multiset_check
|
hash_func(&addrs[i], &derefs[i], &(read_ts[i] + Scalar::one()))
|
||||||
|
- r_multiset_check
|
||||||
})
|
})
|
||||||
.collect::<Vec<Scalar>>(),
|
.collect::<Vec<Scalar>>(),
|
||||||
);
|
);
|
||||||
@@ -1419,16 +1419,18 @@ impl PolyEvalNetworkProof {
|
|||||||
let num_cells = rx.len().pow2();
|
let num_cells = rx.len().pow2();
|
||||||
assert_eq!(rx.len(), ry.len());
|
assert_eq!(rx.len(), ry.len());
|
||||||
|
|
||||||
let (claims_mem, rand_mem, mut claims_ops, claims_dotp, rand_ops) = self
|
let (claims_mem, rand_mem, mut claims_ops, claims_dotp, rand_ops) =
|
||||||
.proof_prod_layer
|
self.proof_prod_layer
|
||||||
.verify(num_ops, num_cells, evals, transcript)?;
|
.verify(num_ops, num_cells, evals, transcript)?;
|
||||||
assert_eq!(claims_mem.len(), 4);
|
assert_eq!(claims_mem.len(), 4);
|
||||||
assert_eq!(claims_ops.len(), 4 * num_instances);
|
assert_eq!(claims_ops.len(), 4 * num_instances);
|
||||||
assert_eq!(claims_dotp.len(), 3 * num_instances);
|
assert_eq!(claims_dotp.len(), 3 * num_instances);
|
||||||
|
|
||||||
let (claims_ops_row, claims_ops_col) = claims_ops.split_at_mut(2 * num_instances);
|
let (claims_ops_row, claims_ops_col) = claims_ops.split_at_mut(2 * num_instances);
|
||||||
let (claims_ops_row_read, claims_ops_row_write) = claims_ops_row.split_at_mut(num_instances);
|
let (claims_ops_row_read, claims_ops_row_write) =
|
||||||
let (claims_ops_col_read, claims_ops_col_write) = claims_ops_col.split_at_mut(num_instances);
|
claims_ops_row.split_at_mut(num_instances);
|
||||||
|
let (claims_ops_col_read, claims_ops_col_write) =
|
||||||
|
claims_ops_col.split_at_mut(num_instances);
|
||||||
|
|
||||||
// verify the proof of hash layer
|
// verify the proof of hash layer
|
||||||
self.proof_hash_layer.verify(
|
self.proof_hash_layer.verify(
|
||||||
@@ -1685,7 +1687,8 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// commitment
|
// commitment
|
||||||
let (poly_comm, dense) = SparseMatPolynomial::multi_commit(&[&poly_M, &poly_M, &poly_M], &gens);
|
let (poly_comm, dense) =
|
||||||
|
SparseMatPolynomial::multi_commit(&[&poly_M, &poly_M, &poly_M], &gens);
|
||||||
|
|
||||||
// evaluation
|
// evaluation
|
||||||
let rx: Vec<Scalar> = (0..num_vars_x)
|
let rx: Vec<Scalar> = (0..num_vars_x)
|
||||||
|
|||||||
@@ -377,7 +377,8 @@ impl SumcheckInstanceProof {
|
|||||||
// eval 2: bound_func is -A(low) + 2*A(high)
|
// eval 2: bound_func is -A(low) + 2*A(high)
|
||||||
let poly_A_bound_point = poly_A[len + i] + poly_A[len + i] - poly_A[i];
|
let poly_A_bound_point = poly_A[len + i] + poly_A[len + i] - poly_A[i];
|
||||||
let poly_B_bound_point = poly_B[len + i] + poly_B[len + i] - poly_B[i];
|
let poly_B_bound_point = poly_B[len + i] + poly_B[len + i] - poly_B[i];
|
||||||
let poly_C_bound_point = poly_C_par[len + i] + poly_C_par[len + i] - poly_C_par[i];
|
let poly_C_bound_point =
|
||||||
|
poly_C_par[len + i] + poly_C_par[len + i] - poly_C_par[i];
|
||||||
eval_point_2 += comb_func(
|
eval_point_2 += comb_func(
|
||||||
&poly_A_bound_point,
|
&poly_A_bound_point,
|
||||||
&poly_B_bound_point,
|
&poly_B_bound_point,
|
||||||
@@ -387,7 +388,8 @@ impl SumcheckInstanceProof {
|
|||||||
// eval 3: bound_func is -2A(low) + 3A(high); computed incrementally with bound_func applied to eval(2)
|
// eval 3: bound_func is -2A(low) + 3A(high); computed incrementally with bound_func applied to eval(2)
|
||||||
let poly_A_bound_point = poly_A_bound_point + poly_A[len + i] - poly_A[i];
|
let poly_A_bound_point = poly_A_bound_point + poly_A[len + i] - poly_A[i];
|
||||||
let poly_B_bound_point = poly_B_bound_point + poly_B[len + i] - poly_B[i];
|
let poly_B_bound_point = poly_B_bound_point + poly_B[len + i] - poly_B[i];
|
||||||
let poly_C_bound_point = poly_C_bound_point + poly_C_par[len + i] - poly_C_par[i];
|
let poly_C_bound_point =
|
||||||
|
poly_C_bound_point + poly_C_par[len + i] - poly_C_par[i];
|
||||||
|
|
||||||
eval_point_3 += comb_func(
|
eval_point_3 += comb_func(
|
||||||
&poly_A_bound_point,
|
&poly_A_bound_point,
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ impl UniPoly {
|
|||||||
|
|
||||||
let d = evals[0];
|
let d = evals[0];
|
||||||
let a = six_inv
|
let a = six_inv
|
||||||
* (evals[3] - evals[2] - evals[2] - evals[2] + evals[1] + evals[1] + evals[1] - evals[0]);
|
* (evals[3] - evals[2] - evals[2] - evals[2] + evals[1] + evals[1] + evals[1]
|
||||||
|
- evals[0]);
|
||||||
let b = two_inv
|
let b = two_inv
|
||||||
* (evals[0] + evals[0] - evals[1] - evals[1] - evals[1] - evals[1] - evals[1]
|
* (evals[0] + evals[0] - evals[1] - evals[1] - evals[1] - evals[1] - evals[1]
|
||||||
+ evals[2]
|
+ evals[2]
|
||||||
|
|||||||
Reference in New Issue
Block a user