From 3aa4d872b7e684ef87dfabffa6ab2f4651eb208a Mon Sep 17 00:00:00 2001 From: Ash Date: Fri, 18 Dec 2020 15:07:35 +0800 Subject: [PATCH] impl (From, Hash, Ord) for Scalar --- src/g1.rs | 4 ++-- src/scalar.rs | 42 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/g1.rs b/src/g1.rs index 5a28f943..b0f1bf03 100644 --- a/src/g1.rs +++ b/src/g1.rs @@ -1538,7 +1538,7 @@ fn test_mul_by_x() { }; assert_eq!(generator.mul_by_x(), generator * x); - let point = G1Projective::generator() * Scalar::from(42); + let point = G1Projective::generator() * Scalar::from(42u64); assert_eq!(point.mul_by_x(), point * x); } @@ -1588,7 +1588,7 @@ fn test_clear_cofactor() { // in BLS12-381 the cofactor in G1 can be // cleared multiplying by (1-x) - let h_eff = Scalar::from(1) + Scalar::from(crate::BLS_X); + let h_eff = Scalar::from(1u64) + Scalar::from(crate::BLS_X); assert_eq!(point.clear_cofactor(), point * h_eff); } diff --git a/src/scalar.rs b/src/scalar.rs index f2359d24..3a13cae7 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -17,7 +17,7 @@ use crate::util::{adc, mac, sbb}; // The internal representation of this type is four 64-bit unsigned // integers in little-endian order. `Scalar` values are always in // Montgomery form; i.e., Scalar(a) = aR mod q, with R = 2^256. -#[derive(Clone, Copy, Eq)] +#[derive(Clone, Copy, Eq, Hash)] pub struct Scalar(pub(crate) [u64; 4]); impl fmt::Debug for Scalar { @@ -37,6 +37,12 @@ impl fmt::Display for Scalar { } } +impl From for Scalar { + fn from(val: u32) -> Scalar { + Scalar([val as u64, 0, 0, 0]) * R2 + } +} + impl From for Scalar { fn from(val: u64) -> Scalar { Scalar([val, 0, 0, 0]) * R2 @@ -59,6 +65,22 @@ impl PartialEq for Scalar { } } +impl Ord for Scalar { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + let mut self_bytes = self.0; + let mut other_bytes = other.0; + &self_bytes.reverse(); + &other_bytes.reverse(); + self_bytes.cmp(&other_bytes) + } +} + +impl PartialOrd for Scalar { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + impl ConditionallySelectable for Scalar { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { Scalar([ @@ -1231,3 +1253,21 @@ fn test_double() { assert_eq!(a.double(), a + a); } + +#[test] +fn test_ord() { + assert!(Scalar::one() > Scalar::zero()); + let x = Scalar::from_raw([ + 0x0000_0000_0000_0000, + 0x0000_0000_0000_0000, + 0x1111_1111_1111_1111, + 0x1111_1111_1111_1111, + ]); + let y = Scalar::from_raw([ + 0x1111_1111_1111_1111, + 0x0000_0000_0000_0000, + 0x1111_1111_1111_1111, + 0x0000_0000_0000_0000, + ]); + assert!(y < x); +}