1#![cfg_attr(feature = "digest", doc = "```")]
92#![cfg_attr(not(feature = "digest"), doc = "```ignore")]
93use core::borrow::Borrow;
115use core::fmt::Debug;
116use core::iter::{Product, Sum};
117use core::ops::Index;
118use core::ops::Neg;
119use core::ops::{Add, AddAssign};
120use core::ops::{Mul, MulAssign};
121use core::ops::{Sub, SubAssign};
122
123use cfg_if::cfg_if;
124
125#[cfg(feature = "group")]
126use group::ff::{Field, FromUniformBytes, PrimeField};
127
128#[cfg(feature = "group")]
129use rand_core::TryRng;
130
131#[cfg(feature = "rand_core")]
132use rand_core::CryptoRng;
133
134#[cfg(feature = "digest")]
135use digest::Digest;
136#[cfg(feature = "digest")]
137use digest::array::typenum::U64;
138
139use subtle::Choice;
140use subtle::ConditionallySelectable;
141use subtle::ConstantTimeEq;
142use subtle::CtOption;
143
144#[cfg(feature = "zeroize")]
145use zeroize::Zeroize;
146
147use crate::backend;
148use crate::constants;
149
150cfg_if! {
151 if #[cfg(curve25519_dalek_backend = "fiat")] {
152 #[cfg(curve25519_dalek_bits = "32")]
157 #[cfg_attr(
158 docsrs,
159 doc(cfg(all(feature = "fiat_backend", curve25519_dalek_bits = "32")))
160 )]
161 type UnpackedScalar = backend::serial::fiat_u32::scalar::Scalar29;
162
163 #[cfg(curve25519_dalek_bits = "64")]
168 #[cfg_attr(
169 docsrs,
170 doc(cfg(all(feature = "fiat_backend", curve25519_dalek_bits = "64")))
171 )]
172 type UnpackedScalar = backend::serial::fiat_u64::scalar::Scalar52;
173 } else if #[cfg(curve25519_dalek_bits = "64")] {
174 #[cfg_attr(docsrs, doc(cfg(curve25519_dalek_bits = "64")))]
179 type UnpackedScalar = backend::serial::u64::scalar::Scalar52;
180 } else {
181 #[cfg_attr(docsrs, doc(cfg(curve25519_dalek_bits = "64")))]
186 type UnpackedScalar = backend::serial::u32::scalar::Scalar29;
187 }
188}
189
190#[allow(clippy::derived_hash_with_manual_eq)]
192#[derive(Copy, Clone, Hash)]
193pub struct Scalar {
194 pub(crate) bytes: [u8; 32],
230}
231
232impl Scalar {
233 pub fn from_bytes_mod_order(bytes: [u8; 32]) -> Scalar {
236 let s_unreduced = Scalar { bytes };
238
239 let s = s_unreduced.reduce();
241 debug_assert_eq!(0u8, s[31] >> 7);
242
243 s
244 }
245
246 pub fn from_bytes_mod_order_wide(input: &[u8; 64]) -> Scalar {
249 UnpackedScalar::from_bytes_wide(input).pack()
250 }
251
252 pub fn from_canonical_bytes(bytes: [u8; 32]) -> CtOption<Scalar> {
260 let high_bit_unset = (bytes[31] >> 7).ct_eq(&0);
261 let candidate = Scalar { bytes };
262 CtOption::new(candidate, high_bit_unset & candidate.is_canonical())
263 }
264
265 #[cfg(feature = "legacy_compatibility")]
272 pub const fn from_bits(bytes: [u8; 32]) -> Scalar {
273 let mut s = Scalar { bytes };
274 s.bytes[31] &= 0b0111_1111;
276
277 s
278 }
279}
280
281impl Debug for Scalar {
282 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
283 write!(f, "Scalar{{\n\tbytes: {:?},\n}}", &self.bytes)
284 }
285}
286
287impl Eq for Scalar {}
288impl PartialEq for Scalar {
289 fn eq(&self, other: &Self) -> bool {
290 self.ct_eq(other).into()
291 }
292}
293
294impl ConstantTimeEq for Scalar {
295 fn ct_eq(&self, other: &Self) -> Choice {
296 self.bytes.ct_eq(&other.bytes)
297 }
298}
299
300impl Index<usize> for Scalar {
301 type Output = u8;
302
303 fn index(&self, _index: usize) -> &u8 {
305 &(self.bytes[_index])
306 }
307}
308
309impl<'a> MulAssign<&'a Scalar> for Scalar {
310 fn mul_assign(&mut self, _rhs: &'a Scalar) {
311 *self = UnpackedScalar::mul(&self.unpack(), &_rhs.unpack()).pack();
312 }
313}
314
315define_mul_assign_variants!(LHS = Scalar, RHS = Scalar);
316
317impl<'a> Mul<&'a Scalar> for &Scalar {
318 type Output = Scalar;
319 fn mul(self, _rhs: &'a Scalar) -> Scalar {
320 UnpackedScalar::mul(&self.unpack(), &_rhs.unpack()).pack()
321 }
322}
323
324define_mul_variants!(LHS = Scalar, RHS = Scalar, Output = Scalar);
325
326impl<'a> AddAssign<&'a Scalar> for Scalar {
327 fn add_assign(&mut self, _rhs: &'a Scalar) {
328 *self = *self + _rhs;
329 }
330}
331
332define_add_assign_variants!(LHS = Scalar, RHS = Scalar);
333
334impl<'a> Add<&'a Scalar> for &Scalar {
335 type Output = Scalar;
336 #[allow(non_snake_case)]
337 fn add(self, _rhs: &'a Scalar) -> Scalar {
338 UnpackedScalar::add(&self.unpack(), &_rhs.unpack()).pack()
341 }
342}
343
344define_add_variants!(LHS = Scalar, RHS = Scalar, Output = Scalar);
345
346impl<'a> SubAssign<&'a Scalar> for Scalar {
347 fn sub_assign(&mut self, _rhs: &'a Scalar) {
348 *self = *self - _rhs;
349 }
350}
351
352define_sub_assign_variants!(LHS = Scalar, RHS = Scalar);
353
354impl<'a> Sub<&'a Scalar> for &Scalar {
355 type Output = Scalar;
356 #[allow(non_snake_case)]
357 fn sub(self, rhs: &'a Scalar) -> Scalar {
358 UnpackedScalar::sub(&self.unpack(), &rhs.unpack()).pack()
361 }
362}
363
364define_sub_variants!(LHS = Scalar, RHS = Scalar, Output = Scalar);
365
366impl Neg for &Scalar {
367 type Output = Scalar;
368 #[allow(non_snake_case)]
369 fn neg(self) -> Scalar {
370 let self_R = UnpackedScalar::mul_internal(&self.unpack(), &constants::R);
371 let self_mod_l = UnpackedScalar::montgomery_reduce(&self_R);
372 UnpackedScalar::sub(&UnpackedScalar::ZERO, &self_mod_l).pack()
373 }
374}
375
376impl Neg for Scalar {
377 type Output = Scalar;
378 fn neg(self) -> Scalar {
379 -&self
380 }
381}
382
383impl ConditionallySelectable for Scalar {
384 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
385 let mut bytes = [0u8; 32];
386 #[allow(clippy::needless_range_loop)]
387 for i in 0..32 {
388 bytes[i] = u8::conditional_select(&a.bytes[i], &b.bytes[i], choice);
389 }
390 Scalar { bytes }
391 }
392}
393
394#[cfg(feature = "serde")]
395use serde::de::Visitor;
396#[cfg(feature = "serde")]
397use serde::{Deserialize, Deserializer, Serialize, Serializer};
398
399#[cfg(feature = "serde")]
400#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
401impl Serialize for Scalar {
402 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
403 where
404 S: Serializer,
405 {
406 use serde::ser::SerializeTuple;
407 let mut tup = serializer.serialize_tuple(32)?;
408 for byte in self.as_bytes().iter() {
409 tup.serialize_element(byte)?;
410 }
411 tup.end()
412 }
413}
414
415#[cfg(feature = "serde")]
416#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
417impl<'de> Deserialize<'de> for Scalar {
418 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
419 where
420 D: Deserializer<'de>,
421 {
422 struct ScalarVisitor;
423
424 impl<'de> Visitor<'de> for ScalarVisitor {
425 type Value = Scalar;
426
427 fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
428 formatter.write_str(
429 "a sequence of 32 bytes whose little-endian interpretation is less than the \
430 basepoint order ℓ",
431 )
432 }
433
434 fn visit_seq<A>(self, mut seq: A) -> Result<Scalar, A::Error>
435 where
436 A: serde::de::SeqAccess<'de>,
437 {
438 let mut bytes = [0u8; 32];
439 #[allow(clippy::needless_range_loop)]
440 for i in 0..32 {
441 bytes[i] = seq
442 .next_element()?
443 .ok_or_else(|| serde::de::Error::invalid_length(i, &"expected 32 bytes"))?;
444 }
445 Option::from(Scalar::from_canonical_bytes(bytes))
446 .ok_or_else(|| serde::de::Error::custom("scalar was not canonically encoded"))
447 }
448 }
449
450 deserializer.deserialize_tuple(32, ScalarVisitor)
451 }
452}
453
454impl<T> Product<T> for Scalar
455where
456 T: Borrow<Scalar>,
457{
458 fn product<I>(iter: I) -> Self
459 where
460 I: Iterator<Item = T>,
461 {
462 iter.fold(Scalar::ONE, |acc, item| acc * item.borrow())
463 }
464}
465
466impl<T> Sum<T> for Scalar
467where
468 T: Borrow<Scalar>,
469{
470 fn sum<I>(iter: I) -> Self
471 where
472 I: Iterator<Item = T>,
473 {
474 iter.fold(Scalar::ZERO, |acc, item| acc + item.borrow())
475 }
476}
477
478impl Default for Scalar {
479 fn default() -> Scalar {
480 Scalar::ZERO
481 }
482}
483
484impl From<u8> for Scalar {
485 fn from(x: u8) -> Scalar {
486 let mut s_bytes = [0u8; 32];
487 s_bytes[0] = x;
488 Scalar { bytes: s_bytes }
489 }
490}
491
492impl From<u16> for Scalar {
493 fn from(x: u16) -> Scalar {
494 let mut s_bytes = [0u8; 32];
495 let x_bytes = x.to_le_bytes();
496 s_bytes[0..x_bytes.len()].copy_from_slice(&x_bytes);
497 Scalar { bytes: s_bytes }
498 }
499}
500
501impl From<u32> for Scalar {
502 fn from(x: u32) -> Scalar {
503 let mut s_bytes = [0u8; 32];
504 let x_bytes = x.to_le_bytes();
505 s_bytes[0..x_bytes.len()].copy_from_slice(&x_bytes);
506 Scalar { bytes: s_bytes }
507 }
508}
509
510impl From<u64> for Scalar {
511 fn from(x: u64) -> Scalar {
533 let mut s_bytes = [0u8; 32];
534 let x_bytes = x.to_le_bytes();
535 s_bytes[0..x_bytes.len()].copy_from_slice(&x_bytes);
536 Scalar { bytes: s_bytes }
537 }
538}
539
540impl From<u128> for Scalar {
541 fn from(x: u128) -> Scalar {
542 let mut s_bytes = [0u8; 32];
543 let x_bytes = x.to_le_bytes();
544 s_bytes[0..x_bytes.len()].copy_from_slice(&x_bytes);
545 Scalar { bytes: s_bytes }
546 }
547}
548
549#[cfg(feature = "zeroize")]
550impl Zeroize for Scalar {
551 fn zeroize(&mut self) {
552 self.bytes.zeroize();
553 }
554}
555
556impl Scalar {
557 pub const ZERO: Self = Self { bytes: [0u8; 32] };
559
560 pub const ONE: Self = Self {
562 bytes: [
563 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, 0,
564 0, 0, 0,
565 ],
566 };
567
568 #[cfg(feature = "rand_core")]
589 pub fn random<R: CryptoRng + ?Sized>(rng: &mut R) -> Self {
590 let mut scalar_bytes = [0u8; 64];
591 rng.fill_bytes(&mut scalar_bytes);
592 Scalar::from_bytes_mod_order_wide(&scalar_bytes)
593 }
594
595 #[cfg(feature = "digest")]
596 #[cfg_attr(feature = "digest", doc = "```")]
606 #[cfg_attr(not(feature = "digest"), doc = "```ignore")]
607 pub fn hash_from_bytes<D>(input: &[u8]) -> Scalar
618 where
619 D: Digest<OutputSize = U64> + Default,
620 {
621 let mut hash = D::default();
622 hash.update(input);
623 Scalar::from_hash(hash)
624 }
625
626 #[cfg(feature = "digest")]
627 pub fn from_hash<D>(hash: D) -> Scalar
664 where
665 D: Digest<OutputSize = U64>,
666 {
667 let mut output = [0u8; 64];
668 output.copy_from_slice(hash.finalize().as_slice());
669 Scalar::from_bytes_mod_order_wide(&output)
670 }
671
672 pub const fn to_bytes(&self) -> [u8; 32] {
684 self.bytes
685 }
686
687 pub const fn as_bytes(&self) -> &[u8; 32] {
699 &self.bytes
700 }
701
702 pub fn invert(&self) -> Scalar {
740 self.unpack().invert().pack()
741 }
742
743 pub fn invert_batch<const N: usize>(inputs: &mut [Scalar; N]) -> Scalar {
780 let one: UnpackedScalar = Scalar::ONE.unpack().as_montgomery();
781
782 let mut scratch = [one; N];
783
784 Self::invert_batch_internal(inputs, &mut scratch)
785 }
786
787 #[cfg(feature = "alloc")]
802 pub fn invert_batch_alloc(inputs: &mut [Scalar]) -> Scalar {
803 let n = inputs.len();
804 let one: UnpackedScalar = Scalar::ONE.unpack().as_montgomery();
805
806 let mut scratch = vec![one; n];
807
808 Self::invert_batch_internal(inputs, &mut scratch)
809 }
810
811 fn invert_batch_internal(inputs: &mut [Scalar], scratch: &mut [UnpackedScalar]) -> Scalar {
812 let mut acc = Scalar::ONE.unpack().as_montgomery();
821
822 for (input, scratch) in inputs.iter_mut().zip(scratch.iter_mut()) {
825 *scratch = acc;
826
827 let tmp = input.unpack().as_montgomery();
830 *input = tmp.pack();
831 acc = UnpackedScalar::montgomery_mul(&acc, &tmp);
832 }
833
834 debug_assert!(acc.pack() != Scalar::ZERO);
836
837 acc = acc.montgomery_invert().from_montgomery();
839
840 let ret = acc.pack();
842
843 for (input, scratch) in inputs.iter_mut().rev().zip(scratch.iter().rev()) {
846 let tmp = UnpackedScalar::montgomery_mul(&acc, &input.unpack());
847 *input = UnpackedScalar::montgomery_mul(&acc, scratch).pack();
848 acc = tmp;
849 }
850
851 #[cfg(feature = "zeroize")]
852 Zeroize::zeroize(&mut scratch.iter_mut());
853
854 ret
855 }
856
857 pub fn div_by_2(&self) -> Self {
859 let is_odd = Choice::from(self.as_bytes()[0] & 1);
864 let mut scalar = self.unpack();
865 scalar.conditional_add_l(is_odd);
866
867 let carry = scalar.shr1_assign();
868 debug_assert_eq!(carry, 0);
869
870 scalar.pack()
871 }
872
873 pub(crate) fn bits_le(&self) -> impl DoubleEndedIterator<Item = bool> + '_ {
875 (0..256).map(|i| {
876 ((self.bytes[i >> 3] >> (i & 7)) & 1u8) == 1
880 })
881 }
882
883 pub(crate) fn non_adjacent_form(&self, w: usize) -> [i8; 256] {
956 debug_assert!(w >= 2);
958 debug_assert!(w <= 8);
960
961 let mut naf = [0i8; 256];
962
963 let mut x_u64 = [0u64; 5];
964 read_le_u64_into(&self.bytes, &mut x_u64[0..4]);
965
966 let width = 1 << w;
967 let window_mask = width - 1;
968
969 let mut pos = 0;
970 let mut carry = 0;
971 while pos < 256 {
972 let u64_idx = pos / 64;
974 let bit_idx = pos % 64;
975 let bit_buf: u64 = if bit_idx < 64 - w {
976 x_u64[u64_idx] >> bit_idx
978 } else {
979 (x_u64[u64_idx] >> bit_idx) | (x_u64[1 + u64_idx] << (64 - bit_idx))
981 };
982
983 let window = carry + (bit_buf & window_mask);
985
986 if window & 1 == 0 {
987 pos += 1;
992 continue;
993 }
994
995 if window < width / 2 {
996 carry = 0;
997 naf[pos] = window as i8;
998 } else {
999 carry = 1;
1000 naf[pos] = (window as i8).wrapping_sub(width as i8);
1001 }
1002
1003 pos += w;
1004 }
1005
1006 naf
1007 }
1008
1009 pub(crate) fn as_radix_16(&self) -> [i8; 64] {
1020 debug_assert!(self[31] <= 127);
1021 let mut output = [0i8; 64];
1022
1023 #[allow(clippy::identity_op)]
1026 #[inline(always)]
1027 fn bot_half(x: u8) -> u8 {
1028 (x >> 0) & 15
1029 }
1030 #[inline(always)]
1031 fn top_half(x: u8) -> u8 {
1032 (x >> 4) & 15
1033 }
1034
1035 for i in 0..32 {
1036 output[2 * i] = bot_half(self[i]) as i8;
1037 output[2 * i + 1] = top_half(self[i]) as i8;
1038 }
1039 for i in 0..63 {
1043 let carry = (output[i] + 8) >> 4;
1044 output[i] -= carry << 4;
1045 output[i + 1] += carry;
1046 }
1047 output
1051 }
1052
1053 #[cfg(any(feature = "alloc", all(test, feature = "precomputed-tables")))]
1056 pub(crate) fn to_radix_2w_size_hint(w: usize) -> usize {
1057 debug_assert!(w >= 4);
1058 debug_assert!(w <= 8);
1059
1060 let digits_count = match w {
1061 4..=7 => 256_usize.div_ceil(w),
1062 8 => 256_usize.div_ceil(w) + 1_usize,
1064 _ => panic!("invalid radix parameter"),
1065 };
1066
1067 debug_assert!(digits_count <= 64);
1068 digits_count
1069 }
1070
1071 #[cfg(any(feature = "alloc", feature = "precomputed-tables"))]
1093 pub(crate) fn as_radix_2w(&self, w: usize) -> [i8; 64] {
1094 debug_assert!(w >= 4);
1095 debug_assert!(w <= 8);
1096
1097 if w == 4 {
1098 return self.as_radix_16();
1099 }
1100
1101 let mut scalar64x4 = [0u64; 4];
1103 read_le_u64_into(&self.bytes, &mut scalar64x4[0..4]);
1104
1105 let radix: u64 = 1 << w;
1106 let window_mask: u64 = radix - 1;
1107
1108 let mut carry = 0u64;
1109 let mut digits = [0i8; 64];
1110 let digits_count = 256_usize.div_ceil(w);
1111 #[allow(clippy::needless_range_loop)]
1112 for i in 0..digits_count {
1113 let bit_offset = i * w;
1115 let u64_idx = bit_offset / 64;
1116 let bit_idx = bit_offset % 64;
1117
1118 let bit_buf: u64 = if bit_idx < 64 - w || u64_idx == 3 {
1120 scalar64x4[u64_idx] >> bit_idx
1123 } else {
1124 (scalar64x4[u64_idx] >> bit_idx) | (scalar64x4[1 + u64_idx] << (64 - bit_idx))
1126 };
1127
1128 let coef = carry + (bit_buf & window_mask); carry = (coef + (radix / 2)) >> w;
1133 digits[i] = ((coef as i64) - (carry << w) as i64) as i8;
1134 }
1135
1136 match w {
1145 8 => digits[digits_count] += carry as i8,
1146 _ => digits[digits_count - 1] += (carry << w) as i8,
1147 }
1148
1149 digits
1150 }
1151
1152 pub(crate) fn unpack(&self) -> UnpackedScalar {
1154 UnpackedScalar::from_bytes(&self.bytes)
1155 }
1156
1157 #[allow(non_snake_case)]
1159 fn reduce(&self) -> Scalar {
1160 let x = self.unpack();
1161 let xR = UnpackedScalar::mul_internal(&x, &constants::R);
1162 let x_mod_l = UnpackedScalar::montgomery_reduce(&xR);
1163 x_mod_l.pack()
1164 }
1165
1166 fn is_canonical(&self) -> Choice {
1169 self.ct_eq(&self.reduce())
1170 }
1171}
1172
1173impl UnpackedScalar {
1174 fn pack(&self) -> Scalar {
1176 Scalar {
1177 bytes: self.to_bytes(),
1178 }
1179 }
1180
1181 #[rustfmt::skip] #[allow(clippy::just_underscores_and_digits)]
1184 pub fn montgomery_invert(&self) -> UnpackedScalar {
1185 let _1 = *self;
1188 let _10 = _1.montgomery_square();
1189 let _100 = _10.montgomery_square();
1190 let _11 = UnpackedScalar::montgomery_mul(&_10, &_1);
1191 let _101 = UnpackedScalar::montgomery_mul(&_10, &_11);
1192 let _111 = UnpackedScalar::montgomery_mul(&_10, &_101);
1193 let _1001 = UnpackedScalar::montgomery_mul(&_10, &_111);
1194 let _1011 = UnpackedScalar::montgomery_mul(&_10, &_1001);
1195 let _1111 = UnpackedScalar::montgomery_mul(&_100, &_1011);
1196
1197 let mut y = UnpackedScalar::montgomery_mul(&_1111, &_1);
1199
1200 #[inline]
1201 fn square_multiply(y: &mut UnpackedScalar, squarings: usize, x: &UnpackedScalar) {
1202 for _ in 0..squarings {
1203 *y = y.montgomery_square();
1204 }
1205 *y = UnpackedScalar::montgomery_mul(y, x);
1206 }
1207
1208 square_multiply(&mut y, 123 + 3, &_101);
1209 square_multiply(&mut y, 2 + 2, &_11);
1210 square_multiply(&mut y, 1 + 4, &_1111);
1211 square_multiply(&mut y, 1 + 4, &_1111);
1212 square_multiply(&mut y, 4, &_1001);
1213 square_multiply(&mut y, 2, &_11);
1214 square_multiply(&mut y, 1 + 4, &_1111);
1215 square_multiply(&mut y, 1 + 3, &_101);
1216 square_multiply(&mut y, 3 + 3, &_101);
1217 square_multiply(&mut y, 3, &_111);
1218 square_multiply(&mut y, 1 + 4, &_1111);
1219 square_multiply(&mut y, 2 + 3, &_111);
1220 square_multiply(&mut y, 2 + 2, &_11);
1221 square_multiply(&mut y, 1 + 4, &_1011);
1222 square_multiply(&mut y, 2 + 4, &_1011);
1223 square_multiply(&mut y, 6 + 4, &_1001);
1224 square_multiply(&mut y, 2 + 2, &_11);
1225 square_multiply(&mut y, 3 + 2, &_11);
1226 square_multiply(&mut y, 3 + 2, &_11);
1227 square_multiply(&mut y, 1 + 4, &_1001);
1228 square_multiply(&mut y, 1 + 3, &_111);
1229 square_multiply(&mut y, 2 + 4, &_1111);
1230 square_multiply(&mut y, 1 + 4, &_1011);
1231 square_multiply(&mut y, 3, &_101);
1232 square_multiply(&mut y, 2 + 4, &_1111);
1233 square_multiply(&mut y, 3, &_101);
1234 square_multiply(&mut y, 1 + 2, &_11);
1235
1236 y
1237 }
1238
1239 pub fn invert(&self) -> UnpackedScalar {
1241 self.as_montgomery().montgomery_invert().from_montgomery()
1242 }
1243}
1244
1245#[cfg(feature = "group")]
1246impl Field for Scalar {
1247 const ZERO: Self = Self::ZERO;
1248 const ONE: Self = Self::ONE;
1249
1250 fn try_random<R: TryRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
1251 let mut scalar_bytes = [0u8; 64];
1253 rng.try_fill_bytes(&mut scalar_bytes)?;
1254 Ok(Self::from_bytes_mod_order_wide(&scalar_bytes))
1255 }
1256
1257 fn square(&self) -> Self {
1258 self * self
1259 }
1260
1261 fn double(&self) -> Self {
1262 self + self
1263 }
1264
1265 fn invert(&self) -> CtOption<Self> {
1266 CtOption::new(self.invert(), !self.is_zero())
1267 }
1268
1269 fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self) {
1270 #[allow(unused_qualifications)]
1271 group::ff::helpers::sqrt_ratio_generic(num, div)
1272 }
1273
1274 fn sqrt(&self) -> CtOption<Self> {
1275 #[allow(unused_qualifications)]
1276 group::ff::helpers::sqrt_tonelli_shanks(
1277 self,
1278 [
1279 0xcb02_4c63_4b9e_ba7d,
1280 0x029b_df3b_d45e_f39a,
1281 0x0000_0000_0000_0000,
1282 0x0200_0000_0000_0000,
1283 ],
1284 )
1285 }
1286}
1287
1288#[cfg(feature = "group")]
1289impl PrimeField for Scalar {
1290 type Repr = [u8; 32];
1291
1292 fn from_repr(repr: Self::Repr) -> CtOption<Self> {
1293 Self::from_canonical_bytes(repr)
1294 }
1295
1296 fn from_repr_vartime(repr: Self::Repr) -> Option<Self> {
1297 if (repr[31] >> 7) != 0u8 {
1299 return None;
1300 }
1301
1302 let candidate = Scalar { bytes: repr };
1303
1304 if candidate == candidate.reduce() {
1305 Some(candidate)
1306 } else {
1307 None
1308 }
1309 }
1310
1311 fn to_repr(&self) -> Self::Repr {
1312 self.to_bytes()
1313 }
1314
1315 fn is_odd(&self) -> Choice {
1316 Choice::from(self.as_bytes()[0] & 1)
1317 }
1318
1319 const MODULUS: &'static str =
1320 "0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed";
1321 const NUM_BITS: u32 = 253;
1322 const CAPACITY: u32 = 252;
1323
1324 const TWO_INV: Self = Self {
1325 bytes: [
1326 0xf7, 0xe9, 0x7a, 0x2e, 0x8d, 0x31, 0x09, 0x2c, 0x6b, 0xce, 0x7b, 0x51, 0xef, 0x7c,
1327 0x6f, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1328 0x00, 0x00, 0x00, 0x08,
1329 ],
1330 };
1331 const MULTIPLICATIVE_GENERATOR: Self = Self {
1332 bytes: [
1333 2, 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,
1334 0, 0, 0,
1335 ],
1336 };
1337 const S: u32 = 2;
1338 const ROOT_OF_UNITY: Self = Self {
1339 bytes: [
1340 0xd4, 0x07, 0xbe, 0xeb, 0xdf, 0x75, 0x87, 0xbe, 0xfe, 0x83, 0xce, 0x42, 0x53, 0x56,
1341 0xf0, 0x0e, 0x7a, 0xc2, 0xc1, 0xab, 0x60, 0x6d, 0x3d, 0x7d, 0xe7, 0x81, 0x79, 0xe0,
1342 0x10, 0x73, 0x4a, 0x09,
1343 ],
1344 };
1345 const ROOT_OF_UNITY_INV: Self = Self {
1346 bytes: [
1347 0x19, 0xcc, 0x37, 0x71, 0x3a, 0xed, 0x8a, 0x99, 0xd7, 0x18, 0x29, 0x60, 0x8b, 0xa3,
1348 0xee, 0x05, 0x86, 0x3d, 0x3e, 0x54, 0x9f, 0x92, 0xc2, 0x82, 0x18, 0x7e, 0x86, 0x1f,
1349 0xef, 0x8c, 0xb5, 0x06,
1350 ],
1351 };
1352 const DELTA: Self = Self {
1353 bytes: [
1354 16, 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,
1355 0, 0, 0,
1356 ],
1357 };
1358}
1359
1360#[cfg(feature = "group")]
1361impl FromUniformBytes<64> for Scalar {
1362 fn from_uniform_bytes(bytes: &[u8; 64]) -> Self {
1363 Scalar::from_bytes_mod_order_wide(bytes)
1364 }
1365}
1366
1367fn read_le_u64_into(src: &[u8], dst: &mut [u64]) {
1372 assert!(
1373 src.len() == 8 * dst.len(),
1374 "src.len() = {}, dst.len() = {}",
1375 src.len(),
1376 dst.len()
1377 );
1378 for (bytes, val) in src.chunks(8).zip(dst.iter_mut()) {
1379 *val = u64::from_le_bytes(
1380 bytes
1381 .try_into()
1382 .expect("Incorrect src length, should be 8 * dst.len()"),
1383 );
1384 }
1385}
1386
1387#[must_use]
1407pub const fn clamp_integer(mut bytes: [u8; 32]) -> [u8; 32] {
1408 bytes[0] &= 0b1111_1000;
1409 bytes[31] &= 0b0111_1111;
1410 bytes[31] |= 0b0100_0000;
1411 bytes
1412}
1413
1414#[cfg(test)]
1415pub(crate) mod test {
1416 use super::*;
1417 use getrandom::{
1418 SysRng,
1419 rand_core::{Rng, UnwrapErr},
1420 };
1421
1422 #[cfg(feature = "alloc")]
1423 use alloc::vec::Vec;
1424
1425 pub static X: Scalar = Scalar {
1427 bytes: [
1428 0x4e, 0x5a, 0xb4, 0x34, 0x5d, 0x47, 0x08, 0x84, 0x59, 0x13, 0xb4, 0x64, 0x1b, 0xc2,
1429 0x7d, 0x52, 0x52, 0xa5, 0x85, 0x10, 0x1b, 0xcc, 0x42, 0x44, 0xd4, 0x49, 0xf4, 0xa8,
1430 0x79, 0xd9, 0xf2, 0x04,
1431 ],
1432 };
1433 pub static XINV: Scalar = Scalar {
1435 bytes: [
1436 0x1c, 0xdc, 0x17, 0xfc, 0xe0, 0xe9, 0xa5, 0xbb, 0xd9, 0x24, 0x7e, 0x56, 0xbb, 0x01,
1437 0x63, 0x47, 0xbb, 0xba, 0x31, 0xed, 0xd5, 0xa9, 0xbb, 0x96, 0xd5, 0x0b, 0xcd, 0x7a,
1438 0x3f, 0x96, 0x2a, 0x0f,
1439 ],
1440 };
1441 pub static Y: Scalar = Scalar {
1443 bytes: [
1444 0x90, 0x76, 0x33, 0xfe, 0x1c, 0x4b, 0x66, 0xa4, 0xa2, 0x8d, 0x2d, 0xd7, 0x67, 0x83,
1445 0x86, 0xc3, 0x53, 0xd0, 0xde, 0x54, 0x55, 0xd4, 0xfc, 0x9d, 0xe8, 0xef, 0x7a, 0xc3,
1446 0x1f, 0x35, 0xbb, 0x05,
1447 ],
1448 };
1449
1450 pub(crate) static LARGEST_UNREDUCED_SCALAR: Scalar = Scalar {
1456 bytes: [
1457 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1458 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1459 0xff, 0xff, 0xff, 0x7f,
1460 ],
1461 };
1462
1463 static X_TIMES_Y: Scalar = Scalar {
1465 bytes: [
1466 0x6c, 0x33, 0x74, 0xa1, 0x89, 0x4f, 0x62, 0x21, 0x0a, 0xaa, 0x2f, 0xe1, 0x86, 0xa6,
1467 0xf9, 0x2c, 0xe0, 0xaa, 0x75, 0xc2, 0x77, 0x95, 0x81, 0xc2, 0x95, 0xfc, 0x08, 0x17,
1468 0x9a, 0x73, 0x94, 0x0c,
1469 ],
1470 };
1471
1472 static CANONICAL_2_256_MINUS_1: Scalar = Scalar {
1476 bytes: [
1477 28, 149, 152, 141, 116, 49, 236, 214, 112, 207, 125, 115, 244, 91, 239, 198, 254, 255,
1478 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 15,
1479 ],
1480 };
1481
1482 static A_SCALAR: Scalar = Scalar {
1483 bytes: [
1484 0x1a, 0x0e, 0x97, 0x8a, 0x90, 0xf6, 0x62, 0x2d, 0x37, 0x47, 0x02, 0x3f, 0x8a, 0xd8,
1485 0x26, 0x4d, 0xa7, 0x58, 0xaa, 0x1b, 0x88, 0xe0, 0x40, 0xd1, 0x58, 0x9e, 0x7b, 0x7f,
1486 0x23, 0x76, 0xef, 0x09,
1487 ],
1488 };
1489
1490 static A_NAF: [i8; 256] = [
1491 0, 13, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, -9, 0, 0, 0, 0, -11, 0, 0, 0, 0, 3, 0, 0,
1492 0, 0, 1, 0, 0, 0, 0, 9, 0, 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 11, 0, 0, 0, 0,
1493 11, 0, 0, 0, 0, 0, -9, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1494 0, -1, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, -15, 0, 0, 0, 0, -7, 0, 0, 0, 0, -9, 0, 0, 0, 0, 0, 5,
1495 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, -11, 0, 0, 0, 0, -7, 0, 0, 0, 0, -13, 0, 0,
1496 0, 0, 11, 0, 0, 0, 0, -9, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -15, 0, 0, 0, 0, 1, 0, 0, 0, 0,
1497 7, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 15,
1498 0, 0, 0, 0, 0, -9, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, -15, 0,
1499 0, 0, 0, 0, 15, 0, 0, 0, 0, 15, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
1500 ];
1501
1502 const BASEPOINT_ORDER_MINUS_ONE: Scalar = Scalar {
1503 bytes: [
1504 0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9,
1505 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1506 0x00, 0x00, 0x00, 0x10,
1507 ],
1508 };
1509
1510 static LARGEST_CLAMPED_INTEGER: [u8; 32] = clamp_integer(LARGEST_UNREDUCED_SCALAR.bytes);
1512
1513 #[test]
1514 fn fuzzer_testcase_reduction() {
1515 let a_bytes = [
1517 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1518 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1519 ];
1520 let b_bytes = [
1522 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 210, 210,
1523 210, 255, 255, 255, 255, 10,
1524 ];
1525 let c_bytes = [
1527 134, 171, 119, 216, 180, 128, 178, 62, 171, 132, 32, 62, 34, 119, 104, 193, 47, 215,
1528 181, 250, 14, 207, 172, 93, 75, 207, 211, 103, 144, 204, 56, 14,
1529 ];
1530
1531 let a = Scalar::from_bytes_mod_order(a_bytes);
1532 let b = Scalar::from_bytes_mod_order(b_bytes);
1533 let c = Scalar::from_bytes_mod_order(c_bytes);
1534
1535 let mut tmp = [0u8; 64];
1536
1537 tmp[0..32].copy_from_slice(&a_bytes[..]);
1539 let also_a = Scalar::from_bytes_mod_order_wide(&tmp);
1540
1541 tmp[0..32].copy_from_slice(&b_bytes[..]);
1543 let also_b = Scalar::from_bytes_mod_order_wide(&tmp);
1544
1545 let expected_c = a * b;
1546 let also_expected_c = also_a * also_b;
1547
1548 assert_eq!(c, expected_c);
1549 assert_eq!(c, also_expected_c);
1550 }
1551
1552 #[test]
1553 fn non_adjacent_form_test_vector() {
1554 let naf = A_SCALAR.non_adjacent_form(5);
1555 for i in 0..256 {
1556 assert_eq!(naf[i], A_NAF[i]);
1557 }
1558 }
1559
1560 #[cfg(feature = "rand_core")]
1561 fn non_adjacent_form_iter(w: usize, x: &Scalar) {
1562 let naf = x.non_adjacent_form(w);
1563
1564 let mut y = Scalar::ZERO;
1566 for i in (0..256).rev() {
1567 y += y;
1568 let digit = if naf[i] < 0 {
1569 -Scalar::from((-naf[i]) as u64)
1570 } else {
1571 Scalar::from(naf[i] as u64)
1572 };
1573 y += digit;
1574 }
1575
1576 assert_eq!(*x, y);
1577 }
1578
1579 #[cfg(feature = "rand_core")]
1580 #[test]
1581 fn non_adjacent_form_random() {
1582 let mut rng = UnwrapErr(SysRng);
1583 for _ in 0..1_000 {
1584 let x = Scalar::random(&mut rng);
1585 for w in &[5, 6, 7, 8] {
1586 non_adjacent_form_iter(*w, &x);
1587 }
1588 }
1589 }
1590
1591 #[test]
1592 fn from_u64() {
1593 let val: u64 = 0xdeadbeefdeadbeef;
1594 let s = Scalar::from(val);
1595 assert_eq!(s[7], 0xde);
1596 assert_eq!(s[6], 0xad);
1597 assert_eq!(s[5], 0xbe);
1598 assert_eq!(s[4], 0xef);
1599 assert_eq!(s[3], 0xde);
1600 assert_eq!(s[2], 0xad);
1601 assert_eq!(s[1], 0xbe);
1602 assert_eq!(s[0], 0xef);
1603 }
1604
1605 #[test]
1606 fn scalar_mul_by_one() {
1607 let test_scalar = X * Scalar::ONE;
1608 for i in 0..32 {
1609 assert!(test_scalar[i] == X[i]);
1610 }
1611 }
1612
1613 #[test]
1614 fn add_reduces() {
1615 assert_eq!(BASEPOINT_ORDER_MINUS_ONE + Scalar::ONE, Scalar::ZERO);
1617 }
1618
1619 #[test]
1620 fn sub_reduces() {
1621 assert_eq!(Scalar::ZERO - Scalar::ONE, BASEPOINT_ORDER_MINUS_ONE);
1623 }
1624
1625 #[test]
1626 fn impl_add() {
1627 let two = Scalar::from(2u64);
1628 let one = Scalar::ONE;
1629 let should_be_two = one + one;
1630 assert_eq!(should_be_two, two);
1631 }
1632
1633 #[allow(non_snake_case)]
1634 #[test]
1635 fn impl_mul() {
1636 let should_be_X_times_Y = X * Y;
1637 assert_eq!(should_be_X_times_Y, X_TIMES_Y);
1638 }
1639
1640 #[allow(non_snake_case)]
1641 #[test]
1642 #[cfg(feature = "alloc")]
1643 fn impl_product() {
1644 let X_Y_vector = [X, Y];
1646 let should_be_X_times_Y: Scalar = X_Y_vector.iter().product();
1647 assert_eq!(should_be_X_times_Y, X_TIMES_Y);
1648
1649 let one = Scalar::ONE;
1651 let empty_vector = [];
1652 let should_be_one: Scalar = empty_vector.iter().product();
1653 assert_eq!(should_be_one, one);
1654
1655 let xs = [Scalar::from(2u64); 10];
1657 let ys = [Scalar::from(3u64); 10];
1658 let zs = xs.iter().zip(ys.iter()).map(|(x, y)| x * y);
1660
1661 let x_prod: Scalar = xs.iter().product();
1662 let y_prod: Scalar = ys.iter().product();
1663 let z_prod: Scalar = zs.product();
1664
1665 assert_eq!(x_prod, Scalar::from(1024u64));
1666 assert_eq!(y_prod, Scalar::from(59049u64));
1667 assert_eq!(z_prod, Scalar::from(60466176u64));
1668 assert_eq!(x_prod * y_prod, z_prod);
1669 }
1670
1671 #[test]
1672 #[cfg(feature = "alloc")]
1673 fn impl_sum() {
1674 let two = Scalar::from(2u64);
1676 let one_vector = [Scalar::ONE, Scalar::ONE];
1677 let should_be_two: Scalar = one_vector.iter().sum();
1678 assert_eq!(should_be_two, two);
1679
1680 let zero = Scalar::ZERO;
1682 let empty_vector = [];
1683 let should_be_zero: Scalar = empty_vector.iter().sum();
1684 assert_eq!(should_be_zero, zero);
1685
1686 let xs = [Scalar::from(1u64); 10];
1688 let ys = [Scalar::from(2u64); 10];
1689 let zs = xs.iter().zip(ys.iter()).map(|(x, y)| x + y);
1691
1692 let x_sum: Scalar = xs.iter().sum();
1693 let y_sum: Scalar = ys.iter().sum();
1694 let z_sum: Scalar = zs.sum();
1695
1696 assert_eq!(x_sum, Scalar::from(10u64));
1697 assert_eq!(y_sum, Scalar::from(20u64));
1698 assert_eq!(z_sum, Scalar::from(30u64));
1699 assert_eq!(x_sum + y_sum, z_sum);
1700 }
1701
1702 #[test]
1703 fn square() {
1704 let expected = X * X;
1705 let actual = X.unpack().square().pack();
1706 for i in 0..32 {
1707 assert!(expected[i] == actual[i]);
1708 }
1709 }
1710
1711 #[test]
1712 fn div_by_2() {
1713 for i in 0u64..32 {
1715 let scalar = Scalar::from(i);
1716 let dividend = scalar.div_by_2();
1717 assert_eq!(scalar, dividend + dividend);
1718 }
1719
1720 for i in 0u64..32 {
1722 let scalar = Scalar::ZERO - Scalar::from(i);
1723 let dividend = scalar.div_by_2();
1724 assert_eq!(scalar, dividend + dividend);
1725 }
1726 }
1727
1728 #[test]
1729 fn reduce() {
1730 let biggest = Scalar::from_bytes_mod_order([0xff; 32]);
1731 assert_eq!(biggest, CANONICAL_2_256_MINUS_1);
1732 }
1733
1734 #[test]
1735 fn from_bytes_mod_order_wide() {
1736 let mut bignum = [0u8; 64];
1737 for i in 0..32 {
1739 bignum[i] = X[i];
1740 bignum[32 + i] = X[i];
1741 }
1742 let reduced = Scalar {
1745 bytes: [
1746 216, 154, 179, 139, 210, 121, 2, 71, 69, 99, 158, 216, 23, 173, 63, 100, 204, 0,
1747 91, 50, 219, 153, 57, 249, 28, 82, 31, 197, 100, 165, 192, 8,
1748 ],
1749 };
1750 let test_red = Scalar::from_bytes_mod_order_wide(&bignum);
1751 for i in 0..32 {
1752 assert!(test_red[i] == reduced[i]);
1753 }
1754 }
1755
1756 #[allow(non_snake_case)]
1757 #[test]
1758 fn invert() {
1759 let inv_X = X.invert();
1760 assert_eq!(inv_X, XINV);
1761 let should_be_one = inv_X * X;
1762 assert_eq!(should_be_one, Scalar::ONE);
1763 }
1764
1765 #[allow(non_snake_case)]
1767 #[test]
1768 fn neg_twice_is_identity() {
1769 let negative_X = -&X;
1770 let should_be_X = -&negative_X;
1771
1772 assert_eq!(should_be_X, X);
1773 }
1774
1775 #[test]
1776 fn to_bytes_from_bytes_roundtrips() {
1777 let unpacked = X.unpack();
1778 let bytes = unpacked.to_bytes();
1779 let should_be_unpacked = UnpackedScalar::from_bytes(&bytes);
1780
1781 assert_eq!(should_be_unpacked.0, unpacked.0);
1782 }
1783
1784 #[test]
1785 fn montgomery_reduce_matches_from_bytes_mod_order_wide() {
1786 let mut bignum = [0u8; 64];
1787
1788 for i in 0..32 {
1790 bignum[i] = X[i];
1791 bignum[32 + i] = X[i];
1792 }
1793 let expected = Scalar {
1796 bytes: [
1797 216, 154, 179, 139, 210, 121, 2, 71, 69, 99, 158, 216, 23, 173, 63, 100, 204, 0,
1798 91, 50, 219, 153, 57, 249, 28, 82, 31, 197, 100, 165, 192, 8,
1799 ],
1800 };
1801 let reduced = Scalar::from_bytes_mod_order_wide(&bignum);
1802
1803 assert_eq!(reduced.bytes, expected.bytes);
1805
1806 let interim =
1808 UnpackedScalar::mul_internal(&UnpackedScalar::from_bytes_wide(&bignum), &constants::R);
1809 let montgomery_reduced = UnpackedScalar::montgomery_reduce(&interim);
1811
1812 assert_eq!(montgomery_reduced.0, reduced.unpack().0);
1814 assert_eq!(montgomery_reduced.0, expected.unpack().0)
1815 }
1816
1817 #[test]
1818 fn canonical_decoding() {
1819 let canonical_bytes = [
1821 99, 99, 99, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1822 0, 0, 0, 0,
1823 ];
1824
1825 let non_canonical_bytes_because_unreduced = [16; 32];
1830
1831 let non_canonical_bytes_because_highbit = [
1833 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, 0,
1834 0, 0, 128,
1835 ];
1836
1837 assert!(bool::from(
1838 Scalar::from_canonical_bytes(canonical_bytes).is_some()
1839 ));
1840 assert!(bool::from(
1841 Scalar::from_canonical_bytes(non_canonical_bytes_because_unreduced).is_none()
1842 ));
1843 assert!(bool::from(
1844 Scalar::from_canonical_bytes(non_canonical_bytes_because_highbit).is_none()
1845 ));
1846 }
1847
1848 #[test]
1849 #[cfg(feature = "serde")]
1850 fn serde_postcard_scalar_roundtrip() {
1851 let encoded = postcard::to_allocvec(&X).unwrap();
1852 let parsed: Scalar = postcard::from_bytes(&encoded).unwrap();
1853 assert_eq!(parsed, X);
1854
1855 assert_eq!(encoded.len(), 32);
1857
1858 assert_eq!(X, postcard::from_bytes(X.as_bytes()).unwrap(),);
1862 }
1863
1864 #[cfg(debug_assertions)]
1865 #[test]
1866 #[should_panic]
1867 fn invert_batch_with_a_zero_input_panics() {
1868 let mut xs = [Scalar::ONE; 16];
1869 xs[3] = Scalar::ZERO;
1870 Scalar::invert_batch(&mut xs);
1872 }
1873
1874 #[test]
1875 fn invert_batch_empty() {
1876 assert_eq!(Scalar::ONE, Scalar::invert_batch(&mut []));
1877 }
1878
1879 #[test]
1880 fn invert_batch_consistency() {
1881 let mut x = Scalar::from(1u64);
1882 let mut v1: [Scalar; 16] = core::array::from_fn(|_| {
1883 let tmp = x;
1884 x = x + x;
1885 tmp
1886 });
1887 let v2 = v1;
1888
1889 let expected: Scalar = v1.iter().product();
1890 let expected = expected.invert();
1891 let ret = Scalar::invert_batch(&mut v1);
1892 assert_eq!(ret, expected);
1893
1894 for (a, b) in v1.iter().zip(v2.iter()) {
1895 assert_eq!(a * b, Scalar::ONE);
1896 }
1897 }
1898
1899 #[test]
1900 #[cfg(feature = "alloc")]
1901 fn batch_vec_invert_consistency() {
1902 let mut x = Scalar::from(1u64);
1903 let mut v1: Vec<_> = (0..16)
1904 .map(|_| {
1905 let tmp = x;
1906 x = x + x;
1907 tmp
1908 })
1909 .collect();
1910 let v2 = v1.clone();
1911
1912 let expected: Scalar = v1.iter().product();
1913 let expected = expected.invert();
1914 let ret = Scalar::invert_batch_alloc(&mut v1);
1915 assert_eq!(ret, expected);
1916
1917 for (a, b) in v1.iter().zip(v2.iter()) {
1918 assert_eq!(a * b, Scalar::ONE);
1919 }
1920 }
1921
1922 #[cfg(feature = "precomputed-tables")]
1923 fn test_pippenger_radix_iter(scalar: Scalar, w: usize) {
1924 let digits_count = Scalar::to_radix_2w_size_hint(w);
1925 let digits = scalar.as_radix_2w(w);
1926
1927 let radix = Scalar::from((1 << w) as u64);
1928 let mut term = Scalar::ONE;
1929 let mut recovered_scalar = Scalar::ZERO;
1930 for digit in &digits[0..digits_count] {
1931 let digit = *digit;
1932 if digit != 0 {
1933 let sdigit = if digit < 0 {
1934 -Scalar::from((-(digit as i64)) as u64)
1935 } else {
1936 Scalar::from(digit as u64)
1937 };
1938 recovered_scalar += term * sdigit;
1939 }
1940 term *= radix;
1941 }
1942 assert_eq!(recovered_scalar, scalar.reduce());
1944 }
1945
1946 #[test]
1947 #[cfg(feature = "precomputed-tables")]
1948 fn test_pippenger_radix() {
1949 use core::iter;
1950 let cases = (2..100)
1953 .map(|s| Scalar::from(s as u64).invert())
1954 .chain(iter::once(LARGEST_UNREDUCED_SCALAR));
1957
1958 for scalar in cases {
1959 test_pippenger_radix_iter(scalar, 6);
1960 test_pippenger_radix_iter(scalar, 7);
1961 test_pippenger_radix_iter(scalar, 8);
1962 }
1963 }
1964
1965 #[test]
1966 #[cfg(feature = "alloc")]
1967 fn test_read_le_u64_into() {
1968 let cases: &[(&[u8], &[u64])] = &[
1969 (
1970 &[0xFE, 0xEF, 0x10, 0x01, 0x1F, 0xF1, 0x0F, 0xF0],
1971 &[0xF00F_F11F_0110_EFFE],
1972 ),
1973 (
1974 &[
1975 0xFE, 0xEF, 0x10, 0x01, 0x1F, 0xF1, 0x0F, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A,
1976 0xBC, 0xDE, 0xF0,
1977 ],
1978 &[0xF00F_F11F_0110_EFFE, 0xF0DE_BC9A_7856_3412],
1979 ),
1980 ];
1981
1982 for (src, expected) in cases {
1983 let mut dst = vec![0; expected.len()];
1984 read_le_u64_into(src, &mut dst);
1985
1986 assert_eq!(&dst, expected, "Expected {:x?} got {:x?}", expected, dst);
1987 }
1988 }
1989
1990 #[test]
1992 fn test_scalar_from_int() {
1993 let s1 = Scalar::ONE;
1994
1995 let x = 0x23u8;
1999 let sx = Scalar::from(x);
2000 assert_eq!(sx + s1, Scalar::from(x + 1));
2001
2002 let x = 0x2323u16;
2003 let sx = Scalar::from(x);
2004 assert_eq!(sx + s1, Scalar::from(x + 1));
2005
2006 let x = 0x2323_2323u32;
2007 let sx = Scalar::from(x);
2008 assert_eq!(sx + s1, Scalar::from(x + 1));
2009
2010 let x = 0x2323_2323_2323_2323u64;
2011 let sx = Scalar::from(x);
2012 assert_eq!(sx + s1, Scalar::from(x + 1));
2013
2014 let x = 0x2323_2323_2323_2323_2323_2323_2323_2323u128;
2015 let sx = Scalar::from(x);
2016 assert_eq!(sx + s1, Scalar::from(x + 1));
2017 }
2018
2019 #[cfg(feature = "group")]
2020 #[test]
2021 fn ff_constants() {
2022 assert_eq!(Scalar::from(2u64) * Scalar::TWO_INV, Scalar::ONE);
2023
2024 assert_eq!(
2025 Scalar::ROOT_OF_UNITY * Scalar::ROOT_OF_UNITY_INV,
2026 Scalar::ONE,
2027 );
2028
2029 assert_eq!(
2031 Scalar::ROOT_OF_UNITY.pow(&[1u64 << Scalar::S, 0, 0, 0]),
2032 Scalar::ONE,
2033 );
2034
2035 assert_eq!(
2037 Scalar::DELTA.pow(&[
2038 0x9604_98c6_973d_74fb,
2039 0x0537_be77_a8bd_e735,
2040 0x0000_0000_0000_0000,
2041 0x0400_0000_0000_0000,
2042 ]),
2043 Scalar::ONE,
2044 );
2045 }
2046
2047 #[cfg(feature = "group")]
2048 #[test]
2049 fn ff_impls() {
2050 assert!(bool::from(Scalar::ZERO.is_even()));
2051 assert!(bool::from(Scalar::ONE.is_odd()));
2052 assert!(bool::from(Scalar::from(2u64).is_even()));
2053 assert!(bool::from(Scalar::DELTA.is_even()));
2054
2055 assert!(bool::from(Field::invert(&Scalar::ZERO).is_none()));
2056 assert_eq!(Field::invert(&X).unwrap(), XINV);
2057
2058 let x_sq = X.square();
2059 assert!([X, -X].contains(&x_sq.sqrt().unwrap()));
2061
2062 assert_eq!(Scalar::from_repr_vartime(X.to_repr()), Some(X));
2063 assert_eq!(Scalar::from_repr_vartime([0xff; 32]), None);
2064
2065 assert_eq!(Scalar::from_repr(X.to_repr()).unwrap(), X);
2066 assert!(bool::from(Scalar::from_repr([0xff; 32]).is_none()));
2067 }
2068
2069 #[test]
2070 #[should_panic]
2071 fn test_read_le_u64_into_should_panic_on_bad_input() {
2072 let mut dst = [0_u64; 1];
2073 read_le_u64_into(&[0xFE, 0xEF, 0x10, 0x01, 0x1F, 0xF1, 0x0F], &mut dst);
2075 }
2076
2077 #[test]
2078 fn test_scalar_clamp() {
2079 let input = A_SCALAR.bytes;
2080 let expected = [
2081 0x18, 0x0e, 0x97, 0x8a, 0x90, 0xf6, 0x62, 0x2d, 0x37, 0x47, 0x02, 0x3f, 0x8a, 0xd8,
2082 0x26, 0x4d, 0xa7, 0x58, 0xaa, 0x1b, 0x88, 0xe0, 0x40, 0xd1, 0x58, 0x9e, 0x7b, 0x7f,
2083 0x23, 0x76, 0xef, 0x49,
2084 ];
2085 let actual = clamp_integer(input);
2086 assert_eq!(actual, expected);
2087
2088 let expected = [
2089 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, 0,
2090 0, 0, 0x40,
2091 ];
2092 let actual = clamp_integer([0; 32]);
2093 assert_eq!(expected, actual);
2094 let expected = [
2095 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2096 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2097 0xff, 0xff, 0xff, 0x7f,
2098 ];
2099 let actual = clamp_integer([0xff; 32]);
2100 assert_eq!(actual, expected);
2101
2102 assert_eq!(
2103 LARGEST_CLAMPED_INTEGER,
2104 clamp_integer(LARGEST_CLAMPED_INTEGER)
2105 );
2106 }
2107
2108 #[test]
2112 fn test_mul_reduction_invariance() {
2113 let mut rng = UnwrapErr(SysRng);
2114
2115 for _ in 0..10 {
2116 let (a, b, c) = {
2119 let mut a_bytes = [0u8; 32];
2120 let mut b_bytes = [0u8; 32];
2121 let mut c_bytes = [0u8; 32];
2122 rng.fill_bytes(&mut a_bytes);
2123 rng.fill_bytes(&mut b_bytes);
2124 rng.fill_bytes(&mut c_bytes);
2125 (
2126 Scalar { bytes: a_bytes },
2127 Scalar { bytes: b_bytes },
2128 Scalar {
2129 bytes: clamp_integer(c_bytes),
2130 },
2131 )
2132 };
2133
2134 let reduced_mul_ab = a.reduce() * b.reduce();
2136 let reduced_mul_ac = a.reduce() * c.reduce();
2137 assert_eq!(a * b, reduced_mul_ab);
2138 assert_eq!(a.reduce() * b, reduced_mul_ab);
2139 assert_eq!(a * b.reduce(), reduced_mul_ab);
2140 assert_eq!(a * c, reduced_mul_ac);
2141 assert_eq!(a.reduce() * c, reduced_mul_ac);
2142 assert_eq!(a * c.reduce(), reduced_mul_ac);
2143 }
2144 }
2145}