use dusk_curves::bls12_381::BlsScalar;
use super::Commitment;
#[derive(Copy, Clone, Debug)]
#[allow(dead_code)]
pub(crate) struct Proof {
pub(crate) commitment_to_witness: Commitment,
pub(crate) evaluated_point: BlsScalar,
pub(crate) commitment_to_polynomial: Commitment,
}
#[cfg(feature = "alloc")]
pub(crate) mod alloc {
use super::*;
use crate::util::powers_of;
#[rustfmt::skip]
use ::alloc::vec::Vec;
use dusk_curves::bls12_381::G1Projective;
#[cfg(feature = "std")]
use rayon::prelude::*;
#[derive(Debug)]
#[allow(dead_code)]
pub(crate) struct AggregateProof {
pub(crate) commitment_to_witness: Commitment,
pub(crate) evaluated_points: Vec<BlsScalar>,
pub(crate) commitments_to_polynomials: Vec<Commitment>,
}
#[allow(dead_code)]
impl AggregateProof {
pub(crate) fn with_witness(witness: Commitment) -> AggregateProof {
AggregateProof {
commitment_to_witness: witness,
evaluated_points: Vec::new(),
commitments_to_polynomials: Vec::new(),
}
}
pub(crate) fn add_part(&mut self, part: (BlsScalar, Commitment)) {
self.evaluated_points.push(part.0);
self.commitments_to_polynomials.push(part.1);
}
pub(crate) fn flatten(&self, v_challenge: &BlsScalar) -> Proof {
let powers = powers_of(
v_challenge,
self.commitments_to_polynomials.len() - 1,
);
#[cfg(not(feature = "std"))]
let flattened_poly_commitments_iter =
self.commitments_to_polynomials.iter().zip(powers.iter());
#[cfg(not(feature = "std"))]
let flattened_poly_evaluations_iter =
self.evaluated_points.iter().zip(powers.iter());
#[cfg(feature = "std")]
let flattened_poly_commitments_iter = self
.commitments_to_polynomials
.par_iter()
.zip(powers.par_iter());
#[cfg(feature = "std")]
let flattened_poly_evaluations_iter =
self.evaluated_points.par_iter().zip(powers.par_iter());
let flattened_poly_commitments: G1Projective =
flattened_poly_commitments_iter
.map(|(poly, v_challenge)| poly.0 * v_challenge)
.sum();
let flattened_poly_evaluations: BlsScalar =
flattened_poly_evaluations_iter
.map(|(eval, v_challenge)| eval * v_challenge)
.sum();
Proof {
commitment_to_witness: self.commitment_to_witness,
evaluated_point: flattened_poly_evaluations,
commitment_to_polynomial: Commitment::from(
flattened_poly_commitments,
),
}
}
}
}
#[cfg(all(test, feature = "alloc"))]
mod tests {
use dusk_curves::bls12_381::{G1Affine, G1Projective};
use super::*;
#[test]
fn aggregate_proof_flatten_is_linear_combination() {
let witness_commitment: Commitment = G1Affine::generator().into();
let mut agg = alloc::AggregateProof::with_witness(witness_commitment);
let c0: Commitment =
(G1Projective::generator() * BlsScalar::from(2u64)).into();
let c1: Commitment =
(G1Projective::generator() * BlsScalar::from(3u64)).into();
let c2: Commitment =
(G1Projective::generator() * BlsScalar::from(5u64)).into();
let e0 = BlsScalar::from(11u64);
let e1 = BlsScalar::from(13u64);
let e2 = BlsScalar::from(17u64);
agg.add_part((e0, c0));
agg.add_part((e1, c1));
agg.add_part((e2, c2));
let v = BlsScalar::from(7u64);
let proof = agg.flatten(&v);
assert_eq!(proof.commitment_to_witness, witness_commitment);
let powers = crate::util::powers_of(&v, 2);
assert_eq!(powers.len(), 3);
let expected_eval = e0 * powers[0] + e1 * powers[1] + e2 * powers[2];
assert_eq!(proof.evaluated_point, expected_eval);
let expected_commitment_proj: G1Projective =
c0.0 * &powers[0] + c1.0 * &powers[1] + c2.0 * &powers[2];
let expected_commitment: Commitment = expected_commitment_proj.into();
assert_eq!(proof.commitment_to_polynomial, expected_commitment);
}
}