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.

125 lines
3.5 KiB

  1. use ark_ec::{AffineRepr, CurveGroup, Group};
  2. use ark_ff::PrimeField;
  3. use ark_serialize::CanonicalSerialize;
  4. use std::marker::PhantomData;
  5. use ark_r1cs_std::fields::fp::FpVar;
  6. use ark_crypto_primitives::sponge::poseidon::{
  7. constraints::PoseidonSpongeVar, PoseidonConfig, PoseidonSponge,
  8. };
  9. use ark_crypto_primitives::sponge::{
  10. constraints::CryptographicSpongeVar, Absorb, CryptographicSponge,
  11. };
  12. use ark_relations::r1cs::{ConstraintSystemRef, SynthesisError};
  13. use ark_poly::DenseUVPolynomial;
  14. pub struct Transcript<F: PrimeField + Absorb, C: CurveGroup>
  15. where
  16. <C as CurveGroup>::BaseField: Absorb,
  17. {
  18. // where F is the Constraint Field (eq. C::ScalarField)
  19. sponge: PoseidonSponge<F>,
  20. _c: PhantomData<C>,
  21. }
  22. impl<F: PrimeField + Absorb, C: CurveGroup> Transcript<F, C>
  23. where
  24. <C as CurveGroup>::BaseField: Absorb,
  25. {
  26. pub fn new(poseidon_config: &PoseidonConfig<F>) -> Self {
  27. let mut sponge = PoseidonSponge::<F>::new(&poseidon_config);
  28. Transcript {
  29. sponge,
  30. _c: PhantomData,
  31. }
  32. }
  33. pub fn add(&mut self, v: &F) {
  34. self.sponge.absorb(&v);
  35. }
  36. pub fn add_vec(&mut self, v: &[F]) {
  37. self.sponge.absorb(&v);
  38. }
  39. pub fn add_point(&mut self, v: &C) {
  40. let v_affine = v.into_affine();
  41. let xy = v_affine.xy().unwrap(); // WIP
  42. self.sponge.absorb(&vec![xy.0, xy.1]);
  43. }
  44. pub fn get_challenge(&mut self) -> F {
  45. let c = self.sponge.squeeze_field_elements(1);
  46. self.add(&c[0]);
  47. c[0]
  48. }
  49. pub fn get_challenge_vec(&mut self, n: usize) -> Vec<F> {
  50. let c = self.sponge.squeeze_field_elements(n);
  51. self.sponge.absorb(&c);
  52. c
  53. }
  54. }
  55. pub struct TranscriptVar<F: PrimeField> {
  56. // where F is the Constraint Field
  57. sponge: PoseidonSpongeVar<F>,
  58. }
  59. impl<F: PrimeField> TranscriptVar<F> {
  60. pub fn new(cs: ConstraintSystemRef<F>, poseidon_config: PoseidonConfig<F>) -> Self {
  61. let mut sponge = PoseidonSpongeVar::<F>::new(cs.clone(), &poseidon_config);
  62. Self { sponge }
  63. }
  64. pub fn add(&mut self, v: FpVar<F>) -> Result<(), SynthesisError> {
  65. self.sponge.absorb(&v)
  66. }
  67. pub fn get_challenge(&mut self) -> Result<FpVar<F>, SynthesisError> {
  68. let c = self.sponge.squeeze_field_elements(1)?;
  69. self.sponge.absorb(&c[0]);
  70. Ok(c[0].clone())
  71. }
  72. pub fn get_challenge_vec(&mut self, n: usize) -> Result<Vec<FpVar<F>>, SynthesisError> {
  73. let c = self.sponge.squeeze_field_elements(n)?;
  74. self.sponge.absorb(&c);
  75. Ok(c)
  76. }
  77. }
  78. use ark_crypto_primitives::sponge::poseidon::find_poseidon_ark_and_mds;
  79. // WARNING this is for test only
  80. pub fn poseidon_test_config<F: PrimeField>() -> PoseidonConfig<F> {
  81. let full_rounds = 8;
  82. let partial_rounds = 31;
  83. let alpha = 5;
  84. let rate = 2;
  85. let (ark, mds) = find_poseidon_ark_and_mds::<F>(
  86. F::MODULUS_BIT_SIZE as u64,
  87. rate,
  88. full_rounds,
  89. partial_rounds,
  90. 0,
  91. );
  92. PoseidonConfig::new(
  93. full_rounds as usize,
  94. partial_rounds as usize,
  95. alpha,
  96. mds,
  97. ark,
  98. rate,
  99. 1,
  100. )
  101. }
  102. // #[cfg(test)]
  103. // mod tests {
  104. // use super::*;
  105. // use ark_mnt4_298::{Fr, G1Projective}; // scalar field
  106. // use ark_std::{One, Zero};
  107. //
  108. // #[test]
  109. // fn test_poseidon() {
  110. // let config = poseidon_test_config::<Fr>();
  111. // let mut tr = Transcript::<Fr, G1Projective>::new(&config);
  112. // tr.add(&Fr::one());
  113. // println!("c {:?}", tr.get_challenge().to_string());
  114. // }
  115. // }