liminal_ark_relations/preimage/
relation.rs

1use liminal_ark_relation_macro::snark_relation;
2
3/// This relation showcases how to use Poseidon in r1cs circuits
4#[snark_relation]
5mod relation {
6    #[cfg(feature = "circuit")]
7    use {
8        crate::environment::FpVar,
9        ark_r1cs_std::{alloc::AllocVar, eq::EqGadget},
10        ark_relations::ns,
11        liminal_ark_poseidon::circuit,
12    };
13
14    use crate::{
15        environment::CircuitField,
16        preimage::{FrontendHash, FrontendPreimage},
17        shielder::convert_hash,
18    };
19
20    /// Preimage relation : H(preimage)=hash
21    /// where:
22    /// - hash : public input
23    /// - preimage : private witness
24    #[relation_object_definition]
25    #[derive(Clone, Debug)]
26    struct PreimageRelation {
27        #[private_input(frontend_type = "FrontendPreimage", parse_with = "convert_hash")]
28        pub preimage: CircuitField,
29        #[public_input(frontend_type = "FrontendHash", parse_with = "convert_hash")]
30        pub hash: CircuitField,
31    }
32
33    #[cfg(feature = "circuit")]
34    #[circuit_definition]
35    fn generate_constraints(
36        self,
37        cs: ConstraintSystemRef<CircuitField>,
38    ) -> Result<(), SynthesisError> {
39        let preimage = FpVar::new_witness(ns!(cs, "preimage"), || self.preimage())?;
40        let hash = FpVar::new_input(ns!(cs, "hash"), || self.hash())?;
41        let hash_result = circuit::one_to_one_hash(cs, [preimage])?;
42
43        hash.enforce_equal(&hash_result)?;
44
45        Ok(())
46    }
47}