1#[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#[derive(Clone, Copy, Debug, PartialOrd, Ord)]
75pub struct Scalar(fiat_p521_scalar_montgomery_domain_field_element);
76
77impl Scalar {
78 pub const ZERO: Self = Self::from_u64(0);
80
81 pub const ONE: Self = Self::from_u64(1);
83
84 const BYTES: usize = 66;
86
87 pub fn from_bytes(repr: &FieldBytes) -> CtOption<Self> {
89 Self::from_uint(FieldBytesEncoding::<NistP521>::decode_field_bytes(repr))
90 }
91
92 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 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 #[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 pub const fn from_u64(w: u64) -> Self {
123 Self::from_uint_unchecked(U576::from_u64(w))
124 }
125
126 #[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 #[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 pub fn to_bytes(self) -> FieldBytes {
150 FieldBytesEncoding::<NistP521>::encode_field_bytes(&self.to_canonical())
151 }
152
153 #[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 #[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 pub fn is_odd(&self) -> Choice {
175 self.to_canonical().is_odd()
176 }
177
178 pub fn is_even(&self) -> Choice {
184 !self.is_odd()
185 }
186
187 pub fn is_zero(&self) -> Choice {
193 self.ct_eq(&Self::ZERO)
194 }
195
196 pub const fn add(&self, rhs: &Self) -> Self {
198 Self(fiat_p521_scalar_add(&self.0, &rhs.0))
199 }
200
201 #[must_use]
203 pub const fn double(&self) -> Self {
204 self.add(self)
205 }
206
207 pub const fn sub(&self, rhs: &Self) -> Self {
209 Self(fiat_p521_scalar_sub(&self.0, &rhs.0))
210 }
211
212 pub const fn neg(&self) -> Self {
214 Self(fiat_p521_scalar_opp(&self.0))
215 }
216
217 pub const fn multiply(&self, rhs: &Self) -> Self {
219 Self(fiat_p521_scalar_mul(&self.0, &rhs.0))
220 }
221
222 pub fn invert(&self) -> CtOption<Self> {
224 CtOption::new(self.invert_unchecked(), !self.is_zero())
225 }
226
227 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 #[must_use]
251 pub const fn square(&self) -> Self {
252 Self(fiat_p521_scalar_square(&self.0))
253 }
254
255 pub fn sqrt(&self) -> CtOption<Self> {
257 todo!("`sqrt` not yet implemented")
258 }
259
260 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 #[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 #[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 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 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}