Skip to content

Commit ba02294

Browse files
committed
additional methods for scalar
Signed-off-by: Michael Lodder <[email protected]>
1 parent 8a38f70 commit ba02294

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

curve25519-dalek/src/scalar.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,13 @@ use subtle::ConditionallySelectable;
145145
use subtle::ConstantTimeEq;
146146
use subtle::CtOption;
147147

148+
#[cfg(feature = "group")]
149+
use elliptic_curve::{
150+
bigint::{ArrayEncoding, Encoding, U256, U512},
151+
ops::{Reduce, Invert},
152+
scalar::{FromUintUnchecked, IsHigh},
153+
};
154+
148155
#[cfg(feature = "zeroize")]
149156
use zeroize::Zeroize;
150157

@@ -266,6 +273,15 @@ impl Scalar {
266273
CtOption::new(candidate, high_bit_unset & candidate.is_canonical())
267274
}
268275

276+
/// Converts from an integer representation in little endian into
277+
/// its (congruent) `Scalar` representation.
278+
/// Incorrectly using this can lead to mathematically invalid results,
279+
/// which can lead to potential security vulnerabilities.
280+
/// Use only if you know the input is congruent to a scalar.
281+
pub const fn from_canonical_bytes_unchecked(bytes: [u8; 32]) -> Scalar {
282+
Scalar { bytes }
283+
}
284+
269285
/// Construct a `Scalar` from the low 255 bits of a 256-bit integer. This breaks the invariant
270286
/// that scalars are always reduced. Scalar-scalar arithmetic, i.e., addition, subtraction,
271287
/// multiplication, **does not work** on scalars produced from this function. You may only use
@@ -1343,6 +1359,56 @@ impl FromUniformBytes<64> for Scalar {
13431359
}
13441360
}
13451361

1362+
#[cfg(feature = "group")]
1363+
impl Reduce<U256> for Scalar {
1364+
type Bytes = [u8; 32];
1365+
1366+
fn reduce(n: U256) -> Self {
1367+
Scalar::from_bytes_mod_order(n.to_le_bytes())
1368+
}
1369+
1370+
fn reduce_bytes(bytes: &Self::Bytes) -> Self {
1371+
Scalar::from_bytes_mod_order(*bytes)
1372+
}
1373+
}
1374+
1375+
#[cfg(feature = "group")]
1376+
impl Reduce<U512> for Scalar {
1377+
type Bytes = [u8; 64];
1378+
1379+
fn reduce(n: U512) -> Self {
1380+
Scalar::from_bytes_mod_order_wide(&n.to_le_bytes())
1381+
}
1382+
1383+
fn reduce_bytes(bytes: &Self::Bytes) -> Self {
1384+
Scalar::from_bytes_mod_order_wide(bytes)
1385+
}
1386+
}
1387+
1388+
#[cfg(feature = "group")]
1389+
impl IsHigh for Scalar {
1390+
fn is_high(&self) -> Choice {
1391+
self.is_canonical()
1392+
}
1393+
}
1394+
1395+
#[cfg(feature = "group")]
1396+
impl Invert for Scalar {
1397+
type Output = Self;
1398+
fn invert(&self) -> Self::Output {
1399+
self.invert()
1400+
}
1401+
}
1402+
1403+
#[cfg(feature = "group")]
1404+
impl FromUintUnchecked for Scalar {
1405+
type Uint = U256;
1406+
1407+
fn from_uint_unchecked(n: Self::Uint) -> Self {
1408+
Scalar::from_bytes_mod_order(n.to_le_bytes())
1409+
}
1410+
}
1411+
13461412
/// Read one or more u64s stored as little endian bytes.
13471413
///
13481414
/// ## Panics

0 commit comments

Comments
 (0)