pairing_plus/
signum.rs

1/*!
2Signum trait: sgn0 for field elements
3*/
4
5use ff::Field;
6use std::ops::BitXor;
7
8/// Result of Sgn0
9#[derive(Debug, PartialEq, Eq)]
10pub enum Sgn0Result {
11    /// Either 0 or positive
12    NonNegative,
13    /// Neither 0 nor positive
14    Negative,
15}
16
17impl BitXor for Sgn0Result {
18    type Output = Self;
19    fn bitxor(self, rhs: Self) -> Self {
20        if self == rhs {
21            Sgn0Result::NonNegative
22        } else {
23            Sgn0Result::Negative
24        }
25    }
26}
27
28/// Signum computations and conditional in-place negation
29pub trait Signum0: Field {
30    /// Returns either Negative or NonNegative
31    fn sgn0(&self) -> Sgn0Result;
32
33    /// Negate if the argument is Negative
34    fn negate_if(&mut self, sgn: Sgn0Result) {
35        if sgn == Sgn0Result::Negative {
36            self.negate();
37        }
38    }
39}
40
41#[test]
42#[allow(clippy::eq_op)]
43fn test_sgn0result_xor() {
44    assert_eq!(
45        Sgn0Result::Negative ^ Sgn0Result::Negative,
46        Sgn0Result::NonNegative
47    );
48    assert_eq!(
49        Sgn0Result::Negative ^ Sgn0Result::NonNegative,
50        Sgn0Result::Negative
51    );
52    assert_eq!(
53        Sgn0Result::NonNegative ^ Sgn0Result::Negative,
54        Sgn0Result::Negative
55    );
56    assert_eq!(
57        Sgn0Result::NonNegative ^ Sgn0Result::NonNegative,
58        Sgn0Result::NonNegative
59    );
60}