Skip to content

Commit

Permalink
Adding the first part of the zero knowledge proof computation, comput…
Browse files Browse the repository at this point in the history
…ing the polynomial G
  • Loading branch information
benjaminsavage committed Mar 16, 2024
1 parent 3777d9f commit bba86d0
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 4 deletions.
9 changes: 5 additions & 4 deletions ipa-core/src/protocol/ipa_prf/malicious_security/lagrange.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ where
/// The "x coordinates" of the output points `x_N` to `x_(N+M-1)` are `N*F::ONE` to `(N+M-1)*F::ONE`
/// when generated using `from(denominator)`
/// unless generated using `new(denominator, x_output)` for a specific output "x coordinate" `x_output`.
#[derive(Debug)]
pub struct LagrangeTable<F: Field, N: ArrayLength, M: ArrayLength> {
table: GenericArray<GenericArray<F, N>, M>,
}
Expand Down Expand Up @@ -101,13 +102,13 @@ where
{
/// This function uses the `LagrangeTable` to evaluate `polynomial` on the specified output "x coordinates"
/// outputs the "y coordinates" such that `(x,y)` lies on `polynomial`
pub fn eval(&self, polynomial: &Polynomial<F, N>) -> GenericArray<F, M> {
pub fn eval(&self, y_coordinates: &GenericArray<F, N>) -> GenericArray<F, M> {
self.table
.iter()
.map(|table_row| {
table_row
.iter()
.zip(polynomial.y_coordinates.iter())
.zip(y_coordinates.iter())
.fold(F::ZERO, |acc, (&base, &y)| acc + base * y)
})
.collect()
Expand Down Expand Up @@ -245,7 +246,7 @@ mod test {
let denominator = CanonicalLagrangeDenominator::<TestField, U32>::new();
// generate table using new
let lagrange_table = LagrangeTable::<TestField, U32, U1>::new(&denominator, &output_point);
let output = lagrange_table.eval(&polynomial);
let output = lagrange_table.eval(&polynomial.y_coordinates);
assert_eq!(output, output_expected);
}

Expand All @@ -269,7 +270,7 @@ mod test {
let denominator = CanonicalLagrangeDenominator::<TestField, U8>::new();
// generate table using from
let lagrange_table = LagrangeTable::<TestField, U8, U7>::from(denominator);
let output = lagrange_table.eval(&polynomial);
let output = lagrange_table.eval(&polynomial.y_coordinates);
assert_eq!(output, output_expected);
}

Expand Down
1 change: 1 addition & 0 deletions ipa-core/src/protocol/ipa_prf/malicious_security/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod lagrange;
pub mod prover;
93 changes: 93 additions & 0 deletions ipa-core/src/protocol/ipa_prf/malicious_security/prover.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
use std::{
iter::zip,
ops::{Add, Sub},
};

use generic_array::{arr, sequence::GenericSequence, ArrayLength, GenericArray};
use typenum::{Diff, Sum, Unsigned, U1};

use crate::{
ff::PrimeField,
protocol::ipa_prf::malicious_security::lagrange::{
CanonicalLagrangeDenominator, LagrangeTable, Polynomial,
},
};

pub struct ProofGenerator<F: PrimeField> {
u: Vec<F>,
v: Vec<F>,
}

impl<F> ProofGenerator<F>
where
F: PrimeField,
{
pub fn compute_proof<N: ArrayLength>(self) -> GenericArray<F, Diff<Sum<N, N>, U1>>
where
N: ArrayLength + Add + Sub<U1>,
<N as Add>::Output: Sub<U1>,
<<N as Add>::Output as Sub<U1>>::Output: ArrayLength,
<N as Sub<U1>>::Output: ArrayLength,
{
assert!(self.u.len() % N::USIZE == 0); // We should pad with zeroes eventually

let strip_len = self.u.len() / N::USIZE;

let denominator = CanonicalLagrangeDenominator::<F, N>::new();
let lagrange_table = LagrangeTable::<F, N, <N as Sub<U1>>::Output>::from(denominator);
let extrapolated_points = (0..strip_len).map(|i| {
let p: GenericArray<F, N> = (0..N::USIZE).map(|j| self.u[i * N::USIZE + j]).collect();
let q: GenericArray<F, N> = (0..N::USIZE).map(|j| self.v[i * N::USIZE + j]).collect();
let p_extrapolated = lagrange_table.eval(&p);
let q_extrapolated = lagrange_table.eval(&q);
zip(
p.into_iter().chain(p_extrapolated),
q.into_iter().chain(q_extrapolated),
)
.map(|(a, b)| a * b)
.collect::<GenericArray<F,_>>()
});
extrapolated_points.reduce(|acc, pts| {
zip(acc, pts).map(|(a, b)| a + b).collect()
}).unwrap()
}
}

#[cfg(all(test, unit_test))]
mod test {
use std::fmt::Debug;

use generic_array::{sequence::GenericSequence, ArrayLength, GenericArray};
use proptest::{prelude::*, proptest};
use typenum::{U1, U32, U4, U7, U8};

use super::ProofGenerator;
use crate::{
ff::{Field, Fp31, U128Conversions},
protocol::ipa_prf::malicious_security::lagrange::{
CanonicalLagrangeDenominator, LagrangeTable, Polynomial,
},
};

#[test]
fn sample_proof() {
const U: [u128; 32] = [
0, 0, 1, 15, 0, 0, 0, 15, 2, 30, 30, 16, 29, 1, 1, 15, 0, 0, 0, 15, 0, 0, 0, 15, 2, 30,
30, 16, 0, 0, 1, 15,
];
const V: [u128; 32] = [
30, 30, 30, 30, 0, 1, 0, 1, 0, 0, 0, 30, 0, 30, 0, 30, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
30, 0, 0, 30, 30,
];
const EXPECTED: [u128; 7] = [0, 30, 29, 30, 3, 22, 6];
let pg: ProofGenerator<Fp31> = ProofGenerator {
u: U.into_iter().map(|x| Fp31::try_from(x).unwrap()).collect(),
v: V.into_iter().map(|x| Fp31::try_from(x).unwrap()).collect(),
};
let proof = pg.compute_proof::<U4>();
assert_eq!(
proof.into_iter().map(|x| x.as_u128()).collect::<Vec<_>>(),
EXPECTED
);
}
}

0 comments on commit bba86d0

Please sign in to comment.