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.

277 lines
7.3 KiB

1 year ago
  1. extern crate ark_ed_on_bn254;
  2. use ark_ec::ProjectiveCurve;
  3. use ark_ed_on_bn254::{EdwardsProjective, Fr};
  4. use ark_ff::{fields::PrimeField, Field}; // BigInteger
  5. use ark_std::{UniformRand, Zero};
  6. #[allow(non_snake_case)]
  7. pub struct IPA {
  8. d: u32,
  9. H: EdwardsProjective,
  10. Gs: Vec<EdwardsProjective>,
  11. rng: rand::rngs::ThreadRng,
  12. }
  13. #[allow(non_snake_case)]
  14. pub struct Proof {
  15. a: Fr,
  16. b: Fr, // TODO not needed
  17. G: EdwardsProjective, // TODO not needed
  18. l: Vec<Fr>,
  19. r: Vec<Fr>,
  20. L: Vec<EdwardsProjective>,
  21. R: Vec<EdwardsProjective>,
  22. }
  23. #[allow(non_snake_case)]
  24. #[allow(clippy::many_single_char_names)]
  25. impl IPA {
  26. pub fn new(d: u32) -> IPA {
  27. let mut rng = ark_std::rand::thread_rng();
  28. let mut gs: Vec<EdwardsProjective> = Vec::new();
  29. for _ in 0..d {
  30. gs.push(EdwardsProjective::rand(&mut rng));
  31. }
  32. IPA {
  33. d,
  34. H: EdwardsProjective::rand(&mut rng),
  35. Gs: gs,
  36. rng,
  37. }
  38. }
  39. pub fn commit(&self, a: &[Fr], r: Fr) -> EdwardsProjective {
  40. inner_product_point(a, &self.Gs) + self.H.mul(r.into_repr())
  41. }
  42. pub fn ipa(&mut self, a: &[Fr], b: &[Fr], u: &[Fr], U: &EdwardsProjective) -> Proof {
  43. let mut a = a.to_owned();
  44. let mut b = b.to_owned();
  45. let mut G = self.Gs.clone();
  46. let k = (f64::from(self.d as u32).log2()) as usize;
  47. let mut l: Vec<Fr> = vec![Fr::zero(); k];
  48. let mut r: Vec<Fr> = vec![Fr::zero(); k];
  49. let mut L: Vec<EdwardsProjective> = vec![EdwardsProjective::zero(); k];
  50. let mut R: Vec<EdwardsProjective> = vec![EdwardsProjective::zero(); k];
  51. for j in (0..k).rev() {
  52. let m = a.len() / 2;
  53. let a_lo = a[..m].to_vec();
  54. let a_hi = a[m..].to_vec();
  55. let b_lo = b[..m].to_vec();
  56. let b_hi = b[m..].to_vec();
  57. let G_lo = G[..m].to_vec();
  58. let G_hi = G[m..].to_vec();
  59. l[j] = Fr::rand(&mut self.rng);
  60. r[j] = Fr::rand(&mut self.rng);
  61. L[j] = inner_product_point(&a_lo, &G_hi)
  62. + self.H.mul(l[j].into_repr())
  63. + U.mul(inner_product_field(&a_lo, &b_hi).into_repr());
  64. R[j] = inner_product_point(&a_hi, &G_lo)
  65. + self.H.mul(r[j].into_repr())
  66. + U.mul(inner_product_field(&a_hi, &b_lo).into_repr());
  67. let uj = u[j];
  68. let uj_inv = u[j].inverse().unwrap();
  69. a = vec_add(
  70. &vec_scalar_mul_field(&a_lo, &uj),
  71. &vec_scalar_mul_field(&a_hi, &uj_inv),
  72. );
  73. b = vec_add(
  74. &vec_scalar_mul_field(&b_lo, &uj_inv),
  75. &vec_scalar_mul_field(&b_hi, &uj),
  76. );
  77. G = vec_add_point(
  78. &vec_scalar_mul_point(&G_lo, &uj_inv),
  79. &vec_scalar_mul_point(&G_hi, &uj),
  80. );
  81. }
  82. // TODO assert len a,b,G == 1
  83. Proof {
  84. a: a[0],
  85. b: b[0],
  86. G: G[0],
  87. l,
  88. r,
  89. L,
  90. R,
  91. }
  92. }
  93. pub fn verify(
  94. &self,
  95. P: &EdwardsProjective,
  96. p: &Proof,
  97. r: &Fr,
  98. u: &[Fr],
  99. U: &EdwardsProjective,
  100. ) -> bool {
  101. let mut q_0 = *P;
  102. let mut r = *r;
  103. // TODO compute b & G without getting them in the proof package
  104. #[allow(clippy::needless_range_loop)]
  105. for j in 0..u.len() {
  106. let uj2 = u[j].square();
  107. let uj_inv2 = u[j].inverse().unwrap().square();
  108. q_0 = q_0 + p.L[j].mul(uj2.into_repr()) + p.R[j].mul(uj_inv2.into_repr());
  109. r = r + p.l[j] * uj2 + p.r[j] * uj_inv2;
  110. }
  111. let q_1 =
  112. p.G.mul(p.a.into_repr()) + self.H.mul(r.into_repr()) + U.mul((p.a * p.b).into_repr());
  113. q_0 == q_1
  114. }
  115. }
  116. fn inner_product_field(a: &[Fr], b: &[Fr]) -> Fr {
  117. // TODO require lens equal
  118. let mut c: Fr = Fr::zero();
  119. for i in 0..a.len() {
  120. c += a[i] * b[i];
  121. }
  122. c
  123. }
  124. fn inner_product_point(a: &[Fr], b: &[EdwardsProjective]) -> EdwardsProjective {
  125. // TODO require lens equal
  126. let mut c: EdwardsProjective = EdwardsProjective::zero();
  127. for i in 0..a.len() {
  128. c += b[i].mul(a[i].into_repr());
  129. }
  130. c
  131. }
  132. fn vec_add(a: &[Fr], b: &[Fr]) -> Vec<Fr> {
  133. // TODO require len equal
  134. let mut c: Vec<Fr> = vec![Fr::zero(); a.len()];
  135. for i in 0..a.len() {
  136. c[i] = a[i] + b[i];
  137. }
  138. c
  139. }
  140. fn vec_add_point(a: &[EdwardsProjective], b: &[EdwardsProjective]) -> Vec<EdwardsProjective> {
  141. // TODO require len equal
  142. let mut c: Vec<EdwardsProjective> = vec![EdwardsProjective::zero(); a.len()];
  143. for i in 0..a.len() {
  144. c[i] = a[i] + b[i];
  145. }
  146. c
  147. }
  148. fn vec_scalar_mul_field(a: &[Fr], b: &Fr) -> Vec<Fr> {
  149. let mut c: Vec<Fr> = vec![Fr::zero(); a.len()];
  150. for i in 0..a.len() {
  151. c[i] = a[i] * b;
  152. }
  153. c
  154. }
  155. fn vec_scalar_mul_point(a: &[EdwardsProjective], b: &Fr) -> Vec<EdwardsProjective> {
  156. let mut c: Vec<EdwardsProjective> = vec![EdwardsProjective::zero(); a.len()];
  157. for i in 0..a.len() {
  158. c[i] = a[i].mul(b.into_repr());
  159. }
  160. c
  161. }
  162. #[allow(dead_code)]
  163. fn powers_of(x: Fr, d: u32) -> Vec<Fr> {
  164. let mut c: Vec<Fr> = vec![Fr::zero(); d as usize];
  165. c[0] = x;
  166. for i in 1..d as usize {
  167. // TODO redo better
  168. c[i] = c[i - 1] * x;
  169. }
  170. c
  171. }
  172. // fn inner_product<T>(a: Vec<T>, b: Vec<T>) -> T {
  173. // // require lens equal
  174. // let mut c: T = Zero();
  175. // for i in 0..a.len() {
  176. // c = c + a[i] * b[i];
  177. // }
  178. // c
  179. // }
  180. #[cfg(test)]
  181. #[allow(non_snake_case)]
  182. mod tests {
  183. use super::*;
  184. #[test]
  185. fn test_utils() {
  186. // let a = Fr::from(1 as u32);
  187. // let b = Fr::one();
  188. // println!("A: {:?}", Fr::from(1 as u32));
  189. // println!("A: {:?}", a);
  190. // println!("B: {:?}", b);
  191. let a = vec![
  192. Fr::from(1 as u32),
  193. Fr::from(2 as u32),
  194. Fr::from(3 as u32),
  195. Fr::from(4 as u32),
  196. ];
  197. let b = vec![
  198. Fr::from(1 as u32),
  199. Fr::from(2 as u32),
  200. Fr::from(3 as u32),
  201. Fr::from(4 as u32),
  202. ];
  203. let c = inner_product_field(&a, &b);
  204. println!("c: {:?}", c);
  205. // let result = 2 + 2;
  206. // assert_eq!(result, 4);
  207. }
  208. #[test]
  209. fn test_inner_product() {
  210. let d = 8;
  211. let mut ipa = IPA::new(d);
  212. let a = vec![
  213. Fr::from(1 as u32),
  214. Fr::from(2 as u32),
  215. Fr::from(3 as u32),
  216. Fr::from(4 as u32),
  217. Fr::from(5 as u32),
  218. Fr::from(6 as u32),
  219. Fr::from(7 as u32),
  220. Fr::from(8 as u32),
  221. ];
  222. let x = Fr::from(3 as u32);
  223. let b = powers_of(x, ipa.d);
  224. let r = Fr::rand(&mut ipa.rng);
  225. let mut P = ipa.commit(&a, r);
  226. let v = inner_product_field(&a, &b);
  227. let U = EdwardsProjective::rand(&mut ipa.rng);
  228. let k = (f64::from(ipa.d as u32).log2()) as usize;
  229. let mut u: Vec<Fr> = vec![Fr::zero(); k];
  230. for j in 0..k {
  231. u[j] = Fr::rand(&mut ipa.rng);
  232. }
  233. P = P + U.mul(v.into_repr());
  234. let proof = ipa.ipa(&a, &b, &u, &U);
  235. let verif = ipa.verify(&P, &proof, &r, &u, &U);
  236. assert!(verif);
  237. }
  238. }