mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-08-01 12:51:30 +00:00
Ordering cleanup for Fq/Fq2, with documentation. Closes #9.
This commit is contained in:
@@ -695,7 +695,7 @@ pub mod g1 {
|
|||||||
negy.negate();
|
negy.negate();
|
||||||
|
|
||||||
// Get the parity of the sqrt we found.
|
// Get the parity of the sqrt we found.
|
||||||
let parity = y.into_repr() > negy.into_repr();
|
let parity = y > negy;
|
||||||
|
|
||||||
Ok(G1Affine {
|
Ok(G1Affine {
|
||||||
x: x,
|
x: x,
|
||||||
@@ -735,7 +735,7 @@ pub mod g1 {
|
|||||||
|
|
||||||
// If the correct y coordinate is the largest (lexicographically),
|
// If the correct y coordinate is the largest (lexicographically),
|
||||||
// the bit should be set.
|
// the bit should be set.
|
||||||
if affine.y.into_repr() > negy.into_repr() {
|
if affine.y > negy {
|
||||||
res.0[0] |= 1 << 6; // Set second highest bit.
|
res.0[0] |= 1 << 6; // Set second highest bit.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
use ::{Field, PrimeField, SqrtField, PrimeFieldRepr};
|
use ::{Field, PrimeField, SqrtField, PrimeFieldRepr};
|
||||||
|
use std::cmp::Ordering;
|
||||||
use super::fq2::Fq2;
|
use super::fq2::Fq2;
|
||||||
|
|
||||||
// q = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
|
// q = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
|
||||||
@@ -233,22 +234,22 @@ impl From<u64> for FqRepr {
|
|||||||
|
|
||||||
impl Ord for FqRepr {
|
impl Ord for FqRepr {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn cmp(&self, other: &FqRepr) -> ::std::cmp::Ordering {
|
fn cmp(&self, other: &FqRepr) -> Ordering {
|
||||||
for (a, b) in self.0.iter().rev().zip(other.0.iter().rev()) {
|
for (a, b) in self.0.iter().rev().zip(other.0.iter().rev()) {
|
||||||
if a < b {
|
if a < b {
|
||||||
return ::std::cmp::Ordering::Less
|
return Ordering::Less
|
||||||
} else if a > b {
|
} else if a > b {
|
||||||
return ::std::cmp::Ordering::Greater
|
return Ordering::Greater
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::std::cmp::Ordering::Equal
|
Ordering::Equal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialOrd for FqRepr {
|
impl PartialOrd for FqRepr {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn partial_cmp(&self, other: &FqRepr) -> Option<::std::cmp::Ordering> {
|
fn partial_cmp(&self, other: &FqRepr) -> Option<Ordering> {
|
||||||
Some(self.cmp(other))
|
Some(self.cmp(other))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -357,6 +358,21 @@ impl PrimeFieldRepr for FqRepr {
|
|||||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||||
pub struct Fq(FqRepr);
|
pub struct Fq(FqRepr);
|
||||||
|
|
||||||
|
/// `Fq` elements are ordered lexicographically.
|
||||||
|
impl Ord for Fq {
|
||||||
|
#[inline(always)]
|
||||||
|
fn cmp(&self, other: &Fq) -> Ordering {
|
||||||
|
self.into_repr().cmp(&other.into_repr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for Fq {
|
||||||
|
#[inline(always)]
|
||||||
|
fn partial_cmp(&self, other: &Fq) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ::std::fmt::Debug for Fq
|
impl ::std::fmt::Debug for Fq
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||||
@@ -847,7 +863,7 @@ use rand::{SeedableRng, XorShiftRng, Rand};
|
|||||||
fn test_fq_repr_ordering() {
|
fn test_fq_repr_ordering() {
|
||||||
fn assert_equality(a: FqRepr, b: FqRepr) {
|
fn assert_equality(a: FqRepr, b: FqRepr) {
|
||||||
assert_eq!(a, b);
|
assert_eq!(a, b);
|
||||||
assert!(a.cmp(&b) == ::std::cmp::Ordering::Equal);
|
assert!(a.cmp(&b) == Ordering::Equal);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_lt(a: FqRepr, b: FqRepr) {
|
fn assert_lt(a: FqRepr, b: FqRepr) {
|
||||||
@@ -1718,3 +1734,12 @@ fn fq_field_tests() {
|
|||||||
::tests::field::random_sqrt_tests::<Fq>();
|
::tests::field::random_sqrt_tests::<Fq>();
|
||||||
::tests::field::random_frobenius_tests::<Fq, _>(Fq::char(), 13);
|
::tests::field::random_frobenius_tests::<Fq, _>(Fq::char(), 13);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fq_ordering() {
|
||||||
|
// FqRepr's ordering is well-tested, but we still need to make sure the Fq
|
||||||
|
// elements aren't being compared in Montgomery form.
|
||||||
|
for i in 0..100 {
|
||||||
|
assert!(Fq::from_repr(FqRepr::from(i+1)) > Fq::from_repr(FqRepr::from(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
use rand::{Rng, Rand};
|
use rand::{Rng, Rand};
|
||||||
use ::{Field, SqrtField, PrimeField};
|
use ::{Field, SqrtField};
|
||||||
use super::fq::{Fq, FROBENIUS_COEFF_FQ2_C1, NEGATIVE_ONE};
|
use super::fq::{Fq, FROBENIUS_COEFF_FQ2_C1, NEGATIVE_ONE};
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
@@ -11,13 +11,14 @@ pub struct Fq2 {
|
|||||||
pub c1: Fq
|
pub c1: Fq
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `Fq2` elements are ordered lexicographically.
|
||||||
impl Ord for Fq2 {
|
impl Ord for Fq2 {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn cmp(&self, other: &Fq2) -> Ordering {
|
fn cmp(&self, other: &Fq2) -> Ordering {
|
||||||
match self.c1.into_repr().cmp(&other.c1.into_repr()) {
|
match self.c1.cmp(&other.c1) {
|
||||||
Ordering::Greater => Ordering::Greater,
|
Ordering::Greater => Ordering::Greater,
|
||||||
Ordering::Less => Ordering::Less,
|
Ordering::Less => Ordering::Less,
|
||||||
Ordering::Equal => self.c0.into_repr().cmp(&other.c0.into_repr())
|
Ordering::Equal => self.c0.cmp(&other.c0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user