ff: PrimeField::{is_even, is_odd}

This commit is contained in:
Jack Grigg 2020-04-21 19:05:19 +12:00
parent 232f0a50b8
commit 1fdca393bb
10 changed files with 54 additions and 8 deletions

View File

@ -332,6 +332,10 @@ impl PrimeField for Fr {
FrRepr::from(*self) FrRepr::from(*self)
} }
fn is_odd(&self) -> bool {
(self.0).0 % 2 != 0
}
fn char() -> FrRepr { fn char() -> FrRepr {
Fr(MODULUS_R).into() Fr(MODULUS_R).into()
} }

View File

@ -1029,6 +1029,11 @@ fn prime_field_impl(
r.0 r.0
} }
#[inline(always)]
fn is_odd(&self) -> bool {
self.into_repr().is_odd()
}
fn char() -> #repr { fn char() -> #repr {
MODULUS MODULUS
} }

View File

@ -309,6 +309,15 @@ pub trait PrimeField: Field + From<u64> {
/// the number is an element of the field. /// the number is an element of the field.
fn into_repr(&self) -> Self::Repr; fn into_repr(&self) -> Self::Repr;
/// Returns true iff this element is odd.
fn is_odd(&self) -> bool;
/// Returns true iff this element is even.
#[inline(always)]
fn is_even(&self) -> bool {
!self.is_odd()
}
/// Returns the field characteristic; the modulus. /// Returns the field characteristic; the modulus.
fn char() -> Self::Repr; fn char() -> Self::Repr;

View File

@ -2182,6 +2182,18 @@ fn test_fq_display() {
); );
} }
#[test]
fn test_fq_is_odd() {
assert!(!Fq::from(0).is_odd());
assert!(Fq::from(0).is_even());
assert!(Fq::from(1).is_odd());
assert!(!Fq::from(1).is_even());
assert!(!Fq::from(324834872).is_odd());
assert!(Fq::from(324834872).is_even());
assert!(Fq::from(324834873).is_odd());
assert!(!Fq::from(324834873).is_even());
}
#[test] #[test]
fn test_fq_num_bits() { fn test_fq_num_bits() {
assert_eq!(Fq::NUM_BITS, 381); assert_eq!(Fq::NUM_BITS, 381);

View File

@ -950,6 +950,18 @@ fn test_fr_display() {
); );
} }
#[test]
fn test_fr_is_odd() {
assert!(!Fr::from(0).is_odd());
assert!(Fr::from(0).is_even());
assert!(Fr::from(1).is_odd());
assert!(!Fr::from(1).is_even());
assert!(!Fr::from(324834872).is_odd());
assert!(Fr::from(324834872).is_even());
assert!(Fr::from(324834873).is_odd());
assert!(!Fr::from(324834873).is_even());
}
#[test] #[test]
fn test_fr_num_bits() { fn test_fr_num_bits() {
assert_eq!(Fr::NUM_BITS, 255); assert_eq!(Fr::NUM_BITS, 255);

View File

@ -127,7 +127,7 @@ impl<E: JubjubEngine> Point<E, Unknown> {
tmp1.mul_assign(&tmp2); tmp1.mul_assign(&tmp2);
tmp1.sqrt().map(|mut x| { tmp1.sqrt().map(|mut x| {
if x.into_repr().is_odd() != sign { if x.is_odd() != sign {
x = x.neg(); x = x.neg();
} }
@ -172,9 +172,8 @@ impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
assert_eq!(E::Fr::NUM_BITS, 255); assert_eq!(E::Fr::NUM_BITS, 255);
let x_repr = x.into_repr();
let mut y_repr = y.into_repr(); let mut y_repr = y.into_repr();
if x_repr.is_odd() { if x.is_odd() {
y_repr.as_mut()[3] |= 0x8000000000000000u64; y_repr.as_mut()[3] |= 0x8000000000000000u64;
} }

View File

@ -481,6 +481,11 @@ impl PrimeField for Fs {
r.0 r.0
} }
#[inline(always)]
fn is_odd(&self) -> bool {
self.into_repr().is_odd()
}
fn char() -> FsRepr { fn char() -> FsRepr {
MODULUS MODULUS
} }

View File

@ -1,4 +1,4 @@
use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField}; use ff::{BitIterator, Field, PrimeField, SqrtField};
use std::ops::{AddAssign, MulAssign, Neg, SubAssign}; use std::ops::{AddAssign, MulAssign, Neg, SubAssign};
use subtle::CtOption; use subtle::CtOption;
@ -60,7 +60,7 @@ impl<E: JubjubEngine> Point<E, Unknown> {
rhs.add_assign(&x2); rhs.add_assign(&x2);
rhs.sqrt().map(|mut y| { rhs.sqrt().map(|mut y| {
if y.into_repr().is_odd() != sign { if y.is_odd() != sign {
y = y.neg(); y = y.neg();
} }

View File

@ -237,7 +237,7 @@ fn test_get_for<E: JubjubEngine>(params: &E::Params) {
let p = edwards::Point::<E, _>::get_for_y(y, sign, params); let p = edwards::Point::<E, _>::get_for_y(y, sign, params);
if bool::from(p.is_some()) { if bool::from(p.is_some()) {
let mut p = p.unwrap(); let mut p = p.unwrap();
assert!(p.to_xy().0.into_repr().is_odd() == sign); assert!(p.to_xy().0.is_odd() == sign);
p = p.negate(); p = p.negate();
assert!(edwards::Point::<E, _>::get_for_y(y, !sign, params).unwrap() == p); assert!(edwards::Point::<E, _>::get_for_y(y, !sign, params).unwrap() == p);
} }

View File

@ -1,6 +1,6 @@
//! The Sapling circuits. //! The Sapling circuits.
use ff::{Field, PrimeField, PrimeFieldRepr}; use ff::{Field, PrimeField};
use bellman::{Circuit, ConstraintSystem, SynthesisError}; use bellman::{Circuit, ConstraintSystem, SynthesisError};
@ -478,7 +478,7 @@ impl<'a, E: JubjubEngine> Circuit<E> for Output<'a, E> {
// Witness the sign bit // Witness the sign bit
let sign_bit = boolean::Boolean::from(boolean::AllocatedBit::alloc( let sign_bit = boolean::Boolean::from(boolean::AllocatedBit::alloc(
cs.namespace(|| "pk_d bit of x"), cs.namespace(|| "pk_d bit of x"),
pk_d.map(|e| e.0.into_repr().is_odd()), pk_d.map(|e| e.0.is_odd()),
)?); )?);
// Extend the note with pk_d representation // Extend the note with pk_d representation