use super::*;
impl<E: Environment> Equal<Self> for StringType<E> {
type Output = Boolean<E>;
fn is_equal(&self, other: &Self) -> Self::Output {
let this = self.to_fields();
let that = other.to_fields();
self.size_in_bytes.is_equal(&other.size_in_bytes)
& this.iter().zip(&that).fold(Boolean::constant(true), |acc, (a, b)| acc & a.is_equal(b))
}
fn is_not_equal(&self, other: &Self) -> Self::Output {
!self.is_equal(other)
}
}
#[cfg(test)]
mod tests {
use super::*;
use snarkvm_circuit_environment::Circuit;
fn sample_string(mode: Mode, rng: &mut TestRng) -> StringType<Circuit> {
let given = rng.next_string(Circuit::MAX_STRING_BYTES / 4, true);
StringType::<Circuit>::new(mode, console::StringType::new(&given))
}
fn check_is_equal(
mode: Mode,
num_constants: u64,
num_public: u64,
num_private: u64,
num_constraints: u64,
) -> Result<()> {
let mut rng = TestRng::default();
let string_a = sample_string(mode, &mut rng);
let string_b = sample_string(mode, &mut rng);
Circuit::scope(format!("{mode}"), || {
let candidate = string_a.is_equal(&string_a);
assert!(candidate.eject_value());
assert_scope!(num_constants, num_public, num_private, num_constraints);
});
Circuit::scope(format!("{mode}"), || {
let candidate = string_a.is_equal(&string_b);
assert!(!candidate.eject_value());
assert_scope!(num_constants, num_public, num_private, num_constraints);
});
Circuit::reset();
Ok(())
}
fn check_is_not_equal(
mode: Mode,
num_constants: u64,
num_public: u64,
num_private: u64,
num_constraints: u64,
) -> Result<()> {
let mut rng = TestRng::default();
let string_a = sample_string(mode, &mut rng);
let string_b = sample_string(mode, &mut rng);
Circuit::scope(format!("{mode}"), || {
let candidate = string_a.is_not_equal(&string_b);
assert!(candidate.eject_value());
assert_scope!(num_constants, num_public, num_private, num_constraints);
});
Circuit::scope(format!("{mode}"), || {
let candidate = string_a.is_not_equal(&string_a);
assert!(!candidate.eject_value());
assert_scope!(num_constants, num_public, num_private, num_constraints);
});
Circuit::reset();
Ok(())
}
#[test]
fn test_is_equal_constant() -> Result<()> {
check_is_equal(Mode::Constant, 9, 0, 0, 0)
}
#[test]
fn test_is_equal_public() -> Result<()> {
check_is_equal(Mode::Public, 0, 0, 26, 35)
}
#[test]
fn test_is_equal_private() -> Result<()> {
check_is_equal(Mode::Private, 0, 0, 26, 35)
}
#[test]
fn test_is_not_equal_constant() -> Result<()> {
check_is_not_equal(Mode::Constant, 9, 0, 0, 0)
}
#[test]
fn test_is_not_equal_public() -> Result<()> {
check_is_not_equal(Mode::Public, 0, 0, 26, 35)
}
#[test]
fn test_is_not_equal_private() -> Result<()> {
check_is_not_equal(Mode::Private, 0, 0, 26, 35)
}
}