impl<F: FftFriendlyFieldElement> ClientMemory<F> { pub(crate) fn prove_with<G>(&mutself, dimension: usize, init_function: G) -> Vec<F> where
G: FnOnce(&mut [F]),
{ letmut proof = vec![F::zero(); proof_length(dimension)]; // unpack one long vector to different subparts let unpacked = unpack_proof_mut(&mut proof, dimension).unwrap(); // initialize the data part
init_function(unpacked.data); // fill in the rest
construct_proof(
unpacked.data,
dimension,
unpacked.f0,
unpacked.g0,
unpacked.h0,
unpacked.points_h_packed, self,
);
proof
}
}
/// Returns the number of field elements in the proof for given dimension of /// data elements /// /// Proof is a vector, where the first `dimension` elements are the data /// elements, the next 3 elements are the zero terms for polynomials f, g and h /// and the remaining elements are non-zero points of h(x). pub(crate) fn proof_length(dimension: usize) -> usize { // number of data items + number of zero terms + N
dimension + 3 + (dimension + 1).next_power_of_two()
}
/// Unpacked proof with subcomponents #[derive(Debug)] pub(crate) struct UnpackedProof<'a, F: FftFriendlyFieldElement> { /// Data pub data: &'a [F], /// Zeroth coefficient of polynomial f pub f0: &'a F, /// Zeroth coefficient of polynomial g pub g0: &'a F, /// Zeroth coefficient of polynomial h pub h0: &'a F, /// Non-zero points of polynomial h pub points_h_packed: &'a [F],
}
/// Unpacked proof with mutable subcomponents #[derive(Debug)] pub(crate) struct UnpackedProofMut<'a, F: FftFriendlyFieldElement> { /// Data pub data: &'a mut [F], /// Zeroth coefficient of polynomial f pub f0: &'a mut F, /// Zeroth coefficient of polynomial g pub g0: &'a mut F, /// Zeroth coefficient of polynomial h pub h0: &'a mut F, /// Non-zero points of polynomial h pub points_h_packed: &'a mut [F],
}
fn interpolate_and_evaluate_at_2n<F: FftFriendlyFieldElement>(
n: usize,
points_in: &[F],
evals_out: &mut [F],
mem: &mut PolyAuxMemory<F>,
) { // interpolate through roots of unity
poly_fft(
&mut mem.coeffs,
points_in,
&mem.roots_n_inverted,
n, true,
&mut mem.fft_memory,
); // evaluate at 2N roots of unity
poly_fft(
evals_out,
&mem.coeffs,
&mem.roots_2n, 2 * n, false,
&mut mem.fft_memory,
);
}
/// Proof construction /// /// Based on Theorem 2.3.3 from Henry Corrigan-Gibbs' dissertation /// This constructs the output \pi by doing the necessesary calculations fn construct_proof<F: FftFriendlyFieldElement>(
data: &[F],
dimension: usize,
f0: &mut F,
g0: &mut F,
h0: &mut F,
points_h_packed: &mut [F],
mem: &mut ClientMemory<F>,
) { let n = (dimension + 1).next_power_of_two();
// set zero terms to random
*f0 = mem.prng.get();
*g0 = mem.prng.get();
mem.points_f[0] = *f0;
mem.points_g[0] = *g0;
// set zero term for the proof polynomial
*h0 = *f0 * *g0;
// set f_i = data_(i - 1) // set g_i = f_i - 1 for ((f_coeff, g_coeff), data_val) in mem.points_f[1..1 + dimension]
.iter_mut()
.zip(mem.points_g[1..1 + dimension].iter_mut())
.zip(data[..dimension].iter())
{
*f_coeff = *data_val;
*g_coeff = *data_val - F::one();
}
// interpolate and evaluate at roots of unity
interpolate_and_evaluate_at_2n(n, &mem.points_f, &mut mem.evals_f, & style='color:red'>mut mem.poly_mem);
interpolate_and_evaluate_at_2n(n, &mem.points_g, &mut mem.evals_g, & style='color:red'>mut mem.poly_mem);
// calculate the proof polynomial as evals_f(r) * evals_g(r) // only add non-zero points letmut j: usize = 0; letmut i: usize = 1; while i < 2 * n {
points_h_packed[j] = mem.evals_f[i] * mem.evals_g[i];
j += 1;
i += 2;
}
}
#[cfg(test)] mod tests { use assert_matches::assert_matches;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.