diff options
Diffstat (limited to 'vendor/elliptic-curve/src/dev.rs')
-rw-r--r-- | vendor/elliptic-curve/src/dev.rs | 334 |
1 files changed, 192 insertions, 142 deletions
diff --git a/vendor/elliptic-curve/src/dev.rs b/vendor/elliptic-curve/src/dev.rs index be0c156e5..36c684ad4 100644 --- a/vendor/elliptic-curve/src/dev.rs +++ b/vendor/elliptic-curve/src/dev.rs @@ -6,26 +6,27 @@ use crate::{ bigint::{Limb, U256}, error::{Error, Result}, - ops::{LinearCombination, Reduce}, + generic_array::typenum::U32, + ops::{Invert, LinearCombination, MulByGenerator, Reduce, ShrAssign}, pkcs8, + point::AffineCoordinates, rand_core::RngCore, - sec1::{FromEncodedPoint, ToEncodedPoint}, + scalar::{FromUintUnchecked, IsHigh}, + sec1::{CompressedPoint, FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, zeroize::DefaultIsZeroes, - AffineArithmetic, AffineXCoordinate, Curve, IsHigh, PrimeCurve, ProjectiveArithmetic, - ScalarArithmetic, + Curve, CurveArithmetic, FieldBytesEncoding, PrimeCurve, }; use core::{ - iter::Sum, + iter::{Product, Sum}, ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}, }; use ff::{Field, PrimeField}; -use generic_array::arr; use hex_literal::hex; use pkcs8::AssociatedOid; #[cfg(feature = "bits")] -use crate::group::ff::PrimeFieldBits; +use ff::PrimeFieldBits; #[cfg(feature = "jwk")] use crate::JwkParameters; @@ -49,13 +50,13 @@ pub type PublicKey = crate::PublicKey<MockCurve>; /// Secret key. pub type SecretKey = crate::SecretKey<MockCurve>; -/// Scalar core. -// TODO(tarcieri): make this the scalar type -pub type ScalarCore = crate::ScalarCore<MockCurve>; +/// Scalar primitive type. +// TODO(tarcieri): make this the scalar type when it's more capable +pub type ScalarPrimitive = crate::ScalarPrimitive<MockCurve>; /// Scalar bits. #[cfg(feature = "bits")] -pub type ScalarBits = crate::ScalarBits<MockCurve>; +pub type ScalarBits = crate::scalar::ScalarBits<MockCurve>; /// Mock elliptic curve type useful for writing tests which require a concrete /// curve type. @@ -66,7 +67,8 @@ pub type ScalarBits = crate::ScalarBits<MockCurve>; pub struct MockCurve; impl Curve for MockCurve { - type UInt = U256; + type FieldBytesSize = U32; + type Uint = U256; const ORDER: U256 = U256::from_be_hex("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551"); @@ -74,15 +76,9 @@ impl Curve for MockCurve { impl PrimeCurve for MockCurve {} -impl AffineArithmetic for MockCurve { +impl CurveArithmetic for MockCurve { type AffinePoint = AffinePoint; -} - -impl ProjectiveArithmetic for MockCurve { type ProjectivePoint = ProjectivePoint; -} - -impl ScalarArithmetic for MockCurve { type Scalar = Scalar; } @@ -92,16 +88,18 @@ impl AssociatedOid for MockCurve { } #[cfg(feature = "jwk")] -#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl JwkParameters for MockCurve { const CRV: &'static str = "P-256"; } /// Example scalar type -#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] -pub struct Scalar(ScalarCore); +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, PartialOrd, Ord)] +pub struct Scalar(ScalarPrimitive); impl Field for Scalar { + const ZERO: Self = Self(ScalarPrimitive::ZERO); + const ONE: Self = Self(ScalarPrimitive::ONE); + fn random(mut rng: impl RngCore) -> Self { let mut bytes = FieldBytes::default(); @@ -113,14 +111,6 @@ impl Field for Scalar { } } - fn zero() -> Self { - Self(ScalarCore::ZERO) - } - - fn one() -> Self { - Self(ScalarCore::ONE) - } - fn is_zero(&self) -> Choice { self.0.is_zero() } @@ -142,39 +132,37 @@ impl Field for Scalar { fn sqrt(&self) -> CtOption<Self> { unimplemented!(); } + + fn sqrt_ratio(_num: &Self, _div: &Self) -> (Choice, Self) { + unimplemented!(); + } } impl PrimeField for Scalar { type Repr = FieldBytes; + const MODULUS: &'static str = + "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff"; const NUM_BITS: u32 = 256; const CAPACITY: u32 = 255; + const TWO_INV: Self = Self::ZERO; // BOGUS! + const MULTIPLICATIVE_GENERATOR: Self = Self::ZERO; // BOGUS! Should be 7 const S: u32 = 4; + const ROOT_OF_UNITY: Self = Self::ZERO; // BOGUS! Should be 0xffc97f062a770992ba807ace842a3dfc1546cad004378daf0592d7fbb41e6602 + const ROOT_OF_UNITY_INV: Self = Self::ZERO; // BOGUS! + const DELTA: Self = Self::ZERO; // BOGUS! fn from_repr(bytes: FieldBytes) -> CtOption<Self> { - ScalarCore::from_be_bytes(bytes).map(Self) + ScalarPrimitive::from_bytes(&bytes).map(Self) } fn to_repr(&self) -> FieldBytes { - self.0.to_be_bytes() + self.0.to_bytes() } fn is_odd(&self) -> Choice { self.0.is_odd() } - - fn multiplicative_generator() -> Self { - 7u64.into() - } - - fn root_of_unity() -> Self { - Self::from_repr(arr![u8; - 0xff, 0xc9, 0x7f, 0x06, 0x2a, 0x77, 0x09, 0x92, 0xba, 0x80, 0x7a, 0xce, 0x84, 0x2a, - 0x3d, 0xfc, 0x15, 0x46, 0xca, 0xd0, 0x04, 0x37, 0x8d, 0xaf, 0x05, 0x92, 0xd7, 0xfb, - 0xb4, 0x1e, 0x66, 0x02, - ]) - .unwrap() - } } #[cfg(feature = "bits")] @@ -194,23 +182,15 @@ impl PrimeFieldBits for Scalar { } } -impl TryFrom<U256> for Scalar { - type Error = Error; - - fn try_from(w: U256) -> Result<Self> { - Option::from(ScalarCore::new(w)).map(Self).ok_or(Error) - } -} - -impl From<Scalar> for U256 { - fn from(scalar: Scalar) -> U256 { - *scalar.0.as_uint() +impl AsRef<Scalar> for Scalar { + fn as_ref(&self) -> &Scalar { + self } } impl ConditionallySelectable for Scalar { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { - Self(ScalarCore::conditional_select(&a.0, &b.0, choice)) + Self(ScalarPrimitive::conditional_select(&a.0, &b.0, choice)) } } @@ -314,27 +294,102 @@ impl Neg for Scalar { } } +impl ShrAssign<usize> for Scalar { + fn shr_assign(&mut self, rhs: usize) { + self.0 >>= rhs; + } +} + +impl Sum for Scalar { + fn sum<I: Iterator<Item = Self>>(_iter: I) -> Self { + unimplemented!(); + } +} + +impl<'a> Sum<&'a Scalar> for Scalar { + fn sum<I: Iterator<Item = &'a Scalar>>(_iter: I) -> Self { + unimplemented!(); + } +} + +impl Product for Scalar { + fn product<I: Iterator<Item = Self>>(_iter: I) -> Self { + unimplemented!(); + } +} + +impl<'a> Product<&'a Scalar> for Scalar { + fn product<I: Iterator<Item = &'a Scalar>>(_iter: I) -> Self { + unimplemented!(); + } +} + +impl Invert for Scalar { + type Output = CtOption<Scalar>; + + fn invert(&self) -> CtOption<Scalar> { + unimplemented!(); + } +} + impl Reduce<U256> for Scalar { - fn from_uint_reduced(w: U256) -> Self { + type Bytes = FieldBytes; + + #[allow(clippy::integer_arithmetic)] + fn reduce(w: U256) -> Self { let (r, underflow) = w.sbb(&MockCurve::ORDER, Limb::ZERO); - let underflow = Choice::from((underflow.0 >> (Limb::BIT_SIZE - 1)) as u8); + let underflow = Choice::from((underflow.0 >> (Limb::BITS - 1)) as u8); let reduced = U256::conditional_select(&w, &r, !underflow); - Self(ScalarCore::new(reduced).unwrap()) + Self(ScalarPrimitive::new(reduced).unwrap()) + } + + fn reduce_bytes(_: &FieldBytes) -> Self { + todo!() } } +impl FieldBytesEncoding<MockCurve> for U256 {} + impl From<u64> for Scalar { fn from(n: u64) -> Scalar { Self(n.into()) } } -impl From<ScalarCore> for Scalar { - fn from(scalar: ScalarCore) -> Scalar { +impl From<ScalarPrimitive> for Scalar { + fn from(scalar: ScalarPrimitive) -> Scalar { Self(scalar) } } +impl From<Scalar> for ScalarPrimitive { + fn from(scalar: Scalar) -> ScalarPrimitive { + scalar.0 + } +} + +impl From<Scalar> for U256 { + fn from(scalar: Scalar) -> U256 { + scalar.0.to_uint() + } +} + +impl TryFrom<U256> for Scalar { + type Error = Error; + + fn try_from(w: U256) -> Result<Self> { + Option::from(ScalarPrimitive::new(w)).map(Self).ok_or(Error) + } +} + +impl FromUintUnchecked for Scalar { + type Uint = U256; + + fn from_uint_unchecked(uint: U256) -> Self { + Self(ScalarPrimitive::from_uint_unchecked(uint)) + } +} + impl From<Scalar> for FieldBytes { fn from(scalar: Scalar) -> Self { Self::from(&scalar) @@ -369,15 +424,28 @@ pub enum AffinePoint { Other(EncodedPoint), } -impl AffineXCoordinate<MockCurve> for AffinePoint { +impl AffineCoordinates for AffinePoint { + type FieldRepr = FieldBytes; + fn x(&self) -> FieldBytes { unimplemented!(); } + + fn y_is_odd(&self) -> Choice { + unimplemented!(); + } } impl ConstantTimeEq for AffinePoint { - fn ct_eq(&self, _other: &Self) -> Choice { - unimplemented!(); + fn ct_eq(&self, other: &Self) -> Choice { + match (self, other) { + (Self::FixedBaseOutput(scalar), Self::FixedBaseOutput(other_scalar)) => { + scalar.ct_eq(other_scalar) + } + (Self::Identity, Self::Identity) | (Self::Generator, Self::Generator) => 1.into(), + (Self::Other(point), Self::Other(other_point)) => u8::from(point == other_point).into(), + _ => 0.into(), + } } } @@ -457,14 +525,25 @@ pub enum ProjectivePoint { } impl ConstantTimeEq for ProjectivePoint { - fn ct_eq(&self, _other: &Self) -> Choice { - unimplemented!(); + fn ct_eq(&self, other: &Self) -> Choice { + match (self, other) { + (Self::FixedBaseOutput(scalar), Self::FixedBaseOutput(other_scalar)) => { + scalar.ct_eq(other_scalar) + } + (Self::Identity, Self::Identity) | (Self::Generator, Self::Generator) => 1.into(), + (Self::Other(point), Self::Other(other_point)) => point.ct_eq(other_point), + _ => 0.into(), + } } } impl ConditionallySelectable for ProjectivePoint { - fn conditional_select(_a: &Self, _b: &Self, _choice: Choice) -> Self { - unimplemented!(); + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + if choice.into() { + *b + } else { + *a + } } } @@ -521,7 +600,7 @@ impl group::Group for ProjectivePoint { } fn is_identity(&self) -> Choice { - Choice::from((self == &Self::Identity) as u8) + Choice::from(u8::from(self == &Self::Identity)) } #[must_use] @@ -530,6 +609,47 @@ impl group::Group for ProjectivePoint { } } +impl group::GroupEncoding for AffinePoint { + type Repr = CompressedPoint<MockCurve>; + + fn from_bytes(bytes: &Self::Repr) -> CtOption<Self> { + EncodedPoint::from_bytes(bytes) + .map(|point| CtOption::new(point, Choice::from(1))) + .unwrap_or_else(|_| { + let is_identity = bytes.ct_eq(&Self::Repr::default()); + CtOption::new(EncodedPoint::identity(), is_identity) + }) + .and_then(|point| Self::from_encoded_point(&point)) + } + + fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self> { + Self::from_bytes(bytes) + } + + fn to_bytes(&self) -> Self::Repr { + let encoded = self.to_encoded_point(true); + let mut result = CompressedPoint::<MockCurve>::default(); + result[..encoded.len()].copy_from_slice(encoded.as_bytes()); + result + } +} + +impl group::GroupEncoding for ProjectivePoint { + type Repr = CompressedPoint<MockCurve>; + + fn from_bytes(bytes: &Self::Repr) -> CtOption<Self> { + <AffinePoint as group::GroupEncoding>::from_bytes(bytes).map(Into::into) + } + + fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self> { + Self::from_bytes(bytes) + } + + fn to_bytes(&self) -> Self::Repr { + group::Curve::to_affine(self).to_bytes() + } +} + impl group::Curve for ProjectivePoint { type AffineRepr = AffinePoint; @@ -699,6 +819,8 @@ impl MulAssign<&Scalar> for ProjectivePoint { } } +impl MulByGenerator for ProjectivePoint {} + impl Neg for ProjectivePoint { type Output = ProjectivePoint; @@ -707,78 +829,6 @@ impl Neg for ProjectivePoint { } } -/// Constant representing the base field modulus -/// p = 2^{224}(2^{32} − 1) + 2^{192} + 2^{96} − 1 -pub const MODULUS: U256 = - U256::from_be_hex("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff"); - -/// Example base field element. -#[derive(Clone, Copy, Debug)] -pub struct FieldElement(pub(crate) U256); - -/// Internal field element representation. -#[cfg(target_pointer_width = "32")] -type FeWords = [u32; 8]; - -/// Internal field element representation. -#[cfg(target_pointer_width = "64")] -type FeWords = [u64; 4]; - -impl_field_element!( - FieldElement, - FieldBytes, - U256, - MODULUS, - FeWords, - p256_from_montgomery, - p256_to_montgomery, - p256_add, - p256_sub, - p256_mul, - p256_opp, - p256_square -); - -impl FieldElement { - /// Returns the multiplicative inverse of self, if self is non-zero. - pub fn invert(&self) -> CtOption<Self> { - unimplemented!() - } - - /// Returns the square root of self mod p, or `None` if no square root exists. - pub fn sqrt(&self) -> CtOption<Self> { - unimplemented!() - } -} - -const fn p256_from_montgomery(_: &FeWords) -> FeWords { - unimplemented!() -} - -const fn p256_to_montgomery(w: &FeWords) -> FeWords { - *w -} - -const fn p256_add(_: &FeWords, _: &FeWords) -> FeWords { - unimplemented!() -} - -const fn p256_sub(_: &FeWords, _: &FeWords) -> FeWords { - unimplemented!() -} - -const fn p256_mul(_: &FeWords, _: &FeWords) -> FeWords { - unimplemented!() -} - -const fn p256_opp(_: &FeWords) -> FeWords { - unimplemented!() -} - -const fn p256_square(_: &FeWords) -> FeWords { - unimplemented!() -} - #[cfg(test)] mod tests { use super::Scalar; |