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.

122 lines
3.1 KiB

  1. use ark_ec::AffineRepr;
  2. use ark_std::{rand::RngCore, UniformRand};
  3. use std::marker::PhantomData;
  4. use crate::transcript::Transcript;
  5. pub struct Proof<C: AffineRepr> {
  6. R: C,
  7. t1: C::ScalarField,
  8. t2: C::ScalarField,
  9. }
  10. pub struct Params<C: AffineRepr> {
  11. g: C,
  12. h: C,
  13. }
  14. pub struct Pedersen<C: AffineRepr> {
  15. _phantom: PhantomData<C>,
  16. }
  17. impl<C: AffineRepr> Pedersen<C> {
  18. pub fn commit<R: RngCore>(
  19. rng: &mut R,
  20. params: &Params<C>,
  21. v: &C::ScalarField,
  22. ) -> (C, C::ScalarField) {
  23. let r = C::ScalarField::rand(rng);
  24. let cm: C = (params.g.mul(v) + params.h.mul(r)).into();
  25. (cm, r)
  26. }
  27. pub fn prove(
  28. params: &Params<C>,
  29. transcript: &mut Transcript<C::ScalarField>,
  30. cm: C,
  31. v: C::ScalarField,
  32. r: C::ScalarField,
  33. ) -> Proof<C> {
  34. let s1 = transcript.get_challenge(b"s_1");
  35. let s2 = transcript.get_challenge(b"s_2");
  36. let R: C = (params.g.mul(s1) + params.h.mul(s2)).into();
  37. transcript.add(b"cm", &cm);
  38. transcript.add(b"R", &R);
  39. let c = transcript.get_challenge(b"c");
  40. let t1 = s1 + v * c;
  41. let t2 = s2 + r * c;
  42. Proof::<C> { R, t1, t2 }
  43. }
  44. pub fn verify(
  45. params: &Params<C>,
  46. transcript: &mut Transcript<C::ScalarField>,
  47. cm: C,
  48. proof: Proof<C>,
  49. ) -> bool {
  50. // s1, s2 just to match Prover's transcript
  51. transcript.get_challenge(b"s_1");
  52. transcript.get_challenge(b"s_2");
  53. transcript.add(b"cm", &cm);
  54. transcript.add(b"R", &proof.R);
  55. let c = transcript.get_challenge(b"c");
  56. let lhs = proof.R + cm.mul(c);
  57. let rhs = params.g.mul(proof.t1) + params.h.mul(proof.t2);
  58. if lhs != rhs {
  59. return false;
  60. }
  61. true
  62. }
  63. }
  64. pub struct Commitment<C: AffineRepr> {
  65. pub cm: C,
  66. pub r: C::ScalarField,
  67. }
  68. impl<C: AffineRepr> Commitment<C> {
  69. pub fn prove(
  70. self,
  71. params: &Params<C>,
  72. transcript: &mut Transcript<C::ScalarField>,
  73. v: C::ScalarField,
  74. ) -> Proof<C> {
  75. Pedersen::<C>::prove(params, transcript, self.cm, v, self.r)
  76. }
  77. }
  78. #[cfg(test)]
  79. mod tests {
  80. use super::*;
  81. use ark_bn254::{g1::G1Affine, Fr};
  82. use ark_ec::CurveGroup;
  83. use std::ops::Mul;
  84. #[test]
  85. fn test_pedersen() {
  86. let mut rng = ark_std::test_rng();
  87. // setup params
  88. let h_scalar = Fr::rand(&mut rng);
  89. let g: G1Affine = G1Affine::generator();
  90. let params: Params<G1Affine> = Params::<G1Affine> {
  91. g,
  92. h: g.mul(h_scalar).into_affine(),
  93. };
  94. // init Prover's transcript
  95. let mut transcript_p: Transcript<Fr> = Transcript::<Fr>::new();
  96. // init Verifier's transcript
  97. let mut transcript_v: Transcript<Fr> = Transcript::<Fr>::new();
  98. let v = Fr::rand(&mut rng);
  99. let (cm, r) = Pedersen::commit(&mut rng, &params, &v);
  100. let proof = Pedersen::prove(&params, &mut transcript_p, cm, v, r);
  101. let v = Pedersen::verify(&params, &mut transcript_v, cm, proof);
  102. assert!(v);
  103. }
  104. }