summaryrefslogtreecommitdiffstats
path: root/vendor/p384/src/arithmetic/scalar.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/p384/src/arithmetic/scalar.rs')
-rw-r--r--vendor/p384/src/arithmetic/scalar.rs370
1 files changed, 370 insertions, 0 deletions
diff --git a/vendor/p384/src/arithmetic/scalar.rs b/vendor/p384/src/arithmetic/scalar.rs
new file mode 100644
index 000000000..db7994e20
--- /dev/null
+++ b/vendor/p384/src/arithmetic/scalar.rs
@@ -0,0 +1,370 @@
+//! 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, U384};
+use core::ops::{AddAssign, MulAssign, Neg, SubAssign};
+use elliptic_curve::{
+ bigint::{self, Encoding, Limb},
+ ff::PrimeField,
+ ops::Reduce,
+ subtle::{Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, CtOption},
+ Curve as _, Error, IsHigh, Result, ScalarArithmetic, ScalarCore,
+};
+
+#[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};
+
+impl ScalarArithmetic for NistP384 {
+ type Scalar = Scalar;
+}
+
+/// 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)]
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+pub struct Scalar(U384);
+
+elliptic_curve::impl_field_element!(
+ 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 {
+ /// `2^s` root of unity.
+ pub const ROOT_OF_UNITY: Self = Self::from_be_hex("ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972");
+
+ /// Compute [`Scalar`] inversion: `1 / self`.
+ pub fn invert(&self) -> CtOption<Self> {
+ let ret = impl_field_invert!(
+ self.to_canonical().to_words(),
+ Self::ONE.0.to_words(),
+ Limb::BIT_SIZE,
+ bigint::nlimbs!(U384::BIT_SIZE),
+ 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,
+ );
+ CtOption::new(Self(ret.into()), !self.is_zero())
+ }
+
+ /// Compute modular square root.
+ pub fn sqrt(&self) -> CtOption<Self> {
+ // 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
+ }
+
+ /// Returns the SEC1 encoding of this scalar.
+ ///
+ /// Required for running test vectors.
+ #[cfg(test)]
+ pub fn to_bytes(&self) -> FieldBytes {
+ self.to_be_bytes()
+ }
+}
+
+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 PrimeField for Scalar {
+ type Repr = FieldBytes;
+
+ const CAPACITY: u32 = 383;
+ const NUM_BITS: u32 = 384;
+ const S: u32 = 1;
+
+ fn from_repr(bytes: FieldBytes) -> CtOption<Self> {
+ Self::from_be_bytes(bytes)
+ }
+
+ fn to_repr(&self) -> FieldBytes {
+ self.to_be_bytes()
+ }
+
+ fn is_odd(&self) -> Choice {
+ self.is_odd()
+ }
+
+ fn multiplicative_generator() -> Self {
+ 2u64.into()
+ }
+
+ fn root_of_unity() -> Self {
+ Self::ROOT_OF_UNITY
+ }
+}
+
+#[cfg(feature = "bits")]
+#[cfg_attr(docsrs, doc(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<U384> for Scalar {
+ fn from_uint_reduced(w: U384) -> Self {
+ let (r, underflow) = w.sbb(&NistP384::ORDER, Limb::ZERO);
+ let underflow = Choice::from((underflow.0 >> (Limb::BIT_SIZE - 1)) as u8);
+ Self::from_uint_unchecked(U384::conditional_select(&w, &r, !underflow))
+ }
+}
+
+impl From<u64> for Scalar {
+ fn from(n: u64) -> Scalar {
+ Self::from_uint_unchecked(U384::from(n))
+ }
+}
+
+impl From<ScalarCore<NistP384>> for Scalar {
+ fn from(w: ScalarCore<NistP384>) -> Self {
+ Scalar::from(&w)
+ }
+}
+
+impl From<&ScalarCore<NistP384>> for Scalar {
+ fn from(w: &ScalarCore<NistP384>) -> Scalar {
+ Scalar::from_uint_unchecked(*w.as_uint())
+ }
+}
+
+impl From<Scalar> for ScalarCore<NistP384> {
+ fn from(scalar: Scalar) -> ScalarCore<NistP384> {
+ ScalarCore::from(&scalar)
+ }
+}
+
+impl From<&Scalar> for ScalarCore<NistP384> {
+ fn from(scalar: &Scalar) -> ScalarCore<NistP384> {
+ ScalarCore::new(scalar.into()).unwrap()
+ }
+}
+
+impl From<Scalar> 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<Scalar> 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<U384> for Scalar {
+ type Error = Error;
+
+ fn try_from(w: U384) -> Result<Self> {
+ Option::from(Self::from_uint(w)).ok_or(Error)
+ }
+}
+
+#[cfg(feature = "serde")]
+#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
+impl Serialize for Scalar {
+ fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ ScalarCore::from(self).serialize(serializer)
+ }
+}
+
+#[cfg(feature = "serde")]
+#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
+impl<'de> Deserialize<'de> for Scalar {
+ fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ Ok(ScalarCore::deserialize(deserializer)?.into())
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::Scalar;
+ use crate::FieldBytes;
+ use elliptic_curve::ff::{Field, PrimeField};
+
+ #[test]
+ fn from_to_bytes_roundtrip() {
+ let k: u64 = 42;
+ let mut bytes = FieldBytes::default();
+ bytes[40..].copy_from_slice(k.to_le_bytes().as_ref());
+
+ let scalar = Scalar::from_repr(bytes).unwrap();
+ assert_eq!(bytes, scalar.to_be_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);
+ }
+ }
+}