From ee5958c4072f89d66bde43c170190d8b587db840 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Sun, 19 Feb 2017 19:48:51 -0500 Subject: [PATCH] Add is_[non]negative_decaf functions. Computes whether a point is nonnegative in the same way as Mike Hamburg's code. --- src/field.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/field.rs b/src/field.rs index 572b39f..3910792 100644 --- a/src/field.rs +++ b/src/field.rs @@ -522,6 +522,39 @@ impl FieldElement { (bytes[0] & 1) as i32 } + /// Determine if this `FieldElement` is negative, in the + /// sense used by Decaf: `x` is nonnegative if the least + /// absolute residue for `x` lies in `[0, (p-1)/2]`, and + /// is negative otherwise. + /// + /// # Return + /// + /// Returns `1u8` if negative, `0u8` if nonnegative. + /// + /// # Implementation + /// + /// Uses a trick borrowed from Mike Hamburg's code. Let `x \in + /// F_p` and let `y \in Z` be the least absolute residue for `x`. + /// Suppose `y ≤ (p-1)/2`. Then `2y < p` so `2y = 2y mod p` and + /// `2y mod p` is even. On the other hand, if `y > (p-1)/2` then + /// `2y ≥ p`; since `y < p`, `2y \in [p, 2p)`, so `2y mod p = + /// 2y-p`, which is odd. + /// + /// Thus we can test whether `y ≤ (p-1)/2` by checking whether `2y + /// mod p` is even. + pub fn is_negative_decaf(&self) -> u8 { + let y = self + self; + (y.to_bytes()[0] & 1) as u8 + } + + /// Determine if this `FieldElement` is nonnegative, in the + /// sense used by Decaf: `x` is nonnegative if the least + /// absolute residue for `x` lies in `[0, (p-1)/2]`, and + /// is negative otherwise. + pub fn is_nonnegative_decaf(&self) -> u8 { + 1u8 & (!self.is_negative_decaf()) + } + /// Determine if this `FieldElement` is zero. /// /// # Return