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.

134 lines
4.2 KiB

  1. use ark_crypto_primitives::sponge::Absorb;
  2. use ark_ec::{CurveGroup, Group};
  3. use ark_ff::{Field, PrimeField};
  4. use std::marker::PhantomData;
  5. use ark_crypto_primitives::sponge::poseidon::{PoseidonConfig, PoseidonSponge};
  6. use ark_r1cs_std::{groups::GroupOpsBounds, prelude::CurveVar};
  7. use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError};
  8. use crate::circuits::{AugmentedFCircuit, ConstraintF};
  9. use crate::nifs::{FWit, Phi, NIFS, R1CS};
  10. use crate::pedersen::{Commitment, Params as PedersenParams, Pedersen, Proof as PedersenProof};
  11. use crate::transcript::Transcript;
  12. use ark_std::{One, Zero};
  13. use core::ops::Deref;
  14. pub struct IVCProof<C1: CurveGroup, C2: CurveGroup> {
  15. phi: Phi<C1>,
  16. // w: FWit<C1>,
  17. w: Vec<C1::ScalarField>,
  18. phiBig: Phi<C2>,
  19. // W: FWit<C2>,
  20. W: Vec<C2::ScalarField>,
  21. }
  22. pub struct IVC<
  23. C1: CurveGroup,
  24. GC1: CurveVar<C1, ConstraintF<C1>>,
  25. C2: CurveGroup,
  26. GC2: CurveVar<C2, ConstraintF<C2>>,
  27. > where
  28. C1: CurveGroup<BaseField = <C2 as Group>::ScalarField>,
  29. C2: CurveGroup<BaseField = <C1 as Group>::ScalarField>,
  30. {
  31. _c1: PhantomData<C1>,
  32. _gc1: PhantomData<GC1>,
  33. _c2: PhantomData<C2>,
  34. _gc2: PhantomData<GC2>,
  35. pub poseidon_config: PoseidonConfig<ConstraintF<C2>>,
  36. pub pedersen_params_C1: PedersenParams<C1>,
  37. pub pedersen_params_C2: PedersenParams<C2>,
  38. }
  39. impl<
  40. C1: CurveGroup,
  41. GC1: CurveVar<C1, ConstraintF<C1>>,
  42. C2: CurveGroup,
  43. GC2: CurveVar<C2, ConstraintF<C2>>,
  44. > IVC<C1, GC1, C2, GC2>
  45. where
  46. for<'a> &'a GC1: GroupOpsBounds<'a, C1, GC1>,
  47. for<'a> &'a GC2: GroupOpsBounds<'a, C2, GC2>,
  48. C1: CurveGroup<BaseField = <C2 as Group>::ScalarField>,
  49. C2: CurveGroup<BaseField = <C1 as Group>::ScalarField>,
  50. <C1 as Group>::ScalarField: Absorb,
  51. <C1 as CurveGroup>::BaseField: Absorb,
  52. <<C1 as CurveGroup>::BaseField as Field>::BasePrimeField: Absorb,
  53. <C1 as CurveGroup>::BaseField: PrimeField,
  54. // 2
  55. <C2 as Group>::ScalarField: Absorb,
  56. <C2 as CurveGroup>::BaseField: Absorb,
  57. <<C2 as CurveGroup>::BaseField as Field>::BasePrimeField: Absorb,
  58. <C2 as CurveGroup>::BaseField: PrimeField,
  59. {
  60. pub fn prove(
  61. &self,
  62. cs: ConstraintSystemRef<ConstraintF<C2>>,
  63. tr1: &mut Transcript<C1::ScalarField, C1>,
  64. tr2: &mut Transcript<C2::ScalarField, C2>,
  65. r1cs: &R1CS<C2::ScalarField>,
  66. i: C1::ScalarField,
  67. z_0: C1::ScalarField,
  68. z_i: C1::ScalarField,
  69. // phi1: &Phi<C>,
  70. // phi2: &Phi<C>,
  71. fw1: FWit<C2>,
  72. fw2: FWit<C2>,
  73. ) -> Result<IVCProof<C1, C2>, SynthesisError> {
  74. tr1.get_challenge();
  75. let r = tr2.get_challenge(); // TODO transcript usage is still WIP, will update with expected adds & gets
  76. // fold phi_i and phiBig_i
  77. let (fw3, phi1, phi2, _T, cmT) =
  78. NIFS::<C2>::P(tr2, &self.pedersen_params_C2, r, r1cs, fw1, fw2);
  79. let phi3 = NIFS::<C2>::V(r, &phi1, &phi2, &cmT);
  80. // TODO compute z_{i+1}
  81. let z_i1 = z_i.clone(); // WIP this will be the actual computed z_{i+1}
  82. let c = AugmentedFCircuit::<C2, GC2> {
  83. _c: PhantomData,
  84. _gc: PhantomData,
  85. poseidon_config: self.poseidon_config.clone(),
  86. i: Some(i),
  87. z_0: Some(z_0),
  88. z_i: Some(z_i),
  89. z_i1: Some(z_i1),
  90. phi: Some(phi1),
  91. phiBig: Some(phi2),
  92. phiOut: Some(phi3.clone()),
  93. cmT: Some(cmT.0),
  94. r: Some(r),
  95. };
  96. c.generate_constraints(cs.clone())?;
  97. // get w_{i+1}
  98. let cs1 = cs.borrow().unwrap();
  99. let cs2 = cs1.deref();
  100. let w_i1 = cs2.witness_assignment.clone();
  101. let x_i1 = cs2.instance_assignment.clone();
  102. let rW = tr1.get_challenge();
  103. let _ = tr2.get_challenge();
  104. // phi_{i+1} small
  105. let phi = Phi::<C1> {
  106. cmE: Commitment::<C1>(C1::zero()),
  107. u: C1::ScalarField::one(),
  108. cmW: Pedersen::commit(&self.pedersen_params_C1, &w_i1, &rW),
  109. x: x_i1[0], // check if pos 0 is 1
  110. };
  111. Ok(IVCProof {
  112. phiBig: phi3,
  113. W: fw3.W,
  114. phi, // phi_{i+1}
  115. w: w_i1, // w_{i+1}
  116. })
  117. }
  118. }