You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

188 lines
5.2 KiB

  1. use ark_ec::AffineRepr;
  2. use ark_ff::fields::PrimeField;
  3. use core::ops::{Add, Sub};
  4. use std::fmt;
  5. pub 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. }
  13. pub 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. }
  23. pub 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. // rlin: random linear combination
  33. // pub fn rlin<F: PrimeField>(a: Vec<F>, b: Vec<F>, r: F) -> Vec<F> {
  34. // vec_add(a, vector_elem_product(&b, &r)) // WIP probably group loops
  35. // }
  36. pub fn naive_msm<C: AffineRepr>(s: &Vec<C::ScalarField>, p: &Vec<C>) -> C {
  37. // TODO check lengths, or at least check s.len()>= p.len()
  38. let mut r = p[0].mul(s[0]);
  39. for i in 1..s.len() {
  40. r = p[i].mul(s[i]);
  41. }
  42. r.into()
  43. }
  44. pub fn vec_add<F: PrimeField>(a: &Vec<F>, b: &Vec<F>) -> Vec<F> {
  45. let mut r: Vec<F> = vec![F::zero(); a.len()];
  46. for i in 0..a.len() {
  47. r[i] = a[i] + b[i];
  48. }
  49. r
  50. }
  51. pub fn vec_sub<F: PrimeField>(a: Vec<F>, b: Vec<F>) -> Vec<F> {
  52. let mut r: Vec<F> = vec![F::zero(); a.len()];
  53. for i in 0..a.len() {
  54. r[i] = a[i] - b[i];
  55. }
  56. r
  57. }
  58. // instead of vec_{add/sub} can use Ve wrapper which has '+', '-' operators
  59. #[derive(Debug, Clone, PartialEq)]
  60. pub struct Ve<F: PrimeField>(pub Vec<F>);
  61. impl<F: PrimeField> fmt::Display for Ve<F> {
  62. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  63. for (i, e) in self.0.iter().enumerate() {
  64. if i == self.0.len() - 1 {
  65. write!(f, "{}", e)?;
  66. break;
  67. }
  68. write!(f, "{}, ", e)?;
  69. }
  70. Ok(())
  71. }
  72. }
  73. impl<F: PrimeField> Add<Ve<F>> for Ve<F> {
  74. type Output = Ve<F>;
  75. fn add(self, rhs_vec: Self) -> Ve<F> {
  76. let lhs = self.0.clone();
  77. let rhs = rhs_vec.0.clone();
  78. let mut r: Vec<F> = vec![F::zero(); lhs.len()];
  79. for i in 0..self.0.len() {
  80. r[i] = lhs[i] + rhs[i];
  81. }
  82. Ve(r)
  83. }
  84. }
  85. impl<F: PrimeField> Sub<Ve<F>> for Ve<F> {
  86. type Output = Ve<F>;
  87. fn sub(self, rhs_vec: Self) -> Ve<F> {
  88. let lhs = self.0.clone();
  89. let rhs = rhs_vec.0.clone();
  90. let mut r: Vec<F> = vec![F::zero(); lhs.len()];
  91. for i in 0..self.0.len() {
  92. r[i] = lhs[i] - rhs[i];
  93. }
  94. Ve(r)
  95. }
  96. }
  97. pub fn to_F_matrix<F: PrimeField>(M: Vec<Vec<usize>>) -> Vec<Vec<F>> {
  98. let mut R: Vec<Vec<F>> = vec![Vec::new(); M.len()];
  99. for i in 0..M.len() {
  100. R[i] = vec![F::zero(); M[i].len()];
  101. for j in 0..M[i].len() {
  102. R[i][j] = F::from(M[i][j] as u64);
  103. }
  104. }
  105. R
  106. }
  107. pub fn to_F_vec<F: PrimeField>(z: Vec<usize>) -> Vec<F> {
  108. let mut r: Vec<F> = vec![F::zero(); z.len()];
  109. for i in 0..z.len() {
  110. r[i] = F::from(z[i] as u64);
  111. }
  112. r
  113. }
  114. #[cfg(test)]
  115. mod tests {
  116. use super::*;
  117. use ark_bn254::{g1::G1Affine, Fr};
  118. use ark_ec::CurveGroup;
  119. use ark_std::{One, Zero};
  120. use std::ops::Mul;
  121. #[test]
  122. fn test_matrix_vector_product() {
  123. let A = to_F_matrix::<Fr>(vec![
  124. vec![0, 1, 0, 0, 0, 0],
  125. vec![0, 0, 0, 1, 0, 0],
  126. vec![0, 1, 0, 0, 1, 0],
  127. vec![5, 0, 0, 0, 0, 1],
  128. ]);
  129. let z = to_F_vec(vec![1, 3, 35, 9, 27, 30]);
  130. let Az = matrix_vector_product(&A, &z);
  131. assert_eq!(Az, to_F_vec(vec![3, 9, 30, 35]));
  132. }
  133. #[test]
  134. fn test_hadamard_product() {
  135. let a = to_F_vec::<Fr>(vec![1, 2, 3, 4, 5, 6]);
  136. let b = to_F_vec(vec![7, 8, 9, 10, 11, 12]);
  137. assert_eq!(
  138. hadamard_product(a, b),
  139. to_F_vec(vec![7, 16, 27, 40, 55, 72])
  140. );
  141. }
  142. #[test]
  143. fn test_vec_add() {
  144. let a: Vec<Fr> = to_F_vec::<Fr>(vec![1, 2, 3, 4, 5, 6]);
  145. let b: Vec<Fr> = to_F_vec(vec![7, 8, 9, 10, 11, 12]);
  146. assert_eq!(vec_add(&a, &b), (Ve(a) + Ve(b)).0);
  147. }
  148. #[test]
  149. fn test_ABC_hadamard() {
  150. let A = to_F_matrix::<Fr>(vec![
  151. vec![0, 1, 0, 0, 0, 0],
  152. vec![0, 0, 0, 1, 0, 0],
  153. vec![0, 1, 0, 0, 1, 0],
  154. vec![5, 0, 0, 0, 0, 1],
  155. ]);
  156. let B = to_F_matrix(vec![
  157. vec![0, 1, 0, 0, 0, 0],
  158. vec![0, 1, 0, 0, 0, 0],
  159. vec![1, 0, 0, 0, 0, 0],
  160. vec![1, 0, 0, 0, 0, 0],
  161. ]);
  162. let C = to_F_matrix(vec![
  163. vec![0, 0, 0, 1, 0, 0],
  164. vec![0, 0, 0, 0, 1, 0],
  165. vec![0, 0, 0, 0, 0, 1],
  166. vec![0, 0, 1, 0, 0, 0],
  167. ]);
  168. let z = to_F_vec(vec![1, 3, 35, 9, 27, 30]);
  169. let Az = matrix_vector_product(&A, &z);
  170. let Bz = matrix_vector_product(&B, &z);
  171. let Cz = matrix_vector_product(&C, &z);
  172. assert_eq!(hadamard_product(Az, Bz), Cz);
  173. }
  174. }