1use ark_ff::{Field, PrimeField};
2use ark_relations::gr1cs::SynthesisError;
3
4use crate::{boolean::Boolean, eq::EqGadget, GR1CSVar};
5
6pub trait CmpGadget<F: Field>: GR1CSVar<F> + EqGadget<F> {
8 fn is_gt(&self, other: &Self) -> Result<Boolean<F>, SynthesisError> {
10 other.is_lt(self)
11 }
12
13 fn is_ge(&self, other: &Self) -> Result<Boolean<F>, SynthesisError>;
15
16 fn is_lt(&self, other: &Self) -> Result<Boolean<F>, SynthesisError> {
18 Ok(!self.is_ge(other)?)
19 }
20
21 fn is_le(&self, other: &Self) -> Result<Boolean<F>, SynthesisError> {
23 other.is_ge(self)
24 }
25}
26
27impl<F: Field> CmpGadget<F> for () {
29 fn is_gt(&self, _other: &Self) -> Result<Boolean<F>, SynthesisError> {
30 Ok(Boolean::FALSE)
31 }
32
33 fn is_ge(&self, _other: &Self) -> Result<Boolean<F>, SynthesisError> {
34 Ok(Boolean::TRUE)
35 }
36
37 fn is_lt(&self, _other: &Self) -> Result<Boolean<F>, SynthesisError> {
38 Ok(Boolean::FALSE)
39 }
40
41 fn is_le(&self, _other: &Self) -> Result<Boolean<F>, SynthesisError> {
42 Ok(Boolean::TRUE)
43 }
44}
45
46impl<T: CmpGadget<F>, F: PrimeField> CmpGadget<F> for [T] {
49 fn is_ge(&self, other: &Self) -> Result<Boolean<F>, SynthesisError> {
50 let mut result = Boolean::TRUE;
51 let mut all_equal_so_far = Boolean::TRUE;
52 for (a, b) in self.iter().zip(other) {
53 all_equal_so_far &= a.is_eq(b)?;
54 result &= a.is_gt(b)? | &all_equal_so_far;
55 }
56 Ok(result)
57 }
58}