done? now fix transcripts for multiple challenges
This commit is contained in:
parent
ae9716a428
commit
fafa64749e
@ -33,7 +33,8 @@ blake2-rfc = {version = "0.2.18", optional = true}
|
||||
|
||||
[features]
|
||||
#default = ["multicore"]
|
||||
default = ["multicore", "gm17", "sonic"]
|
||||
default = ["multicore", "sonic"]
|
||||
#default = ["multicore", "gm17", "sonic"]
|
||||
#default = ["wasm"]
|
||||
multicore = ["futures-cpupool", "num_cpus", "crossbeam"]
|
||||
sonic = ["tiny-keccak", "blake2-rfc"]
|
||||
|
@ -57,7 +57,7 @@ pub trait Backend<E: Engine> {
|
||||
fn new_linear_constraint(&mut self) -> Self::LinearConstraintIndex;
|
||||
|
||||
/// Insert a term into a linear constraint. TODO: bad name of function
|
||||
fn insert_coefficient(&mut self, _var: Variable, _coeff: Coeff<E>, y: &Self::LinearConstraintIndex) { }
|
||||
fn insert_coefficient(&mut self, _var: Variable, _coeff: Coeff<E>, _y: &Self::LinearConstraintIndex) { }
|
||||
|
||||
/// Compute a `LinearConstraintIndex` from `q`.
|
||||
fn get_for_q(&self, q: usize) -> Self::LinearConstraintIndex;
|
||||
|
@ -106,8 +106,6 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
|
||||
|
||||
let value = compute_value::<E>(&w, &s_poly_positive, &s_poly_negative);
|
||||
|
||||
println!("Helper s(z, w) = {}", value);
|
||||
|
||||
let opening = {
|
||||
let mut value = value;
|
||||
value.negate();
|
||||
|
@ -18,7 +18,7 @@ pub struct Preprocess<E: Engine> {
|
||||
impl<'a, E: Engine> Backend<E> for &'a mut Preprocess<E> {
|
||||
type LinearConstraintIndex = ();
|
||||
|
||||
fn get_for_q(&self, q: usize) -> Self::LinearConstraintIndex { () }
|
||||
fn get_for_q(&self, _q: usize) -> Self::LinearConstraintIndex { () }
|
||||
|
||||
fn new_k_power(&mut self, index: usize) {
|
||||
self.k_map.push(index);
|
||||
@ -57,7 +57,8 @@ impl<'a, E: Engine> Backend<E> for &'a mut Wires<E> {
|
||||
|
||||
fn new_linear_constraint(&mut self) -> Self::LinearConstraintIndex { () }
|
||||
|
||||
fn get_for_q(&self, q: usize) -> Self::LinearConstraintIndex { () }
|
||||
fn get_for_q(&self, _q: usize) -> Self::LinearConstraintIndex { () }
|
||||
|
||||
fn new_multiplication_gate(&mut self) {
|
||||
self.a.push(E::Fr::zero());
|
||||
self.b.push(E::Fr::zero());
|
||||
@ -118,7 +119,7 @@ pub struct CountNandQ<S: SynthesisDriver> {
|
||||
impl<'a, E: Engine, S: SynthesisDriver> Backend<E> for &'a mut CountNandQ<S> {
|
||||
type LinearConstraintIndex = ();
|
||||
|
||||
fn get_for_q(&self, q: usize) -> Self::LinearConstraintIndex { () }
|
||||
fn get_for_q(&self, _q: usize) -> Self::LinearConstraintIndex { () }
|
||||
|
||||
fn new_multiplication_gate(&mut self) {
|
||||
self.n += 1;
|
||||
@ -151,7 +152,7 @@ impl<'a, E: Engine, S: SynthesisDriver> Backend<E> for &'a mut CountN<S> {
|
||||
|
||||
fn new_linear_constraint(&mut self) -> Self::LinearConstraintIndex { () }
|
||||
|
||||
fn get_for_q(&self, q: usize) -> Self::LinearConstraintIndex { () }
|
||||
fn get_for_q(&self, _q: usize) -> Self::LinearConstraintIndex { () }
|
||||
|
||||
fn new_multiplication_gate(&mut self) {
|
||||
self.n += 1;
|
||||
|
@ -505,10 +505,9 @@ fn test_succinct_sonic_mimc() {
|
||||
|
||||
use crate::sonic::cs::{Circuit, ConstraintSystem, LinearCombination, Coeff};
|
||||
|
||||
// let perm_structure = create_permutation_structure::<Bls12, _>(&AdaptorCircuit(circuit.clone()));
|
||||
let perm_structure = create_permutation_structure::<Bls12, _>(&AdaptorCircuit(circuit.clone()));
|
||||
let s1_srs = perm_structure.create_permutation_special_reference(&srs);
|
||||
let s2_srs = perm_structure.calculate_s2_commitment_value(&srs);
|
||||
// let s2_srs = perm_structure.calculate_s2_commitment_value(&srs);
|
||||
|
||||
let info = get_circuit_parameters_for_succinct_sonic::<Bls12, _>(circuit.clone()).expect("Must get circuit info");
|
||||
println!("{:?}", info);
|
||||
@ -529,8 +528,6 @@ fn test_succinct_sonic_mimc() {
|
||||
let aggregate = create_aggregate_on_srs::<Bls12, _, Permutation3>(&AdaptorCircuit(circuit.clone()), &proofs, &srs, &s1_srs);
|
||||
println!("done in {:?}", start.elapsed());
|
||||
|
||||
|
||||
let _ = crate::sonic::helped::helper::create_aggregate_on_srs::<Bls12, _, Permutation3>(&AdaptorCircuit(circuit.clone()), &proofs, &srs);
|
||||
// {
|
||||
// let rng = thread_rng();
|
||||
// let mut verifier = MultiVerifier::<Bls12, _, Permutation3, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||
@ -561,14 +558,7 @@ fn test_succinct_sonic_mimc() {
|
||||
|
||||
{
|
||||
use rand::{XorShiftRng, SeedableRng, Rand, Rng};
|
||||
let mut rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||
let start = Instant::now();
|
||||
|
||||
// let aggregate =
|
||||
// let (perm_commitments, s_prime_challenges, perm_proof, perm_arg_proof, z_prime, num_poly, s1_naive) = perm_structure.create_permutation_arguments(aggregate.w, aggregate.z, &mut rng, &srs);
|
||||
// let s2_proof = perm_structure.calculate_s2_proof(aggregate.z, aggregate.w, &srs);
|
||||
|
||||
// println!("Permutation argument done in {:?}", start.elapsed());
|
||||
let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||
|
||||
let mut verifier = SuccinctMultiVerifier::<Bls12, _, Permutation3, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||
println!("verifying 100 proofs with succinct advice");
|
||||
@ -581,7 +571,6 @@ fn test_succinct_sonic_mimc() {
|
||||
&proofs,
|
||||
&aggregate,
|
||||
&srs,
|
||||
&s1_srs
|
||||
);
|
||||
assert_eq!(verifier.check_all(), true); // TODO
|
||||
}
|
||||
|
@ -115,12 +115,8 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
|
||||
// Open C at w
|
||||
let w: E::Fr = transcript.get_challenge_scalar();
|
||||
|
||||
println!("Aggregate: Z = {}, W = {}", z, w);
|
||||
|
||||
let value = compute_value::<E>(&w, &s_poly_positive, &s_poly_negative);
|
||||
|
||||
println!("Aggregate: S(z,w) = {}", value);
|
||||
|
||||
let opening = {
|
||||
let mut value = value;
|
||||
value.negate();
|
||||
|
@ -49,7 +49,6 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
z: E::Fr,
|
||||
srs: &SRS<E>,
|
||||
) -> GrandProductSignature<E> {
|
||||
println!("Making grand product argument for {} grand products", grand_products.len());
|
||||
let mut a_commitments = vec![];
|
||||
let mut b_commitments = vec![];
|
||||
|
||||
@ -160,15 +159,18 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
assert_eq!(c_poly.len(), n);
|
||||
a_poly.extend(p0);
|
||||
assert_eq!(a_poly.len(), n);
|
||||
|
||||
// v = a_{n+1} = c_{n}^-1
|
||||
// let v = c_poly[n-1].inverse().unwrap();
|
||||
let v = c_coeff.inverse().unwrap();
|
||||
|
||||
// ! IMPORTANT
|
||||
// This line is indeed assigning a_{n+1} to zero instead of v
|
||||
// for the practical purpose later we manually evaluate T polynomial
|
||||
// and assign v to the term X^{n+1}
|
||||
a_poly.push(E::Fr::zero());
|
||||
// a_poly.push(v);
|
||||
|
||||
// add c_{n+1}
|
||||
let mut c_coeff = E::Fr::one();
|
||||
c_poly.push(c_coeff);
|
||||
@ -238,16 +240,19 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
let mut results = vec![];
|
||||
|
||||
for a_poly in self.a_polynomials.iter() {
|
||||
let a = & a_poly[0..n];
|
||||
let b = & a_poly[(n+1)..];
|
||||
assert_eq!(a.len(), n);
|
||||
assert_eq!(b.len(), n);
|
||||
let mut val = evaluate_at_consequitive_powers(a, yz, yz);
|
||||
{
|
||||
let tmp = yz.pow([(n+2) as u64]);
|
||||
let v = evaluate_at_consequitive_powers(b, tmp, yz);
|
||||
val.add_assign(&v);
|
||||
}
|
||||
assert_eq!(a_poly[n], E::Fr::zero()); // there is no term for n+1 power
|
||||
let val = evaluate_at_consequitive_powers(&a_poly[..], yz, yz);
|
||||
|
||||
// let a = & a_poly[0..n]; // powers [1, n]
|
||||
// let b = & a_poly[(n+1)..]; // there is no n+1 term (numerated as `n`), skip it and start b
|
||||
// assert_eq!(a.len(), n);
|
||||
// assert_eq!(b.len(), n);
|
||||
// let mut val = evaluate_at_consequitive_powers(a, yz, yz);
|
||||
// {
|
||||
// let tmp = yz.pow([(n+2) as u64]);
|
||||
// let v = evaluate_at_consequitive_powers(b, tmp, yz);
|
||||
// val.add_assign(&v);
|
||||
// }
|
||||
|
||||
let mut constant_term = val;
|
||||
constant_term.negate();
|
||||
@ -256,11 +261,20 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
0,
|
||||
2*n + 1,
|
||||
Some(constant_term).iter()
|
||||
.chain_ext(a.iter())
|
||||
.chain_ext(Some(E::Fr::zero()).iter())
|
||||
.chain_ext(b.iter()),
|
||||
.chain_ext(a_poly.iter()),
|
||||
yz,
|
||||
&srs);
|
||||
&srs
|
||||
);
|
||||
|
||||
// let opening = polynomial_commitment_opening(
|
||||
// 0,
|
||||
// 2*n + 1,
|
||||
// Some(constant_term).iter()
|
||||
// .chain_ext(a.iter())
|
||||
// .chain_ext(Some(E::Fr::zero()).iter())
|
||||
// .chain_ext(b.iter()),
|
||||
// yz,
|
||||
// &srs);
|
||||
|
||||
results.push((val, opening));
|
||||
|
||||
@ -274,11 +288,14 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
|
||||
let mut results = vec![];
|
||||
|
||||
let n = self.c_polynomials[0].len();
|
||||
let two_n_plus_1 = self.c_polynomials[0].len();
|
||||
|
||||
for (p, v) in self.c_polynomials.iter().zip(self.v_elements.iter()) {
|
||||
let n = self.n;
|
||||
assert_eq!(p[n], E::Fr::one(), "C_(n+1) must be one");
|
||||
|
||||
let c = multiexp(
|
||||
srs.g_positive_x_alpha[0..n].iter(),
|
||||
srs.g_positive_x_alpha[0..two_n_plus_1].iter(),
|
||||
p.iter()
|
||||
).into_affine();
|
||||
|
||||
@ -421,6 +438,8 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
|
||||
let z_inv = z.inverse().unwrap();
|
||||
|
||||
let mut t_subcomponent = E::Fr::zero();
|
||||
|
||||
for (((a, c), challenge), v) in a_zy.iter()
|
||||
.zip(c_polynomials.into_iter())
|
||||
.zip(challenges.iter())
|
||||
@ -455,6 +474,9 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
let mut ry = y;
|
||||
ry.mul_assign(challenge);
|
||||
|
||||
t_subcomponent.add_assign(&rc);
|
||||
t_subcomponent.sub_assign(&challenge);
|
||||
|
||||
if e_polynomial.is_some() && f_polynomial.is_some() {
|
||||
if let Some(e_poly) = e_polynomial.as_mut() {
|
||||
if let Some(f_poly) = f_polynomial.as_mut() {
|
||||
@ -502,15 +524,24 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
e_val.negate();
|
||||
f_val.negate();
|
||||
|
||||
t_subcomponent.add_assign(&e_val);
|
||||
t_subcomponent.sub_assign(&f_val);
|
||||
|
||||
let mut t_poly = self.t_polynomial.unwrap();
|
||||
assert_eq!(t_poly.len(), 4*n + 3);
|
||||
|
||||
assert!(t_poly[2*n + 1].is_zero());
|
||||
|
||||
// largest negative power of t is -2n-1
|
||||
let t_zy = {
|
||||
let tmp = z_inv.pow([(2*n+1) as u64]);
|
||||
evaluate_at_consequitive_powers(&t_poly, tmp, z)
|
||||
};
|
||||
|
||||
assert_eq!(t_zy, t_subcomponent);
|
||||
|
||||
assert!(t_poly[2*n + 1].is_zero());
|
||||
|
||||
t_poly[2*n + 1].sub_assign(&t_zy);
|
||||
|
||||
let t_opening = polynomial_commitment_opening(
|
||||
@ -529,7 +560,8 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn verify_ab_commitment(n: usize,
|
||||
pub fn verify_ab_commitment(
|
||||
n: usize,
|
||||
randomness: & Vec<E::Fr>,
|
||||
a_commitments: &Vec<E::G1Affine>,
|
||||
b_commitments: &Vec<E::G1Affine>,
|
||||
@ -550,7 +582,8 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
|
||||
let h_alpha_precomp = srs.h_positive_x_alpha[0].prepare();
|
||||
|
||||
let mut h_x_n_plus_one_precomp = srs.h_positive_x[n];
|
||||
// H^(x^(n+1)) is n+1 indexed
|
||||
let mut h_x_n_plus_one_precomp = srs.h_positive_x[n+1];
|
||||
h_x_n_plus_one_precomp.negate();
|
||||
let h_x_n_plus_one_precomp = h_x_n_plus_one_precomp.prepare();
|
||||
|
||||
@ -760,17 +793,38 @@ fn test_grand_product_argument() {
|
||||
|
||||
let srs_x = Fr::from_str("23923").unwrap();
|
||||
let srs_alpha = Fr::from_str("23728792").unwrap();
|
||||
let srs = SRS::<Bls12>::dummy(830564, srs_x, srs_alpha);
|
||||
// let srs = SRS::<Bls12>::dummy(830564, srs_x, srs_alpha);
|
||||
let srs = SRS::<Bls12>::new(128, srs_x, srs_alpha);
|
||||
|
||||
let n: usize = 1 << 8;
|
||||
let n: usize = 1 << 5;
|
||||
let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||
let coeffs = (0..n).map(|_| Fr::rand(rng)).collect::<Vec<_>>();
|
||||
let coeffs = (1..=n).map(|_| Fr::rand(rng)).collect::<Vec<_>>();
|
||||
let mut permutation = coeffs.clone();
|
||||
rng.shuffle(&mut permutation);
|
||||
|
||||
let coeffs_product = coeffs.iter().fold(Fr::one(), |mut sum, x| {
|
||||
sum.mul_assign(&x);
|
||||
|
||||
sum
|
||||
});
|
||||
|
||||
let permutation_product = permutation.iter().fold(Fr::one(), |mut sum, x| {
|
||||
sum.mul_assign(&x);
|
||||
|
||||
sum
|
||||
});
|
||||
|
||||
assert_eq!(coeffs_product, permutation_product);
|
||||
assert!(!coeffs_product.is_zero());
|
||||
|
||||
let a_commitment = multiexp(srs.g_positive_x_alpha[0..n].iter(), coeffs.iter()).into_affine();
|
||||
let b_commitment = multiexp(srs.g_positive_x_alpha[0..n].iter(), permutation.iter()).into_affine();
|
||||
|
||||
let (a, b) = GrandProductArgument::commit_for_individual_products(&coeffs[..], &permutation[..], &srs);
|
||||
|
||||
assert_eq!(a_commitment, a);
|
||||
assert_eq!(b_commitment, b);
|
||||
|
||||
let mut argument = GrandProductArgument::new(vec![(coeffs, permutation)]);
|
||||
|
||||
let commitments_and_v_values = argument.commit_to_individual_c_polynomials(&srs);
|
||||
@ -789,14 +843,16 @@ fn test_grand_product_argument() {
|
||||
|
||||
let randomness = (0..1).map(|_| Fr::rand(rng)).collect::<Vec<_>>();
|
||||
|
||||
let valid = GrandProductArgument::verify_ab_commitment(n,
|
||||
let valid = GrandProductArgument::verify_ab_commitment(
|
||||
n,
|
||||
&randomness,
|
||||
&vec![a_commitment],
|
||||
&vec![b_commitment],
|
||||
&grand_product_openings,
|
||||
y,
|
||||
z,
|
||||
&srs);
|
||||
&srs
|
||||
);
|
||||
|
||||
assert!(valid, "grand product commitments should be valid");
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
mod s2_proof;
|
||||
mod wellformed_argument;
|
||||
mod grand_product_argument;
|
||||
pub mod grand_product_argument;
|
||||
mod permutation_argument;
|
||||
mod verifier;
|
||||
pub mod permutation_structure;
|
||||
|
@ -55,19 +55,19 @@ pub struct SignatureOfCorrectComputation<E: Engine> {
|
||||
pub grand_product_signature: GrandProductSignature<E>
|
||||
}
|
||||
|
||||
fn permute<F: Field>(coeffs: &[F], permutation: & [usize]) -> Vec<F>{
|
||||
assert_eq!(coeffs.len(), permutation.len());
|
||||
let mut result: Vec<F> = vec![F::zero(); coeffs.len()];
|
||||
for (i, j) in permutation.iter().enumerate() {
|
||||
// if *j < 1 {
|
||||
// // if permutation information is missing coefficient itself must be zero!
|
||||
// assert!(coeffs[i].is_zero());
|
||||
// continue;
|
||||
// fn permute<F: Field>(coeffs: &[F], permutation: & [usize]) -> Vec<F>{
|
||||
// assert_eq!(coeffs.len(), permutation.len());
|
||||
// let mut result: Vec<F> = vec![F::zero(); coeffs.len()];
|
||||
// for (i, j) in permutation.iter().enumerate() {
|
||||
// // if *j < 1 {
|
||||
// // // if permutation information is missing coefficient itself must be zero!
|
||||
// // assert!(coeffs[i].is_zero());
|
||||
// // continue;
|
||||
// // }
|
||||
// result[*j - 1] = coeffs[i];
|
||||
// }
|
||||
// result
|
||||
// }
|
||||
result[*j - 1] = coeffs[i];
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn permute_inverse<F: Field>(permuted_coeffs: &[F], permutation: & [usize]) -> Vec<F>{
|
||||
assert_eq!(permuted_coeffs.len(), permutation.len());
|
||||
@ -174,7 +174,7 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
|
||||
let mut non_permuted_at_y_coefficients = vec![];
|
||||
// let mut permuted_coefficients = vec![];
|
||||
let mut permuted_at_y_coefficients = vec![];
|
||||
// let mut permuted_at_y_coefficients = vec![];
|
||||
let mut inverse_permuted_at_y_coefficients = vec![];
|
||||
|
||||
// naive algorithms
|
||||
@ -218,7 +218,7 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
|
||||
self.non_permuted_at_y_coefficients = non_permuted_at_y_coefficients;
|
||||
// self.permuted_coefficients = permuted_coefficients;
|
||||
self.permuted_at_y_coefficients = permuted_at_y_coefficients;
|
||||
// self.permuted_at_y_coefficients = permuted_at_y_coefficients;
|
||||
self.inverse_permuted_at_y_coefficients = inverse_permuted_at_y_coefficients;
|
||||
|
||||
result
|
||||
@ -293,7 +293,6 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
_specialized_srs: &SpecializedSRS<E>,
|
||||
srs: &SRS<E>
|
||||
) -> PermutationArgumentProof<E> {
|
||||
panic!("");
|
||||
// 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
|
||||
|
||||
@ -304,8 +303,7 @@ 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()
|
||||
for c in self.inverse_permuted_at_y_coefficients.iter()
|
||||
{
|
||||
if s_polynomial.is_some() {
|
||||
if let Some(poly) = s_polynomial.as_mut() {
|
||||
@ -319,8 +317,6 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
// evaluate at z
|
||||
let s_zy = evaluate_at_consequitive_powers(& s_polynomial[..], z, z);
|
||||
|
||||
println!("S_zy = {}", s_zy);
|
||||
|
||||
let mut s_zy_neg = s_zy;
|
||||
s_zy_neg.negate();
|
||||
|
||||
@ -345,10 +341,9 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
|
||||
let mut grand_products = vec![];
|
||||
|
||||
for (((non_permuted, inv_permuted), permutation), permuted) in self.non_permuted_at_y_coefficients.into_iter()
|
||||
for ((non_permuted, inv_permuted), permutation) 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())
|
||||
|
||||
{
|
||||
// in S combination at the place i there should be term coeff[sigma(i)] * Y^sigma(i), that we can take
|
||||
@ -356,7 +351,7 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
// let mut s_combination = permute_inverse(&non_permuted[..], &permutation);
|
||||
let mut s_combination = inv_permuted;
|
||||
{
|
||||
let p_4_values: Vec<E::Fr> = permutation.clone().into_iter().map(|el| {
|
||||
let p_4_values: Vec<E::Fr> = permutation.into_iter().map(|el| {
|
||||
let mut repr = <<E as ScalarEngine>::Fr as PrimeField>::Repr::default();
|
||||
repr.as_mut()[0] = el as u64;
|
||||
let fe = E::Fr::from_repr(repr).unwrap();
|
||||
@ -367,19 +362,6 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
mul_add_polynomials(&mut s_combination[..], & p_1_values[..], gamma);
|
||||
}
|
||||
|
||||
let mut s_combination_may_be = permuted;
|
||||
{
|
||||
let p_4_values: Vec<E::Fr> = permutation.clone().into_iter().map(|el| {
|
||||
let mut repr = <<E as ScalarEngine>::Fr as PrimeField>::Repr::default();
|
||||
repr.as_mut()[0] = el as u64;
|
||||
let fe = E::Fr::from_repr(repr).unwrap();
|
||||
|
||||
fe
|
||||
}).collect();
|
||||
mul_add_polynomials(&mut s_combination_may_be[..], & p_4_values[..], beta);
|
||||
mul_add_polynomials(&mut s_combination_may_be[..], & p_1_values[..], gamma);
|
||||
}
|
||||
|
||||
// combination of coeff[i]*Y^i + beta * i + gamma
|
||||
let mut s_prime_combination = non_permuted.clone();
|
||||
{
|
||||
@ -403,15 +385,6 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
sum
|
||||
});
|
||||
|
||||
let s_product_may_be = s_combination_may_be.iter().fold(E::Fr::one(), |mut sum, x|
|
||||
{
|
||||
sum.mul_assign(&x);
|
||||
|
||||
sum
|
||||
});
|
||||
|
||||
println!("S = {}, S may be = {}, S' = {}", s_product, s_product_may_be, s_prime_product);
|
||||
|
||||
assert_eq!(s_product, s_prime_product, "product of coefficients must be the same");
|
||||
|
||||
grand_products.push((s_combination, s_prime_combination));
|
||||
@ -487,7 +460,7 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
}
|
||||
|
||||
pub fn verify_s_prime_commitment(
|
||||
n: usize,
|
||||
_n: usize,
|
||||
randomness: & Vec<E::Fr>,
|
||||
challenges: & Vec<E::Fr>,
|
||||
commitments: &Vec<E::G1Affine>,
|
||||
@ -699,9 +672,7 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
srs: &SRS<E>
|
||||
) -> (PermutationArgumentProof<E>, GrandProductSignature<E>, E::Fr, E::Fr) {
|
||||
let beta: E::Fr = transcript.get_challenge_scalar();
|
||||
println!("Beta in prover = {}", beta);
|
||||
let gamma: E::Fr = transcript.get_challenge_scalar();
|
||||
println!("Gamma in prover = {}", 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
|
||||
@ -797,6 +768,7 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
});
|
||||
|
||||
assert_eq!(s_product, s_prime_product, "product of coefficients must be the same");
|
||||
assert!(!s_product.is_zero(), "grand products must not be zero");
|
||||
|
||||
grand_products.push((s_combination, s_prime_combination));
|
||||
}
|
||||
@ -829,7 +801,7 @@ fn test_permutation_argument() {
|
||||
let srs_x = Fr::from_str("23923").unwrap();
|
||||
let srs_alpha = Fr::from_str("23728792").unwrap();
|
||||
// let srs = SRS::<Bls12>::dummy(830564, srs_x, srs_alpha);
|
||||
let srs = SRS::<Bls12>::new(1024, srs_x, srs_alpha);
|
||||
let srs = SRS::<Bls12>::new(128, srs_x, srs_alpha);
|
||||
|
||||
let n: usize = 1 << 4;
|
||||
let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||
|
@ -383,7 +383,7 @@ impl<E: Engine> PermutationStructure<E> {
|
||||
|
||||
for i in 0..m {
|
||||
let mut fillers: Vec<usize> = (1..=(3*n+1)).map(|el| el).collect();
|
||||
for (p, c) in permutations[i].iter_mut().zip(non_permuted_coeffs[i].iter()) {
|
||||
for (p, _c) in permutations[i].iter_mut().zip(non_permuted_coeffs[i].iter()) {
|
||||
if *p == 0 {
|
||||
continue;
|
||||
// assert!(c.is_zero());
|
||||
@ -638,7 +638,7 @@ fn test_simple_succinct_sonic() {
|
||||
|
||||
{
|
||||
use rand::{XorShiftRng, SeedableRng, Rand, Rng};
|
||||
let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||
let _rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||
|
||||
use crate::sonic::sonic::Basic;
|
||||
use crate::sonic::sonic::AdaptorCircuit;
|
||||
@ -672,7 +672,7 @@ fn test_simple_succinct_sonic() {
|
||||
for i in 0..non_permuted_coeffs[j].len() {
|
||||
let sigma_i = permutations[j][i];
|
||||
let coeff_i = non_permuted_coeffs[j][i];
|
||||
let coeff_sigma_i = non_permuted_coeffs[j][sigma_i - 1];
|
||||
// let coeff_sigma_i = non_permuted_coeffs[j][sigma_i - 1];
|
||||
|
||||
let y_power = y.pow([sigma_i as u64]);
|
||||
let x_power = z.pow([(i+1) as u64]);
|
||||
|
@ -73,8 +73,7 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier
|
||||
&mut self,
|
||||
proofs: &[(Proof<E>, SxyAdvice<E>)],
|
||||
aggregate: &SuccinctAggregate<E>,
|
||||
srs: &SRS<E>,
|
||||
specialized_srs: &SpecializedSRS<E>
|
||||
srs: &SRS<E>
|
||||
)
|
||||
{
|
||||
let mut transcript = Transcript::new(&[]);
|
||||
@ -95,8 +94,6 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier
|
||||
|
||||
let w: E::Fr = transcript.get_challenge_scalar();
|
||||
|
||||
println!("Verifier: Z = {}, W = {}", z, w);
|
||||
|
||||
let szw = {
|
||||
// prover will supply s1 and s2, need to calculate
|
||||
// s(z, w) = X^-(N+1) * Y^N * s1 - X^N * s2
|
||||
@ -246,13 +243,13 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier
|
||||
// from already known elements
|
||||
|
||||
let beta: E::Fr = transcript.get_challenge_scalar();
|
||||
println!("Beta in verifier = {}", beta);
|
||||
let gamma: E::Fr = transcript.get_challenge_scalar();
|
||||
println!("Gamma in verifier = {}", gamma);
|
||||
|
||||
let mut a_commitments = vec![];
|
||||
let mut b_commitments = vec![];
|
||||
|
||||
let mut wellformedness_argument_commitments = vec![];
|
||||
|
||||
use crate::pairing::CurveAffine;
|
||||
use crate::pairing::ff::PrimeField;
|
||||
|
||||
@ -283,8 +280,13 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier
|
||||
|
||||
a_commitments.push(a);
|
||||
b_commitments.push(b);
|
||||
wellformedness_argument_commitments.push(a);
|
||||
wellformedness_argument_commitments.push(b);
|
||||
}
|
||||
|
||||
// commitments to invidvidual grand products are assembled, now check first part of a grand
|
||||
// product argument
|
||||
|
||||
// Now perform an actual check
|
||||
{
|
||||
let randomness: Vec<E::Fr> = (0..aggregate.signature.s_commitments.len()).map(|_| self.randomness_source.gen()).collect();
|
||||
@ -294,7 +296,7 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier
|
||||
let h_alpha_x_precomp = srs.h_positive_x_alpha[1].prepare();
|
||||
let h_alpha_precomp = srs.h_positive_x_alpha[0].prepare();
|
||||
|
||||
let mut h_x_n_plus_one_precomp = srs.h_positive_x[self.n];
|
||||
let mut h_x_n_plus_one_precomp = srs.h_positive_x[self.n+1];
|
||||
h_x_n_plus_one_precomp.negate();
|
||||
let h_x_n_plus_one_precomp = h_x_n_plus_one_precomp.prepare();
|
||||
|
||||
@ -352,42 +354,175 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier
|
||||
])).unwrap() == E::Fqk::one();
|
||||
|
||||
// TODO
|
||||
// assert!(valid, "grand product arguments must be valid for individual commitments");
|
||||
assert!(valid, "grand product arguments must be valid for individual commitments");
|
||||
|
||||
}
|
||||
|
||||
// Now the second part of the grand product argument
|
||||
|
||||
// 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()));
|
||||
{
|
||||
let mut grand_product_challenges = vec![];
|
||||
|
||||
// assert!(lhs.into_affine() == *a);
|
||||
for _ in 0..aggregate.signature.grand_product_signature.c_commitments.len() {
|
||||
let c: E::Fr = transcript.get_challenge_scalar();
|
||||
grand_product_challenges.push(c);
|
||||
}
|
||||
// first re-calculate cj and t(z,y)
|
||||
|
||||
// // Sj′(P3j)β(P1j)γ
|
||||
let mut yz = w;
|
||||
yz.mul_assign(&z);
|
||||
|
||||
// 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()));
|
||||
let z_inv = z.inverse().unwrap();
|
||||
|
||||
// assert!(rhs.into_affine() == *b);
|
||||
// }
|
||||
let mut t_zy = E::Fr::zero();
|
||||
|
||||
let mut commitments_points = vec![];
|
||||
let mut rc_vec = vec![];
|
||||
let mut ry_vec = vec![];
|
||||
|
||||
// in grand product arguments n is not a number of gates, but 3n+1 - number of variables + 1
|
||||
let three_n_plus_1 = 3*self.n + 1;
|
||||
|
||||
for ((r, commitment), (a, _)) in grand_product_challenges.iter()
|
||||
.zip(aggregate.signature.grand_product_signature.c_commitments.iter())
|
||||
.zip(aggregate.signature.grand_product_signature.grand_product_openings.iter())
|
||||
{
|
||||
let (c, v) = commitment;
|
||||
commitments_points.push(*c);
|
||||
|
||||
// cj = ((aj + vj(yz)n+1)y + zn+2 + zn+1y − z2n+2y)z−1
|
||||
let mut c_zy = yz.pow([(three_n_plus_1 + 1) as u64]);
|
||||
c_zy.mul_assign(v);
|
||||
c_zy.add_assign(a);
|
||||
c_zy.mul_assign(&w);
|
||||
|
||||
let mut z_n_plus_1 = z.pow([(three_n_plus_1 + 1) as u64]);
|
||||
|
||||
let mut z_n_plus_2 = z_n_plus_1;
|
||||
z_n_plus_2.mul_assign(&z);
|
||||
|
||||
let mut z_2n_plus_2 = z_n_plus_1;
|
||||
z_2n_plus_2.square();
|
||||
z_2n_plus_2.mul_assign(&w);
|
||||
|
||||
z_n_plus_1.mul_assign(&w);
|
||||
|
||||
c_zy.add_assign(&z_n_plus_1);
|
||||
c_zy.add_assign(&z_n_plus_2);
|
||||
c_zy.sub_assign(&z_2n_plus_2);
|
||||
|
||||
c_zy.mul_assign(&z_inv);
|
||||
|
||||
let mut rc = c_zy;
|
||||
rc.mul_assign(&r);
|
||||
rc_vec.push(rc);
|
||||
|
||||
let mut ry = w;
|
||||
ry.mul_assign(&r);
|
||||
ry_vec.push(ry);
|
||||
|
||||
let mut val = rc;
|
||||
val.sub_assign(&r);
|
||||
t_zy.add_assign(&val);
|
||||
}
|
||||
|
||||
t_zy.add_assign(&aggregate.signature.grand_product_signature.proof.e_zinv);
|
||||
t_zy.sub_assign(&aggregate.signature.grand_product_signature.proof.f_y);
|
||||
|
||||
// t(z, y) is now calculated
|
||||
|
||||
let c_rc = multiexp(
|
||||
commitments_points.iter(),
|
||||
rc_vec.iter(),
|
||||
).into_affine();
|
||||
|
||||
let c_ry = multiexp(
|
||||
commitments_points.iter(),
|
||||
ry_vec.iter(),
|
||||
).into_affine();
|
||||
|
||||
// e(E,h^alphax)e(E^-z^-1,h^alpha) = e(\sumCj^(rj*cj),h)e(g^-e,h^alpha)
|
||||
|
||||
{
|
||||
let random: E::Fr = self.randomness_source.gen();
|
||||
|
||||
self.batch.add_opening(aggregate.signature.grand_product_signature.proof.e_opening, random, z_inv);
|
||||
self.batch.add_opening_value(random, aggregate.signature.grand_product_signature.proof.e_zinv);
|
||||
self.batch.add_commitment(c_rc, random);
|
||||
}
|
||||
|
||||
// e(F,h^alphax)e(F^-y,h) = e(\sumCj^(rj&y),h)e(g^-f,h^alpha)
|
||||
|
||||
{
|
||||
let random: E::Fr = self.randomness_source.gen();
|
||||
|
||||
self.batch.add_opening(aggregate.signature.grand_product_signature.proof.f_opening, random, w);
|
||||
self.batch.add_opening_value(random, aggregate.signature.grand_product_signature.proof.f_y);
|
||||
self.batch.add_commitment(c_ry, random);
|
||||
}
|
||||
|
||||
// e(T′,hαx)e(T′−z,hα) = e(T,h)e(g−t(z,y),hα)
|
||||
|
||||
{
|
||||
let random: E::Fr = self.randomness_source.gen();
|
||||
|
||||
self.batch.add_opening(aggregate.signature.grand_product_signature.proof.t_opening, random, z);
|
||||
self.batch.add_opening_value(random, t_zy);
|
||||
self.batch.add_commitment(aggregate.signature.grand_product_signature.t_commitment, random);
|
||||
}
|
||||
}
|
||||
|
||||
// finally check the wellformedness arguments
|
||||
|
||||
{
|
||||
let mut wellformedness_challenges = vec![];
|
||||
|
||||
for _ in 0..wellformedness_argument_commitments.len() {
|
||||
let c: E::Fr = transcript.get_challenge_scalar();
|
||||
wellformedness_challenges.push(c);
|
||||
}
|
||||
|
||||
let d = srs.d;
|
||||
let n = 3*self.n + 1; // same as for grand products
|
||||
|
||||
let alpha_x_d_precomp = srs.h_positive_x_alpha[d].prepare();
|
||||
// TODO: not strictly required
|
||||
assert!(n < d);
|
||||
let d_minus_n = d - n;
|
||||
let alpha_x_n_minus_d_precomp = srs.h_negative_x_alpha[d_minus_n].prepare();
|
||||
let mut h_prep = srs.h_positive_x[0];
|
||||
h_prep.negate();
|
||||
let h_prep = h_prep.prepare();
|
||||
|
||||
let a = multiexp(
|
||||
wellformedness_argument_commitments.iter(),
|
||||
wellformedness_challenges.iter(),
|
||||
).into_affine();
|
||||
|
||||
let r1: E::Fr = self.randomness_source.gen();
|
||||
let r2: E::Fr = self.randomness_source.gen();
|
||||
|
||||
let mut r = r1;
|
||||
r.add_assign(&r2);
|
||||
let l_r1 = aggregate.signature.grand_product_signature.wellformedness_signature.proof.l.mul(r1.into_repr()).into_affine();
|
||||
let r_r2 = aggregate.signature.grand_product_signature.wellformedness_signature.proof.r.mul(r2.into_repr()).into_affine();
|
||||
|
||||
let a_r = a.mul(r.into_repr()).into_affine();
|
||||
|
||||
let valid = E::final_exponentiation(&E::miller_loop(&[
|
||||
(&a_r.prepare(), &h_prep),
|
||||
(&l_r1.prepare(), &alpha_x_d_precomp),
|
||||
(&r_r2.prepare(), &alpha_x_n_minus_d_precomp)
|
||||
])).unwrap() == E::Fqk::one();
|
||||
|
||||
assert!(valid, "wellformedness argument must be valid");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
szw
|
||||
};
|
||||
|
||||
println!("Verifier: S(z,w) = {}", szw);
|
||||
|
||||
{
|
||||
let random: E::Fr = self.randomness_source.gen();
|
||||
|
||||
|
@ -34,7 +34,6 @@ impl<E: Engine> WellformednessArgument<E> {
|
||||
srs: &SRS<E>
|
||||
) -> WellformednessSignature<E> {
|
||||
let j = all_polys.len();
|
||||
println!("Making wellformedness argument for {} polys", j);
|
||||
let wellformed_argument = WellformednessArgument::new(all_polys);
|
||||
// TODO: remove commitments
|
||||
let commitments = wellformed_argument.commit(&srs);
|
||||
@ -108,18 +107,21 @@ impl<E: Engine> WellformednessArgument<E> {
|
||||
|
||||
let d = srs.d;
|
||||
|
||||
// TODO: it's not necessary to have n < d, fix later
|
||||
|
||||
assert!(n < d);
|
||||
|
||||
// here the multiplier is x^-d, so largest negative power is -(d - 1), smallest negative power is - (d - n)
|
||||
// H^{x^k} are labeled from 0 power, so we need to use proper indexes
|
||||
let l = multiexp(
|
||||
srs.g_negative_x[(d - n)..d].iter().rev(),
|
||||
srs.g_negative_x[(d - n)..=(d - 1)].iter().rev(),
|
||||
p0.iter()
|
||||
).into_affine();
|
||||
|
||||
// here the multiplier is x^d-n, so largest positive power is d, smallest positive power is d - n + 1
|
||||
|
||||
let r = multiexp(
|
||||
srs.g_positive_x[(d - n + 1)..].iter().rev(),
|
||||
srs.g_positive_x[(d - n + 1)..=d].iter(),
|
||||
p0.iter()
|
||||
).into_affine();
|
||||
|
||||
@ -133,7 +135,10 @@ impl<E: Engine> WellformednessArgument<E> {
|
||||
let d = srs.d;
|
||||
|
||||
let alpha_x_d_precomp = srs.h_positive_x_alpha[d].prepare();
|
||||
let alpha_x_n_minus_d_precomp = srs.h_negative_x_alpha[d - n].prepare();
|
||||
// TODO: not strictly required
|
||||
assert!(n < d);
|
||||
let d_minus_n = d - n;
|
||||
let alpha_x_n_minus_d_precomp = srs.h_negative_x_alpha[d_minus_n].prepare();
|
||||
let mut h_prep = srs.h_positive_x[0];
|
||||
h_prep.negate();
|
||||
let h_prep = h_prep.prepare();
|
||||
@ -175,11 +180,12 @@ fn test_argument() {
|
||||
|
||||
let srs_x = Fr::from_str("23923").unwrap();
|
||||
let srs_alpha = Fr::from_str("23728792").unwrap();
|
||||
let srs = SRS::<Bls12>::dummy(830564, srs_x, srs_alpha);
|
||||
// let srs = SRS::<Bls12>::dummy(830564, srs_x, srs_alpha);
|
||||
let srs = SRS::<Bls12>::new(128, srs_x, srs_alpha);
|
||||
|
||||
let n: usize = 1 << 16;
|
||||
let n: usize = 1 << 5;
|
||||
let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||
let coeffs = (0..n).map(|_| Fr::rand(rng)).collect::<Vec<_>>();
|
||||
let coeffs = (1..=n).map(|_| Fr::rand(rng)).collect::<Vec<_>>();
|
||||
|
||||
let argument = WellformednessArgument::new(vec![coeffs]);
|
||||
let challenges = (0..1).map(|_| Fr::rand(rng)).collect::<Vec<_>>();
|
||||
@ -205,12 +211,12 @@ fn test_argument_soundness() {
|
||||
|
||||
let n: usize = 1 << 8;
|
||||
let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||
let coeffs = (0..n).map(|_| Fr::rand(rng)).collect::<Vec<_>>();
|
||||
let coeffs = (1..=n).map(|_| Fr::rand(rng)).collect::<Vec<_>>();
|
||||
|
||||
let argument = WellformednessArgument::new(vec![coeffs]);
|
||||
let commitments = argument.commit(&srs);
|
||||
|
||||
let coeffs = (0..n).map(|_| Fr::rand(rng)).collect::<Vec<_>>();
|
||||
let coeffs = (1..=n).map(|_| Fr::rand(rng)).collect::<Vec<_>>();
|
||||
let argument = WellformednessArgument::new(vec![coeffs]);
|
||||
let challenges = (0..1).map(|_| Fr::rand(rng)).collect::<Vec<_>>();
|
||||
|
||||
|
@ -116,7 +116,7 @@ pub fn polynomial_commitment_opening<
|
||||
I: IntoIterator<Item = &'a E::Fr>
|
||||
>(
|
||||
largest_negative_power: usize,
|
||||
largest_positive_power: usize,
|
||||
_largest_positive_power: usize,
|
||||
polynomial_coefficients: I,
|
||||
point: E::Fr,
|
||||
srs: &'a SRS<E>,
|
||||
@ -221,7 +221,7 @@ pub fn mut_evaluate_at_consequitive_powers<'a, F: Field> (
|
||||
|
||||
let mut acc = F::zero();
|
||||
|
||||
for mut p in coeffs {
|
||||
for p in coeffs {
|
||||
p.mul_assign(¤t_power);
|
||||
acc.add_assign(&p);
|
||||
|
||||
@ -268,7 +268,7 @@ pub fn mut_distribute_consequitive_powers<'a, F: Field> (
|
||||
let mut current_power = base.pow(&[(i*chunk) as u64]);
|
||||
current_power.mul_assign(&first_power);
|
||||
|
||||
for mut p in coeffs_chunk {
|
||||
for p in coeffs_chunk {
|
||||
p.mul_assign(¤t_power);
|
||||
|
||||
current_power.mul_assign(&base);
|
||||
@ -464,7 +464,7 @@ where
|
||||
|
||||
/// Divides polynomial `a` in `x` by `x - b` with
|
||||
/// no remainder using fft.
|
||||
pub fn parallel_kate_divison<'a, E: Engine, I: IntoIterator<Item = &'a E::Fr>>(a: I, mut b: E::Fr) -> Vec<E::Fr>
|
||||
pub fn parallel_kate_divison<'a, E: Engine, I: IntoIterator<Item = &'a E::Fr>>(a: I, b: E::Fr) -> Vec<E::Fr>
|
||||
where
|
||||
I::IntoIter: DoubleEndedIterator + ExactSizeIterator,
|
||||
{
|
||||
@ -1002,7 +1002,7 @@ fn test_mut_eval_at_powers() {
|
||||
{
|
||||
let mut tmp = x.pow(&[n as u64]);
|
||||
|
||||
for mut coeff in a.iter_mut() {
|
||||
for coeff in a.iter_mut() {
|
||||
coeff.mul_assign(&tmp);
|
||||
acc.add_assign(&coeff);
|
||||
tmp.mul_assign(&x);
|
||||
@ -1033,7 +1033,7 @@ fn test_mut_distribute_powers() {
|
||||
{
|
||||
let mut tmp = x.pow(&[n as u64]);
|
||||
|
||||
for mut coeff in a.iter_mut() {
|
||||
for coeff in a.iter_mut() {
|
||||
coeff.mul_assign(&tmp);
|
||||
tmp.mul_assign(&x);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user