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.

139 lines
4.4 KiB

  1. use ark_crypto_primitives::sponge::Absorb;
  2. use ark_ec::{CurveGroup, Group};
  3. use ark_ff::{BigInteger, 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, FCircuit};
  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. FC: FCircuit<C1::ScalarField>,
  28. > where
  29. C1: CurveGroup<BaseField = <C2 as Group>::ScalarField>,
  30. C2: CurveGroup<BaseField = <C1 as Group>::ScalarField>,
  31. {
  32. _c1: PhantomData<C1>,
  33. _gc1: PhantomData<GC1>,
  34. _c2: PhantomData<C2>,
  35. _gc2: PhantomData<GC2>,
  36. _fc: PhantomData<FC>,
  37. pub poseidon_config: PoseidonConfig<ConstraintF<C2>>,
  38. pub pedersen_params_C1: PedersenParams<C1>,
  39. pub pedersen_params_C2: PedersenParams<C2>,
  40. pub F: FC, // F circuit
  41. }
  42. impl<
  43. C1: CurveGroup,
  44. GC1: CurveVar<C1, ConstraintF<C1>>,
  45. C2: CurveGroup,
  46. GC2: CurveVar<C2, ConstraintF<C2>>,
  47. FC: FCircuit<C1::ScalarField>,
  48. > IVC<C1, GC1, C2, GC2, FC>
  49. where
  50. for<'a> &'a GC1: GroupOpsBounds<'a, C1, GC1>,
  51. for<'a> &'a GC2: GroupOpsBounds<'a, C2, GC2>,
  52. C1: CurveGroup<BaseField = <C2 as Group>::ScalarField>,
  53. C2: CurveGroup<BaseField = <C1 as Group>::ScalarField>,
  54. <C1 as Group>::ScalarField: Absorb,
  55. <C1 as CurveGroup>::BaseField: Absorb,
  56. <<C1 as CurveGroup>::BaseField as Field>::BasePrimeField: Absorb,
  57. <C1 as CurveGroup>::BaseField: PrimeField,
  58. // 2
  59. <C2 as Group>::ScalarField: Absorb,
  60. <C2 as CurveGroup>::BaseField: Absorb,
  61. <<C2 as CurveGroup>::BaseField as Field>::BasePrimeField: Absorb,
  62. <C2 as CurveGroup>::BaseField: PrimeField,
  63. {
  64. pub fn prove(
  65. &self,
  66. cs: ConstraintSystemRef<ConstraintF<C2>>,
  67. // TODO move part of these parameters to struct constructor instead of prove method
  68. tr1: &mut Transcript<C1::ScalarField, C1>,
  69. tr2: &mut Transcript<C2::ScalarField, C2>,
  70. r1cs: &R1CS<C2::ScalarField>,
  71. i: C1::ScalarField,
  72. z_0: C1::ScalarField,
  73. z_i: C1::ScalarField,
  74. fw1: FWit<C2>,
  75. fw2: FWit<C2>,
  76. ) -> Result<IVCProof<C1, C2>, SynthesisError> {
  77. tr1.get_challenge();
  78. let r = tr2.get_challenge(); // TODO transcript usage is still WIP, will update with expected adds & gets
  79. // fold phi_i and phiBig_i
  80. let (fw3, phi1, phi2, _T, cmT) =
  81. NIFS::<C2>::P(tr2, &self.pedersen_params_C2, r, r1cs, fw1, fw2);
  82. let phi3 = NIFS::<C2>::V(r, &phi1, &phi2, &cmT);
  83. // get z_{i+1}
  84. let (_, F_z_i1) = self.F.public();
  85. let c = AugmentedFCircuit::<C2, GC2, FC> {
  86. _c: PhantomData,
  87. _gc: PhantomData,
  88. poseidon_config: self.poseidon_config.clone(),
  89. i: Some(i),
  90. z_0: Some(z_0),
  91. z_i: Some(z_i),
  92. z_i1: Some(F_z_i1),
  93. phi: Some(phi1),
  94. phiBig: Some(phi2),
  95. phiBigOut: Some(phi3.clone()),
  96. cmT: Some(cmT.0),
  97. r: Some(r),
  98. F: self.F,
  99. x: i, // TODO WIP put x in there
  100. };
  101. c.generate_constraints(cs.clone())?;
  102. // get w_{i+1}
  103. let cs1 = cs.borrow().unwrap();
  104. let cs2 = cs1.deref();
  105. let w_i1 = cs2.witness_assignment.clone();
  106. let x_i1 = cs2.instance_assignment.clone();
  107. let rW = tr1.get_challenge();
  108. let _ = tr2.get_challenge();
  109. // phi_{i+1} small
  110. let phi = Phi::<C1> {
  111. cmE: Commitment::<C1>(C1::zero()),
  112. u: C1::ScalarField::one(),
  113. cmW: Pedersen::commit(&self.pedersen_params_C1, &w_i1, &rW),
  114. x: x_i1[0], // check if pos 0 is 1
  115. };
  116. Ok(IVCProof {
  117. phiBig: phi3,
  118. W: fw3.W,
  119. phi, // phi_{i+1}
  120. w: w_i1, // w_{i+1}
  121. })
  122. }
  123. }