Skip to content

Commit

Permalink
additional methods for scalar
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Lodder <[email protected]>
  • Loading branch information
mikelodder7 committed Jul 24, 2024
1 parent 1ff2917 commit 4fb7408
Showing 1 changed file with 66 additions and 0 deletions.
66 changes: 66 additions & 0 deletions curve25519-dalek/src/scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,13 @@ use subtle::ConditionallySelectable;
use subtle::ConstantTimeEq;
use subtle::CtOption;

#[cfg(feature = "group")]
use elliptic_curve::{
bigint::{ArrayEncoding, Encoding, U256, U512},
ops::{Reduce, Invert},
scalar::{FromUintUnchecked, IsHigh},
};

#[cfg(feature = "zeroize")]
use zeroize::Zeroize;

Expand Down Expand Up @@ -264,6 +271,15 @@ impl Scalar {
CtOption::new(candidate, high_bit_unset & candidate.is_canonical())
}

/// Converts from an integer representation in little endian into
/// its (congruent) `Scalar` representation.
/// Incorrectly using this can lead to mathematically invalid results,
/// which can lead to potential security vulnerabilities.
/// Use only if you know the input is congruent to a scalar.
pub const fn from_canonical_bytes_unchecked(bytes: [u8; 32]) -> Scalar {
Scalar { bytes }
}

/// Construct a `Scalar` from the low 255 bits of a 256-bit integer. This breaks the invariant
/// that scalars are always reduced. Scalar-scalar arithmetic, i.e., addition, subtraction,
/// multiplication, **does not work** on scalars produced from this function. You may only use
Expand Down Expand Up @@ -1343,6 +1359,56 @@ impl FromUniformBytes<64> for Scalar {
}
}

#[cfg(feature = "group")]
impl Reduce<U256> for Scalar {
type Bytes = [u8; 32];

fn reduce(n: U256) -> Self {
Scalar::from_bytes_mod_order(n.to_le_bytes())
}

fn reduce_bytes(bytes: &Self::Bytes) -> Self {
Scalar::from_bytes_mod_order(*bytes)
}
}

#[cfg(feature = "group")]
impl Reduce<U512> for Scalar {
type Bytes = [u8; 64];

fn reduce(n: U512) -> Self {
Scalar::from_bytes_mod_order_wide(&n.to_le_bytes())
}

fn reduce_bytes(bytes: &Self::Bytes) -> Self {
Scalar::from_bytes_mod_order_wide(bytes)
}
}

#[cfg(feature = "group")]
impl IsHigh for Scalar {
fn is_high(&self) -> Choice {
self.is_canonical()
}
}

#[cfg(feature = "group")]
impl Invert for Scalar {
type Output = Self;
fn invert(&self) -> Self::Output {
self.invert()
}
}

#[cfg(feature = "group")]
impl FromUintUnchecked for Scalar {
type Uint = U256;

fn from_uint_unchecked(n: Self::Uint) -> Self {
Scalar::from_bytes_mod_order(n.to_le_bytes())
}
}

/// Read one or more u64s stored as little endian bytes.
///
/// ## Panics
Expand Down

0 comments on commit 4fb7408

Please sign in to comment.