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.

215 lines
6.2 KiB

  1. use ark_ec::AffineRepr;
  2. use ark_std::{
  3. rand::{Rng, RngCore},
  4. UniformRand,
  5. };
  6. use std::marker::PhantomData;
  7. use crate::transcript::Transcript;
  8. use crate::utils::{naive_msm, vec_add, vector_elem_product};
  9. pub struct Proof_elem<C: AffineRepr> {
  10. R: C,
  11. t1: C::ScalarField,
  12. t2: C::ScalarField,
  13. }
  14. pub struct Proof<C: AffineRepr> {
  15. R: C,
  16. u_: Vec<C::ScalarField>,
  17. ru_: C::ScalarField,
  18. }
  19. pub struct Params<C: AffineRepr> {
  20. g: C,
  21. h: C,
  22. pub r_vec: Vec<C>,
  23. }
  24. pub struct Pedersen<C: AffineRepr> {
  25. _phantom: PhantomData<C>,
  26. }
  27. impl<C: AffineRepr> Pedersen<C> {
  28. pub fn new_params<R: Rng>(rng: &mut R, max: usize) -> Params<C> {
  29. let h_scalar = C::ScalarField::rand(rng);
  30. let g: C = C::generator();
  31. let r_vec: Vec<C> = vec![C::rand(rng); max];
  32. let params: Params<C> = Params::<C> {
  33. g,
  34. h: g.mul(h_scalar).into(),
  35. r_vec, // will need 2 r: rE, rW
  36. };
  37. params
  38. }
  39. pub fn commit_elem<R: RngCore>(
  40. rng: &mut R,
  41. params: &Params<C>,
  42. v: &C::ScalarField,
  43. ) -> CommitmentElem<C> {
  44. let r = C::ScalarField::rand(rng);
  45. let cm: C = (params.g.mul(v) + params.h.mul(r)).into();
  46. CommitmentElem::<C> { cm, r }
  47. }
  48. pub fn commit(
  49. params: &Params<C>,
  50. v: &Vec<C::ScalarField>,
  51. r: &C::ScalarField, // random value is provided, in order to be choosen by other parts of the protocol
  52. ) -> Commitment<C> {
  53. let cm = params.h.mul(r) + naive_msm(v, &params.r_vec);
  54. Commitment::<C>(cm.into())
  55. }
  56. pub fn prove_elem(
  57. params: &Params<C>,
  58. transcript: &mut Transcript<C::ScalarField>,
  59. cm: C,
  60. v: C::ScalarField,
  61. r: C::ScalarField,
  62. ) -> Proof_elem<C> {
  63. let r1 = transcript.get_challenge(b"r_1");
  64. let r2 = transcript.get_challenge(b"r_2");
  65. let R: C = (params.g.mul(r1) + params.h.mul(r2)).into();
  66. transcript.add(b"cm", &cm);
  67. transcript.add(b"R", &R);
  68. let e = transcript.get_challenge(b"e");
  69. let t1 = r1 + v * e;
  70. let t2 = r2 + r * e;
  71. Proof_elem::<C> { R, t1, t2 }
  72. }
  73. pub fn prove(
  74. params: &Params<C>,
  75. transcript: &mut Transcript<C::ScalarField>,
  76. cm: &Commitment<C>, // TODO maybe it makes sense to not have a type wrapper and use directly C
  77. v: Vec<C::ScalarField>,
  78. r: C::ScalarField,
  79. ) -> Proof<C> {
  80. let r1 = transcript.get_challenge(b"r_1");
  81. let d = transcript.get_challenge_vec(b"d", v.len());
  82. let R: C = (params.h.mul(r1) + naive_msm(&d, &params.r_vec)).into();
  83. transcript.add(b"cm", &cm.0);
  84. transcript.add(b"R", &R);
  85. let e = transcript.get_challenge(b"e");
  86. let u_ = vec_add(&vector_elem_product(&v, &e), &d);
  87. let ru_ = e * r + r1;
  88. Proof::<C> { R, u_, ru_ }
  89. }
  90. pub fn verify(
  91. params: &Params<C>,
  92. transcript: &mut Transcript<C::ScalarField>,
  93. cm: Commitment<C>,
  94. proof: Proof<C>,
  95. ) -> bool {
  96. // r1, d just to match Prover's transcript
  97. transcript.get_challenge(b"r_1");
  98. transcript.get_challenge_vec(b"d", proof.u_.len());
  99. transcript.add(b"cm", &cm.0);
  100. transcript.add(b"R", &proof.R);
  101. let e = transcript.get_challenge(b"e");
  102. let lhs = proof.R + cm.0.mul(e);
  103. let rhs = params.h.mul(proof.ru_) + naive_msm(&proof.u_, &params.r_vec);
  104. if lhs != rhs {
  105. return false;
  106. }
  107. true
  108. }
  109. pub fn verify_elem(
  110. params: &Params<C>,
  111. transcript: &mut Transcript<C::ScalarField>,
  112. cm: C,
  113. proof: Proof_elem<C>,
  114. ) -> bool {
  115. // s1, s2 just to match Prover's transcript
  116. transcript.get_challenge(b"r_1");
  117. transcript.get_challenge(b"r_2");
  118. transcript.add(b"cm", &cm);
  119. transcript.add(b"R", &proof.R);
  120. let e = transcript.get_challenge(b"e");
  121. let lhs = proof.R + cm.mul(e);
  122. let rhs = params.g.mul(proof.t1) + params.h.mul(proof.t2);
  123. if lhs != rhs {
  124. return false;
  125. }
  126. true
  127. }
  128. }
  129. pub struct Commitment<C: AffineRepr>(pub C);
  130. pub struct CommitmentElem<C: AffineRepr> {
  131. pub cm: C,
  132. pub r: C::ScalarField,
  133. }
  134. impl<C: AffineRepr> CommitmentElem<C> {
  135. pub fn prove(
  136. &self,
  137. params: &Params<C>,
  138. transcript: &mut Transcript<C::ScalarField>,
  139. v: C::ScalarField,
  140. ) -> Proof_elem<C> {
  141. Pedersen::<C>::prove_elem(params, transcript, self.cm, v, self.r)
  142. }
  143. }
  144. #[cfg(test)]
  145. mod tests {
  146. use super::*;
  147. use ark_bn254::{g1::G1Affine, Fr};
  148. use ark_ec::CurveGroup;
  149. use std::ops::Mul;
  150. #[test]
  151. fn test_pedersen_single_element() {
  152. let mut rng = ark_std::test_rng();
  153. // setup params
  154. let params = Pedersen::<G1Affine>::new_params(
  155. &mut rng, 0, /* 0, as here we don't use commit_vec */
  156. );
  157. // init Prover's transcript
  158. let mut transcript_p: Transcript<Fr> = Transcript::<Fr>::new();
  159. // init Verifier's transcript
  160. let mut transcript_v: Transcript<Fr> = Transcript::<Fr>::new();
  161. let v = Fr::rand(&mut rng);
  162. let cm = Pedersen::commit_elem(&mut rng, &params, &v);
  163. let proof = cm.prove(&params, &mut transcript_p, v);
  164. // also can use:
  165. // let proof = Pedersen::prove_elem(&params, &mut transcript_p, cm.cm, v, cm.r);
  166. let v = Pedersen::verify_elem(&params, &mut transcript_v, cm.cm, proof);
  167. assert!(v);
  168. }
  169. #[test]
  170. fn test_pedersen_vector() {
  171. let mut rng = ark_std::test_rng();
  172. const n: usize = 10;
  173. // setup params
  174. let params = Pedersen::<G1Affine>::new_params(&mut rng, n);
  175. // init Prover's transcript
  176. let mut transcript_p: Transcript<Fr> = Transcript::<Fr>::new();
  177. // init Verifier's transcript
  178. let mut transcript_v: Transcript<Fr> = Transcript::<Fr>::new();
  179. let v: Vec<Fr> = vec![Fr::rand(&mut rng); n];
  180. let r: Fr = Fr::rand(&mut rng);
  181. let cm = Pedersen::commit(&params, &v, &r);
  182. let proof = Pedersen::prove(&params, &mut transcript_p, &cm, v, r);
  183. let v = Pedersen::verify(&params, &mut transcript_v, cm, proof);
  184. assert!(v);
  185. }
  186. }