nam_blstrs/
scalar.rs

1//! An implementation of the BLS12-381 scalar field $\mathbb{F}_q$
2//! where `q = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001`
3
4use core::{
5    borrow::Borrow,
6    cmp,
7    convert::TryInto,
8    fmt,
9    iter::{Product, Sum},
10    ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
11};
12
13use blst::*;
14use byte_slice_cast::AsByteSlice;
15use ff::{Field, FieldBits, PrimeField, PrimeFieldBits};
16use rand_core::RngCore;
17use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
18
19/// Represents an element of the scalar field $\mathbb{F}_q$ of the BLS12-381 elliptic
20/// curve construction.
21///
22/// The inner representation `blst_fr` is stored in Montgomery form as little-endian `u64` limbs.
23#[derive(Default, Clone, Copy)]
24#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
25#[repr(transparent)]
26pub struct Scalar(pub(crate) blst_fr);
27
28// GENERATOR = 7 (multiplicative generator of r-1 order, that is also quadratic nonresidue)
29const GENERATOR: Scalar = Scalar(blst_fr {
30    l: [
31        0x0000_000e_ffff_fff1,
32        0x17e3_63d3_0018_9c0f,
33        0xff9c_5787_6f84_57b0,
34        0x3513_3220_8fc5_a8c4,
35    ],
36});
37
38// Little-endian non-Montgomery form not reduced mod p.
39#[allow(dead_code)]
40const MODULUS: [u64; 4] = [
41    0xffff_ffff_0000_0001,
42    0x53bd_a402_fffe_5bfe,
43    0x3339_d808_09a1_d805,
44    0x73ed_a753_299d_7d48,
45];
46
47/// The modulus as u32 limbs.
48#[cfg(not(target_pointer_width = "64"))]
49const MODULUS_LIMBS_32: [u32; 8] = [
50    0x0000_0001,
51    0xffff_ffff,
52    0xfffe_5bfe,
53    0x53bd_a402,
54    0x09a1_d805,
55    0x3339_d808,
56    0x299d_7d48,
57    0x73ed_a753,
58];
59
60// Little-endian non-Montgomery form not reduced mod p.
61const MODULUS_REPR: [u8; 32] = [
62    0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x5b, 0xfe, 0xff, 0x02, 0xa4, 0xbd, 0x53,
63    0x05, 0xd8, 0xa1, 0x09, 0x08, 0xd8, 0x39, 0x33, 0x48, 0x7d, 0x9d, 0x29, 0x53, 0xa7, 0xed, 0x73,
64];
65
66// `2^S` root of unity in little-endian Montgomery form.
67const ROOT_OF_UNITY: Scalar = Scalar(blst_fr {
68    l: [
69        0xb9b5_8d8c_5f0e_466a,
70        0x5b1b_4c80_1819_d7ec,
71        0x0af5_3ae3_52a3_1e64,
72        0x5bf3_adda_19e9_b27b,
73    ],
74});
75
76const ZERO: Scalar = Scalar(blst_fr { l: [0, 0, 0, 0] });
77
78/// `R = 2^256 mod q` in little-endian Montgomery form which is equivalent to 1 in little-endian
79/// non-Montgomery form.
80///
81/// sage> mod(2^256, 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001)
82/// sage> 0x1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffe
83const R: Scalar = Scalar(blst_fr {
84    l: [
85        0x0000_0001_ffff_fffe,
86        0x5884_b7fa_0003_4802,
87        0x998c_4fef_ecbc_4ff5,
88        0x1824_b159_acc5_056f,
89    ],
90});
91
92/// `R^2 = 2^512 mod q` in little-endian Montgomery form.
93///
94/// sage> mod(2^512, 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001)
95/// sage> 0x748d9d99f59ff1105d314967254398f2b6cedcb87925c23c999e990f3f29c6d
96#[allow(dead_code)]
97const R2: Scalar = Scalar(blst_fr {
98    l: [
99        0xc999_e990_f3f2_9c6d,
100        0x2b6c_edcb_8792_5c23,
101        0x05d3_1496_7254_398f,
102        0x0748_d9d9_9f59_ff11,
103    ],
104});
105
106pub const S: u32 = 32;
107
108impl fmt::Debug for Scalar {
109    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
110        let be_bytes = self.to_bytes_be();
111        write!(f, "Scalar(0x")?;
112        for &b in be_bytes.iter() {
113            write!(f, "{:02x}", b)?;
114        }
115        write!(f, ")")?;
116        Ok(())
117    }
118}
119
120impl fmt::Display for Scalar {
121    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
122        write!(f, "{:?}", self)
123    }
124}
125
126impl Ord for Scalar {
127    #[allow(clippy::comparison_chain)]
128    fn cmp(&self, other: &Scalar) -> cmp::Ordering {
129        for (a, b) in self.to_bytes_be().iter().zip(other.to_bytes_be().iter()) {
130            if a > b {
131                return cmp::Ordering::Greater;
132            } else if a < b {
133                return cmp::Ordering::Less;
134            }
135        }
136        cmp::Ordering::Equal
137    }
138}
139
140impl PartialOrd for Scalar {
141    #[inline(always)]
142    fn partial_cmp(&self, other: &Scalar) -> Option<cmp::Ordering> {
143        Some(self.cmp(other))
144    }
145}
146
147impl PartialEq for Scalar {
148    #[inline]
149    fn eq(&self, other: &Self) -> bool {
150        self.0.l == other.0.l
151    }
152}
153
154impl Eq for Scalar {}
155
156impl ConstantTimeEq for Scalar {
157    fn ct_eq(&self, other: &Self) -> Choice {
158        self.0.l[0].ct_eq(&other.0.l[0])
159            & self.0.l[1].ct_eq(&other.0.l[1])
160            & self.0.l[2].ct_eq(&other.0.l[2])
161            & self.0.l[3].ct_eq(&other.0.l[3])
162    }
163}
164
165impl ConditionallySelectable for Scalar {
166    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
167        Scalar(blst_fr {
168            l: [
169                u64::conditional_select(&a.0.l[0], &b.0.l[0], choice),
170                u64::conditional_select(&a.0.l[1], &b.0.l[1], choice),
171                u64::conditional_select(&a.0.l[2], &b.0.l[2], choice),
172                u64::conditional_select(&a.0.l[3], &b.0.l[3], choice),
173            ],
174        })
175    }
176}
177
178impl From<Scalar> for blst_fr {
179    fn from(val: Scalar) -> blst_fr {
180        val.0
181    }
182}
183
184impl From<blst_fr> for Scalar {
185    fn from(val: blst_fr) -> Scalar {
186        Scalar(val)
187    }
188}
189
190impl From<u64> for Scalar {
191    fn from(val: u64) -> Scalar {
192        let mut repr = [0u8; 32];
193        repr[..8].copy_from_slice(&val.to_le_bytes());
194        Scalar::from_bytes_le(&repr).unwrap()
195    }
196}
197
198#[allow(clippy::from_over_into)]
199impl Into<blst_scalar> for Scalar {
200    fn into(self) -> blst_scalar {
201        let mut out = blst_scalar::default();
202        unsafe {
203            blst_scalar_from_fr(&mut out, &self.0);
204        }
205
206        out
207    }
208}
209
210#[derive(Debug, Clone)]
211pub struct NotInFieldError;
212
213impl fmt::Display for NotInFieldError {
214    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
215        write!(f, "Not in field")
216    }
217}
218
219impl std::error::Error for NotInFieldError {}
220
221impl TryInto<Scalar> for blst_scalar {
222    type Error = NotInFieldError;
223
224    fn try_into(self) -> Result<Scalar, Self::Error> {
225        if !unsafe { blst_scalar_fr_check(&self) } {
226            return Err(NotInFieldError);
227        }
228
229        let mut out = blst_fr::default();
230
231        unsafe { blst_fr_from_scalar(&mut out, &self) };
232
233        Ok(Scalar(out))
234    }
235}
236
237impl Neg for &Scalar {
238    type Output = Scalar;
239
240    #[inline]
241    fn neg(self) -> Scalar {
242        let mut neg = *self;
243        unsafe { blst_fr_cneg(&mut neg.0, &self.0, true) };
244        neg
245    }
246}
247
248impl Neg for Scalar {
249    type Output = Scalar;
250
251    #[inline]
252    fn neg(self) -> Scalar {
253        -&self
254    }
255}
256
257impl Add<&Scalar> for &Scalar {
258    type Output = Scalar;
259
260    #[inline]
261    fn add(self, rhs: &Scalar) -> Scalar {
262        let mut out = *self;
263        out += rhs;
264        out
265    }
266}
267
268impl Sub<&Scalar> for &Scalar {
269    type Output = Scalar;
270
271    #[inline]
272    fn sub(self, rhs: &Scalar) -> Scalar {
273        let mut out = *self;
274        out -= rhs;
275        out
276    }
277}
278
279impl Mul<&Scalar> for &Scalar {
280    type Output = Scalar;
281
282    #[inline]
283    fn mul(self, rhs: &Scalar) -> Scalar {
284        let mut out = *self;
285        out *= rhs;
286        out
287    }
288}
289
290impl AddAssign<&Scalar> for Scalar {
291    #[inline]
292    fn add_assign(&mut self, rhs: &Scalar) {
293        unsafe { blst_fr_add(&mut self.0, &self.0, &rhs.0) };
294    }
295}
296
297impl SubAssign<&Scalar> for Scalar {
298    #[inline]
299    fn sub_assign(&mut self, rhs: &Scalar) {
300        unsafe { blst_fr_sub(&mut self.0, &self.0, &rhs.0) };
301    }
302}
303
304impl MulAssign<&Scalar> for Scalar {
305    #[inline]
306    fn mul_assign(&mut self, rhs: &Scalar) {
307        unsafe { blst_fr_mul(&mut self.0, &self.0, &rhs.0) };
308    }
309}
310
311impl<T> Sum<T> for Scalar
312where
313    T: Borrow<Scalar>,
314{
315    fn sum<I>(iter: I) -> Self
316    where
317        I: Iterator<Item = T>,
318    {
319        iter.fold(Scalar::ZERO, |sum, x| sum + x.borrow())
320    }
321}
322
323impl<T> Product<T> for Scalar
324where
325    T: Borrow<Scalar>,
326{
327    fn product<I>(iter: I) -> Self
328    where
329        I: Iterator<Item = T>,
330    {
331        iter.fold(Scalar::ONE, |product, x| product * x.borrow())
332    }
333}
334
335impl_add_sub!(Scalar);
336impl_add_sub_assign!(Scalar);
337impl_mul!(Scalar);
338impl_mul_assign!(Scalar);
339
340/// The number of bits we should "shave" from a randomly sampled reputation.
341const REPR_SHAVE_BITS: usize = 256 - Scalar::NUM_BITS as usize;
342
343impl Field for Scalar {
344    fn random(mut rng: impl RngCore) -> Self {
345        loop {
346            let mut raw = [0u64; 4];
347            for int in raw.iter_mut() {
348                *int = rng.next_u64();
349            }
350
351            // Mask away the unused most-significant bits.
352            raw[3] &= 0xffffffffffffffff >> REPR_SHAVE_BITS;
353
354            if let Some(scalar) = Scalar::from_u64s_le(&raw).into() {
355                return scalar;
356            }
357        }
358    }
359
360    const ZERO: Self = ZERO;
361
362    const ONE: Self = R;
363
364    fn is_zero(&self) -> Choice {
365        self.ct_eq(&ZERO)
366    }
367
368    fn square(&self) -> Self {
369        let mut out = *self;
370        out.square_assign();
371        out
372    }
373
374    fn double(&self) -> Self {
375        let mut out = *self;
376        out += self;
377        out
378    }
379
380    fn invert(&self) -> CtOption<Self> {
381        let mut inv = blst_fr::default();
382        unsafe { blst_fr_eucl_inverse(&mut inv, &self.0) };
383        let is_invertible = !self.ct_eq(&Scalar::ZERO);
384        CtOption::new(Scalar(inv), is_invertible)
385    }
386
387    fn sqrt(&self) -> CtOption<Self> {
388        // (t - 1) // 2 = 6104339283789297388802252303364915521546564123189034618274734669823
389        ff::helpers::sqrt_tonelli_shanks(
390            self,
391            [
392                0x7fff_2dff_7fff_ffff,
393                0x04d0_ec02_a9de_d201,
394                0x94ce_bea4_199c_ec04,
395                0x0000_0000_39f6_d3a9,
396            ],
397        )
398    }
399
400    fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self) {
401        ff::helpers::sqrt_ratio_generic(num, div)
402    }
403}
404
405/// Checks if the passed in bytes are less than the MODULUS. (both in non-Montgomery form and little endian).
406/// Assumes that `a` is exactly 4 elements long.
407#[allow(clippy::comparison_chain)]
408fn is_valid(a: &[u64]) -> bool {
409    debug_assert_eq!(a.len(), 4);
410    for (a, b) in a.iter().zip(MODULUS.iter()).rev() {
411        if a > b {
412            return false;
413        } else if a < b {
414            return true;
415        }
416    }
417
418    false
419}
420
421#[inline]
422fn u64s_from_bytes(bytes: &[u8; 32]) -> [u64; 4] {
423    [
424        u64::from_le_bytes(bytes[0..8].try_into().unwrap()),
425        u64::from_le_bytes(bytes[8..16].try_into().unwrap()),
426        u64::from_le_bytes(bytes[16..24].try_into().unwrap()),
427        u64::from_le_bytes(bytes[24..32].try_into().unwrap()),
428    ]
429}
430
431impl PrimeField for Scalar {
432    // Little-endian non-Montgomery form bigint mod p.
433    type Repr = [u8; 32];
434
435    const NUM_BITS: u32 = 255;
436    const CAPACITY: u32 = Self::NUM_BITS - 1;
437    const S: u32 = S;
438
439    /// 2^-1
440    const TWO_INV: Scalar = Scalar(blst_fr {
441        l: [
442            0x0000_0000_ffff_ffff,
443            0xac42_5bfd_0001_a401,
444            0xccc6_27f7_f65e_27fa,
445            0x0c12_58ac_d662_82b7,
446        ],
447    });
448
449    /// ROOT_OF_UNITY^-1
450    const ROOT_OF_UNITY_INV: Scalar = Scalar(blst_fr {
451        l: [
452            0x4256_481a_dcf3_219a,
453            0x45f3_7b7f_96b6_cad3,
454            0xf9c3_f1d7_5f7a_3b27,
455            0x2d2f_c049_658a_fd43,
456        ],
457    });
458
459    // GENERATOR^{2^s} where t * 2^s + 1 = q with t odd.
460    /// In other words, this is a t root of unity.
461    const DELTA: Scalar = Scalar(blst_fr {
462        l: [
463            0x70e3_10d3_d146_f96a,
464            0x4b64_c089_19e2_99e6,
465            0x51e1_1418_6a8b_970d,
466            0x6185_d066_27c0_67cb,
467        ],
468    });
469
470    /// Constant representing the modulus
471    const MODULUS: &'static str =
472        "0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001";
473
474    /// Converts a little-endian non-Montgomery form `repr` into a Montgomery form `Scalar`.
475    fn from_repr(repr: Self::Repr) -> CtOption<Self> {
476        Self::from_bytes_le(&repr)
477    }
478
479    fn from_repr_vartime(repr: Self::Repr) -> Option<Self> {
480        let bytes_u64 = u64s_from_bytes(&repr);
481
482        if !is_valid(&bytes_u64) {
483            return None;
484        }
485        let mut out = blst_fr::default();
486        unsafe { blst_fr_from_uint64(&mut out, bytes_u64.as_ptr()) };
487        Some(Scalar(out))
488    }
489
490    /// Converts a Montgomery form `Scalar` into little-endian non-Montgomery from.
491    fn to_repr(&self) -> Self::Repr {
492        self.to_bytes_le()
493    }
494
495    fn is_odd(&self) -> Choice {
496        Choice::from(self.to_repr()[0] & 1)
497    }
498
499    const MULTIPLICATIVE_GENERATOR: Self = GENERATOR;
500
501    const ROOT_OF_UNITY: Self = ROOT_OF_UNITY;
502}
503
504#[cfg(not(target_pointer_width = "64"))]
505type ReprBits = [u32; 8];
506
507#[cfg(target_pointer_width = "64")]
508type ReprBits = [u64; 4];
509
510impl PrimeFieldBits for Scalar {
511    // Representation in non-Montgomery form.
512    type ReprBits = ReprBits;
513
514    #[cfg(target_pointer_width = "64")]
515    fn to_le_bits(&self) -> FieldBits<Self::ReprBits> {
516        let mut limbs = [0u64; 4];
517        unsafe { blst_uint64_from_fr(limbs.as_mut_ptr(), &self.0) };
518
519        FieldBits::new(limbs)
520    }
521
522    #[cfg(not(target_pointer_width = "64"))]
523    fn to_le_bits(&self) -> FieldBits<Self::ReprBits> {
524        let bytes = self.to_bytes_le();
525        let limbs = [
526            u32::from_le_bytes(bytes[0..4].try_into().unwrap()),
527            u32::from_le_bytes(bytes[4..8].try_into().unwrap()),
528            u32::from_le_bytes(bytes[8..12].try_into().unwrap()),
529            u32::from_le_bytes(bytes[12..16].try_into().unwrap()),
530            u32::from_le_bytes(bytes[16..20].try_into().unwrap()),
531            u32::from_le_bytes(bytes[20..24].try_into().unwrap()),
532            u32::from_le_bytes(bytes[24..28].try_into().unwrap()),
533            u32::from_le_bytes(bytes[28..32].try_into().unwrap()),
534        ];
535        FieldBits::new(limbs)
536    }
537
538    fn char_le_bits() -> FieldBits<Self::ReprBits> {
539        #[cfg(not(target_pointer_width = "64"))]
540        {
541            FieldBits::new(MODULUS_LIMBS_32)
542        }
543
544        #[cfg(target_pointer_width = "64")]
545        FieldBits::new(MODULUS)
546    }
547}
548
549impl Scalar {
550    /// Attempts to convert a little-endian byte representation of
551    /// a scalar into a `Scalar`, failing if the input is not canonical.
552    pub fn from_bytes_le(bytes: &[u8; 32]) -> CtOption<Scalar> {
553        let is_some =
554            Choice::from(unsafe { blst_scalar_fr_check(&blst_scalar { b: *bytes }) as u8 });
555
556        let mut out = blst_fr::default();
557        let bytes_u64 = u64s_from_bytes(bytes);
558
559        unsafe { blst_fr_from_uint64(&mut out, bytes_u64.as_ptr()) };
560
561        CtOption::new(Scalar(out), is_some)
562    }
563
564    /// Attempts to convert a big-endian byte representation of
565    /// a scalar into a `Scalar`, failing if the input is not canonical.
566    pub fn from_bytes_be(be_bytes: &[u8; 32]) -> CtOption<Scalar> {
567        let mut le_bytes = *be_bytes;
568        le_bytes.reverse();
569        Self::from_bytes_le(&le_bytes)
570    }
571
572    /// Converts an element of `Scalar` into a byte representation in
573    /// little-endian byte order.
574    #[inline]
575    pub fn to_bytes_le(&self) -> [u8; 32] {
576        let mut out = [0u64; 4];
577        unsafe { blst_uint64_from_fr(out.as_mut_ptr(), &self.0) };
578        out.as_byte_slice().try_into().unwrap()
579    }
580
581    /// Converts an element of `Scalar` into a byte representation in
582    /// big-endian byte order.
583    pub fn to_bytes_be(&self) -> [u8; 32] {
584        let mut bytes = self.to_bytes_le();
585        bytes.reverse();
586        bytes
587    }
588
589    // `u64s` represent a little-endian non-Montgomery form integer mod p.
590    pub fn from_u64s_le(bytes: &[u64; 4]) -> CtOption<Self> {
591        let mut raw = blst_scalar::default();
592        let mut out = blst_fr::default();
593
594        unsafe { blst_scalar_from_uint64(&mut raw, bytes.as_ptr()) };
595        let is_some = Choice::from(unsafe { blst_scalar_fr_check(&raw) as u8 });
596        unsafe { blst_fr_from_scalar(&mut out, &raw) };
597
598        CtOption::new(Scalar(out), is_some)
599    }
600
601    #[allow(clippy::match_like_matches_macro)]
602    pub fn is_quad_res(&self) -> Choice {
603        match self.legendre() {
604            0 | 1 => Choice::from(1u8),
605            _ => Choice::from(0u8),
606        }
607    }
608
609    pub fn legendre(&self) -> i8 {
610        const MOD_MINUS_1_OVER_2: [u64; 4] = [
611            0x7fffffff80000000,
612            0xa9ded2017fff2dff,
613            0x199cec0404d0ec02,
614            0x39f6d3a994cebea4,
615        ];
616        // s = self^((modulus - 1) // 2)
617        let s = self.pow_vartime(MOD_MINUS_1_OVER_2);
618        if s == Self::ZERO {
619            0
620        } else if s == Self::ONE {
621            1
622        } else {
623            -1
624        }
625    }
626
627    pub fn char() -> <Self as PrimeField>::Repr {
628        MODULUS_REPR
629    }
630
631    pub fn num_bits(&self) -> u32 {
632        let mut ret = 256;
633        for i in self.to_bytes_be().iter() {
634            let leading = i.leading_zeros();
635            ret -= leading;
636            if leading != 8 {
637                break;
638            }
639        }
640
641        ret
642    }
643
644    /// Multiplies `self` with `3`, returning the result.
645    pub fn mul3(&self) -> Self {
646        let mut out = blst_fr::default();
647
648        unsafe { blst_fr_mul_by_3(&mut out, &self.0) };
649
650        Scalar(out)
651    }
652
653    /// Left shift `self` by `count`, returning the result.
654    pub fn shl(&self, count: usize) -> Self {
655        let mut out = blst_fr::default();
656
657        unsafe { blst_fr_lshift(&mut out, &self.0, count) };
658
659        Scalar(out)
660    }
661
662    /// Right shift `self` by `count`, returning the result.
663    pub fn shr(&self, count: usize) -> Self {
664        let mut out = blst_fr::default();
665
666        unsafe { blst_fr_rshift(&mut out, &self.0, count) };
667
668        Scalar(out)
669    }
670
671    /// Calculates the `square` of this element.
672    #[inline]
673    pub fn square_assign(&mut self) {
674        unsafe { blst_fr_sqr(&mut self.0, &self.0) };
675    }
676}
677
678#[cfg(feature = "gpu")]
679impl ec_gpu::GpuName for Scalar {
680    fn name() -> String {
681        ec_gpu::name!()
682    }
683}
684
685#[cfg(feature = "gpu")]
686impl ec_gpu::GpuField for Scalar {
687    fn one() -> Vec<u32> {
688        crate::u64_to_u32(&R.0.l[..])
689    }
690
691    fn r2() -> Vec<u32> {
692        crate::u64_to_u32(&R2.0.l[..])
693    }
694
695    fn modulus() -> Vec<u32> {
696        crate::u64_to_u32(&MODULUS[..])
697    }
698}
699
700#[cfg(test)]
701mod tests {
702    use super::*;
703
704    use rand_core::SeedableRng;
705    use rand_xorshift::XorShiftRng;
706
707    /// INV = -(q^{-1} mod 2^64) mod 2^64
708    const INV: u64 = 0xfffffffeffffffff;
709
710    const LARGEST: Scalar = Scalar(blst::blst_fr {
711        l: [
712            0xffffffff00000000,
713            0x53bda402fffe5bfe,
714            0x3339d80809a1d805,
715            0x73eda753299d7d48,
716        ],
717    });
718
719    #[test]
720    fn test_inv() {
721        // Compute -(q^{-1} mod 2^64) mod 2^64 by exponentiating
722        // by totient(2**64) - 1
723
724        let mut inv = 1u64;
725        for _ in 0..63 {
726            inv = inv.wrapping_mul(inv);
727            inv = inv.wrapping_mul(MODULUS[0]);
728        }
729        inv = inv.wrapping_neg();
730
731        assert_eq!(inv, INV);
732    }
733
734    #[test]
735    fn test_debug() {
736        assert_eq!(
737            format!("{:?}", Scalar::ZERO),
738            "Scalar(0x0000000000000000000000000000000000000000000000000000000000000000)"
739        );
740        assert_eq!(
741            format!("{:?}", Scalar::ONE),
742            "Scalar(0x0000000000000000000000000000000000000000000000000000000000000001)"
743        );
744        assert_eq!(
745            format!("{:?}", R2),
746            "Scalar(0x1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffe)"
747        );
748    }
749
750    #[test]
751    fn test_equality() {
752        assert_eq!(Scalar::ZERO, Scalar::ZERO);
753        assert_eq!(Scalar::ONE, Scalar::ONE);
754
755        assert_ne!(Scalar::ZERO, Scalar::ONE);
756        assert_ne!(Scalar::ONE, R2);
757    }
758
759    #[test]
760    fn test_to_bytes() {
761        assert_eq!(
762            Scalar::ZERO.to_bytes_le(),
763            [
764                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
765                0, 0, 0, 0
766            ]
767        );
768
769        assert_eq!(
770            Scalar::ONE.to_bytes_le(),
771            [
772                1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
773                0, 0, 0, 0
774            ]
775        );
776
777        assert_eq!(
778            R2.to_bytes_le(),
779            [
780                254, 255, 255, 255, 1, 0, 0, 0, 2, 72, 3, 0, 250, 183, 132, 88, 245, 79, 188, 236,
781                239, 79, 140, 153, 111, 5, 197, 172, 89, 177, 36, 24
782            ]
783        );
784
785        assert_eq!(
786            (-&Scalar::ONE).to_bytes_le(),
787            [
788                0, 0, 0, 0, 255, 255, 255, 255, 254, 91, 254, 255, 2, 164, 189, 83, 5, 216, 161, 9,
789                8, 216, 57, 51, 72, 125, 157, 41, 83, 167, 237, 115
790            ]
791        );
792    }
793
794    #[test]
795    fn test_from_bytes() {
796        assert_eq!(
797            Scalar::from_bytes_le(&[
798                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
799                0, 0, 0, 0
800            ])
801            .unwrap(),
802            Scalar::ZERO
803        );
804
805        assert_eq!(
806            Scalar::from_bytes_le(&[
807                1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
808                0, 0, 0, 0
809            ])
810            .unwrap(),
811            Scalar::ONE
812        );
813
814        assert_eq!(
815            Scalar::from_bytes_le(&[
816                254, 255, 255, 255, 1, 0, 0, 0, 2, 72, 3, 0, 250, 183, 132, 88, 245, 79, 188, 236,
817                239, 79, 140, 153, 111, 5, 197, 172, 89, 177, 36, 24
818            ])
819            .unwrap(),
820            R2,
821        );
822
823        // -1 should work
824        assert!(bool::from(
825            Scalar::from_bytes_le(&[
826                0, 0, 0, 0, 255, 255, 255, 255, 254, 91, 254, 255, 2, 164, 189, 83, 5, 216, 161, 9,
827                8, 216, 57, 51, 72, 125, 157, 41, 83, 167, 237, 115
828            ])
829            .is_some()
830        ));
831
832        // modulus is invalid
833        assert!(bool::from(Scalar::from_bytes_le(&MODULUS_REPR).is_none()));
834
835        // Anything larger than the modulus is invalid
836        assert!(bool::from(
837            Scalar::from_bytes_le(&[
838                2, 0, 0, 0, 255, 255, 255, 255, 254, 91, 254, 255, 2, 164, 189, 83, 5, 216, 161, 9,
839                8, 216, 57, 51, 72, 125, 157, 41, 83, 167, 237, 115
840            ])
841            .is_none()
842        ));
843        assert!(bool::from(
844            Scalar::from_bytes_le(&[
845                1, 0, 0, 0, 255, 255, 255, 255, 254, 91, 254, 255, 2, 164, 189, 83, 5, 216, 161, 9,
846                8, 216, 58, 51, 72, 125, 157, 41, 83, 167, 237, 115
847            ])
848            .is_none()
849        ));
850        assert!(bool::from(
851            Scalar::from_bytes_le(&[
852                1, 0, 0, 0, 255, 255, 255, 255, 254, 91, 254, 255, 2, 164, 189, 83, 5, 216, 161, 9,
853                8, 216, 57, 51, 72, 125, 157, 41, 83, 167, 237, 116
854            ])
855            .is_none()
856        ));
857    }
858
859    #[test]
860    fn test_zero() {
861        assert_eq!(Scalar::ZERO, -&Scalar::ZERO);
862        assert_eq!(Scalar::ZERO, Scalar::ZERO + Scalar::ZERO);
863        assert_eq!(Scalar::ZERO, Scalar::ZERO - Scalar::ZERO);
864        assert_eq!(Scalar::ZERO, Scalar::ZERO * Scalar::ZERO);
865    }
866
867    #[test]
868    fn test_addition() {
869        let mut tmp = LARGEST;
870        tmp += &LARGEST;
871
872        assert_eq!(
873            tmp,
874            Scalar(blst::blst_fr {
875                l: [
876                    0xfffffffeffffffff,
877                    0x53bda402fffe5bfe,
878                    0x3339d80809a1d805,
879                    0x73eda753299d7d48
880                ]
881            })
882        );
883
884        let mut tmp = LARGEST;
885        tmp += &Scalar(blst::blst_fr { l: [1, 0, 0, 0] });
886
887        assert_eq!(tmp, Scalar::ZERO);
888    }
889
890    #[test]
891    fn test_negation() {
892        let tmp = -&LARGEST;
893
894        assert_eq!(tmp, Scalar(blst::blst_fr { l: [1, 0, 0, 0] }));
895
896        let tmp = -&Scalar::ZERO;
897        assert_eq!(tmp, Scalar::ZERO);
898        let tmp = -&Scalar(blst::blst_fr { l: [1, 0, 0, 0] });
899        assert_eq!(tmp, LARGEST);
900
901        {
902            let mut a = Scalar::ZERO;
903            a = -a;
904
905            assert!(bool::from(a.is_zero()));
906        }
907
908        let mut rng = XorShiftRng::from_seed([
909            0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
910            0xbc, 0xe5,
911        ]);
912
913        for _ in 0..1000 {
914            // Ensure (a - (-a)) = 0.
915            let mut a = Scalar::random(&mut rng);
916            let mut b = a;
917            b = -b;
918            a += &b;
919
920            assert!(bool::from(a.is_zero()));
921        }
922    }
923
924    #[test]
925    fn test_subtraction() {
926        let mut tmp = LARGEST;
927        tmp -= &LARGEST;
928
929        assert_eq!(tmp, Scalar::ZERO);
930
931        let mut tmp = Scalar::ZERO;
932        tmp -= &LARGEST;
933
934        let mut tmp2 = Scalar(blst::blst_fr { l: MODULUS });
935        tmp2 -= &LARGEST;
936
937        assert_eq!(tmp, tmp2);
938    }
939
940    #[test]
941    fn test_multiplication() {
942        let mut tmp = Scalar(blst::blst_fr {
943            l: [
944                0x6b7e9b8faeefc81a,
945                0xe30a8463f348ba42,
946                0xeff3cb67a8279c9c,
947                0x3d303651bd7c774d,
948            ],
949        });
950        tmp *= &Scalar(blst::blst_fr {
951            l: [
952                0x13ae28e3bc35ebeb,
953                0xa10f4488075cae2c,
954                0x8160e95a853c3b5d,
955                0x5ae3f03b561a841d,
956            ],
957        });
958        assert!(
959            tmp == Scalar(blst::blst_fr {
960                l: [
961                    0x23717213ce710f71,
962                    0xdbee1fe53a16e1af,
963                    0xf565d3e1c2a48000,
964                    0x4426507ee75df9d7
965                ]
966            })
967        );
968
969        let mut rng = XorShiftRng::from_seed([
970            0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
971            0xbc, 0xe5,
972        ]);
973
974        for _ in 0..1000000 {
975            // Ensure that (a * b) * c = a * (b * c)
976            let a = Scalar::random(&mut rng);
977            let b = Scalar::random(&mut rng);
978            let c = Scalar::random(&mut rng);
979
980            let mut tmp1 = a;
981            tmp1 *= &b;
982            tmp1 *= &c;
983
984            let mut tmp2 = b;
985            tmp2 *= &c;
986            tmp2 *= &a;
987
988            assert_eq!(tmp1, tmp2);
989        }
990
991        for _ in 0..1000000 {
992            // Ensure that r * (a + b + c) = r*a + r*b + r*c
993
994            let r = Scalar::random(&mut rng);
995            let mut a = Scalar::random(&mut rng);
996            let mut b = Scalar::random(&mut rng);
997            let mut c = Scalar::random(&mut rng);
998
999            let mut tmp1 = a;
1000            tmp1 += &b;
1001            tmp1 += &c;
1002            tmp1 *= &r;
1003
1004            a *= &r;
1005            b *= &r;
1006            c *= &r;
1007
1008            a += &b;
1009            a += &c;
1010
1011            assert_eq!(tmp1, a);
1012        }
1013    }
1014
1015    #[test]
1016    fn test_inverse_is_pow() {
1017        let q_minus_2 = [
1018            0xfffffffeffffffff,
1019            0x53bda402fffe5bfe,
1020            0x3339d80809a1d805,
1021            0x73eda753299d7d48,
1022        ];
1023
1024        let mut r1 = R;
1025        let mut r2 = r1;
1026
1027        for _ in 0..100 {
1028            r1 = r1.invert().unwrap();
1029            r2 = r2.pow_vartime(q_minus_2);
1030
1031            assert_eq!(r1, r2);
1032            // Add R so we check something different next time around
1033            r1 += R;
1034            r2 = r1;
1035        }
1036    }
1037
1038    #[test]
1039    fn test_sqrt() {
1040        {
1041            assert_eq!(Scalar::ZERO.sqrt().unwrap(), Scalar::ZERO);
1042        }
1043
1044        let mut square = Scalar(blst::blst_fr {
1045            l: [
1046                0x46cd85a5f273077e,
1047                0x1d30c47dd68fc735,
1048                0x77f656f60beca0eb,
1049                0x494aa01bdf32468d,
1050            ],
1051        });
1052
1053        let mut none_count = 0;
1054
1055        for _ in 0..100 {
1056            let square_root = square.sqrt();
1057            if square_root.is_none().into() {
1058                none_count += 1;
1059            } else {
1060                assert_eq!(square_root.unwrap() * square_root.unwrap(), square);
1061            }
1062            square -= Scalar::ONE;
1063        }
1064
1065        assert_eq!(49, none_count);
1066    }
1067
1068    #[test]
1069    fn test_double() {
1070        let a = Scalar::from_u64s_le(&[
1071            0x1fff3231233ffffd,
1072            0x4884b7fa00034802,
1073            0x998c4fefecbc4ff3,
1074            0x1824b159acc50562,
1075        ])
1076        .unwrap();
1077
1078        assert_eq!(a.double(), a + a);
1079    }
1080
1081    #[test]
1082    fn test_scalar_ordering() {
1083        fn assert_equality(a: Scalar, b: Scalar) {
1084            assert_eq!(a, b);
1085            assert!(a.cmp(&b) == core::cmp::Ordering::Equal);
1086        }
1087
1088        fn assert_lt(a: Scalar, b: Scalar) {
1089            assert!(a < b);
1090            assert!(b > a);
1091        }
1092
1093        assert_equality(
1094            Scalar::from_u64s_le(&[9999, 9999, 9999, 9999]).unwrap(),
1095            Scalar::from_u64s_le(&[9999, 9999, 9999, 9999]).unwrap(),
1096        );
1097        assert_equality(
1098            Scalar::from_u64s_le(&[9999, 9998, 9999, 9999]).unwrap(),
1099            Scalar::from_u64s_le(&[9999, 9998, 9999, 9999]).unwrap(),
1100        );
1101        assert_equality(
1102            Scalar::from_u64s_le(&[9999, 9999, 9999, 9997]).unwrap(),
1103            Scalar::from_u64s_le(&[9999, 9999, 9999, 9997]).unwrap(),
1104        );
1105        assert_lt(
1106            Scalar::from_u64s_le(&[9999, 9997, 9999, 9998]).unwrap(),
1107            Scalar::from_u64s_le(&[9999, 9997, 9999, 9999]).unwrap(),
1108        );
1109        assert_lt(
1110            Scalar::from_u64s_le(&[9999, 9997, 9998, 9999]).unwrap(),
1111            Scalar::from_u64s_le(&[9999, 9997, 9999, 9999]).unwrap(),
1112        );
1113        assert_lt(
1114            Scalar::from_u64s_le(&[9, 9999, 9999, 9997]).unwrap(),
1115            Scalar::from_u64s_le(&[9999, 9999, 9999, 9997]).unwrap(),
1116        );
1117    }
1118
1119    #[test]
1120    fn test_scalar_from_u64() {
1121        let a = Scalar::from(100);
1122        let mut expected_bytes = [0u8; 32];
1123        expected_bytes[0] = 100;
1124        assert_eq!(a.to_bytes_le(), expected_bytes);
1125    }
1126
1127    #[test]
1128    fn test_scalar_is_odd() {
1129        assert!(bool::from(Scalar::from(0).is_even()));
1130        assert!(bool::from(Scalar::from(1).is_odd()));
1131        assert!(bool::from(Scalar::from(324834872).is_even()));
1132        assert!(bool::from(Scalar::from(324834873).is_odd()));
1133    }
1134
1135    #[test]
1136    fn test_scalar_is_zero() {
1137        assert!(bool::from(Scalar::from(0).is_zero()));
1138        assert!(!bool::from(Scalar::from(1).is_zero()));
1139        assert!(!bool::from(
1140            Scalar::from_u64s_le(&[0, 0, 1, 0]).unwrap().is_zero()
1141        ));
1142    }
1143
1144    #[test]
1145    fn test_scalar_num_bits() {
1146        assert_eq!(Scalar::NUM_BITS, 255);
1147        assert_eq!(Scalar::CAPACITY, 254);
1148
1149        let mut a = Scalar::from(0);
1150        assert_eq!(0, a.num_bits());
1151        a = Scalar::from(1);
1152        assert_eq!(1, a.num_bits());
1153        for i in 2..Scalar::NUM_BITS {
1154            a = a.shl(1);
1155            assert_eq!(i, a.num_bits());
1156        }
1157    }
1158
1159    #[test]
1160    fn test_scalar_legendre() {
1161        assert_eq!(Scalar::ZERO.sqrt().unwrap(), Scalar::ZERO);
1162        assert_eq!(Scalar::ONE.sqrt().unwrap(), Scalar::ONE);
1163
1164        let e = Scalar::from_u64s_le(&[
1165            0x0dbc5349cd5664da,
1166            0x8ac5b6296e3ae29d,
1167            0x127cb819feceaa3b,
1168            0x3a6b21fb03867191,
1169        ])
1170        .unwrap();
1171        assert!(bool::from(e.is_quad_res()));
1172
1173        let e = Scalar::from_u64s_le(&[
1174            0x96341aefd047c045,
1175            0x9b5f4254500a4d65,
1176            0x1ee08223b68ac240,
1177            0x31d9cd545c0ec7c6,
1178        ])
1179        .unwrap();
1180        assert!(!bool::from(e.is_quad_res()));
1181    }
1182
1183    #[test]
1184    fn test_scalar_add_assign() {
1185        {
1186            // Random number
1187            let mut tmp = Scalar(blst::blst_fr {
1188                l: [
1189                    0x437ce7616d580765,
1190                    0xd42d1ccb29d1235b,
1191                    0xed8f753821bd1423,
1192                    0x4eede1c9c89528ca,
1193                ],
1194            });
1195            // assert!(tmp.is_valid());
1196            // Test that adding zero has no effect.
1197            tmp.add_assign(&Scalar(blst::blst_fr { l: [0, 0, 0, 0] }));
1198            assert_eq!(
1199                tmp,
1200                Scalar(blst::blst_fr {
1201                    l: [
1202                        0x437ce7616d580765,
1203                        0xd42d1ccb29d1235b,
1204                        0xed8f753821bd1423,
1205                        0x4eede1c9c89528ca
1206                    ]
1207                })
1208            );
1209            // Add one and test for the result.
1210            tmp.add_assign(&Scalar(blst::blst_fr { l: [1, 0, 0, 0] }));
1211            assert_eq!(
1212                tmp,
1213                Scalar(blst::blst_fr {
1214                    l: [
1215                        0x437ce7616d580766,
1216                        0xd42d1ccb29d1235b,
1217                        0xed8f753821bd1423,
1218                        0x4eede1c9c89528ca
1219                    ]
1220                })
1221            );
1222            // Add another random number that exercises the reduction.
1223            tmp.add_assign(&Scalar(blst::blst_fr {
1224                l: [
1225                    0x946f435944f7dc79,
1226                    0xb55e7ee6533a9b9b,
1227                    0x1e43b84c2f6194ca,
1228                    0x58717ab525463496,
1229                ],
1230            }));
1231            assert_eq!(
1232                tmp,
1233                Scalar(blst::blst_fr {
1234                    l: [
1235                        0xd7ec2abbb24fe3de,
1236                        0x35cdf7ae7d0d62f7,
1237                        0xd899557c477cd0e9,
1238                        0x3371b52bc43de018
1239                    ]
1240                })
1241            );
1242            // Add one to (r - 1) and test for the result.
1243            tmp = Scalar(blst::blst_fr {
1244                l: [
1245                    0xffffffff00000000,
1246                    0x53bda402fffe5bfe,
1247                    0x3339d80809a1d805,
1248                    0x73eda753299d7d48,
1249                ],
1250            });
1251            tmp.add_assign(&Scalar(blst::blst_fr { l: [1, 0, 0, 0] }));
1252            assert!(bool::from(tmp.is_zero()));
1253            // Add a random number to another one such that the result is r - 1
1254            tmp = Scalar(blst::blst_fr {
1255                l: [
1256                    0xade5adacdccb6190,
1257                    0xaa21ee0f27db3ccd,
1258                    0x2550f4704ae39086,
1259                    0x591d1902e7c5ba27,
1260                ],
1261            });
1262            tmp.add_assign(&Scalar(blst::blst_fr {
1263                l: [
1264                    0x521a525223349e70,
1265                    0xa99bb5f3d8231f31,
1266                    0xde8e397bebe477e,
1267                    0x1ad08e5041d7c321,
1268                ],
1269            }));
1270            assert_eq!(
1271                tmp,
1272                Scalar(blst::blst_fr {
1273                    l: [
1274                        0xffffffff00000000,
1275                        0x53bda402fffe5bfe,
1276                        0x3339d80809a1d805,
1277                        0x73eda753299d7d48
1278                    ]
1279                })
1280            );
1281            // Add one to the result and test for it.
1282            tmp.add_assign(&Scalar(blst::blst_fr { l: [1, 0, 0, 0] }));
1283            assert!(bool::from(tmp.is_zero()));
1284        }
1285
1286        // Test associativity
1287
1288        let mut rng = XorShiftRng::from_seed([
1289            0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
1290            0xbc, 0xe5,
1291        ]);
1292
1293        for i in 0..1000 {
1294            // Generate a, b, c and ensure (a + b) + c == a + (b + c).
1295            let a = Scalar::random(&mut rng);
1296            let b = Scalar::random(&mut rng);
1297            let c = Scalar::random(&mut rng);
1298
1299            let mut tmp1 = a;
1300            tmp1.add_assign(&b);
1301            tmp1.add_assign(&c);
1302
1303            let mut tmp2 = b;
1304            tmp2.add_assign(&c);
1305            tmp2.add_assign(&a);
1306
1307            // assert!(tmp1.is_valid());
1308            // assert!(tmp2.is_valid());
1309            assert_eq!(tmp1, tmp2, "round {}", i);
1310        }
1311    }
1312
1313    #[test]
1314    fn test_scalar_sub_assign() {
1315        {
1316            // Test arbitrary subtraction that tests reduction.
1317            let mut tmp = Scalar(blst::blst_fr {
1318                l: [
1319                    0x6a68c64b6f735a2b,
1320                    0xd5f4d143fe0a1972,
1321                    0x37c17f3829267c62,
1322                    0xa2f37391f30915c,
1323                ],
1324            });
1325            tmp.sub_assign(&Scalar(blst::blst_fr {
1326                l: [
1327                    0xade5adacdccb6190,
1328                    0xaa21ee0f27db3ccd,
1329                    0x2550f4704ae39086,
1330                    0x591d1902e7c5ba27,
1331                ],
1332            }));
1333            assert_eq!(
1334                tmp,
1335                Scalar(blst::blst_fr {
1336                    l: [
1337                        0xbc83189d92a7f89c,
1338                        0x7f908737d62d38a3,
1339                        0x45aa62cfe7e4c3e1,
1340                        0x24ffc5896108547d
1341                    ]
1342                })
1343            );
1344
1345            // Test the opposite subtraction which doesn't test reduction.
1346            tmp = Scalar(blst::blst_fr {
1347                l: [
1348                    0xade5adacdccb6190,
1349                    0xaa21ee0f27db3ccd,
1350                    0x2550f4704ae39086,
1351                    0x591d1902e7c5ba27,
1352                ],
1353            });
1354            tmp.sub_assign(&Scalar(blst::blst_fr {
1355                l: [
1356                    0x6a68c64b6f735a2b,
1357                    0xd5f4d143fe0a1972,
1358                    0x37c17f3829267c62,
1359                    0xa2f37391f30915c,
1360                ],
1361            }));
1362            assert_eq!(
1363                tmp,
1364                Scalar(blst::blst_fr {
1365                    l: [
1366                        0x437ce7616d580765,
1367                        0xd42d1ccb29d1235b,
1368                        0xed8f753821bd1423,
1369                        0x4eede1c9c89528ca
1370                    ]
1371                })
1372            );
1373
1374            // Test for sensible results with zero
1375            tmp = Scalar(blst::blst_fr { l: [0, 0, 0, 0] });
1376            tmp.sub_assign(&Scalar(blst::blst_fr { l: [0, 0, 0, 0] }));
1377            assert!(bool::from(tmp.is_zero()));
1378
1379            tmp = Scalar(blst::blst_fr {
1380                l: [
1381                    0x437ce7616d580765,
1382                    0xd42d1ccb29d1235b,
1383                    0xed8f753821bd1423,
1384                    0x4eede1c9c89528ca,
1385                ],
1386            });
1387            tmp.sub_assign(&Scalar(blst::blst_fr { l: [0, 0, 0, 0] }));
1388            assert_eq!(
1389                tmp,
1390                Scalar(blst::blst_fr {
1391                    l: [
1392                        0x437ce7616d580765,
1393                        0xd42d1ccb29d1235b,
1394                        0xed8f753821bd1423,
1395                        0x4eede1c9c89528ca
1396                    ]
1397                })
1398            );
1399        }
1400
1401        let mut rng = XorShiftRng::from_seed([
1402            0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
1403            0xbc, 0xe5,
1404        ]);
1405
1406        for _ in 0..1000 {
1407            // Ensure that (a - b) + (b - a) = 0.
1408            let a = Scalar::random(&mut rng);
1409            let b = Scalar::random(&mut rng);
1410
1411            let mut tmp1 = a;
1412            tmp1.sub_assign(&b);
1413
1414            let mut tmp2 = b;
1415            tmp2.sub_assign(&a);
1416
1417            tmp1.add_assign(&tmp2);
1418            assert!(bool::from(tmp1.is_zero()));
1419        }
1420    }
1421
1422    #[test]
1423    fn test_scalar_mul_assign() {
1424        let mut tmp = Scalar(blst::blst_fr {
1425            l: [
1426                0x6b7e9b8faeefc81a,
1427                0xe30a8463f348ba42,
1428                0xeff3cb67a8279c9c,
1429                0x3d303651bd7c774d,
1430            ],
1431        });
1432        tmp.mul_assign(&Scalar(blst::blst_fr {
1433            l: [
1434                0x13ae28e3bc35ebeb,
1435                0xa10f4488075cae2c,
1436                0x8160e95a853c3b5d,
1437                0x5ae3f03b561a841d,
1438            ],
1439        }));
1440        assert!(
1441            tmp == Scalar(blst::blst_fr {
1442                l: [
1443                    0x23717213ce710f71,
1444                    0xdbee1fe53a16e1af,
1445                    0xf565d3e1c2a48000,
1446                    0x4426507ee75df9d7
1447                ]
1448            })
1449        );
1450
1451        let mut rng = XorShiftRng::from_seed([
1452            0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
1453            0xbc, 0xe5,
1454        ]);
1455
1456        for _ in 0..1000000 {
1457            // Ensure that (a * b) * c = a * (b * c)
1458            let a = Scalar::random(&mut rng);
1459            let b = Scalar::random(&mut rng);
1460            let c = Scalar::random(&mut rng);
1461
1462            let mut tmp1 = a;
1463            tmp1.mul_assign(&b);
1464            tmp1.mul_assign(&c);
1465
1466            let mut tmp2 = b;
1467            tmp2.mul_assign(&c);
1468            tmp2.mul_assign(&a);
1469
1470            assert_eq!(tmp1, tmp2);
1471        }
1472
1473        for _ in 0..1000000 {
1474            // Ensure that r * (a + b + c) = r*a + r*b + r*c
1475
1476            let r = Scalar::random(&mut rng);
1477            let mut a = Scalar::random(&mut rng);
1478            let mut b = Scalar::random(&mut rng);
1479            let mut c = Scalar::random(&mut rng);
1480
1481            let mut tmp1 = a;
1482            tmp1.add_assign(&b);
1483            tmp1.add_assign(&c);
1484            tmp1.mul_assign(&r);
1485
1486            a.mul_assign(&r);
1487            b.mul_assign(&r);
1488            c.mul_assign(&r);
1489
1490            a.add_assign(&b);
1491            a.add_assign(&c);
1492
1493            assert_eq!(tmp1, a);
1494        }
1495    }
1496
1497    #[test]
1498    fn test_scalar_squaring() {
1499        let a = Scalar(blst::blst_fr {
1500            l: [
1501                0xffffffffffffffff,
1502                0xffffffffffffffff,
1503                0xffffffffffffffff,
1504                0x73eda753299d7d47,
1505            ],
1506        });
1507        // assert!(a.is_valid());
1508        assert_eq!(
1509            a.square(),
1510            Scalar::from_u64s_le(&[
1511                0xc0d698e7bde077b8,
1512                0xb79a310579e76ec2,
1513                0xac1da8d0a9af4e5f,
1514                0x13f629c49bf23e97
1515            ])
1516            .unwrap()
1517        );
1518
1519        let mut rng = XorShiftRng::from_seed([
1520            0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
1521            0xbc, 0xe5,
1522        ]);
1523
1524        for _ in 0..1000000 {
1525            // Ensure that (a * a) = a^2
1526            let a = Scalar::random(&mut rng);
1527
1528            let tmp = a.square();
1529
1530            let mut tmp2 = a;
1531            tmp2.mul_assign(&a);
1532
1533            assert_eq!(tmp, tmp2);
1534        }
1535    }
1536
1537    #[test]
1538    fn test_scalar_inverse() {
1539        assert_eq!(Scalar::ZERO.invert().is_none().unwrap_u8(), 1);
1540
1541        let mut rng = XorShiftRng::from_seed([
1542            0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
1543            0xbc, 0xe5,
1544        ]);
1545
1546        let one = Scalar::ONE;
1547
1548        for i in 0..1000 {
1549            // Ensure that a * a^-1 = 1
1550            let mut a = Scalar::random(&mut rng);
1551            let ainv = a.invert().unwrap();
1552            a.mul_assign(&ainv);
1553            assert_eq!(a, one, "round {}", i);
1554        }
1555    }
1556
1557    #[test]
1558    fn test_scalar_double() {
1559        let mut rng = XorShiftRng::from_seed([
1560            0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
1561            0xbc, 0xe5,
1562        ]);
1563
1564        for _ in 0..1000 {
1565            // Ensure doubling a is equivalent to adding a to itself.
1566            let a = Scalar::random(&mut rng);
1567            let mut b = a;
1568            b.add_assign(&a);
1569            assert_eq!(a.double(), b);
1570        }
1571    }
1572
1573    #[test]
1574    fn test_scalar_negate() {
1575        {
1576            let a = Scalar::ZERO;
1577            assert!(bool::from((-a).is_zero()));
1578        }
1579
1580        let mut rng = XorShiftRng::from_seed([
1581            0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
1582            0xbc, 0xe5,
1583        ]);
1584
1585        for _ in 0..1000 {
1586            // Ensure (a - (-a)) = 0.
1587            let mut a = Scalar::random(&mut rng);
1588            a.add_assign(-a);
1589            assert!(bool::from(a.is_zero()));
1590        }
1591    }
1592
1593    #[test]
1594    fn test_scalar_pow() {
1595        let mut rng = XorShiftRng::from_seed([
1596            0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
1597            0xbc, 0xe5,
1598        ]);
1599
1600        for i in 0..1000 {
1601            // Exponentiate by various small numbers and ensure it consists with repeated
1602            // multiplication.
1603            let a = Scalar::random(&mut rng);
1604            let target = a.pow_vartime([i]);
1605            let mut c = Scalar::ONE;
1606            for _ in 0..i {
1607                c.mul_assign(&a);
1608            }
1609            assert_eq!(c, target);
1610        }
1611
1612        for _ in 0..1000 {
1613            // Exponentiating by the modulus should have no effect in a prime field.
1614            let a = Scalar::random(&mut rng);
1615
1616            assert_eq!(a, a.pow_vartime(MODULUS));
1617        }
1618    }
1619
1620    #[test]
1621    fn test_scalar_sqrt() {
1622        let mut rng = XorShiftRng::from_seed([
1623            0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
1624            0xbc, 0xe5,
1625        ]);
1626
1627        assert_eq!(Scalar::ZERO.sqrt().unwrap(), Scalar::ZERO);
1628        assert_eq!(Scalar::ONE.sqrt().unwrap(), Scalar::ONE);
1629
1630        for _ in 0..1000 {
1631            // Ensure sqrt(a^2) = a or -a
1632            let a = Scalar::random(&mut rng);
1633            let a_new = a.square().sqrt().unwrap();
1634            assert!(a_new == a || a_new == -a);
1635        }
1636
1637        for _ in 0..1000 {
1638            // Ensure sqrt(a)^2 = a for random a
1639            let a = Scalar::random(&mut rng);
1640            let sqrt = a.sqrt();
1641            if sqrt.is_some().into() {
1642                assert_eq!(sqrt.unwrap().square(), a);
1643            }
1644        }
1645    }
1646
1647    #[test]
1648    fn test_scalar_from_into_repr() {
1649        // r + 1 should not be in the field
1650        assert!(bool::from(
1651            Scalar::from_u64s_le(&[
1652                0xffffffff00000002,
1653                0x53bda402fffe5bfe,
1654                0x3339d80809a1d805,
1655                0x73eda753299d7d48
1656            ])
1657            .is_none()
1658        ));
1659
1660        // Modulus should not be in the field
1661        assert!(bool::from(Scalar::from_repr(Scalar::char()).is_none()));
1662        assert!(Scalar::from_repr_vartime(Scalar::char()).is_none());
1663
1664        // Multiply some arbitrary representations to see if the result is as expected.
1665        let mut a = Scalar::from_u64s_le(&[
1666            0x25ebe3a3ad3c0c6a,
1667            0x6990e39d092e817c,
1668            0x941f900d42f5658e,
1669            0x44f8a103b38a71e0,
1670        ])
1671        .unwrap();
1672        let b = Scalar::from_u64s_le(&[
1673            0x264e9454885e2475,
1674            0x46f7746bb0308370,
1675            0x4683ef5347411f9,
1676            0x58838d7f208d4492,
1677        ])
1678        .unwrap();
1679        let c = Scalar::from_u64s_le(&[
1680            0x48a09ab93cfc740d,
1681            0x3a6600fbfc7a671,
1682            0x838567017501d767,
1683            0x7161d6da77745512,
1684        ])
1685        .unwrap();
1686        a.mul_assign(&b);
1687        assert_eq!(a, c);
1688
1689        // Zero should be in the field.
1690        assert!(bool::from(Scalar::from_repr([0u8; 32]).unwrap().is_zero()));
1691        assert!(bool::from(
1692            Scalar::from_repr_vartime([0u8; 32]).unwrap().is_zero()
1693        ));
1694
1695        let mut rng = XorShiftRng::from_seed([
1696            0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
1697            0xbc, 0xe5,
1698        ]);
1699
1700        for i in 0..1000 {
1701            // Try to turn Scalar elements into representations and back again, and compare.
1702            let a = Scalar::random(&mut rng);
1703            let a_again = Scalar::from_repr(a.to_repr()).unwrap();
1704            assert_eq!(a, a_again, "{}", i);
1705            let a_yet_again = Scalar::from_repr_vartime(a.to_repr()).unwrap();
1706            assert_eq!(a, a_yet_again);
1707        }
1708    }
1709
1710    #[test]
1711    fn test_scalar_display() {
1712        assert_eq!(
1713            format!(
1714                "{}",
1715                Scalar::from_u64s_le(&[
1716                    0xc3cae746a3b5ecc7,
1717                    0x185ec8eb3f5b5aee,
1718                    0x684499ffe4b9dd99,
1719                    0x7c9bba7afb68faa
1720                ])
1721                .unwrap()
1722            ),
1723            "Scalar(0x07c9bba7afb68faa684499ffe4b9dd99185ec8eb3f5b5aeec3cae746a3b5ecc7)"
1724                .to_string()
1725        );
1726        assert_eq!(
1727            format!(
1728                "{}",
1729                Scalar::from_u64s_le(&[
1730                    0x44c71298ff198106,
1731                    0xb0ad10817df79b6a,
1732                    0xd034a80a2b74132b,
1733                    0x41cf9a1336f50719
1734                ])
1735                .unwrap()
1736            ),
1737            "Scalar(0x41cf9a1336f50719d034a80a2b74132bb0ad10817df79b6a44c71298ff198106)"
1738                .to_string()
1739        );
1740    }
1741
1742    #[test]
1743    fn test_scalar_root_of_unity() {
1744        assert_eq!(Scalar::S, 32);
1745        assert_eq!(Scalar::MULTIPLICATIVE_GENERATOR, Scalar::from(7));
1746        assert_eq!(
1747            Scalar::MULTIPLICATIVE_GENERATOR.pow_vartime([
1748                0xfffe5bfeffffffff,
1749                0x9a1d80553bda402,
1750                0x299d7d483339d808,
1751                0x73eda753
1752            ]),
1753            Scalar::ROOT_OF_UNITY
1754        );
1755        assert_eq!(
1756            Scalar::ROOT_OF_UNITY.pow_vartime([1 << Scalar::S]),
1757            Scalar::ONE
1758        );
1759        assert!(!bool::from(Scalar::MULTIPLICATIVE_GENERATOR.is_quad_res()));
1760    }
1761
1762    #[test]
1763    fn scalar_field_tests() {
1764        crate::tests::field::random_field_tests::<Scalar>();
1765        crate::tests::field::random_sqrt_tests::<Scalar>();
1766        crate::tests::field::from_str_tests::<Scalar>();
1767    }
1768
1769    #[test]
1770    fn test_scalar_repr_conversion() {
1771        let a = Scalar::from(1);
1772        let mut expected_bytes = [0u8; 32];
1773        expected_bytes[0] = 1;
1774        assert_eq!(a, Scalar::from_repr(a.to_repr()).unwrap());
1775        assert_eq!(a.to_repr(), expected_bytes);
1776        assert_eq!(a, Scalar::from_repr(expected_bytes).unwrap());
1777
1778        let a = Scalar::from(12);
1779        let mut expected_bytes = [0u8; 32];
1780        expected_bytes[0] = 12;
1781        assert_eq!(a, Scalar::from_repr(a.to_repr()).unwrap());
1782        assert_eq!(a.to_repr(), expected_bytes);
1783        assert_eq!(a, Scalar::from_repr(expected_bytes).unwrap());
1784    }
1785
1786    #[test]
1787    fn test_scalar_repr_vartime_conversion() {
1788        let a = Scalar::from(1);
1789        let mut expected_bytes = [0u8; 32];
1790        expected_bytes[0] = 1;
1791        assert_eq!(a, Scalar::from_repr_vartime(a.to_repr()).unwrap());
1792        assert_eq!(a.to_repr(), expected_bytes);
1793        assert_eq!(a, Scalar::from_repr_vartime(expected_bytes).unwrap());
1794
1795        let a = Scalar::from(12);
1796        let mut expected_bytes = [0u8; 32];
1797        expected_bytes[0] = 12;
1798        assert_eq!(a, Scalar::from_repr_vartime(a.to_repr()).unwrap());
1799        assert_eq!(a.to_repr(), expected_bytes);
1800        assert_eq!(a, Scalar::from_repr_vartime(expected_bytes).unwrap());
1801    }
1802
1803    #[test]
1804    fn test_scalar_to_le_bits() {
1805        let mut bits = Scalar::ONE.to_le_bits().into_iter();
1806        assert!(bits.next().unwrap());
1807        for bit in bits {
1808            assert!(!bit);
1809        }
1810
1811        let mut bits = Scalar::from(u64::MAX).to_le_bits().into_iter();
1812        for _ in 0..64 {
1813            assert!(bits.next().unwrap());
1814        }
1815        for _ in 64..Scalar::NUM_BITS {
1816            assert!(!bits.next().unwrap());
1817        }
1818        // Check that the final bit in the backing representation, i.e. the 256-th bit, is false.
1819        // This bit should always be `false` because it exceeds the field size modulus.
1820        assert!(!bits.next().unwrap());
1821        // Check that the bitvec's size does not exceed the size of the backing representation
1822        // `[u8; 32]`, i.e. 256-bits.
1823        assert!(bits.next().is_none());
1824
1825        let mut neg1_bits = (-Scalar::ONE).to_le_bits().into_iter();
1826        let mut modulus_bits = Scalar::char_le_bits().into_iter();
1827        assert_ne!(neg1_bits.next().unwrap(), modulus_bits.next().unwrap());
1828        for (b1, b2) in neg1_bits.zip(modulus_bits) {
1829            assert_eq!(b1, b2);
1830        }
1831    }
1832
1833    #[test]
1834    fn m1_inv_bug() {
1835        // This fails on aarch64-darwin.
1836        let bad = Scalar::ZERO - Scalar::from(7);
1837
1838        let inv = bad.invert().unwrap();
1839        let check = inv * bad;
1840        assert_eq!(Scalar::ONE, check);
1841    }
1842    #[test]
1843    fn m1_inv_bug_more() {
1844        let mut bad = Vec::new();
1845        for i in 1..1000000 {
1846            // Ensure that a * a^-1 = 1
1847            let a = Scalar::ZERO - Scalar::from(i);
1848            let ainv = a.invert().unwrap();
1849            let check = a * ainv;
1850            let one = Scalar::ONE;
1851
1852            if check != one {
1853                bad.push((i, a));
1854            }
1855        }
1856        assert_eq!(0, bad.len());
1857    }
1858
1859    fn scalar_from_u64s(parts: [u64; 4]) -> Scalar {
1860        let mut le_bytes = [0u8; 32];
1861        le_bytes[0..8].copy_from_slice(&parts[0].to_le_bytes());
1862        le_bytes[8..16].copy_from_slice(&parts[1].to_le_bytes());
1863        le_bytes[16..24].copy_from_slice(&parts[2].to_le_bytes());
1864        le_bytes[24..32].copy_from_slice(&parts[3].to_le_bytes());
1865        let mut repr = <Scalar as PrimeField>::Repr::default();
1866        repr.as_mut().copy_from_slice(&le_bytes[..]);
1867        Scalar::from_repr_vartime(repr).expect("u64s exceed BLS12-381 scalar field modulus")
1868    }
1869
1870    #[test]
1871    fn m1_inv_bug_special() {
1872        let maybe_bad = [scalar_from_u64s([
1873            0xb3fb72ea181b4e82,
1874            0x9435fcaf3a85c901,
1875            0x9eaf4fa6b9635037,
1876            0x2164d020b3bd14cc,
1877        ])];
1878
1879        let mut yep_bad = Vec::new();
1880
1881        for a in maybe_bad.iter() {
1882            let ainv = a.invert().unwrap();
1883            let check = a * ainv;
1884            let one = Scalar::ONE;
1885
1886            if check != one {
1887                yep_bad.push(a);
1888            }
1889        }
1890        assert_eq!(0, yep_bad.len());
1891    }
1892}