1use self::scalar_impl::barrett_reduce;
4use crate::{FieldBytes, NistP256, ORDER_HEX};
5use core::{
6 fmt::{self, Debug},
7 iter::{Product, Sum},
8 ops::{Add, AddAssign, Mul, MulAssign, Neg, Shr, ShrAssign, Sub, SubAssign},
9};
10use elliptic_curve::{
11 Curve, Generate,
12 bigint::{ArrayEncoding, Limb, Odd, U256, Uint, cpubits, modular::Retrieve},
13 ctutils,
14 group::ff::{self, Field, FromUniformBytes, PrimeField},
15 ops::{Invert, Reduce, ReduceNonZero},
16 rand_core::TryRng,
17 scalar::{FromUintUnchecked, IsHigh},
18 subtle::{
19 Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess,
20 CtOption,
21 },
22 zeroize::DefaultIsZeroes,
23};
24use primefield::{FieldExt, PrimeFieldExt};
25use primeorder::wnaf;
26
27cpubits! {
28 32 => {
29 #[path = "scalar/scalar32.rs"]
30 mod scalar_impl;
31 }
32 64 => {
33 #[path = "scalar/scalar64.rs"]
34 mod scalar_impl;
35 }
36}
37
38#[cfg(feature = "serde")]
39use {
40 elliptic_curve::ScalarValue,
41 serdect::serde::{Deserialize, Serialize, de, ser},
42};
43
44pub(crate) const MODULUS: Odd<U256> = NistP256::ORDER;
47
48const FRAC_MODULUS_2: Scalar = Scalar(MODULUS.as_ref().shr_vartime(1));
50
51#[doc = primefield::monty_field_element_doc!("Scalars are elements in the finite field modulo n.")]
52#[derive(Clone, Copy, Default)]
53pub struct Scalar(pub(crate) U256);
54
55impl Scalar {
56 pub const ZERO: Self = Self(U256::ZERO);
58
59 pub const ONE: Self = Self(U256::ONE);
61
62 #[must_use]
64 pub fn to_bytes(&self) -> FieldBytes {
65 self.0.to_be_byte_array()
66 }
67
68 #[must_use]
70 pub const fn add(&self, rhs: &Self) -> Self {
71 Self(self.0.add_mod(&rhs.0, NistP256::ORDER.as_nz_ref()))
72 }
73
74 #[must_use]
76 pub const fn double(&self) -> Self {
77 self.add(self)
78 }
79
80 #[must_use]
82 pub const fn sub(&self, rhs: &Self) -> Self {
83 Self(self.0.sub_mod(&rhs.0, NistP256::ORDER.as_nz_ref()))
84 }
85
86 #[must_use]
88 pub const fn multiply(&self, rhs: &Self) -> Self {
89 let (lo, hi) = self.0.widening_mul(&rhs.0);
90 Self(barrett_reduce(lo, hi))
91 }
92
93 #[must_use]
95 pub const fn square(&self) -> Self {
96 self.multiply(self)
98 }
99
100 #[must_use]
104 pub const fn shr_vartime(&self, shift: u32) -> Scalar {
105 Self(self.0.unbounded_shr_vartime(shift))
106 }
107
108 pub fn invert(&self) -> CtOption<Self> {
110 self.0
111 .invert_odd_mod(const { &Odd::from_be_hex(ORDER_HEX) })
112 .map(Self)
113 .into()
114 }
115
116 pub fn invert_vartime(&self) -> CtOption<Self> {
118 self.0
119 .invert_odd_mod_vartime(const { &Odd::from_be_hex(ORDER_HEX) })
120 .map(Self)
121 .into()
122 }
123
124 const fn invert_unwrap(&self) -> Self {
129 Self(
130 self.0
131 .invert_odd_mod(const { &Odd::from_be_hex(ORDER_HEX) })
132 .expect_copied("input should be non-zero"),
133 )
134 }
135
136 #[must_use]
142 pub const fn pow_vartime<const RHS_LIMBS: usize>(&self, exp: &Uint<RHS_LIMBS>) -> Self {
143 let mut res = Self::ONE;
144 let mut i = RHS_LIMBS;
145
146 while i > 0 {
147 i -= 1;
148
149 let mut j = Limb::BITS;
150 while j > 0 {
151 j -= 1;
152 res = res.square();
153
154 if ((exp.as_limbs()[i].0 >> j) & 1) == 1 {
155 res = res.multiply(self);
156 }
157 }
158 }
159
160 res
161 }
162
163 #[must_use]
169 pub const fn sqn_vartime(&self, n: usize) -> Self {
170 let mut x = *self;
171 let mut i = 0;
172 while i < n {
173 x = x.square();
174 i += 1;
175 }
176 x
177 }
178
179 #[must_use]
181 pub fn is_odd(&self) -> Choice {
182 self.0.is_odd().into()
183 }
184
185 #[must_use]
187 pub fn is_even(&self) -> Choice {
188 !self.is_odd()
189 }
190}
191
192elliptic_curve::scalar_impls!(NistP256, Scalar);
193
194impl AsRef<Scalar> for Scalar {
195 fn as_ref(&self) -> &Scalar {
196 self
197 }
198}
199
200impl Field for Scalar {
201 const ZERO: Self = Self::ZERO;
202 const ONE: Self = Self::ONE;
203
204 fn try_random<R: TryRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
205 let mut bytes = FieldBytes::default();
206
207 loop {
217 rng.try_fill_bytes(&mut bytes)?;
218 if let Some(scalar) = Scalar::from_repr(bytes).into() {
219 return Ok(scalar);
220 }
221 }
222 }
223
224 fn square(&self) -> Self {
225 Scalar::square(self)
226 }
227
228 fn double(&self) -> Self {
229 self.add(self)
230 }
231
232 fn invert(&self) -> CtOption<Self> {
233 Scalar::invert(self)
234 }
235
236 #[allow(clippy::many_single_char_names)]
239 fn sqrt(&self) -> CtOption<Self> {
240 const EXP: U256 =
241 U256::from_be_hex("07fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a");
242
243 let w = self.pow_vartime(&EXP);
245
246 let mut v = Self::S;
247 let mut x = *self * w;
248 let mut b = x * w;
249 let mut z = Self::ROOT_OF_UNITY;
250
251 for max_v in (1..=Self::S).rev() {
252 let mut k = 1;
253 let mut tmp = b.square();
254 let mut j_less_than_v = Choice::from(1);
255
256 for j in 2..max_v {
257 let tmp_is_one = tmp.ct_eq(&Self::ONE);
258 let squared = Self::conditional_select(&tmp, &z, tmp_is_one).square();
259 tmp = Self::conditional_select(&squared, &tmp, tmp_is_one);
260 let new_z = Self::conditional_select(&z, &squared, tmp_is_one);
261 j_less_than_v &= !ConstantTimeEq::ct_eq(&j, &v);
262 k = u32::conditional_select(&j, &k, tmp_is_one);
263 z = Self::conditional_select(&z, &new_z, j_less_than_v);
264 }
265
266 let result = x * z;
267 x = Self::conditional_select(&result, &x, b.ct_eq(&Self::ONE));
268 z = z.square();
269 b *= z;
270 v = k;
271 }
272
273 CtOption::new(x, x.square().ct_eq(self))
274 }
275
276 fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self) {
277 ff::helpers::sqrt_ratio_generic(num, div)
278 }
279}
280
281impl Generate for Scalar {
282 fn try_generate_from_rng<R: TryRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
283 Self::try_random(rng)
284 }
285}
286
287impl PrimeField for Scalar {
288 type Repr = FieldBytes;
289
290 const MODULUS: &'static str = ORDER_HEX;
291 const NUM_BITS: u32 = 256;
292 const CAPACITY: u32 = 255;
293 const TWO_INV: Self = Self(U256::from_u8(2)).invert_unwrap();
294 const MULTIPLICATIVE_GENERATOR: Self = Self(U256::from_u8(7));
295 const S: u32 = 4;
296 const ROOT_OF_UNITY: Self = Self(U256::from_be_hex(
297 "ffc97f062a770992ba807ace842a3dfc1546cad004378daf0592d7fbb41e6602",
298 ));
299 const ROOT_OF_UNITY_INV: Self = Self::ROOT_OF_UNITY.invert_unwrap();
300 const DELTA: Self = Self(U256::from_u64(33232930569601));
301
302 fn from_repr(bytes: FieldBytes) -> CtOption<Self> {
307 let inner = U256::from_be_byte_array(bytes);
308 CtOption::new(
309 Self(inner),
310 ConstantTimeLess::ct_lt(&inner, &NistP256::ORDER),
311 )
312 }
313
314 fn to_repr(&self) -> FieldBytes {
315 self.to_bytes()
316 }
317
318 fn is_odd(&self) -> Choice {
319 self.0.is_odd().into()
320 }
321}
322
323impl FieldExt for Scalar {}
324impl PrimeFieldExt for Scalar {}
325
326wnaf::impl_wnaf_size_for_scalar!(Scalar);
327
328impl Retrieve for Scalar {
329 type Output = U256;
330
331 fn retrieve(&self) -> U256 {
332 self.0
333 }
334}
335
336impl DefaultIsZeroes for Scalar {}
337
338impl Eq for Scalar {}
339
340impl FromUintUnchecked for Scalar {
341 type Uint = U256;
342
343 fn from_uint_unchecked(uint: Self::Uint) -> Self {
344 Self(uint)
345 }
346}
347
348impl Invert for Scalar {
349 type Output = CtOption<Self>;
350
351 fn invert(&self) -> CtOption<Self> {
352 self.invert()
353 }
354
355 fn invert_vartime(&self) -> CtOption<Self> {
356 self.invert_vartime()
357 }
358}
359
360impl IsHigh for Scalar {
361 fn is_high(&self) -> Choice {
362 ConstantTimeGreater::ct_gt(&self.0, &FRAC_MODULUS_2.0)
363 }
364}
365
366impl Shr<usize> for Scalar {
367 type Output = Self;
368
369 #[allow(clippy::cast_possible_truncation, reason = "TODO")]
370 fn shr(self, rhs: usize) -> Self::Output {
371 self.shr_vartime(rhs as u32)
372 }
373}
374
375impl Shr<usize> for &Scalar {
376 type Output = Scalar;
377
378 #[allow(clippy::cast_possible_truncation, reason = "TODO")]
379 fn shr(self, rhs: usize) -> Self::Output {
380 self.shr_vartime(rhs as u32)
381 }
382}
383
384impl ShrAssign<usize> for Scalar {
385 fn shr_assign(&mut self, rhs: usize) {
386 *self = *self >> rhs;
387 }
388}
389
390impl PartialEq for Scalar {
391 fn eq(&self, other: &Self) -> bool {
392 self.ct_eq(other).into()
393 }
394}
395
396impl PartialOrd for Scalar {
397 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
398 Some(self.cmp(other))
399 }
400}
401
402impl Ord for Scalar {
403 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
404 self.0.cmp(&other.0)
405 }
406}
407
408impl From<u32> for Scalar {
409 fn from(k: u32) -> Self {
410 Scalar(k.into())
411 }
412}
413
414impl From<u64> for Scalar {
415 fn from(k: u64) -> Self {
416 Scalar(k.into())
417 }
418}
419
420impl From<u128> for Scalar {
421 fn from(k: u128) -> Self {
422 Scalar(k.into())
423 }
424}
425
426impl From<Scalar> for FieldBytes {
427 fn from(scalar: Scalar) -> Self {
428 scalar.to_bytes()
429 }
430}
431
432impl From<&Scalar> for FieldBytes {
433 fn from(scalar: &Scalar) -> Self {
434 scalar.to_bytes()
435 }
436}
437
438impl From<Scalar> for U256 {
439 fn from(scalar: Scalar) -> U256 {
440 scalar.0
441 }
442}
443
444impl From<&Scalar> for U256 {
445 fn from(scalar: &Scalar) -> U256 {
446 scalar.0
447 }
448}
449
450impl FromUniformBytes<64> for Scalar {
451 fn from_uniform_bytes(bytes: &[u8; 64]) -> Self {
452 Self(barrett_reduce(
453 U256::from_be_slice(&bytes[32..]),
454 U256::from_be_slice(&bytes[..32]),
455 ))
456 }
457}
458
459impl Add<Scalar> for Scalar {
460 type Output = Scalar;
461
462 fn add(self, other: Scalar) -> Scalar {
463 Scalar::add(&self, &other)
464 }
465}
466
467impl Add<&Scalar> for &Scalar {
468 type Output = Scalar;
469
470 fn add(self, other: &Scalar) -> Scalar {
471 Scalar::add(self, other)
472 }
473}
474
475impl Add<&Scalar> for Scalar {
476 type Output = Scalar;
477
478 fn add(self, other: &Scalar) -> Scalar {
479 Scalar::add(&self, other)
480 }
481}
482
483impl AddAssign<Scalar> for Scalar {
484 fn add_assign(&mut self, rhs: Scalar) {
485 *self = Scalar::add(self, &rhs);
486 }
487}
488
489impl AddAssign<&Scalar> for Scalar {
490 fn add_assign(&mut self, rhs: &Scalar) {
491 *self = Scalar::add(self, rhs);
492 }
493}
494
495impl Sub<Scalar> for Scalar {
496 type Output = Scalar;
497
498 fn sub(self, other: Scalar) -> Scalar {
499 Scalar::sub(&self, &other)
500 }
501}
502
503impl Sub<&Scalar> for &Scalar {
504 type Output = Scalar;
505
506 fn sub(self, other: &Scalar) -> Scalar {
507 Scalar::sub(self, other)
508 }
509}
510
511impl Sub<&Scalar> for Scalar {
512 type Output = Scalar;
513
514 fn sub(self, other: &Scalar) -> Scalar {
515 Scalar::sub(&self, other)
516 }
517}
518
519impl SubAssign<Scalar> for Scalar {
520 fn sub_assign(&mut self, rhs: Scalar) {
521 *self = Scalar::sub(self, &rhs);
522 }
523}
524
525impl SubAssign<&Scalar> for Scalar {
526 fn sub_assign(&mut self, rhs: &Scalar) {
527 *self = Scalar::sub(self, rhs);
528 }
529}
530
531impl Mul<Scalar> for Scalar {
532 type Output = Scalar;
533
534 fn mul(self, other: Scalar) -> Scalar {
535 Scalar::multiply(&self, &other)
536 }
537}
538
539impl Mul<&Scalar> for &Scalar {
540 type Output = Scalar;
541
542 fn mul(self, other: &Scalar) -> Scalar {
543 Scalar::multiply(self, other)
544 }
545}
546
547impl Mul<&Scalar> for Scalar {
548 type Output = Scalar;
549
550 fn mul(self, other: &Scalar) -> Scalar {
551 Scalar::multiply(&self, other)
552 }
553}
554
555impl MulAssign<Scalar> for Scalar {
556 fn mul_assign(&mut self, rhs: Scalar) {
557 *self = Scalar::multiply(self, &rhs);
558 }
559}
560
561impl MulAssign<&Scalar> for Scalar {
562 fn mul_assign(&mut self, rhs: &Scalar) {
563 *self = Scalar::multiply(self, rhs);
564 }
565}
566
567impl Neg for Scalar {
568 type Output = Scalar;
569
570 fn neg(self) -> Scalar {
571 Scalar::ZERO - self
572 }
573}
574
575impl Neg for &Scalar {
576 type Output = Scalar;
577
578 fn neg(self) -> Scalar {
579 Scalar::ZERO - self
580 }
581}
582
583impl Reduce<U256> for Scalar {
584 fn reduce(w: &U256) -> Self {
585 let (r, underflow) = w.borrowing_sub(&NistP256::ORDER, Limb::ZERO);
586 let underflow = Choice::from((underflow.0 >> (Limb::BITS - 1)) as u8);
587 Self(U256::conditional_select(w, &r, !underflow))
588 }
589}
590
591impl Reduce<FieldBytes> for Scalar {
592 #[inline]
593 fn reduce(bytes: &FieldBytes) -> Self {
594 Self::reduce(&U256::from_be_byte_array(*bytes))
595 }
596}
597
598impl ReduceNonZero<U256> for Scalar {
599 fn reduce_nonzero(w: &U256) -> Self {
600 const ORDER_MINUS_ONE: U256 = NistP256::ORDER.as_ref().wrapping_sub(&U256::ONE);
601 let (r, underflow) = w.borrowing_sub(&ORDER_MINUS_ONE, Limb::ZERO);
602 let underflow = Choice::from((underflow.0 >> (Limb::BITS - 1)) as u8);
603 Self(U256::conditional_select(w, &r, !underflow).wrapping_add(&U256::ONE))
604 }
605}
606
607impl ReduceNonZero<FieldBytes> for Scalar {
608 #[inline]
609 fn reduce_nonzero(bytes: &FieldBytes) -> Self {
610 Self::reduce_nonzero(&U256::from_be_byte_array(*bytes))
611 }
612}
613
614impl Sum for Scalar {
615 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
616 iter.reduce(Add::add).unwrap_or(Self::ZERO)
617 }
618}
619
620impl<'a> Sum<&'a Scalar> for Scalar {
621 fn sum<I: Iterator<Item = &'a Scalar>>(iter: I) -> Self {
622 iter.copied().sum()
623 }
624}
625
626impl Product for Scalar {
627 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
628 iter.reduce(Mul::mul).unwrap_or(Self::ONE)
629 }
630}
631
632impl<'a> Product<&'a Scalar> for Scalar {
633 fn product<I: Iterator<Item = &'a Scalar>>(iter: I) -> Self {
634 iter.copied().product()
635 }
636}
637
638impl ConditionallySelectable for Scalar {
639 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
640 Self(U256::conditional_select(&a.0, &b.0, choice))
641 }
642}
643
644impl ConstantTimeEq for Scalar {
645 fn ct_eq(&self, other: &Self) -> Choice {
646 ConstantTimeEq::ct_eq(&self.0, &other.0)
647 }
648}
649
650impl ctutils::CtEq for Scalar {
651 fn ct_eq(&self, other: &Self) -> ctutils::Choice {
652 ConstantTimeEq::ct_eq(self, other).into()
653 }
654}
655
656impl ctutils::CtSelect for Scalar {
657 fn ct_select(&self, other: &Self, choice: ctutils::Choice) -> Self {
658 ConditionallySelectable::conditional_select(self, other, choice.into())
659 }
660}
661
662impl Debug for Scalar {
663 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
664 write!(f, "Scalar(0x{:X})", &self.0)
665 }
666}
667
668#[cfg(feature = "serde")]
669impl Serialize for Scalar {
670 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
671 where
672 S: ser::Serializer,
673 {
674 ScalarValue::from(self).serialize(serializer)
675 }
676}
677
678#[cfg(feature = "serde")]
679impl<'de> Deserialize<'de> for Scalar {
680 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
681 where
682 D: de::Deserializer<'de>,
683 {
684 Ok(ScalarValue::deserialize(deserializer)?.into())
685 }
686}
687
688#[cfg(test)]
689mod tests {
690 use super::{Scalar, U256};
691 use crate::{FieldBytes, NistP256, SecretKey};
692 use elliptic_curve::{Curve, array::Array, group::ff::PrimeField, ops::ReduceNonZero};
693
694 primefield::test_primefield!(Scalar, U256);
695
696 #[test]
697 fn from_to_bytes_roundtrip() {
698 let k: u64 = 42;
699 let mut bytes = FieldBytes::default();
700 bytes[24..].copy_from_slice(k.to_be_bytes().as_ref());
701
702 let scalar = Scalar::from_repr(bytes).unwrap();
703 assert_eq!(bytes, scalar.to_bytes());
704 }
705
706 #[test]
708 fn multiply() {
709 let one = Scalar::ONE;
710 let two = one + one;
711 let three = two + one;
712 let six = three + three;
713 assert_eq!(six, two * three);
714
715 let minus_two = -two;
716 let minus_three = -three;
717 assert_eq!(two, -minus_two);
718
719 assert_eq!(minus_three * minus_two, minus_two * minus_three);
720 assert_eq!(six, minus_two * minus_three);
721 }
722
723 #[test]
725 fn from_ec_secret() {
726 let scalar = Scalar::ONE;
727 let secret = SecretKey::from_bytes(&scalar.to_bytes()).unwrap();
728 let rederived_scalar = Scalar::from(&secret);
729 assert_eq!(scalar.0, rederived_scalar.0);
730 }
731
732 #[test]
733 fn reduce_nonzero() {
734 assert_eq!(Scalar::reduce_nonzero(&Array::default()).0, U256::ONE,);
735 assert_eq!(Scalar::reduce_nonzero(&U256::ONE).0, U256::from_u8(2),);
736 assert_eq!(
737 Scalar::reduce_nonzero(&U256::from_u8(2)).0,
738 U256::from_u8(3),
739 );
740
741 assert_eq!(
742 Scalar::reduce_nonzero(NistP256::ORDER.as_ref()).0,
743 U256::from_u8(2),
744 );
745 assert_eq!(
746 Scalar::reduce_nonzero(&NistP256::ORDER.wrapping_sub(&U256::from_u8(1))).0,
747 U256::ONE,
748 );
749 assert_eq!(
750 Scalar::reduce_nonzero(&NistP256::ORDER.wrapping_sub(&U256::from_u8(2))).0,
751 NistP256::ORDER.wrapping_sub(&U256::ONE),
752 );
753 assert_eq!(
754 Scalar::reduce_nonzero(&NistP256::ORDER.wrapping_sub(&U256::from_u8(3))).0,
755 NistP256::ORDER.wrapping_sub(&U256::from_u8(2)),
756 );
757
758 assert_eq!(
759 Scalar::reduce_nonzero(&NistP256::ORDER.wrapping_add(&U256::ONE)).0,
760 U256::from_u8(3),
761 );
762 assert_eq!(
763 Scalar::reduce_nonzero(&NistP256::ORDER.wrapping_add(&U256::from_u8(2))).0,
764 U256::from_u8(4),
765 );
766 }
767}