p521/arithmetic/
scalar.rs

1//! secp521r1 scalar field elements.
2//!
3//! Arithmetic implementations have been synthesized using fiat-crypto.
4//!
5//! # License
6//!
7//! Copyright (c) 2015-2020 the fiat-crypto authors
8//!
9//! fiat-crypto is distributed under the terms of the MIT License, the
10//! Apache License (Version 2.0), and the BSD 1-Clause License;
11//! users may pick which license to apply.
12
13// TODO(tarcieri): 32-bit backend?
14#[path = "scalar/p521_scalar_64.rs"]
15mod scalar_impl;
16
17use self::scalar_impl::*;
18use crate::{FieldBytes, NistP521, SecretKey, U576};
19use core::{
20    iter::{Product, Sum},
21    ops::{AddAssign, MulAssign, Neg, Shr, ShrAssign, SubAssign},
22};
23use elliptic_curve::{
24    bigint::{self, Integer},
25    ff::{self, Field, PrimeField},
26    generic_array::GenericArray,
27    ops::{Invert, Reduce},
28    rand_core::RngCore,
29    scalar::{FromUintUnchecked, IsHigh},
30    subtle::{
31        Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess,
32        CtOption,
33    },
34    zeroize::DefaultIsZeroes,
35    Curve as _, Error, FieldBytesEncoding, Result, ScalarPrimitive,
36};
37use primeorder::{impl_bernstein_yang_invert, impl_field_op};
38
39#[cfg(feature = "bits")]
40use {crate::ScalarBits, elliptic_curve::group::ff::PrimeFieldBits};
41
42#[cfg(feature = "serde")]
43use serdect::serde::{de, ser, Deserialize, Serialize};
44
45#[cfg(doc)]
46use core::ops::{Add, Mul, Sub};
47
48#[cfg(target_pointer_width = "32")]
49use super::util::{u32x18_to_u64x9, u64x9_to_u32x18};
50
51/// Scalars are elements in the finite field modulo `n`.
52///
53/// # Trait impls
54///
55/// Much of the important functionality of scalars is provided by traits from
56/// the [`ff`](https://docs.rs/ff/) crate, which is re-exported as
57/// `p521::elliptic_curve::ff`:
58///
59/// - [`Field`](https://docs.rs/ff/latest/ff/trait.Field.html) -
60///   represents elements of finite fields and provides:
61///   - [`Field::random`](https://docs.rs/ff/latest/ff/trait.Field.html#tymethod.random) -
62///     generate a random scalar
63///   - `double`, `square`, and `invert` operations
64///   - Bounds for [`Add`], [`Sub`], [`Mul`], and [`Neg`] (as well as `*Assign` equivalents)
65///   - Bounds for [`ConditionallySelectable`] from the `subtle` crate
66/// - [`PrimeField`](https://docs.rs/ff/latest/ff/trait.PrimeField.html) -
67///   represents elements of prime fields and provides:
68///   - `from_repr`/`to_repr` for converting field elements from/to big integers.
69///   - `multiplicative_generator` and `root_of_unity` constants.
70/// - [`PrimeFieldBits`](https://docs.rs/ff/latest/ff/trait.PrimeFieldBits.html) -
71///   operations over field elements represented as bits (requires `bits` feature)
72///
73/// Please see the documentation for the relevant traits for more information.
74#[derive(Clone, Copy, Debug, PartialOrd, Ord)]
75pub struct Scalar(fiat_p521_scalar_montgomery_domain_field_element);
76
77impl Scalar {
78    /// Zero element.
79    pub const ZERO: Self = Self::from_u64(0);
80
81    /// Multiplicative identity.
82    pub const ONE: Self = Self::from_u64(1);
83
84    /// Number of bytes in the serialized representation.
85    const BYTES: usize = 66;
86
87    /// Create a [`Scalar`] from a canonical big-endian representation.
88    pub fn from_bytes(repr: &FieldBytes) -> CtOption<Self> {
89        Self::from_uint(FieldBytesEncoding::<NistP521>::decode_field_bytes(repr))
90    }
91
92    /// Decode [`Scalar`] from a big endian byte slice.
93    pub fn from_slice(slice: &[u8]) -> Result<Self> {
94        if slice.len() != Self::BYTES {
95            return Err(Error);
96        }
97
98        Option::from(Self::from_bytes(GenericArray::from_slice(slice))).ok_or(Error)
99    }
100
101    /// Decode [`Scalar`] from [`U576`] converting it into Montgomery form:
102    ///
103    /// ```text
104    /// w * R^2 * R^-1 mod p = wR mod p
105    /// ```
106    pub fn from_uint(uint: U576) -> CtOption<Self> {
107        let is_some = uint.ct_lt(&NistP521::ORDER);
108        CtOption::new(Self::from_uint_unchecked(uint), is_some)
109    }
110
111    /// Parse a [`Scalar`] from big endian hex-encoded bytes.
112    ///
113    /// Does *not* perform a check that the field element does not overflow the order.
114    ///
115    /// This method is primarily intended for defining internal constants.
116    #[allow(dead_code)]
117    pub(crate) const fn from_hex(hex: &str) -> Self {
118        Self::from_uint_unchecked(U576::from_be_hex(hex))
119    }
120
121    /// Convert a `u64` into a [`Scalar`].
122    pub const fn from_u64(w: u64) -> Self {
123        Self::from_uint_unchecked(U576::from_u64(w))
124    }
125
126    /// Decode [`Scalar`] from [`U576`] converting it into Montgomery form.
127    ///
128    /// Does *not* perform a check that the field element does not overflow the order.
129    ///
130    /// Used incorrectly this can lead to invalid results!
131    #[cfg(target_pointer_width = "32")]
132    pub(crate) const fn from_uint_unchecked(w: U576) -> Self {
133        Self(fiat_p521_scalar_to_montgomery(&u32x18_to_u64x9(
134            w.as_words(),
135        )))
136    }
137
138    /// Decode [`Scalar`] from [`U576`] converting it into Montgomery form.
139    ///
140    /// Does *not* perform a check that the field element does not overflow the order.
141    ///
142    /// Used incorrectly this can lead to invalid results!
143    #[cfg(target_pointer_width = "64")]
144    pub(crate) const fn from_uint_unchecked(w: U576) -> Self {
145        Self(fiat_p521_scalar_to_montgomery(w.as_words()))
146    }
147
148    /// Returns the big-endian encoding of this [`Scalar`].
149    pub fn to_bytes(self) -> FieldBytes {
150        FieldBytesEncoding::<NistP521>::encode_field_bytes(&self.to_canonical())
151    }
152
153    /// Translate [`Scalar`] out of the Montgomery domain, returning a [`U576`]
154    /// in canonical form.
155    #[inline]
156    #[cfg(target_pointer_width = "32")]
157    pub const fn to_canonical(self) -> U576 {
158        U576::from_words(u64x9_to_u32x18(&fiat_p521_scalar_from_montgomery(&self.0)))
159    }
160
161    /// Translate [`Scalar`] out of the Montgomery domain, returning a [`U576`]
162    /// in canonical form.
163    #[inline]
164    #[cfg(target_pointer_width = "64")]
165    pub const fn to_canonical(self) -> U576 {
166        U576::from_words(fiat_p521_scalar_from_montgomery(&self.0))
167    }
168
169    /// Determine if this [`Scalar`] is odd in the SEC1 sense: `self mod 2 == 1`.
170    ///
171    /// # Returns
172    ///
173    /// If odd, return `Choice(1)`.  Otherwise, return `Choice(0)`.
174    pub fn is_odd(&self) -> Choice {
175        self.to_canonical().is_odd()
176    }
177
178    /// Determine if this [`Scalar`] is even in the SEC1 sense: `self mod 2 == 0`.
179    ///
180    /// # Returns
181    ///
182    /// If even, return `Choice(1)`.  Otherwise, return `Choice(0)`.
183    pub fn is_even(&self) -> Choice {
184        !self.is_odd()
185    }
186
187    /// Determine if this [`Scalar`] is zero.
188    ///
189    /// # Returns
190    ///
191    /// If zero, return `Choice(1)`.  Otherwise, return `Choice(0)`.
192    pub fn is_zero(&self) -> Choice {
193        self.ct_eq(&Self::ZERO)
194    }
195
196    /// Add elements.
197    pub const fn add(&self, rhs: &Self) -> Self {
198        Self(fiat_p521_scalar_add(&self.0, &rhs.0))
199    }
200
201    /// Double element (add it to itself).
202    #[must_use]
203    pub const fn double(&self) -> Self {
204        self.add(self)
205    }
206
207    /// Subtract elements.
208    pub const fn sub(&self, rhs: &Self) -> Self {
209        Self(fiat_p521_scalar_sub(&self.0, &rhs.0))
210    }
211
212    /// Negate element.
213    pub const fn neg(&self) -> Self {
214        Self(fiat_p521_scalar_opp(&self.0))
215    }
216
217    /// Multiply elements.
218    pub const fn multiply(&self, rhs: &Self) -> Self {
219        Self(fiat_p521_scalar_mul(&self.0, &rhs.0))
220    }
221
222    /// Compute [`Scalar`] inversion: `1 / self`.
223    pub fn invert(&self) -> CtOption<Self> {
224        CtOption::new(self.invert_unchecked(), !self.is_zero())
225    }
226
227    /// Compute [`Scalar`] inversion: `1 / self`.
228    ///
229    /// Does not check that self is non-zero.
230    const fn invert_unchecked(&self) -> Self {
231        let words = impl_bernstein_yang_invert!(
232            &self.0,
233            Self::ONE.0,
234            521,
235            9,
236            u64,
237            fiat_p521_scalar_from_montgomery,
238            fiat_p521_scalar_mul,
239            fiat_p521_scalar_opp,
240            fiat_p521_scalar_divstep_precomp,
241            fiat_p521_scalar_divstep,
242            fiat_p521_scalar_msat,
243            fiat_p521_scalar_selectznz,
244        );
245
246        Self(words)
247    }
248
249    /// Compute modular square.
250    #[must_use]
251    pub const fn square(&self) -> Self {
252        Self(fiat_p521_scalar_square(&self.0))
253    }
254
255    /// Compute modular square root.
256    pub fn sqrt(&self) -> CtOption<Self> {
257        todo!("`sqrt` not yet implemented")
258    }
259
260    /// Returns `self^exp`, where `exp` is a little-endian integer exponent.
261    ///
262    /// **This operation is variable time with respect to the exponent.**
263    ///
264    /// If the exponent is fixed, this operation is effectively constant time.
265    pub const fn pow_vartime(&self, exp: &[u64]) -> Self {
266        let mut res = Self::ONE;
267        let mut i = exp.len();
268
269        while i > 0 {
270            i -= 1;
271
272            let mut j = 64;
273            while j > 0 {
274                j -= 1;
275                res = res.square();
276
277                if ((exp[i] >> j) & 1) == 1 {
278                    res = res.multiply(self);
279                }
280            }
281        }
282
283        res
284    }
285
286    /// Right shifts the scalar.
287    ///
288    /// Note: not constant-time with respect to the `shift` parameter.
289    #[cfg(target_pointer_width = "32")]
290    pub const fn shr_vartime(&self, shift: usize) -> Scalar {
291        Self(u32x18_to_u64x9(
292            &U576::from_words(u64x9_to_u32x18(&self.0))
293                .shr_vartime(shift)
294                .to_words(),
295        ))
296    }
297
298    /// Right shifts the scalar.
299    ///
300    /// Note: not constant-time with respect to the `shift` parameter.
301    #[cfg(target_pointer_width = "64")]
302    pub const fn shr_vartime(&self, shift: usize) -> Scalar {
303        Self(U576::from_words(self.0).shr_vartime(shift).to_words())
304    }
305}
306
307impl AsRef<fiat_p521_scalar_montgomery_domain_field_element> for Scalar {
308    fn as_ref(&self) -> &fiat_p521_scalar_montgomery_domain_field_element {
309        &self.0
310    }
311}
312
313impl Default for Scalar {
314    fn default() -> Self {
315        Self::ZERO
316    }
317}
318
319impl Eq for Scalar {}
320impl PartialEq for Scalar {
321    fn eq(&self, rhs: &Self) -> bool {
322        self.0.ct_eq(&(rhs.0)).into()
323    }
324}
325
326impl From<u32> for Scalar {
327    fn from(n: u32) -> Scalar {
328        Self::from_uint_unchecked(U576::from(n))
329    }
330}
331
332impl From<u64> for Scalar {
333    fn from(n: u64) -> Scalar {
334        Self::from_uint_unchecked(U576::from(n))
335    }
336}
337
338impl From<u128> for Scalar {
339    fn from(n: u128) -> Scalar {
340        Self::from_uint_unchecked(U576::from(n))
341    }
342}
343
344impl ConditionallySelectable for Scalar {
345    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
346        let mut ret = Self::ZERO;
347
348        for i in 0..ret.0.len() {
349            ret.0[i] = u64::conditional_select(&a.0[i], &b.0[i], choice);
350        }
351
352        ret
353    }
354}
355
356impl ConstantTimeEq for Scalar {
357    fn ct_eq(&self, other: &Self) -> Choice {
358        self.0.ct_eq(&other.0)
359    }
360}
361
362impl DefaultIsZeroes for Scalar {}
363
364impl Field for Scalar {
365    const ZERO: Self = Self::ZERO;
366    const ONE: Self = Self::ONE;
367
368    fn random(mut rng: impl RngCore) -> Self {
369        // NOTE: can't use ScalarPrimitive::random due to CryptoRng bound
370        let mut bytes = <FieldBytes>::default();
371
372        loop {
373            rng.fill_bytes(&mut bytes);
374            if let Some(fe) = Self::from_bytes(&bytes).into() {
375                return fe;
376            }
377        }
378    }
379
380    fn is_zero(&self) -> Choice {
381        Self::ZERO.ct_eq(self)
382    }
383
384    #[must_use]
385    fn square(&self) -> Self {
386        self.square()
387    }
388
389    #[must_use]
390    fn double(&self) -> Self {
391        self.double()
392    }
393
394    fn invert(&self) -> CtOption<Self> {
395        self.invert()
396    }
397
398    fn sqrt(&self) -> CtOption<Self> {
399        self.sqrt()
400    }
401
402    fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self) {
403        ff::helpers::sqrt_ratio_generic(num, div)
404    }
405}
406
407impl_field_op!(Scalar, Add, add, fiat_p521_scalar_add);
408impl_field_op!(Scalar, Sub, sub, fiat_p521_scalar_sub);
409impl_field_op!(Scalar, Mul, mul, fiat_p521_scalar_mul);
410
411impl AddAssign<Scalar> for Scalar {
412    #[inline]
413    fn add_assign(&mut self, other: Scalar) {
414        *self = *self + other;
415    }
416}
417
418impl AddAssign<&Scalar> for Scalar {
419    #[inline]
420    fn add_assign(&mut self, other: &Scalar) {
421        *self = *self + other;
422    }
423}
424
425impl SubAssign<Scalar> for Scalar {
426    #[inline]
427    fn sub_assign(&mut self, other: Scalar) {
428        *self = *self - other;
429    }
430}
431
432impl SubAssign<&Scalar> for Scalar {
433    #[inline]
434    fn sub_assign(&mut self, other: &Scalar) {
435        *self = *self - other;
436    }
437}
438
439impl MulAssign<&Scalar> for Scalar {
440    #[inline]
441    fn mul_assign(&mut self, other: &Scalar) {
442        *self = *self * other;
443    }
444}
445
446impl MulAssign for Scalar {
447    #[inline]
448    fn mul_assign(&mut self, other: Scalar) {
449        *self = *self * other;
450    }
451}
452
453impl Neg for Scalar {
454    type Output = Scalar;
455
456    #[inline]
457    fn neg(self) -> Scalar {
458        Self::neg(&self)
459    }
460}
461
462impl Sum for Scalar {
463    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
464        iter.reduce(core::ops::Add::add).unwrap_or(Self::ZERO)
465    }
466}
467
468impl<'a> Sum<&'a Scalar> for Scalar {
469    fn sum<I: Iterator<Item = &'a Scalar>>(iter: I) -> Self {
470        iter.copied().sum()
471    }
472}
473
474impl Product for Scalar {
475    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
476        iter.reduce(core::ops::Mul::mul).unwrap_or(Self::ONE)
477    }
478}
479
480impl<'a> Product<&'a Scalar> for Scalar {
481    fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
482        iter.copied().product()
483    }
484}
485
486impl AsRef<Scalar> for Scalar {
487    fn as_ref(&self) -> &Scalar {
488        self
489    }
490}
491
492impl FromUintUnchecked for Scalar {
493    type Uint = U576;
494
495    fn from_uint_unchecked(uint: Self::Uint) -> Self {
496        Self::from_uint_unchecked(uint)
497    }
498}
499
500impl Invert for Scalar {
501    type Output = CtOption<Self>;
502
503    fn invert(&self) -> CtOption<Self> {
504        self.invert()
505    }
506}
507
508impl IsHigh for Scalar {
509    fn is_high(&self) -> Choice {
510        const MODULUS_SHR1: U576 = NistP521::ORDER.shr_vartime(1);
511        self.to_canonical().ct_gt(&MODULUS_SHR1)
512    }
513}
514
515impl Shr<usize> for Scalar {
516    type Output = Self;
517
518    fn shr(self, rhs: usize) -> Self::Output {
519        self.shr_vartime(rhs)
520    }
521}
522
523impl Shr<usize> for &Scalar {
524    type Output = Scalar;
525
526    fn shr(self, rhs: usize) -> Self::Output {
527        self.shr_vartime(rhs)
528    }
529}
530
531impl ShrAssign<usize> for Scalar {
532    fn shr_assign(&mut self, rhs: usize) {
533        *self = *self >> rhs;
534    }
535}
536
537impl PrimeField for Scalar {
538    type Repr = FieldBytes;
539
540    const MODULUS: &'static str = "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409";
541    const CAPACITY: u32 = 520;
542    const NUM_BITS: u32 = 521;
543    const TWO_INV: Self = Self::from_u64(2).invert_unchecked();
544    const MULTIPLICATIVE_GENERATOR: Self = Self::from_u64(3);
545    const S: u32 = 3;
546    const ROOT_OF_UNITY: Self = Self::from_hex("000000000000009a0a650d44b28c17f3d708ad2fa8c4fbc7e6000d7c12dafa92fcc5673a3055276d535f79ff391dcdbcd998b7836647d3a72472b3da861ac810a7f9c7b7b63e2205");
547    const ROOT_OF_UNITY_INV: Self = Self::ROOT_OF_UNITY.invert_unchecked();
548    const DELTA: Self = Self::from_u64(6561);
549
550    #[inline]
551    fn from_repr(bytes: FieldBytes) -> CtOption<Self> {
552        Self::from_bytes(&bytes)
553    }
554
555    #[inline]
556    fn to_repr(&self) -> FieldBytes {
557        self.to_bytes()
558    }
559
560    #[inline]
561    fn is_odd(&self) -> Choice {
562        self.is_odd()
563    }
564}
565
566#[cfg(feature = "bits")]
567impl PrimeFieldBits for Scalar {
568    type ReprBits = fiat_p521_scalar_montgomery_domain_field_element;
569
570    fn to_le_bits(&self) -> ScalarBits {
571        self.to_canonical().to_words().into()
572    }
573
574    fn char_le_bits() -> ScalarBits {
575        NistP521::ORDER.to_words().into()
576    }
577}
578
579impl Reduce<U576> for Scalar {
580    type Bytes = FieldBytes;
581
582    fn reduce(w: U576) -> Self {
583        let (r, underflow) = w.sbb(&NistP521::ORDER, bigint::Limb::ZERO);
584        let underflow = Choice::from((underflow.0 >> (bigint::Limb::BITS - 1)) as u8);
585        Self::from_uint_unchecked(U576::conditional_select(&w, &r, !underflow))
586    }
587
588    #[inline]
589    fn reduce_bytes(bytes: &FieldBytes) -> Self {
590        let w = <U576 as FieldBytesEncoding<NistP521>>::decode_field_bytes(bytes);
591        Self::reduce(w)
592    }
593}
594
595impl From<ScalarPrimitive<NistP521>> for Scalar {
596    fn from(w: ScalarPrimitive<NistP521>) -> Self {
597        Scalar::from(&w)
598    }
599}
600
601impl From<&ScalarPrimitive<NistP521>> for Scalar {
602    fn from(w: &ScalarPrimitive<NistP521>) -> Scalar {
603        Scalar::from_uint_unchecked(*w.as_uint())
604    }
605}
606
607impl From<Scalar> for ScalarPrimitive<NistP521> {
608    fn from(scalar: Scalar) -> ScalarPrimitive<NistP521> {
609        ScalarPrimitive::from(&scalar)
610    }
611}
612
613impl From<&Scalar> for ScalarPrimitive<NistP521> {
614    fn from(scalar: &Scalar) -> ScalarPrimitive<NistP521> {
615        ScalarPrimitive::new(scalar.into()).unwrap()
616    }
617}
618
619impl From<Scalar> for FieldBytes {
620    fn from(scalar: Scalar) -> Self {
621        scalar.to_repr()
622    }
623}
624
625impl From<&Scalar> for FieldBytes {
626    fn from(scalar: &Scalar) -> Self {
627        scalar.to_repr()
628    }
629}
630
631impl From<Scalar> for U576 {
632    fn from(scalar: Scalar) -> U576 {
633        U576::from(&scalar)
634    }
635}
636
637impl From<&Scalar> for U576 {
638    fn from(scalar: &Scalar) -> U576 {
639        scalar.to_canonical()
640    }
641}
642
643impl From<&SecretKey> for Scalar {
644    fn from(secret_key: &SecretKey) -> Scalar {
645        *secret_key.to_nonzero_scalar()
646    }
647}
648
649impl TryFrom<U576> for Scalar {
650    type Error = Error;
651
652    fn try_from(w: U576) -> Result<Self> {
653        Option::from(Self::from_uint(w)).ok_or(Error)
654    }
655}
656
657#[cfg(feature = "serde")]
658impl Serialize for Scalar {
659    fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
660    where
661        S: ser::Serializer,
662    {
663        ScalarPrimitive::from(self).serialize(serializer)
664    }
665}
666
667#[cfg(feature = "serde")]
668impl<'de> Deserialize<'de> for Scalar {
669    fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
670    where
671        D: de::Deserializer<'de>,
672    {
673        Ok(ScalarPrimitive::deserialize(deserializer)?.into())
674    }
675}
676
677#[cfg(test)]
678mod tests {
679    use super::Scalar;
680    use elliptic_curve::PrimeField;
681    use primeorder::{impl_field_identity_tests, impl_field_invert_tests, impl_primefield_tests};
682
683    /// t = (modulus - 1) >> S
684    const T: [u64; 9] = [
685        0xd76df6e3d2270c81,
686        0x0776b937113388f5,
687        0x6ff980291ee134ba,
688        0x4a30d0f077e5f2cd,
689        0xffffffffffffffff,
690        0xffffffffffffffff,
691        0xffffffffffffffff,
692        0xffffffffffffffff,
693        0x000000000000003f,
694    ];
695
696    impl_field_identity_tests!(Scalar);
697    impl_field_invert_tests!(Scalar);
698    impl_primefield_tests!(Scalar, T);
699}