summaryrefslogtreecommitdiffstats
path: root/vendor/elliptic-curve/src/scalar
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/elliptic-curve/src/scalar')
-rw-r--r--vendor/elliptic-curve/src/scalar/blinded.rs74
-rw-r--r--vendor/elliptic-curve/src/scalar/nonzero.rs170
-rw-r--r--vendor/elliptic-curve/src/scalar/primitive.rs (renamed from vendor/elliptic-curve/src/scalar/core.rs)210
3 files changed, 290 insertions, 164 deletions
diff --git a/vendor/elliptic-curve/src/scalar/blinded.rs b/vendor/elliptic-curve/src/scalar/blinded.rs
new file mode 100644
index 000000000..29cfea98c
--- /dev/null
+++ b/vendor/elliptic-curve/src/scalar/blinded.rs
@@ -0,0 +1,74 @@
+//! Random blinding support for [`Scalar`]
+
+use super::Scalar;
+use crate::{ops::Invert, CurveArithmetic};
+use group::ff::Field;
+use rand_core::CryptoRngCore;
+use subtle::CtOption;
+use zeroize::Zeroize;
+
+/// Scalar blinded with a randomly generated masking value.
+///
+/// This provides a randomly blinded impl of [`Invert`] which is useful for
+/// e.g. ECDSA ephemeral (`k`) scalars.
+///
+/// It implements masked variable-time inversions using Stein's algorithm, which
+/// may be helpful for performance on embedded platforms.
+#[derive(Clone)]
+pub struct BlindedScalar<C>
+where
+ C: CurveArithmetic,
+{
+ /// Actual scalar value.
+ scalar: Scalar<C>,
+
+ /// Mask value.
+ mask: Scalar<C>,
+}
+
+impl<C> BlindedScalar<C>
+where
+ C: CurveArithmetic,
+{
+ /// Create a new [`BlindedScalar`] from a scalar and a [`CryptoRngCore`].
+ pub fn new(scalar: Scalar<C>, rng: &mut impl CryptoRngCore) -> Self {
+ Self {
+ scalar,
+ mask: Scalar::<C>::random(rng),
+ }
+ }
+}
+
+impl<C> AsRef<Scalar<C>> for BlindedScalar<C>
+where
+ C: CurveArithmetic,
+{
+ fn as_ref(&self) -> &Scalar<C> {
+ &self.scalar
+ }
+}
+
+impl<C> Invert for BlindedScalar<C>
+where
+ C: CurveArithmetic,
+{
+ type Output = CtOption<Scalar<C>>;
+
+ fn invert(&self) -> CtOption<Scalar<C>> {
+ // prevent side channel analysis of scalar inversion by pre-and-post-multiplying
+ // with the random masking scalar
+ (self.scalar * self.mask)
+ .invert_vartime()
+ .map(|s| s * self.mask)
+ }
+}
+
+impl<C> Drop for BlindedScalar<C>
+where
+ C: CurveArithmetic,
+{
+ fn drop(&mut self) {
+ self.scalar.zeroize();
+ self.mask.zeroize();
+ }
+}
diff --git a/vendor/elliptic-curve/src/scalar/nonzero.rs b/vendor/elliptic-curve/src/scalar/nonzero.rs
index 7450537a9..c0e45740f 100644
--- a/vendor/elliptic-curve/src/scalar/nonzero.rs
+++ b/vendor/elliptic-curve/src/scalar/nonzero.rs
@@ -1,11 +1,9 @@
//! Non-zero scalar type.
use crate::{
- bigint::Encoding as _,
ops::{Invert, Reduce, ReduceNonZero},
- rand_core::{CryptoRng, RngCore},
- Curve, Error, FieldBytes, IsHigh, PrimeCurve, Result, Scalar, ScalarArithmetic, ScalarCore,
- SecretKey,
+ scalar::IsHigh,
+ CurveArithmetic, Error, FieldBytes, PrimeCurve, Scalar, ScalarPrimitive, SecretKey,
};
use base16ct::HexDisplay;
use core::{
@@ -15,10 +13,14 @@ use core::{
};
use crypto_bigint::{ArrayEncoding, Integer};
use ff::{Field, PrimeField};
-use generic_array::GenericArray;
+use generic_array::{typenum::Unsigned, GenericArray};
+use rand_core::CryptoRngCore;
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
use zeroize::Zeroize;
+#[cfg(feature = "serde")]
+use serdect::serde::{de, ser, Deserialize, Serialize};
+
/// Non-zero scalar type.
///
/// This type ensures that its value is not zero, ala `core::num::NonZero*`.
@@ -27,21 +29,20 @@ use zeroize::Zeroize;
///
/// In the context of ECC, it's useful for ensuring that scalar multiplication
/// cannot result in the point at infinity.
-#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
#[derive(Clone)]
pub struct NonZeroScalar<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
scalar: Scalar<C>,
}
impl<C> NonZeroScalar<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
/// Generate a random `NonZeroScalar`.
- pub fn random(mut rng: impl CryptoRng + RngCore) -> Self {
+ pub fn random(mut rng: &mut impl CryptoRngCore) -> Self {
// Use rejection sampling to eliminate zero values.
// While this method isn't constant-time, the attacker shouldn't learn
// anything about unrelated outputs so long as `rng` is a secure `CryptoRng`.
@@ -62,15 +63,15 @@ where
Scalar::<C>::from_repr(repr).and_then(Self::new)
}
- /// Create a [`NonZeroScalar`] from a `C::UInt`.
- pub fn from_uint(uint: C::UInt) -> CtOption<Self> {
- ScalarCore::new(uint).and_then(|scalar| Self::new(scalar.into()))
+ /// Create a [`NonZeroScalar`] from a `C::Uint`.
+ pub fn from_uint(uint: C::Uint) -> CtOption<Self> {
+ ScalarPrimitive::new(uint).and_then(|scalar| Self::new(scalar.into()))
}
}
impl<C> AsRef<Scalar<C>> for NonZeroScalar<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
fn as_ref(&self) -> &Scalar<C> {
&self.scalar
@@ -79,7 +80,7 @@ where
impl<C> ConditionallySelectable for NonZeroScalar<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
Self {
@@ -90,18 +91,18 @@ where
impl<C> ConstantTimeEq for NonZeroScalar<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
fn ct_eq(&self, other: &Self) -> Choice {
self.scalar.ct_eq(&other.scalar)
}
}
-impl<C> Copy for NonZeroScalar<C> where C: Curve + ScalarArithmetic {}
+impl<C> Copy for NonZeroScalar<C> where C: CurveArithmetic {}
impl<C> Deref for NonZeroScalar<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
type Target = Scalar<C>;
@@ -112,7 +113,7 @@ where
impl<C> From<NonZeroScalar<C>> for FieldBytes<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
fn from(scalar: NonZeroScalar<C>) -> FieldBytes<C> {
Self::from(&scalar)
@@ -121,34 +122,35 @@ where
impl<C> From<&NonZeroScalar<C>> for FieldBytes<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
fn from(scalar: &NonZeroScalar<C>) -> FieldBytes<C> {
scalar.to_repr()
}
}
-impl<C> From<NonZeroScalar<C>> for ScalarCore<C>
+impl<C> From<NonZeroScalar<C>> for ScalarPrimitive<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
- fn from(scalar: NonZeroScalar<C>) -> ScalarCore<C> {
- ScalarCore::from_be_bytes(scalar.to_repr()).unwrap()
+ #[inline]
+ fn from(scalar: NonZeroScalar<C>) -> ScalarPrimitive<C> {
+ Self::from(&scalar)
}
}
-impl<C> From<&NonZeroScalar<C>> for ScalarCore<C>
+impl<C> From<&NonZeroScalar<C>> for ScalarPrimitive<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
- fn from(scalar: &NonZeroScalar<C>) -> ScalarCore<C> {
- ScalarCore::from_be_bytes(scalar.to_repr()).unwrap()
+ fn from(scalar: &NonZeroScalar<C>) -> ScalarPrimitive<C> {
+ ScalarPrimitive::from_bytes(&scalar.to_repr()).unwrap()
}
}
impl<C> From<SecretKey<C>> for NonZeroScalar<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
fn from(sk: SecretKey<C>) -> NonZeroScalar<C> {
Self::from(&sk)
@@ -157,10 +159,10 @@ where
impl<C> From<&SecretKey<C>> for NonZeroScalar<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
fn from(sk: &SecretKey<C>) -> NonZeroScalar<C> {
- let scalar = sk.as_scalar_core().to_scalar();
+ let scalar = sk.as_scalar_primitive().to_scalar();
debug_assert!(!bool::from(scalar.is_zero()));
Self { scalar }
}
@@ -168,21 +170,29 @@ where
impl<C> Invert for NonZeroScalar<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
{
type Output = Self;
fn invert(&self) -> Self {
Self {
// This will always succeed since `scalar` will never be 0
- scalar: ff::Field::invert(&self.scalar).unwrap(),
+ scalar: Invert::invert(&self.scalar).unwrap(),
+ }
+ }
+
+ fn invert_vartime(&self) -> Self::Output {
+ Self {
+ // This will always succeed since `scalar` will never be 0
+ scalar: Invert::invert_vartime(&self.scalar).unwrap(),
}
}
}
impl<C> IsHigh for NonZeroScalar<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
fn is_high(&self) -> Choice {
self.scalar.is_high()
@@ -191,7 +201,7 @@ where
impl<C> Neg for NonZeroScalar<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
type Output = NonZeroScalar<C>;
@@ -204,7 +214,7 @@ where
impl<C> Mul<NonZeroScalar<C>> for NonZeroScalar<C>
where
- C: PrimeCurve + ScalarArithmetic,
+ C: PrimeCurve + CurveArithmetic,
{
type Output = Self;
@@ -216,7 +226,7 @@ where
impl<C> Mul<&NonZeroScalar<C>> for NonZeroScalar<C>
where
- C: PrimeCurve + ScalarArithmetic,
+ C: PrimeCurve + CurveArithmetic,
{
type Output = Self;
@@ -229,39 +239,53 @@ where
}
}
-/// Note: implementation is the same as `ReduceNonZero`
+/// Note: this is a non-zero reduction, as it's impl'd for [`NonZeroScalar`].
impl<C, I> Reduce<I> for NonZeroScalar<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
I: Integer + ArrayEncoding,
- Scalar<C>: ReduceNonZero<I>,
+ Scalar<C>: Reduce<I> + ReduceNonZero<I>,
{
- fn from_uint_reduced(n: I) -> Self {
- Self::from_uint_reduced_nonzero(n)
+ type Bytes = <Scalar<C> as Reduce<I>>::Bytes;
+
+ fn reduce(n: I) -> Self {
+ let scalar = Scalar::<C>::reduce_nonzero(n);
+ debug_assert!(!bool::from(scalar.is_zero()));
+ Self { scalar }
+ }
+
+ fn reduce_bytes(bytes: &Self::Bytes) -> Self {
+ let scalar = Scalar::<C>::reduce_nonzero_bytes(bytes);
+ debug_assert!(!bool::from(scalar.is_zero()));
+ Self { scalar }
}
}
+/// Note: forwards to the [`Reduce`] impl.
impl<C, I> ReduceNonZero<I> for NonZeroScalar<C>
where
- C: Curve + ScalarArithmetic,
+ Self: Reduce<I>,
+ C: CurveArithmetic,
I: Integer + ArrayEncoding,
- Scalar<C>: ReduceNonZero<I>,
+ Scalar<C>: Reduce<I, Bytes = Self::Bytes> + ReduceNonZero<I>,
{
- fn from_uint_reduced_nonzero(n: I) -> Self {
- let scalar = Scalar::<C>::from_uint_reduced_nonzero(n);
- debug_assert!(!bool::from(scalar.is_zero()));
- Self::new(scalar).unwrap()
+ fn reduce_nonzero(n: I) -> Self {
+ Self::reduce(n)
+ }
+
+ fn reduce_nonzero_bytes(bytes: &Self::Bytes) -> Self {
+ Self::reduce_bytes(bytes)
}
}
impl<C> TryFrom<&[u8]> for NonZeroScalar<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
type Error = Error;
- fn try_from(bytes: &[u8]) -> Result<Self> {
- if bytes.len() == C::UInt::BYTE_SIZE {
+ fn try_from(bytes: &[u8]) -> Result<Self, Error> {
+ if bytes.len() == C::FieldBytesSize::USIZE {
Option::from(NonZeroScalar::from_repr(GenericArray::clone_from_slice(
bytes,
)))
@@ -274,7 +298,7 @@ where
impl<C> Zeroize for NonZeroScalar<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
fn zeroize(&mut self) {
// Use zeroize's volatile writes to ensure value is cleared.
@@ -282,22 +306,22 @@ where
// Write a 1 instead of a 0 to ensure this type's non-zero invariant
// is upheld.
- self.scalar = Scalar::<C>::one();
+ self.scalar = Scalar::<C>::ONE;
}
}
impl<C> fmt::Display for NonZeroScalar<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{:X}", self)
+ write!(f, "{self:X}")
}
}
impl<C> fmt::LowerHex for NonZeroScalar<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:x}", HexDisplay(&self.to_repr()))
@@ -306,7 +330,7 @@ where
impl<C> fmt::UpperHex for NonZeroScalar<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:}", HexDisplay(&self.to_repr()))
@@ -315,11 +339,11 @@ where
impl<C> str::FromStr for NonZeroScalar<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
type Err = Error;
- fn from_str(hex: &str) -> Result<Self> {
+ fn from_str(hex: &str) -> Result<Self, Error> {
let mut bytes = FieldBytes::<C>::default();
if base16ct::mixed::decode(hex, &mut bytes)?.len() == bytes.len() {
@@ -330,6 +354,34 @@ where
}
}
+#[cfg(feature = "serde")]
+impl<C> Serialize for NonZeroScalar<C>
+where
+ C: CurveArithmetic,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ ScalarPrimitive::from(self).serialize(serializer)
+ }
+}
+
+#[cfg(feature = "serde")]
+impl<'de, C> Deserialize<'de> for NonZeroScalar<C>
+where
+ C: CurveArithmetic,
+{
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ let scalar = ScalarPrimitive::deserialize(deserializer)?;
+ Option::from(Self::new(scalar.into()))
+ .ok_or_else(|| de::Error::custom("expected non-zero scalar"))
+ }
+}
+
#[cfg(all(test, feature = "dev"))]
mod tests {
use crate::dev::{NonZeroScalar, Scalar};
@@ -348,6 +400,6 @@ mod tests {
fn zeroize() {
let mut scalar = NonZeroScalar::new(Scalar::from(42u64)).unwrap();
scalar.zeroize();
- assert_eq!(*scalar, Scalar::one());
+ assert_eq!(*scalar, Scalar::ONE);
}
}
diff --git a/vendor/elliptic-curve/src/scalar/core.rs b/vendor/elliptic-curve/src/scalar/primitive.rs
index 6a088ca55..a4f64cb58 100644
--- a/vendor/elliptic-curve/src/scalar/core.rs
+++ b/vendor/elliptic-curve/src/scalar/primitive.rs
@@ -1,34 +1,33 @@
-//! Generic scalar type with core functionality.
+//! Generic scalar type with primitive functionality.
use crate::{
bigint::{prelude::*, Limb, NonZero},
- rand_core::{CryptoRng, RngCore},
- subtle::{
- Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess,
- CtOption,
- },
- Curve, Error, FieldBytes, IsHigh, Result,
+ scalar::FromUintUnchecked,
+ scalar::IsHigh,
+ Curve, Error, FieldBytes, FieldBytesEncoding, Result,
};
use base16ct::HexDisplay;
use core::{
cmp::Ordering,
fmt,
- ops::{Add, AddAssign, Neg, Sub, SubAssign},
+ ops::{Add, AddAssign, Neg, ShrAssign, Sub, SubAssign},
str,
};
-use generic_array::GenericArray;
+use generic_array::{typenum::Unsigned, GenericArray};
+use rand_core::CryptoRngCore;
+use subtle::{
+ Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess,
+ CtOption,
+};
use zeroize::DefaultIsZeroes;
#[cfg(feature = "arithmetic")]
-use {
- super::{Scalar, ScalarArithmetic},
- group::ff::PrimeField,
-};
+use super::{CurveArithmetic, Scalar};
#[cfg(feature = "serde")]
use serdect::serde::{de, ser, Deserialize, Serialize};
-/// Generic scalar type with core functionality.
+/// Generic scalar type with primitive functionality.
///
/// This type provides a baseline level of scalar arithmetic functionality
/// which is always available for all curves, regardless of if they implement
@@ -41,73 +40,58 @@ use serdect::serde::{de, ser, Deserialize, Serialize};
///
/// The serialization is a fixed-width big endian encoding. When used with
/// textual formats, the binary data is encoded as hexadecimal.
-// TODO(tarcieri): make this a fully generic `Scalar` type and use it for `ScalarArithmetic`
+// TODO(tarcieri): use `crypto-bigint`'s `Residue` type, expose more functionality?
#[derive(Copy, Clone, Debug, Default)]
-#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
-pub struct ScalarCore<C: Curve> {
+pub struct ScalarPrimitive<C: Curve> {
/// Inner unsigned integer type.
- inner: C::UInt,
+ inner: C::Uint,
}
-impl<C> ScalarCore<C>
+impl<C> ScalarPrimitive<C>
where
C: Curve,
{
/// Zero scalar.
pub const ZERO: Self = Self {
- inner: C::UInt::ZERO,
+ inner: C::Uint::ZERO,
};
/// Multiplicative identity.
pub const ONE: Self = Self {
- inner: C::UInt::ONE,
+ inner: C::Uint::ONE,
};
/// Scalar modulus.
- pub const MODULUS: C::UInt = C::ORDER;
+ pub const MODULUS: C::Uint = C::ORDER;
- /// Generate a random [`ScalarCore`].
- pub fn random(rng: impl CryptoRng + RngCore) -> Self {
+ /// Generate a random [`ScalarPrimitive`].
+ pub fn random(rng: &mut impl CryptoRngCore) -> Self {
Self {
- inner: C::UInt::random_mod(rng, &NonZero::new(Self::MODULUS).unwrap()),
+ inner: C::Uint::random_mod(rng, &NonZero::new(Self::MODULUS).unwrap()),
}
}
- /// Create a new scalar from [`Curve::UInt`].
- pub fn new(uint: C::UInt) -> CtOption<Self> {
+ /// Create a new scalar from [`Curve::Uint`].
+ pub fn new(uint: C::Uint) -> CtOption<Self> {
CtOption::new(Self { inner: uint }, uint.ct_lt(&Self::MODULUS))
}
- /// Decode [`ScalarCore`] from big endian bytes.
- pub fn from_be_bytes(bytes: FieldBytes<C>) -> CtOption<Self> {
- Self::new(C::UInt::from_be_byte_array(bytes))
+ /// Decode [`ScalarPrimitive`] from a serialized field element
+ pub fn from_bytes(bytes: &FieldBytes<C>) -> CtOption<Self> {
+ Self::new(C::Uint::decode_field_bytes(bytes))
}
- /// Decode [`ScalarCore`] from a big endian byte slice.
- pub fn from_be_slice(slice: &[u8]) -> Result<Self> {
- if slice.len() == C::UInt::BYTE_SIZE {
- Option::from(Self::from_be_bytes(GenericArray::clone_from_slice(slice))).ok_or(Error)
+ /// Decode [`ScalarPrimitive`] from a big endian byte slice.
+ pub fn from_slice(slice: &[u8]) -> Result<Self> {
+ if slice.len() == C::FieldBytesSize::USIZE {
+ Option::from(Self::from_bytes(GenericArray::from_slice(slice))).ok_or(Error)
} else {
Err(Error)
}
}
- /// Decode [`ScalarCore`] from little endian bytes.
- pub fn from_le_bytes(bytes: FieldBytes<C>) -> CtOption<Self> {
- Self::new(C::UInt::from_le_byte_array(bytes))
- }
-
- /// Decode [`ScalarCore`] from a little endian byte slice.
- pub fn from_le_slice(slice: &[u8]) -> Result<Self> {
- if slice.len() == C::UInt::BYTE_SIZE {
- Option::from(Self::from_le_bytes(GenericArray::clone_from_slice(slice))).ok_or(Error)
- } else {
- Err(Error)
- }
- }
-
- /// Borrow the inner `C::UInt`.
- pub fn as_uint(&self) -> &C::UInt {
+ /// Borrow the inner `C::Uint`.
+ pub fn as_uint(&self) -> &C::Uint {
&self.inner
}
@@ -116,46 +100,56 @@ where
self.inner.as_ref()
}
- /// Is this [`ScalarCore`] value equal to zero?
+ /// Is this [`ScalarPrimitive`] value equal to zero?
pub fn is_zero(&self) -> Choice {
self.inner.is_zero()
}
- /// Is this [`ScalarCore`] value even?
+ /// Is this [`ScalarPrimitive`] value even?
pub fn is_even(&self) -> Choice {
self.inner.is_even()
}
- /// Is this [`ScalarCore`] value odd?
+ /// Is this [`ScalarPrimitive`] value odd?
pub fn is_odd(&self) -> Choice {
self.inner.is_odd()
}
- /// Encode [`ScalarCore`] as big endian bytes.
- pub fn to_be_bytes(self) -> FieldBytes<C> {
- self.inner.to_be_byte_array()
+ /// Encode [`ScalarPrimitive`] as a serialized field element.
+ pub fn to_bytes(&self) -> FieldBytes<C> {
+ self.inner.encode_field_bytes()
+ }
+
+ /// Convert to a `C::Uint`.
+ pub fn to_uint(&self) -> C::Uint {
+ self.inner
}
+}
+
+impl<C> FromUintUnchecked for ScalarPrimitive<C>
+where
+ C: Curve,
+{
+ type Uint = C::Uint;
- /// Encode [`ScalarCore`] as little endian bytes.
- pub fn to_le_bytes(self) -> FieldBytes<C> {
- self.inner.to_le_byte_array()
+ fn from_uint_unchecked(uint: C::Uint) -> Self {
+ Self { inner: uint }
}
}
#[cfg(feature = "arithmetic")]
-impl<C> ScalarCore<C>
+impl<C> ScalarPrimitive<C>
where
- C: Curve + ScalarArithmetic,
+ C: CurveArithmetic,
{
- /// Convert [`ScalarCore`] into a given curve's scalar type
- // TODO(tarcieri): replace curve-specific scalars with `ScalarCore`
+ /// Convert [`ScalarPrimitive`] into a given curve's scalar type.
pub(super) fn to_scalar(self) -> Scalar<C> {
- Scalar::<C>::from_repr(self.to_be_bytes()).unwrap()
+ Scalar::<C>::from_uint_unchecked(self.inner)
}
}
// TODO(tarcieri): better encapsulate this?
-impl<C> AsRef<[Limb]> for ScalarCore<C>
+impl<C> AsRef<[Limb]> for ScalarPrimitive<C>
where
C: Curve,
{
@@ -164,18 +158,18 @@ where
}
}
-impl<C> ConditionallySelectable for ScalarCore<C>
+impl<C> ConditionallySelectable for ScalarPrimitive<C>
where
C: Curve,
{
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
Self {
- inner: C::UInt::conditional_select(&a.inner, &b.inner, choice),
+ inner: C::Uint::conditional_select(&a.inner, &b.inner, choice),
}
}
}
-impl<C> ConstantTimeEq for ScalarCore<C>
+impl<C> ConstantTimeEq for ScalarPrimitive<C>
where
C: Curve,
{
@@ -184,7 +178,7 @@ where
}
}
-impl<C> ConstantTimeLess for ScalarCore<C>
+impl<C> ConstantTimeLess for ScalarPrimitive<C>
where
C: Curve,
{
@@ -193,7 +187,7 @@ where
}
}
-impl<C> ConstantTimeGreater for ScalarCore<C>
+impl<C> ConstantTimeGreater for ScalarPrimitive<C>
where
C: Curve,
{
@@ -202,11 +196,11 @@ where
}
}
-impl<C: Curve> DefaultIsZeroes for ScalarCore<C> {}
+impl<C: Curve> DefaultIsZeroes for ScalarPrimitive<C> {}
-impl<C: Curve> Eq for ScalarCore<C> {}
+impl<C: Curve> Eq for ScalarPrimitive<C> {}
-impl<C> PartialEq for ScalarCore<C>
+impl<C> PartialEq for ScalarPrimitive<C>
where
C: Curve,
{
@@ -215,7 +209,7 @@ where
}
}
-impl<C> PartialOrd for ScalarCore<C>
+impl<C> PartialOrd for ScalarPrimitive<C>
where
C: Curve,
{
@@ -224,7 +218,7 @@ where
}
}
-impl<C> Ord for ScalarCore<C>
+impl<C> Ord for ScalarPrimitive<C>
where
C: Curve,
{
@@ -233,18 +227,18 @@ where
}
}
-impl<C> From<u64> for ScalarCore<C>
+impl<C> From<u64> for ScalarPrimitive<C>
where
C: Curve,
{
fn from(n: u64) -> Self {
Self {
- inner: C::UInt::from(n),
+ inner: C::Uint::from(n),
}
}
}
-impl<C> Add<ScalarCore<C>> for ScalarCore<C>
+impl<C> Add<ScalarPrimitive<C>> for ScalarPrimitive<C>
where
C: Curve,
{
@@ -255,7 +249,7 @@ where
}
}
-impl<C> Add<&ScalarCore<C>> for ScalarCore<C>
+impl<C> Add<&ScalarPrimitive<C>> for ScalarPrimitive<C>
where
C: Curve,
{
@@ -268,7 +262,7 @@ where
}
}
-impl<C> AddAssign<ScalarCore<C>> for ScalarCore<C>
+impl<C> AddAssign<ScalarPrimitive<C>> for ScalarPrimitive<C>
where
C: Curve,
{
@@ -277,7 +271,7 @@ where
}
}
-impl<C> AddAssign<&ScalarCore<C>> for ScalarCore<C>
+impl<C> AddAssign<&ScalarPrimitive<C>> for ScalarPrimitive<C>
where
C: Curve,
{
@@ -286,7 +280,7 @@ where
}
}
-impl<C> Sub<ScalarCore<C>> for ScalarCore<C>
+impl<C> Sub<ScalarPrimitive<C>> for ScalarPrimitive<C>
where
C: Curve,
{
@@ -297,7 +291,7 @@ where
}
}
-impl<C> Sub<&ScalarCore<C>> for ScalarCore<C>
+impl<C> Sub<&ScalarPrimitive<C>> for ScalarPrimitive<C>
where
C: Curve,
{
@@ -310,7 +304,7 @@ where
}
}
-impl<C> SubAssign<ScalarCore<C>> for ScalarCore<C>
+impl<C> SubAssign<ScalarPrimitive<C>> for ScalarPrimitive<C>
where
C: Curve,
{
@@ -319,7 +313,7 @@ where
}
}
-impl<C> SubAssign<&ScalarCore<C>> for ScalarCore<C>
+impl<C> SubAssign<&ScalarPrimitive<C>> for ScalarPrimitive<C>
where
C: Curve,
{
@@ -328,7 +322,7 @@ where
}
}
-impl<C> Neg for ScalarCore<C>
+impl<C> Neg for ScalarPrimitive<C>
where
C: Curve,
{
@@ -341,18 +335,27 @@ where
}
}
-impl<C> Neg for &ScalarCore<C>
+impl<C> Neg for &ScalarPrimitive<C>
where
C: Curve,
{
- type Output = ScalarCore<C>;
+ type Output = ScalarPrimitive<C>;
- fn neg(self) -> ScalarCore<C> {
+ fn neg(self) -> ScalarPrimitive<C> {
-*self
}
}
-impl<C> IsHigh for ScalarCore<C>
+impl<C> ShrAssign<usize> for ScalarPrimitive<C>
+where
+ C: Curve,
+{
+ fn shr_assign(&mut self, rhs: usize) {
+ self.inner >>= rhs;
+ }
+}
+
+impl<C> IsHigh for ScalarPrimitive<C>
where
C: Curve,
{
@@ -362,34 +365,34 @@ where
}
}
-impl<C> fmt::Display for ScalarCore<C>
+impl<C> fmt::Display for ScalarPrimitive<C>
where
C: Curve,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{:X}", self)
+ write!(f, "{self:X}")
}
}
-impl<C> fmt::LowerHex for ScalarCore<C>
+impl<C> fmt::LowerHex for ScalarPrimitive<C>
where
C: Curve,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{:x}", HexDisplay(&self.to_be_bytes()))
+ write!(f, "{:x}", HexDisplay(&self.to_bytes()))
}
}
-impl<C> fmt::UpperHex for ScalarCore<C>
+impl<C> fmt::UpperHex for ScalarPrimitive<C>
where
C: Curve,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{:X}", HexDisplay(&self.to_be_bytes()))
+ write!(f, "{:X}", HexDisplay(&self.to_bytes()))
}
}
-impl<C> str::FromStr for ScalarCore<C>
+impl<C> str::FromStr for ScalarPrimitive<C>
where
C: Curve,
{
@@ -398,13 +401,12 @@ where
fn from_str(hex: &str) -> Result<Self> {
let mut bytes = FieldBytes::<C>::default();
base16ct::lower::decode(hex, &mut bytes)?;
- Option::from(Self::from_be_bytes(bytes)).ok_or(Error)
+ Self::from_slice(&bytes)
}
}
#[cfg(feature = "serde")]
-#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
-impl<C> Serialize for ScalarCore<C>
+impl<C> Serialize for ScalarPrimitive<C>
where
C: Curve,
{
@@ -412,13 +414,12 @@ where
where
S: ser::Serializer,
{
- serdect::array::serialize_hex_upper_or_bin(&self.to_be_bytes(), serializer)
+ serdect::array::serialize_hex_upper_or_bin(&self.to_bytes(), serializer)
}
}
#[cfg(feature = "serde")]
-#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
-impl<'de, C> Deserialize<'de> for ScalarCore<C>
+impl<'de, C> Deserialize<'de> for ScalarPrimitive<C>
where
C: Curve,
{
@@ -428,7 +429,6 @@ where
{
let mut bytes = FieldBytes::<C>::default();
serdect::array::deserialize_hex_or_bin(&mut bytes, deserializer)?;
- Option::from(Self::from_be_bytes(bytes))
- .ok_or_else(|| de::Error::custom("scalar out of range"))
+ Self::from_slice(&bytes).map_err(|_| de::Error::custom("scalar out of range"))
}
}