Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(utils): Make generic over PrimeField #31

Merged
merged 2 commits into from
Jul 14, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 114 additions & 87 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,10 +278,10 @@ pub(crate) fn log2(x: usize) -> u32 {

#[cfg(test)]
mod tests {
use super::*;
use crate::hypercube::BooleanHypercube;

use super::*;
use pasta_curves::{Ep, Fq};
use pasta_curves::Fq;

fn to_F_vec<F: PrimeField>(v: Vec<u64>) -> Vec<F> {
v.iter().map(|x| F::from(*x)).collect()
Expand All @@ -291,93 +291,85 @@ mod tests {
m.iter().map(|x| to_F_vec(x.clone())).collect()
}

#[test]
fn test_vector_add() {
let a = to_F_vec::<Fq>(vec![1, 2, 3]);
let b = to_F_vec::<Fq>(vec![4, 5, 6]);
let res = vector_add(&a, &b);
assert_eq!(res, to_F_vec::<Fq>(vec![5, 7, 9]));
fn test_vector_add_with<F: PrimeField>() {
let a = to_F_vec::<F>(vec![1, 2, 3]);
let b = to_F_vec::<F>(vec![4, 5, 6]);
let res = vector_add::<F>(&a, &b);
assert_eq!(res, to_F_vec::<F>(vec![5, 7, 9]));
}

#[test]
fn test_vector_elem_product() {
let a = to_F_vec::<Fq>(vec![1, 2, 3]);
let e = Fq::from(2);
fn test_vector_elem_product_with<F: PrimeField>() {
let a = to_F_vec::<F>(vec![1, 2, 3]);
let e = F::from(2);
let res = vector_elem_product(&a, &e);
assert_eq!(res, to_F_vec::<Fq>(vec![2, 4, 6]));
assert_eq!(res, to_F_vec::<F>(vec![2, 4, 6]));
}

#[test]
fn test_matrix_vector_product() {
fn test_matrix_vector_product_with<F: PrimeField>() {
let matrix = vec![vec![1, 2, 3], vec![4, 5, 6]];
let vector = vec![1, 2, 3];
let A = to_F_matrix::<Fq>(matrix);
let z = to_F_vec::<Fq>(vector);
let A = to_F_matrix::<F>(matrix);
let z = to_F_vec::<F>(vector);
let res = matrix_vector_product(&A, &z);

assert_eq!(res, to_F_vec::<Fq>(vec![14, 32]));
assert_eq!(res, to_F_vec::<F>(vec![14, 32]));
}

#[test]
fn test_hadamard_product() {
let a = to_F_vec::<Fq>(vec![1, 2, 3]);
let b = to_F_vec::<Fq>(vec![4, 5, 6]);
fn test_hadamard_product_with<F: PrimeField>() {
let a = to_F_vec::<F>(vec![1, 2, 3]);
let b = to_F_vec::<F>(vec![4, 5, 6]);
let res = hadamard_product(&a, &b);
assert_eq!(res, to_F_vec::<Fq>(vec![4, 10, 18]));
assert_eq!(res, to_F_vec::<F>(vec![4, 10, 18]));
}

#[test]
fn test_matrix_vector_product_sparse() {
fn test_matrix_vector_product_sparse_with<F: PrimeField>() {
let matrix = vec![
(0, 0, Fq::from(1)),
(0, 1, Fq::from(2)),
(0, 2, Fq::from(3)),
(1, 0, Fq::from(4)),
(1, 1, Fq::from(5)),
(1, 2, Fq::from(6)),
(0, 0, F::from(1u64)),
(0, 1, F::from(2u64)),
(0, 2, F::from(3u64)),
(1, 0, F::from(4u64)),
(1, 1, F::from(5u64)),
(1, 2, F::from(6u64)),
];

let z = to_F_vec::<Fq>(vec![1, 2, 3]);
let res =
matrix_vector_product_sparse::<Fq>(&SparseMatrix::<Fq>::with_coeffs(2, 3, matrix), &z);
let z = to_F_vec::<F>(vec![1, 2, 3]);
let res = matrix_vector_product_sparse::<F>(&SparseMatrix::<F>::with_coeffs(2, 3, matrix), &z);

assert_eq!(res, to_F_vec::<Fq>(vec![14, 32]));
assert_eq!(res, to_F_vec::<F>(vec![14, 32]));
}

#[test]
fn test_sparse_matrix_n_cols_rows() {
fn test_sparse_matrix_n_cols_rows_with<F: PrimeField>() {
let matrix = vec![
(0, 0, Fq::from(1u64)),
(0, 1, Fq::from(2u64)),
(0, 2, Fq::from(3u64)),
(1, 0, Fq::from(4u64)),
(1, 1, Fq::from(5u64)),
(1, 2, Fq::from(6u64)),
(4, 5, Fq::from(1u64)),
(0, 0, F::from(1u64)),
(0, 1, F::from(2u64)),
(0, 2, F::from(3u64)),
(1, 0, F::from(4u64)),
(1, 1, F::from(5u64)),
(1, 2, F::from(6u64)),
(4, 5, F::from(1u64)),
];
let A = SparseMatrix::<Fq>::with_coeffs(5, 6, matrix.clone());
let A = SparseMatrix::<F>::with_coeffs(5, 6, matrix.clone());
assert_eq!(A.n_cols(), 6);
assert_eq!(A.n_rows(), 5);

// Since is sparse, the empty rows/cols at the end are not accounted unless we provide the info.
let A = SparseMatrix::<Fq>::with_coeffs(10, 10, matrix);
let A = SparseMatrix::<F>::with_coeffs(10, 10, matrix);
assert_eq!(A.n_cols(), 10);
assert_eq!(A.n_rows(), 10);
}

#[test]
fn test_matrix_to_mle() {
let A = SparseMatrix::<Fq>::with_coeffs(
fn test_matrix_to_mle_with<F: PrimeField>() {
let A = SparseMatrix::<F>::with_coeffs(
5,
5,
vec![
(0usize, 0usize, Fq::from(1u64)),
(0, 1, Fq::from(2u64)),
(0, 2, Fq::from(3u64)),
(1, 0, Fq::from(4u64)),
(1, 1, Fq::from(5u64)),
(1, 2, Fq::from(6u64)),
(3, 4, Fq::from(1u64)),
(0usize, 0usize, F::from(1u64)),
(0, 1, F::from(2u64)),
(0, 2, F::from(3u64)),
(1, 0, F::from(4u64)),
(1, 1, F::from(5u64)),
(1, 2, F::from(6u64)),
(3, 4, F::from(1u64)),
],
);

Expand All @@ -386,42 +378,42 @@ mod tests {

// hardcoded testvector to ensure that in the future the SparseMatrix.to_mle method holds
let expected = vec![
Fq::from(1u64),
Fq::from(2u64),
Fq::from(3u64),
Fq::from(0u64),
Fq::from(0u64),
Fq::from(0u64),
Fq::from(0u64),
Fq::from(0u64),
Fq::from(4u64),
Fq::from(5u64),
Fq::from(6u64),
Fq::from(0u64),
Fq::from(0u64),
Fq::from(0u64),
Fq::from(0u64),
Fq::from(0u64),
Fq::from(0u64),
Fq::from(0u64),
Fq::from(0u64),
Fq::from(0u64),
Fq::from(0u64),
Fq::from(0u64),
Fq::from(0u64),
Fq::from(0u64),
Fq::from(0u64),
Fq::from(0u64),
Fq::from(0u64),
Fq::from(0u64),
Fq::from(1u64),
F::from(1u64),
F::from(2u64),
F::from(3u64),
F::from(0u64),
F::from(0u64),
F::from(0u64),
F::from(0u64),
F::from(0u64),
F::from(4u64),
F::from(5u64),
F::from(6u64),
F::from(0u64),
F::from(0u64),
F::from(0u64),
F::from(0u64),
F::from(0u64),
F::from(0u64),
F::from(0u64),
F::from(0u64),
F::from(0u64),
F::from(0u64),
F::from(0u64),
F::from(0u64),
F::from(0u64),
F::from(0u64),
F::from(0u64),
F::from(0u64),
F::from(0u64),
F::from(1u64),
// the rest are zeroes
];
assert_eq!(A_mle.Z[..29], expected);
assert_eq!(A_mle.Z[29..], vec![Fq::ZERO; 64 - 29]);
assert_eq!(A_mle.Z[29..], vec![F::ZERO; 64 - 29]);

// check that the A_mle evaluated over the boolean hypercube equals the matrix A_i_j values
let bhc = BooleanHypercube::<Fq>::new(A_mle.get_num_vars());
let bhc = BooleanHypercube::<F>::new(A_mle.get_num_vars());
let mut A_padded = A.clone();
A_padded.pad();
for term in A_padded.coeffs.iter() {
Expand All @@ -430,4 +422,39 @@ mod tests {
assert_eq!(&A_mle.evaluate(&s_i_j), coeff)
}
}

#[test]
fn test_vector_add() {
test_vector_add_with::<Fq>();
}

#[test]
fn test_vector_elem_product() {
test_vector_elem_product_with::<Fq>();
}

#[test]
fn test_matrix_vector_product() {
test_matrix_vector_product_with::<Fq>();
}

#[test]
fn test_hadamard_product() {
test_hadamard_product_with::<Fq>();
}

#[test]
fn test_matrix_vector_product_sparse() {
test_matrix_vector_product_sparse_with::<Fq>();
}

#[test]
fn test_sparse_matrix_n_cols_rows() {
test_sparse_matrix_n_cols_rows_with::<Fq>();
}

#[test]
fn test_matrix_to_mle() {
test_matrix_to_mle_with::<Fq>();
}
}
Loading