arnaucube
arnaucube/nova-studyPublic Self-hosted repository
nova-study/src/utils.rs
src/utils.rsRaw
  1use ark_ec::AffineRepr;
  2use ark_ff::fields::PrimeField;
  3use core::ops::Add;
  4
  5pub fn vector_elem_product<F: PrimeField>(a: &Vec<F>, e: &F) -> Vec<F> {
  6    // maybe move this method to operator a * e
  7    let mut r: Vec<F> = vec![F::zero(); a.len()];
  8    for i in 0..a.len() {
  9        r[i] = a[i] * e;
 10    }
 11    r
 12}
 13pub fn matrix_vector_product<F: PrimeField>(M: &Vec<Vec<F>>, z: &Vec<F>) -> Vec<F> {
 14    // TODO assert len
 15    let mut r: Vec<F> = vec![F::zero(); M.len()];
 16    for i in 0..M.len() {
 17        for j in 0..M[i].len() {
 18            r[i] += M[i][j] * z[j];
 19        }
 20    }
 21    r
 22}
 23pub fn hadamard_product<F: PrimeField>(a: Vec<F>, b: Vec<F>) -> Vec<F> {
 24    // maybe move this method to operator a * b
 25    // TODO assert equals len
 26    let mut r: Vec<F> = vec![F::zero(); a.len()];
 27    for i in 0..a.len() {
 28        r[i] = a[i] * b[i];
 29    }
 30    r
 31}
 32
 33pub fn naive_msm<C: AffineRepr>(s: &Vec<C::ScalarField>, p: &Vec<C>) -> C {
 34    // check lengths
 35
 36    let mut r = p[0].mul(s[0]);
 37    for i in 1..s.len() {
 38        r = p[i].mul(s[i]);
 39    }
 40    r.into()
 41}
 42
 43pub fn vec_add<F: PrimeField>(a: Vec<F>, b: Vec<F>) -> Vec<F> {
 44    let mut r: Vec<F> = vec![F::zero(); a.len()];
 45    for i in 0..a.len() {
 46        r[i] = a[i] + b[i];
 47    }
 48    r
 49}
 50// TODO instead of vec_add do:
 51// impl<'a, 'b, F> Add<&'b Vec<F>> for &'a Vec<F> {
 52//     type Output = Vec<F>;
 53//     fn add(self, rhs: &'b Vec<F>) -> Vec<F> {
 54//         let mut r: Vec<F> = vec![F::zero(); self.len()];
 55//         for i in 0..self.len() {
 56//             r[i] = self[i] + rhs[i];
 57//         }
 58//         r
 59//     }
 60// }
 61pub fn vec_sub<F: PrimeField>(a: Vec<F>, b: Vec<F>) -> Vec<F> {
 62    let mut r: Vec<F> = vec![F::zero(); a.len()];
 63    for i in 0..a.len() {
 64        r[i] = a[i] - b[i];
 65    }
 66    r
 67}
 68
 69pub fn to_F_matrix<F: PrimeField>(M: Vec<Vec<usize>>) -> Vec<Vec<F>> {
 70    let mut R: Vec<Vec<F>> = vec![Vec::new(); M.len()];
 71    for i in 0..M.len() {
 72        R[i] = vec![F::zero(); M[i].len()];
 73        for j in 0..M[i].len() {
 74            R[i][j] = F::from(M[i][j] as u64);
 75        }
 76    }
 77    R
 78}
 79pub fn to_F_vec<F: PrimeField>(z: Vec<usize>) -> Vec<F> {
 80    let mut r: Vec<F> = vec![F::zero(); z.len()];
 81    for i in 0..z.len() {
 82        r[i] = F::from(z[i] as u64);
 83    }
 84    r
 85}
 86
 87#[cfg(test)]
 88mod tests {
 89    use super::*;
 90    use ark_bn254::{g1::G1Affine, Fr};
 91    use ark_ec::CurveGroup;
 92    use ark_std::{One, Zero};
 93    use std::ops::Mul;
 94
 95    #[test]
 96    fn test_matrix_vector_product() {
 97        let A = to_F_matrix::<Fr>(vec![
 98            vec![0, 1, 0, 0, 0, 0],
 99            vec![0, 0, 0, 1, 0, 0],
100            vec![0, 1, 0, 0, 1, 0],
101            vec![5, 0, 0, 0, 0, 1],
102        ]);
103        let z = to_F_vec(vec![1, 3, 35, 9, 27, 30]);
104        let Az = matrix_vector_product(&A, &z);
105        assert_eq!(Az, to_F_vec(vec![3, 9, 30, 35]));
106    }
107
108    #[test]
109    fn test_hadamard_product() {
110        let a = to_F_vec::<Fr>(vec![1, 2, 3, 4, 5, 6]);
111        let b = to_F_vec(vec![7, 8, 9, 10, 11, 12]);
112        assert_eq!(
113            hadamard_product(a, b),
114            to_F_vec(vec![7, 16, 27, 40, 55, 72])
115        );
116    }
117
118    #[test]
119    fn test_ABC_hadamard() {
120        let A = to_F_matrix::<Fr>(vec![
121            vec![0, 1, 0, 0, 0, 0],
122            vec![0, 0, 0, 1, 0, 0],
123            vec![0, 1, 0, 0, 1, 0],
124            vec![5, 0, 0, 0, 0, 1],
125        ]);
126        let B = to_F_matrix(vec![
127            vec![0, 1, 0, 0, 0, 0],
128            vec![0, 1, 0, 0, 0, 0],
129            vec![1, 0, 0, 0, 0, 0],
130            vec![1, 0, 0, 0, 0, 0],
131        ]);
132        let C = to_F_matrix(vec![
133            vec![0, 0, 0, 1, 0, 0],
134            vec![0, 0, 0, 0, 1, 0],
135            vec![0, 0, 0, 0, 0, 1],
136            vec![0, 0, 1, 0, 0, 0],
137        ]);
138        let z = to_F_vec(vec![1, 3, 35, 9, 27, 30]);
139
140        let Az = matrix_vector_product(&A, &z);
141        let Bz = matrix_vector_product(&B, &z);
142        let Cz = matrix_vector_product(&C, &z);
143        assert_eq!(hadamard_product(Az, Bz), Cz);
144    }
145}