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.

145 lines
3.8 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;
  9. pub struct Proof<C: AffineRepr> {
  10. R: C,
  11. t1: C::ScalarField,
  12. t2: C::ScalarField,
  13. }
  14. pub struct Params<C: AffineRepr> {
  15. g: C,
  16. h: C,
  17. pub r_vec: Vec<C>,
  18. }
  19. pub struct Pedersen<C: AffineRepr> {
  20. _phantom: PhantomData<C>,
  21. }
  22. impl<C: AffineRepr> Pedersen<C> {
  23. pub fn new_params<R: Rng>(rng: &mut R, max: usize) -> Params<C> {
  24. let h_scalar = C::ScalarField::rand(rng);
  25. let g: C = C::generator();
  26. let r_vec: Vec<C> = vec![C::rand(rng); max];
  27. let params: Params<C> = Params::<C> {
  28. g,
  29. h: g.mul(h_scalar).into(),
  30. r_vec, // will need 2 r: rE, rW
  31. };
  32. params
  33. }
  34. pub fn commit_elem<R: RngCore>(
  35. rng: &mut R,
  36. params: &Params<C>,
  37. v: &C::ScalarField,
  38. ) -> CommitmentElem<C> {
  39. let r = C::ScalarField::rand(rng);
  40. let cm: C = (params.g.mul(v) + params.h.mul(r)).into();
  41. CommitmentElem::<C> { cm, r }
  42. }
  43. pub fn commit(rs: &Vec<C>, v: &Vec<C::ScalarField>) -> Commitment<C> {
  44. let cm = naive_msm(v, &rs);
  45. Commitment::<C>(cm)
  46. }
  47. pub fn prove_elem(
  48. params: &Params<C>,
  49. transcript: &mut Transcript<C::ScalarField>,
  50. cm: C,
  51. v: C::ScalarField,
  52. r: C::ScalarField,
  53. ) -> Proof<C> {
  54. let s1 = transcript.get_challenge(b"s_1");
  55. let s2 = transcript.get_challenge(b"s_2");
  56. let R: C = (params.g.mul(s1) + params.h.mul(s2)).into();
  57. transcript.add(b"cm", &cm);
  58. transcript.add(b"R", &R);
  59. let c = transcript.get_challenge(b"c");
  60. let t1 = s1 + v * c;
  61. let t2 = s2 + r * c;
  62. Proof::<C> { R, t1, t2 }
  63. }
  64. pub fn verify_elem(
  65. params: &Params<C>,
  66. transcript: &mut Transcript<C::ScalarField>,
  67. cm: C,
  68. proof: Proof<C>,
  69. ) -> bool {
  70. // s1, s2 just to match Prover's transcript
  71. transcript.get_challenge(b"s_1");
  72. transcript.get_challenge(b"s_2");
  73. transcript.add(b"cm", &cm);
  74. transcript.add(b"R", &proof.R);
  75. let c = transcript.get_challenge(b"c");
  76. let lhs = proof.R + cm.mul(c);
  77. let rhs = params.g.mul(proof.t1) + params.h.mul(proof.t2);
  78. if lhs != rhs {
  79. return false;
  80. }
  81. true
  82. }
  83. }
  84. pub struct Commitment<C: AffineRepr>(pub C);
  85. pub struct CommitmentElem<C: AffineRepr> {
  86. pub cm: C,
  87. pub r: C::ScalarField,
  88. }
  89. impl<C: AffineRepr> CommitmentElem<C> {
  90. pub fn prove(
  91. &self,
  92. params: &Params<C>,
  93. transcript: &mut Transcript<C::ScalarField>,
  94. v: C::ScalarField,
  95. ) -> Proof<C> {
  96. Pedersen::<C>::prove_elem(params, transcript, self.cm, v, self.r)
  97. }
  98. }
  99. #[cfg(test)]
  100. mod tests {
  101. use super::*;
  102. use ark_bn254::{g1::G1Affine, Fr};
  103. use ark_ec::CurveGroup;
  104. use std::ops::Mul;
  105. #[test]
  106. fn test_pedersen() {
  107. let mut rng = ark_std::test_rng();
  108. // setup params
  109. let params = Pedersen::<G1Affine>::new_params(
  110. &mut rng, 0, /* 0, as here we don't use commit_vec */
  111. );
  112. // init Prover's transcript
  113. let mut transcript_p: Transcript<Fr> = Transcript::<Fr>::new();
  114. // init Verifier's transcript
  115. let mut transcript_v: Transcript<Fr> = Transcript::<Fr>::new();
  116. let v = Fr::rand(&mut rng);
  117. let cm = Pedersen::commit_elem(&mut rng, &params, &v);
  118. let proof = cm.prove(&params, &mut transcript_p, v);
  119. // also can use:
  120. // let proof = Pedersen::prove_elem(&params, &mut transcript_p, cm.cm, v, cm.r);
  121. let v = Pedersen::verify_elem(&params, &mut transcript_v, cm.cm, proof);
  122. assert!(v);
  123. }
  124. }