//! secp384r1 scalar field elements. #![allow(clippy::unusual_byte_groupings)] #[cfg_attr(target_pointer_width = "32", path = "scalar/p384_scalar_32.rs")] #[cfg_attr(target_pointer_width = "64", path = "scalar/p384_scalar_64.rs")] #[allow( clippy::identity_op, clippy::too_many_arguments, clippy::unnecessary_cast )] mod scalar_impl; use self::scalar_impl::*; use crate::{FieldBytes, NistP384, SecretKey, ORDER_HEX, U384}; use core::{ iter::{Product, Sum}, ops::{AddAssign, MulAssign, Neg, Shr, ShrAssign, SubAssign}, }; use elliptic_curve::{ bigint::{self, ArrayEncoding, Limb}, ff::PrimeField, ops::{Invert, Reduce}, scalar::{FromUintUnchecked, IsHigh}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, CtOption}, Curve as _, Error, Result, ScalarPrimitive, }; #[cfg(feature = "bits")] use {crate::ScalarBits, elliptic_curve::group::ff::PrimeFieldBits}; #[cfg(feature = "serde")] use serdect::serde::{de, ser, Deserialize, Serialize}; #[cfg(doc)] use core::ops::{Add, Mul, Sub}; /// Scalars are elements in the finite field modulo `n`. /// /// # Trait impls /// /// Much of the important functionality of scalars is provided by traits from /// the [`ff`](https://docs.rs/ff/) crate, which is re-exported as /// `p384::elliptic_curve::ff`: /// /// - [`Field`](https://docs.rs/ff/latest/ff/trait.Field.html) - /// represents elements of finite fields and provides: /// - [`Field::random`](https://docs.rs/ff/latest/ff/trait.Field.html#tymethod.random) - /// generate a random scalar /// - `double`, `square`, and `invert` operations /// - Bounds for [`Add`], [`Sub`], [`Mul`], and [`Neg`] (as well as `*Assign` equivalents) /// - Bounds for [`ConditionallySelectable`] from the `subtle` crate /// - [`PrimeField`](https://docs.rs/ff/latest/ff/trait.PrimeField.html) - /// represents elements of prime fields and provides: /// - `from_repr`/`to_repr` for converting field elements from/to big integers. /// - `multiplicative_generator` and `root_of_unity` constants. /// - [`PrimeFieldBits`](https://docs.rs/ff/latest/ff/trait.PrimeFieldBits.html) - /// operations over field elements represented as bits (requires `bits` feature) /// /// Please see the documentation for the relevant traits for more information. /// /// # `serde` support /// /// When the `serde` feature of this crate is enabled, the `Serialize` and /// `Deserialize` traits are impl'd for this type. /// /// The serialization is a fixed-width big endian encoding. When used with /// textual formats, the binary data is encoded as hexadecimal. #[derive(Clone, Copy, Debug, PartialOrd, Ord)] pub struct Scalar(U384); primeorder::impl_mont_field_element!( NistP384, Scalar, FieldBytes, U384, NistP384::ORDER, fiat_p384_scalar_montgomery_domain_field_element, fiat_p384_scalar_from_montgomery, fiat_p384_scalar_to_montgomery, fiat_p384_scalar_add, fiat_p384_scalar_sub, fiat_p384_scalar_mul, fiat_p384_scalar_opp, fiat_p384_scalar_square ); impl Scalar { /// Compute [`Scalar`] inversion: `1 / self`. pub fn invert(&self) -> CtOption { CtOption::new(self.invert_unchecked(), !self.is_zero()) } /// Returns the multiplicative inverse of self. /// /// Does not check that self is non-zero. const fn invert_unchecked(&self) -> Self { let words = impl_field_invert!( self.to_canonical().as_words(), Self::ONE.0.to_words(), Limb::BITS, bigint::nlimbs!(U384::BITS), fiat_p384_scalar_mul, fiat_p384_scalar_opp, fiat_p384_scalar_divstep_precomp, fiat_p384_scalar_divstep, fiat_p384_scalar_msat, fiat_p384_scalar_selectznz, ); Self(U384::from_words(words)) } /// Compute modular square root. pub fn sqrt(&self) -> CtOption { // p mod 4 = 3 -> compute sqrt(x) using x^((p+1)/4) = // x^9850501549098619803069760025035903451269934817616361666986726319906914849778315892349739077038073728388608413485661 let t1 = *self; let t10 = t1.square(); let t11 = *self * t10; let t101 = t10 * t11; let t111 = t10 * t101; let t1001 = t10 * t111; let t1011 = t10 * t1001; let t1101 = t10 * t1011; let t1111 = t10 * t1101; let t11110 = t1111.square(); let t11111 = t1 * t11110; let t1111100 = t11111.sqn(2); let t11111000 = t1111100.square(); let i14 = t11111000.square(); let i20 = i14.sqn(5) * i14; let i31 = i20.sqn(10) * i20; let i58 = (i31.sqn(4) * t11111000).sqn(21) * i31; let i110 = (i58.sqn(3) * t1111100).sqn(47) * i58; let x194 = i110.sqn(95) * i110 * t1111; let i225 = ((x194.sqn(6) * t111).sqn(3) * t11).sqn(7); let i235 = ((t1101 * i225).sqn(6) * t1101).square() * t1; let i258 = ((i235.sqn(11) * t11111).sqn(2) * t1).sqn(8); let i269 = ((t1101 * i258).sqn(2) * t11).sqn(6) * t1011; let i286 = ((i269.sqn(4) * t111).sqn(6) * t11111).sqn(5); let i308 = ((t1011 * i286).sqn(10) * t1101).sqn(9) * t1101; let i323 = ((i308.sqn(4) * t1011).sqn(6) * t1001).sqn(3); let i340 = ((t1 * i323).sqn(7) * t1011).sqn(7) * t101; let i357 = ((i340.sqn(5) * t111).sqn(5) * t1111).sqn(5); let i369 = ((t1011 * i357).sqn(4) * t1011).sqn(5) * t111; let i387 = ((i369.sqn(3) * t11).sqn(7) * t11).sqn(6); let i397 = ((t1011 * i387).sqn(4) * t101).sqn(3) * t11; let i413 = ((i397.sqn(4) * t11).sqn(4) * t11).sqn(6); let i427 = ((t101 * i413).sqn(5) * t101).sqn(6) * t1011; let x = i427.sqn(3) * t101; CtOption::new(x, x.square().ct_eq(&t1)) } fn sqn(&self, n: usize) -> Self { let mut x = *self; for _ in 0..n { x = x.square(); } x } /// Right shifts the scalar. /// /// Note: not constant-time with respect to the `shift` parameter. pub const fn shr_vartime(&self, shift: usize) -> Scalar { Self(self.0.shr_vartime(shift)) } } impl AsRef for Scalar { fn as_ref(&self) -> &Scalar { self } } impl FromUintUnchecked for Scalar { type Uint = U384; fn from_uint_unchecked(uint: Self::Uint) -> Self { Self::from_uint_unchecked(uint) } } impl Invert for Scalar { type Output = CtOption; fn invert(&self) -> CtOption { self.invert() } } impl IsHigh for Scalar { fn is_high(&self) -> Choice { const MODULUS_SHR1: U384 = NistP384::ORDER.shr_vartime(1); self.to_canonical().ct_gt(&MODULUS_SHR1) } } impl Shr for Scalar { type Output = Self; fn shr(self, rhs: usize) -> Self::Output { self.shr_vartime(rhs) } } impl Shr for &Scalar { type Output = Scalar; fn shr(self, rhs: usize) -> Self::Output { self.shr_vartime(rhs) } } impl ShrAssign for Scalar { fn shr_assign(&mut self, rhs: usize) { *self = *self >> rhs; } } impl PrimeField for Scalar { type Repr = FieldBytes; const MODULUS: &'static str = ORDER_HEX; const CAPACITY: u32 = 383; const NUM_BITS: u32 = 384; const TWO_INV: Self = Self::from_u64(2).invert_unchecked(); const MULTIPLICATIVE_GENERATOR: Self = Self::from_u64(2); const S: u32 = 1; const ROOT_OF_UNITY: Self = Self::from_hex("ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972"); const ROOT_OF_UNITY_INV: Self = Self::ROOT_OF_UNITY.invert_unchecked(); const DELTA: Self = Self::from_u64(4); #[inline] fn from_repr(bytes: FieldBytes) -> CtOption { Self::from_bytes(&bytes) } #[inline] fn to_repr(&self) -> FieldBytes { self.to_bytes() } #[inline] fn is_odd(&self) -> Choice { self.is_odd() } } #[cfg(feature = "bits")] impl PrimeFieldBits for Scalar { type ReprBits = fiat_p384_scalar_montgomery_domain_field_element; fn to_le_bits(&self) -> ScalarBits { self.to_canonical().to_words().into() } fn char_le_bits() -> ScalarBits { NistP384::ORDER.to_words().into() } } impl Reduce for Scalar { type Bytes = FieldBytes; fn reduce(w: U384) -> Self { let (r, underflow) = w.sbb(&NistP384::ORDER, Limb::ZERO); let underflow = Choice::from((underflow.0 >> (Limb::BITS - 1)) as u8); Self::from_uint_unchecked(U384::conditional_select(&w, &r, !underflow)) } #[inline] fn reduce_bytes(bytes: &FieldBytes) -> Self { Self::reduce(U384::from_be_byte_array(*bytes)) } } impl From> for Scalar { fn from(w: ScalarPrimitive) -> Self { Scalar::from(&w) } } impl From<&ScalarPrimitive> for Scalar { fn from(w: &ScalarPrimitive) -> Scalar { Scalar::from_uint_unchecked(*w.as_uint()) } } impl From for ScalarPrimitive { fn from(scalar: Scalar) -> ScalarPrimitive { ScalarPrimitive::from(&scalar) } } impl From<&Scalar> for ScalarPrimitive { fn from(scalar: &Scalar) -> ScalarPrimitive { ScalarPrimitive::new(scalar.into()).unwrap() } } impl From for FieldBytes { fn from(scalar: Scalar) -> Self { scalar.to_repr() } } impl From<&Scalar> for FieldBytes { fn from(scalar: &Scalar) -> Self { scalar.to_repr() } } impl From for U384 { fn from(scalar: Scalar) -> U384 { U384::from(&scalar) } } impl From<&Scalar> for U384 { fn from(scalar: &Scalar) -> U384 { scalar.to_canonical() } } impl From<&SecretKey> for Scalar { fn from(secret_key: &SecretKey) -> Scalar { *secret_key.to_nonzero_scalar() } } impl TryFrom for Scalar { type Error = Error; fn try_from(w: U384) -> Result { Option::from(Self::from_uint(w)).ok_or(Error) } } #[cfg(feature = "serde")] impl Serialize for Scalar { fn serialize(&self, serializer: S) -> core::result::Result where S: ser::Serializer, { ScalarPrimitive::from(self).serialize(serializer) } } #[cfg(feature = "serde")] impl<'de> Deserialize<'de> for Scalar { fn deserialize(deserializer: D) -> core::result::Result where D: de::Deserializer<'de>, { Ok(ScalarPrimitive::deserialize(deserializer)?.into()) } } #[cfg(test)] mod tests { use super::Scalar; use crate::FieldBytes; use elliptic_curve::ff::PrimeField; use primeorder::impl_primefield_tests; /// t = (modulus - 1) >> S const T: [u64; 6] = [ 0x76760cb5666294b9, 0xac0d06d9245853bd, 0xe3b1a6c0fa1b96ef, 0xffffffffffffffff, 0xffffffffffffffff, 0x7fffffffffffffff, ]; impl_primefield_tests!(Scalar, T); #[test] fn from_to_bytes_roundtrip() { let k: u64 = 42; let mut bytes = FieldBytes::default(); bytes[40..].copy_from_slice(k.to_be_bytes().as_ref()); let scalar = Scalar::from_repr(bytes).unwrap(); assert_eq!(bytes, scalar.to_bytes()); } /// Basic tests that multiplication works. #[test] fn multiply() { let one = Scalar::ONE; let two = one + one; let three = two + one; let six = three + three; assert_eq!(six, two * three); let minus_two = -two; let minus_three = -three; assert_eq!(two, -minus_two); assert_eq!(minus_three * minus_two, minus_two * minus_three); assert_eq!(six, minus_two * minus_three); } /// Basic tests that scalar inversion works. #[test] fn invert() { let one = Scalar::ONE; let three = one + one + one; let inv_three = three.invert().unwrap(); assert_eq!(three * inv_three, one); let minus_three = -three; let inv_minus_three = minus_three.invert().unwrap(); assert_eq!(inv_minus_three, -inv_three); assert_eq!(three * inv_minus_three, -one); } /// Basic tests that sqrt works. #[test] fn sqrt() { for &n in &[1u64, 4, 9, 16, 25, 36, 49, 64] { let scalar = Scalar::from(n); let sqrt = scalar.sqrt().unwrap(); assert_eq!(sqrt.square(), scalar); } } }