1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use super::CRH;
use ark_crypto_primitives::crh::constraints::CRHGadget as CRHGadgetTrait;
use ark_ff::PrimeField;
use ark_r1cs_std::{alloc::AllocVar, fields::fp::FpVar, prelude::*, uint8::UInt8};
use ark_relations::r1cs::{Namespace, SynthesisError};
use ark_std::{marker::PhantomData, vec::Vec};
use arkworks_utils::utils::to_field_var_elements;
use core::borrow::Borrow;
pub struct CRHGadget<F: PrimeField> {
field: PhantomData<F>,
}
#[derive(Clone, Default)]
pub struct Params<F: PrimeField> {
field: PhantomData<F>,
}
impl<F: PrimeField> CRHGadgetTrait<CRH<F>, F> for CRHGadget<F> {
type OutputVar = FpVar<F>;
type ParametersVar = Params<F>;
fn evaluate(
_: &Self::ParametersVar,
input: &[UInt8<F>],
) -> Result<Self::OutputVar, SynthesisError> {
let f_var_inputs: Vec<FpVar<F>> = to_field_var_elements(input)?;
assert!(f_var_inputs.len() == 1);
f_var_inputs
.get(0)
.cloned()
.ok_or(SynthesisError::AssignmentMissing)
}
}
impl<F: PrimeField> AllocVar<(), F> for Params<F> {
fn new_variable<T: Borrow<()>>(
_: impl Into<Namespace<F>>,
_: impl FnOnce() -> Result<T, SynthesisError>,
_: AllocationMode,
) -> Result<Self, SynthesisError> {
Ok(Params { field: PhantomData })
}
}
#[cfg(test)]
mod test {
use super::{CRHGadget, FpVar, Params};
use ark_crypto_primitives::crh::constraints::CRHGadget as CRHGadgetTrait;
use ark_ed_on_bn254::Fq;
use ark_r1cs_std::{alloc::AllocVar, eq::EqGadget, R1CSVar, ToBytesGadget};
use ark_relations::r1cs::ConstraintSystem;
type IdentityCRHGadget = CRHGadget<Fq>;
#[test]
fn should_return_same_data() {
let val = Fq::from(4u64);
let cs = ConstraintSystem::<Fq>::new_ref();
let val_var = FpVar::<Fq>::new_input(cs, || Ok(val)).unwrap();
let bytes_var = val_var.to_bytes().unwrap();
let res_var = IdentityCRHGadget::evaluate(&Params::default(), &bytes_var).unwrap();
assert!(res_var.is_eq(&val_var).unwrap().value().unwrap());
}
}