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.

187 lines
5.1 KiB

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