Skip to content

Commit

Permalink
Implement num_traits::pow for Scalar
Browse files Browse the repository at this point in the history
  • Loading branch information
cargodog committed Jan 2, 2021
1 parent a787300 commit e69be46
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ serde = { version = "1.0", default-features = false, optional = true, features =
# https://github.com/rust-lang/packed_simd/issues/303#issuecomment-701361161
packed_simd = { version = "0.3.4", package = "packed_simd_2", features = ["into_bits"], optional = true }
zeroize = { version = "1", default-features = false }
num-traits = { version = "0.2", default-features = false }

[features]
nightly = ["subtle/nightly"]
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ optimised batch inversion was contributed by Sean Bowe and Daira Hopwood.

The `no_std` and `zeroize` support was contributed by Tony Arcieri.

The `num_traits` support was contributed by Cargodog.

Thanks also to Ashley Hauck, Lucas Salibian, and Manish Goregaokar for their
contributions.

Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ extern crate byteorder;
pub extern crate digest;
extern crate rand_core;
extern crate zeroize;
extern crate num_traits;

// Used for traits related to constant-time code.
extern crate subtle;
Expand Down
77 changes: 77 additions & 0 deletions src/scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ use core::ops::{Add, AddAssign};
use core::ops::{Mul, MulAssign};
use core::ops::{Sub, SubAssign};

use num_traits::identities::{One, Zero};
use num_traits::pow::*;

#[allow(unused_imports)]
use prelude::*;

Expand Down Expand Up @@ -1116,6 +1119,80 @@ impl Scalar {
}
}

impl Zero for Scalar {
/// Construct the scalar \\( 0 \\).
fn zero() -> Self {
Scalar::zero()
}

/// Test if number is equal to zero
fn is_zero(&self) -> bool {
*self == Scalar::zero()
}
}

impl One for Scalar {
/// Construct the scalar \\( 1 \\).
fn one() -> Self {
Scalar::one()
}
}

/// Macro to implement Pow trait. Copied from
/// https://docs.rs/num-traits/0.2.8/src/num_traits/pow.rs.html#21
macro_rules! pow_impl {
($t:ty) => {
pow_impl!($t, u8);
pow_impl!($t, usize);

// FIXME: these should be possible
// pow_impl!($t, u16);
// pow_impl!($t, u32);
// pow_impl!($t, u64);
};
($t:ty, $rhs:ty) => {
pow_impl!($t, $rhs, usize, pow);
};
($t:ty, $rhs:ty, $desired_rhs:ty, $method:expr) => {
impl Pow<$rhs> for $t {
type Output = $t;
#[inline]
fn pow(self, rhs: $rhs) -> $t {
($method)(self, <$desired_rhs>::from(rhs))
}
}

impl<'a> Pow<&'a $rhs> for $t {
type Output = $t;
#[inline]
fn pow(self, rhs: &'a $rhs) -> $t {
($method)(self, <$desired_rhs>::from(*rhs))
}
}

impl<'a> Pow<$rhs> for &'a $t {
type Output = $t;
#[inline]
fn pow(self, rhs: $rhs) -> $t {
($method)(*self, <$desired_rhs>::from(rhs))
}
}

impl<'a, 'b> Pow<&'a $rhs> for &'b $t {
type Output = $t;
#[inline]
fn pow(self, rhs: &'a $rhs) -> $t {
($method)(*self, <$desired_rhs>::from(*rhs))
}
}
};
}

pow_impl!(Scalar, u8, u32, Scalar::pow);
pow_impl!(Scalar, u16, u32, Scalar::pow);
pow_impl!(Scalar, u32, u32, Scalar::pow);
pow_impl!(Scalar, usize);

impl UnpackedScalar {
/// Pack the limbs of this `UnpackedScalar` into a `Scalar`.
fn pack(&self) -> Scalar {
Expand Down

0 comments on commit e69be46

Please sign in to comment.