1use crate::error::{Error, Result};
4use crate::types::{ByteSerializable, ConstantTimeEq as DcryptConstantTimeEq, SecureZeroingType};
5use core::fmt;
6use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
7use dcrypt_internal::constant_time::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
8use dcrypt_internal::zeroing::{zeroizing_bytes_from_slice, Zeroize, Zeroizing, ZeroizingBytes};
9
10#[inline(always)]
13const fn adc(a: u64, b: u64, carry: u64) -> (u64, u64) {
14 let ret = (a as u128) + (b as u128) + (carry as u128);
15 (ret as u64, (ret >> 64) as u64)
16}
17
18#[inline(always)]
20const fn sbb(a: u64, b: u64, borrow: u64) -> (u64, u64) {
21 let ret = (a as u128).wrapping_sub((b as u128) + ((borrow >> 63) as u128));
22 (ret as u64, (ret >> 64) as u64)
23}
24
25#[inline(always)]
27const fn mac(a: u64, b: u64, c: u64, carry: u64) -> (u64, u64) {
28 let ret = (a as u128) + ((b as u128) * (c as u128)) + (carry as u128);
29 (ret as u64, (ret >> 64) as u64)
30}
31
32#[derive(Clone, Copy, Eq)]
40pub struct Scalar(pub(crate) [u64; 4]);
41
42impl fmt::Debug for Scalar {
43 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
44 let tmp = self.to_bytes();
45 write!(f, "0x")?;
46 for &b in tmp.iter().rev() {
47 write!(f, "{:02x}", b)?;
48 }
49 Ok(())
50 }
51}
52
53impl fmt::Display for Scalar {
54 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55 write!(f, "{:?}", self)
56 }
57}
58
59impl From<u64> for Scalar {
60 fn from(val: u64) -> Scalar {
61 Scalar([val, 0, 0, 0]) * R2
62 }
63}
64
65impl ConstantTimeEq for Scalar {
66 fn ct_eq(&self, other: &Self) -> Choice {
67 self.0[0].ct_eq(&other.0[0])
68 & self.0[1].ct_eq(&other.0[1])
69 & self.0[2].ct_eq(&other.0[2])
70 & self.0[3].ct_eq(&other.0[3])
71 }
72}
73
74impl PartialEq for Scalar {
75 #[inline]
76 fn eq(&self, other: &Self) -> bool {
77 bool::from(ConstantTimeEq::ct_eq(self, other))
78 }
79}
80
81impl ConditionallySelectable for Scalar {
82 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
83 Scalar([
84 u64::conditional_select(&a.0[0], &b.0[0], choice),
85 u64::conditional_select(&a.0[1], &b.0[1], choice),
86 u64::conditional_select(&a.0[2], &b.0[2], choice),
87 u64::conditional_select(&a.0[3], &b.0[3], choice),
88 ])
89 }
90}
91
92const MODULUS: Scalar = Scalar([
94 0xffff_ffff_0000_0001,
95 0x53bd_a402_fffe_5bfe,
96 0x3339_d808_09a1_d805,
97 0x73ed_a753_299d_7d48,
98]);
99
100const MODULUS_BE: [u8; 32] = [
102 0x73, 0xed, 0xa7, 0x53, 0x29, 0x9d, 0x7d, 0x48, 0x33, 0x39, 0xd8, 0x08, 0x09, 0xa1, 0xd8, 0x05,
103 0x53, 0xbd, 0xa4, 0x02, 0xff, 0xfe, 0x5b, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
104];
105
106pub(crate) fn secret_be_bytes_are_valid(bytes: &[u8; 32]) -> Choice {
109 let mut nonzero = 0u8;
110 let mut borrow = 0u16;
111 for index in (0..bytes.len()).rev() {
112 nonzero |= bytes[index];
113 let rhs = (MODULUS_BE[index] as u16) + borrow;
114 let difference = (bytes[index] as u16).wrapping_sub(rhs);
115 borrow = (difference >> 15) & 1;
116 }
117
118 Choice::from(borrow as u8) & !nonzero.ct_eq(&0u8)
119}
120
121const INV: u64 = 0xffff_fffe_ffff_ffff;
123
124const R: Scalar = Scalar([
126 0x0000_0001_ffff_fffe,
127 0x5884_b7fa_0003_4802,
128 0x998c_4fef_ecbc_4ff5,
129 0x1824_b159_acc5_056f,
130]);
131
132const R2: Scalar = Scalar([
134 0xc999_e990_f3f2_9c6d,
135 0x2b6c_edcb_8792_5c23,
136 0x05d3_1496_7254_398f,
137 0x0748_d9d9_9f59_ff11,
138]);
139
140const R3: Scalar = Scalar([
142 0xc62c_1807_439b_73af,
143 0x1b3e_0d18_8cf0_6990,
144 0x73d1_3c71_c7b5_f418,
145 0x6e2a_5bb9_c8db_33e9,
146]);
147
148const S: u32 = 32;
151
152const TONELLI_T: [u64; 4] = [
154 0xfffe_5bfe_ffff_ffff,
155 0x09a1_d805_53bd_a402,
156 0x299d_7d48_3339_d808,
157 0x0000_0000_73ed_a753,
158];
159
160const TONELLI_TP1_DIV2: [u64; 4] = [
162 0x7fff_2dff_8000_0000,
163 0x04d0_ec02_a9de_d201,
164 0x94ce_bea4_199c_ec04,
165 0x0000_0000_39f6_d3a9,
166];
167
168#[allow(dead_code)]
170const LEGENDRE_EXP: [u64; 4] = [
171 0x7fff_ffff_8000_0000,
172 0xa9de_d201_7fff_2dff,
173 0x199c_ec04_04d0_ec02,
174 0x39f6_d3a9_94ce_bea4,
175];
176
177impl<'a> Neg for &'a Scalar {
178 type Output = Scalar;
179
180 #[inline]
181 fn neg(self) -> Scalar {
182 self.neg()
183 }
184}
185
186impl Neg for Scalar {
187 type Output = Scalar;
188
189 #[inline]
190 fn neg(self) -> Scalar {
191 -&self
192 }
193}
194
195impl<'a, 'b> Sub<&'b Scalar> for &'a Scalar {
196 type Output = Scalar;
197
198 #[inline]
199 fn sub(self, rhs: &'b Scalar) -> Scalar {
200 self.sub(rhs)
201 }
202}
203
204impl<'a, 'b> Add<&'b Scalar> for &'a Scalar {
205 type Output = Scalar;
206
207 #[inline]
208 fn add(self, rhs: &'b Scalar) -> Scalar {
209 self.add(rhs)
210 }
211}
212
213impl<'a, 'b> Mul<&'b Scalar> for &'a Scalar {
214 type Output = Scalar;
215
216 #[inline]
217 fn mul(self, rhs: &'b Scalar) -> Scalar {
218 self.mul(rhs)
219 }
220}
221
222impl<'b> Add<&'b Scalar> for Scalar {
224 type Output = Scalar;
225 #[inline]
226 fn add(self, rhs: &'b Scalar) -> Scalar {
227 &self + rhs
228 }
229}
230
231impl<'a> Add<Scalar> for &'a Scalar {
232 type Output = Scalar;
233 #[inline]
234 fn add(self, rhs: Scalar) -> Scalar {
235 self + &rhs
236 }
237}
238
239impl Add<Scalar> for Scalar {
240 type Output = Scalar;
241 #[inline]
242 fn add(self, rhs: Scalar) -> Scalar {
243 &self + &rhs
244 }
245}
246
247impl<'b> Sub<&'b Scalar> for Scalar {
248 type Output = Scalar;
249 #[inline]
250 fn sub(self, rhs: &'b Scalar) -> Scalar {
251 &self - rhs
252 }
253}
254
255impl<'a> Sub<Scalar> for &'a Scalar {
256 type Output = Scalar;
257 #[inline]
258 fn sub(self, rhs: Scalar) -> Scalar {
259 self - &rhs
260 }
261}
262
263impl Sub<Scalar> for Scalar {
264 type Output = Scalar;
265 #[inline]
266 fn sub(self, rhs: Scalar) -> Scalar {
267 &self - &rhs
268 }
269}
270
271impl SubAssign<Scalar> for Scalar {
272 #[inline]
273 fn sub_assign(&mut self, rhs: Scalar) {
274 *self = &*self - &rhs;
275 }
276}
277
278impl AddAssign<Scalar> for Scalar {
279 #[inline]
280 fn add_assign(&mut self, rhs: Scalar) {
281 *self = &*self + &rhs;
282 }
283}
284
285impl<'b> SubAssign<&'b Scalar> for Scalar {
286 #[inline]
287 fn sub_assign(&mut self, rhs: &'b Scalar) {
288 *self = &*self - rhs;
289 }
290}
291
292impl<'b> AddAssign<&'b Scalar> for Scalar {
293 #[inline]
294 fn add_assign(&mut self, rhs: &'b Scalar) {
295 *self = &*self + rhs;
296 }
297}
298
299impl<'b> Mul<&'b Scalar> for Scalar {
300 type Output = Scalar;
301 #[inline]
302 fn mul(self, rhs: &'b Scalar) -> Scalar {
303 &self * rhs
304 }
305}
306
307impl<'a> Mul<Scalar> for &'a Scalar {
308 type Output = Scalar;
309 #[inline]
310 fn mul(self, rhs: Scalar) -> Scalar {
311 self * &rhs
312 }
313}
314
315impl Mul<Scalar> for Scalar {
316 type Output = Scalar;
317 #[inline]
318 fn mul(self, rhs: Scalar) -> Scalar {
319 &self * &rhs
320 }
321}
322
323impl MulAssign<Scalar> for Scalar {
324 #[inline]
325 fn mul_assign(&mut self, rhs: Scalar) {
326 *self = &*self * &rhs;
327 }
328}
329
330impl<'b> MulAssign<&'b Scalar> for Scalar {
331 #[inline]
332 fn mul_assign(&mut self, rhs: &'b Scalar) {
333 *self = &*self * rhs;
334 }
335}
336
337impl Default for Scalar {
338 #[inline]
339 fn default() -> Self {
340 Self::zero()
341 }
342}
343
344impl Zeroize for Scalar {
345 fn zeroize(&mut self) {
346 self.0.zeroize();
347 }
348}
349
350impl ByteSerializable for Scalar {
351 type Bytes = ZeroizingBytes;
352
353 fn to_bytes(&self) -> ZeroizingBytes {
354 let mut encoded = Zeroizing::new(self.to_bytes());
355 let output = zeroizing_bytes_from_slice(&encoded[..]);
356 encoded.zeroize();
357 output
358 }
359
360 fn from_bytes(bytes: &[u8]) -> Result<Self> {
361 if bytes.len() != 32 {
362 return Err(Error::Length {
363 context: "Scalar::from_bytes",
364 expected: 32,
365 actual: bytes.len(),
366 });
367 }
368
369 let mut array = Zeroizing::new([0u8; 32]);
370 array.copy_from_slice(bytes);
371
372 Scalar::from_bytes(&array)
373 .into_option()
374 .ok_or_else(|| Error::param("scalar_bytes", "non-canonical scalar"))
375 }
376}
377
378impl DcryptConstantTimeEq for Scalar {
379 fn ct_eq(&self, other: &Self) -> bool {
380 bool::from(ConstantTimeEq::ct_eq(self, other))
381 }
382}
383
384impl SecureZeroingType for Scalar {
385 fn zeroed() -> Self {
386 Self::zero()
387 }
388}
389
390impl Scalar {
391 #[inline]
393 pub const fn zero() -> Scalar {
394 Scalar([0, 0, 0, 0])
395 }
396
397 #[inline]
399 pub const fn one() -> Scalar {
400 R
401 }
402
403 #[inline]
405 pub fn is_zero(&self) -> Choice {
406 (self.0[0] | self.0[1] | self.0[2] | self.0[3]).ct_eq(&0)
407 }
408
409 pub fn secret_key_bytes_are_valid(bytes: &[u8; 32]) -> Choice {
412 secret_be_bytes_are_valid(bytes)
413 }
414
415 #[inline]
417 pub const fn double(&self) -> Scalar {
418 self.add(self)
419 }
420
421 pub fn from_bytes(bytes: &[u8; 32]) -> CtOption<Scalar> {
423 let mut tmp = Scalar([0, 0, 0, 0]);
424
425 tmp.0[0] = u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[0..8]).unwrap());
426 tmp.0[1] = u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[8..16]).unwrap());
427 tmp.0[2] = u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[16..24]).unwrap());
428 tmp.0[3] = u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[24..32]).unwrap());
429
430 let (_, borrow) = sbb(tmp.0[0], MODULUS.0[0], 0);
432 let (_, borrow) = sbb(tmp.0[1], MODULUS.0[1], borrow);
433 let (_, borrow) = sbb(tmp.0[2], MODULUS.0[2], borrow);
434 let (_, borrow) = sbb(tmp.0[3], MODULUS.0[3], borrow);
435
436 let is_some = (borrow as u8) & 1;
437
438 tmp *= &R2;
440
441 CtOption::new(tmp, Choice::from(is_some))
442 }
443
444 pub fn to_bytes(&self) -> [u8; 32] {
446 let tmp = Scalar::montgomery_reduce(self.0[0], self.0[1], self.0[2], self.0[3], 0, 0, 0, 0);
448
449 let mut res = [0; 32];
450 res[0..8].copy_from_slice(&tmp.0[0].to_le_bytes());
451 res[8..16].copy_from_slice(&tmp.0[1].to_le_bytes());
452 res[16..24].copy_from_slice(&tmp.0[2].to_le_bytes());
453 res[24..32].copy_from_slice(&tmp.0[3].to_le_bytes());
454
455 res
456 }
457
458 pub fn from_be_bytes(bytes: &[u8; 32]) -> CtOption<Scalar> {
464 let mut little_endian = Zeroizing::new(*bytes);
465 little_endian.reverse();
466 Self::from_bytes(&little_endian)
467 }
468
469 pub fn to_be_bytes(&self) -> [u8; 32] {
471 let mut bytes = self.to_bytes();
472 bytes.reverse();
473 bytes
474 }
475
476 pub fn to_be_bytes_zeroizing(&self) -> Zeroizing<[u8; 32]> {
481 let mut bytes = Zeroizing::new(self.to_bytes());
482 bytes.reverse();
483 bytes
484 }
485
486 pub fn from_bytes_wide(bytes: &[u8; 64]) -> Scalar {
488 let limbs = Zeroizing::new([
489 u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[0..8]).unwrap()),
490 u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[8..16]).unwrap()),
491 u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[16..24]).unwrap()),
492 u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[24..32]).unwrap()),
493 u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[32..40]).unwrap()),
494 u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[40..48]).unwrap()),
495 u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[48..56]).unwrap()),
496 u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[56..64]).unwrap()),
497 ]);
498 Scalar::from_u512(&limbs)
499 }
500
501 pub fn from_be_bytes_mod_order(bytes: &[u8]) -> Result<Scalar> {
509 if bytes.len() > 64 {
510 return Err(Error::param(
511 "scalar_bytes",
512 "big-endian reduction input exceeds 64 bytes",
513 ));
514 }
515
516 let mut wide = Zeroizing::new([0u8; 64]);
517 for (destination, source) in wide.iter_mut().zip(bytes.iter().rev()) {
518 *destination = *source;
519 }
520 Ok(Self::from_bytes_wide(&wide))
521 }
522
523 pub fn hash_to_field(data: &[u8], dst: &[u8]) -> Result<Self> {
539 let expanded = super::hash_to_curve::expand_message_xmd(data, dst, 48)?;
540 Self::from_be_bytes_mod_order(&expanded)
541 }
542
543 fn from_u512(limbs: &[u64; 8]) -> Scalar {
544 let d0 = Zeroizing::new(Scalar([limbs[0], limbs[1], limbs[2], limbs[3]]));
545 let d1 = Zeroizing::new(Scalar([limbs[4], limbs[5], limbs[6], limbs[7]]));
546 let low = Zeroizing::new(&*d0 * &R2);
547 let high = Zeroizing::new(&*d1 * &R3);
548 &*low + &*high
549 }
550
551 pub const fn from_raw(val: [u64; 4]) -> Self {
554 (&Scalar(val)).mul(&R2)
555 }
556
557 #[inline]
559 pub const fn square(&self) -> Scalar {
560 let (r1, carry) = mac(0, self.0[0], self.0[1], 0);
561 let (r2, carry) = mac(0, self.0[0], self.0[2], carry);
562 let (r3, r4) = mac(0, self.0[0], self.0[3], carry);
563
564 let (r3, carry) = mac(r3, self.0[1], self.0[2], 0);
565 let (r4, r5) = mac(r4, self.0[1], self.0[3], carry);
566
567 let (r5, r6) = mac(r5, self.0[2], self.0[3], 0);
568
569 let r7 = r6 >> 63;
570 let r6 = (r6 << 1) | (r5 >> 63);
571 let r5 = (r5 << 1) | (r4 >> 63);
572 let r4 = (r4 << 1) | (r3 >> 63);
573 let r3 = (r3 << 1) | (r2 >> 63);
574 let r2 = (r2 << 1) | (r1 >> 63);
575 let r1 = r1 << 1;
576
577 let (r0, carry) = mac(0, self.0[0], self.0[0], 0);
578 let (r1, carry) = adc(0, r1, carry);
579 let (r2, carry) = mac(r2, self.0[1], self.0[1], carry);
580 let (r3, carry) = adc(0, r3, carry);
581 let (r4, carry) = mac(r4, self.0[2], self.0[2], carry);
582 let (r5, carry) = adc(0, r5, carry);
583 let (r6, carry) = mac(r6, self.0[3], self.0[3], carry);
584 let (r7, _) = adc(0, r7, carry);
585
586 Scalar::montgomery_reduce(r0, r1, r2, r3, r4, r5, r6, r7)
587 }
588
589 #[inline]
591 pub fn pow2k(mut x: Scalar, mut k: u32) -> Scalar {
592 while k > 0 {
593 x = x.square();
594 k -= 1;
595 }
596 x
597 }
598
599 fn pow_vartime(&self, by: &[u64; 4]) -> Self {
601 let mut res = Self::one();
602 for limb in by.iter().rev() {
603 for i in (0..64).rev() {
604 res = res.square();
605 if ((limb >> i) & 1) == 1 {
606 res *= self;
607 }
608 }
609 }
610 res
611 }
612
613 pub fn sqrt(&self) -> CtOption<Self> {
616 if bool::from(self.is_zero()) {
618 return CtOption::new(Scalar::zero(), Choice::from(1));
619 }
620
621 let z = Scalar::from(5u64);
623
624 let mut c = z.pow_vartime(&TONELLI_T); let mut t = self.pow_vartime(&TONELLI_T); let mut x = self.pow_vartime(&TONELLI_TP1_DIV2); let mut m = S;
629
630 if bool::from(ConstantTimeEq::ct_eq(&t, &Scalar::one())) {
632 return CtOption::new(x, ConstantTimeEq::ct_eq(&x.square(), self));
633 }
634
635 loop {
637 let mut i = 1u32;
639 let mut t2i = t.square();
640 while i < m && !bool::from(ConstantTimeEq::ct_eq(&t2i, &Scalar::one())) {
641 t2i = t2i.square();
642 i += 1;
643 }
644
645 if i == m {
647 return CtOption::new(Scalar::zero(), Choice::from(0));
648 }
649
650 let b = Scalar::pow2k(c, m - i - 1);
652
653 x = x * b;
655 let b2 = b.square();
656 t = t * b2;
657 c = b2;
658 m = i;
659
660 if bool::from(ConstantTimeEq::ct_eq(&t, &Scalar::one())) {
662 break;
663 }
664 }
665
666 CtOption::new(x, ConstantTimeEq::ct_eq(&x.square(), self))
668 }
669
670 pub fn invert(&self) -> CtOption<Self> {
672 #[inline(always)]
673 fn square_assign_multi(n: &mut Scalar, num_times: usize) {
674 for _ in 0..num_times {
675 *n = n.square();
676 }
677 }
678 let mut t0 = self.square();
680 let mut t1 = t0 * self;
681 let mut t16 = t0.square();
682 let mut t6 = t16.square();
683 let mut t5 = t6 * t0;
684 t0 = t6 * t16;
685 let mut t12 = t5 * t16;
686 let mut t2 = t6.square();
687 let mut t7 = t5 * t6;
688 let mut t15 = t0 * t5;
689 let mut t17 = t12.square();
690 t1 *= t17;
691 let mut t3 = t7 * t2;
692 let t8 = t1 * t17;
693 let t4 = t8 * t2;
694 let t9 = t8 * t7;
695 t7 = t4 * t5;
696 let t11 = t4 * t17;
697 t5 = t9 * t17;
698 let t14 = t7 * t15;
699 let t13 = t11 * t12;
700 t12 = t11 * t17;
701 t15 *= &t12;
702 t16 *= &t15;
703 t3 *= &t16;
704 t17 *= &t3;
705 t0 *= &t17;
706 t6 *= &t0;
707 t2 *= &t6;
708 square_assign_multi(&mut t0, 8);
709 t0 *= &t17;
710 square_assign_multi(&mut t0, 9);
711 t0 *= &t16;
712 square_assign_multi(&mut t0, 9);
713 t0 *= &t15;
714 square_assign_multi(&mut t0, 9);
715 t0 *= &t15;
716 square_assign_multi(&mut t0, 7);
717 t0 *= &t14;
718 square_assign_multi(&mut t0, 7);
719 t0 *= &t13;
720 square_assign_multi(&mut t0, 10);
721 t0 *= &t12;
722 square_assign_multi(&mut t0, 9);
723 t0 *= &t11;
724 square_assign_multi(&mut t0, 8);
725 t0 *= &t8;
726 square_assign_multi(&mut t0, 8);
727 t0 *= self;
728 square_assign_multi(&mut t0, 14);
729 t0 *= &t9;
730 square_assign_multi(&mut t0, 10);
731 t0 *= &t8;
732 square_assign_multi(&mut t0, 15);
733 t0 *= &t7;
734 square_assign_multi(&mut t0, 10);
735 t0 *= &t6;
736 square_assign_multi(&mut t0, 8);
737 t0 *= &t5;
738 square_assign_multi(&mut t0, 16);
739 t0 *= &t3;
740 square_assign_multi(&mut t0, 8);
741 t0 *= &t2;
742 square_assign_multi(&mut t0, 7);
743 t0 *= &t4;
744 square_assign_multi(&mut t0, 9);
745 t0 *= &t2;
746 square_assign_multi(&mut t0, 8);
747 t0 *= &t3;
748 square_assign_multi(&mut t0, 8);
749 t0 *= &t2;
750 square_assign_multi(&mut t0, 8);
751 t0 *= &t2;
752 square_assign_multi(&mut t0, 8);
753 t0 *= &t2;
754 square_assign_multi(&mut t0, 8);
755 t0 *= &t3;
756 square_assign_multi(&mut t0, 8);
757 t0 *= &t2;
758 square_assign_multi(&mut t0, 8);
759 t0 *= &t2;
760 square_assign_multi(&mut t0, 5);
761 t0 *= &t1;
762 square_assign_multi(&mut t0, 5);
763 t0 *= &t1;
764
765 CtOption::new(t0, !ConstantTimeEq::ct_eq(self, &Self::zero()))
766 }
767
768 #[inline(always)]
769 const fn montgomery_reduce(
770 r0: u64,
771 r1: u64,
772 r2: u64,
773 r3: u64,
774 r4: u64,
775 r5: u64,
776 r6: u64,
777 r7: u64,
778 ) -> Self {
779 let k = r0.wrapping_mul(INV);
780 let (_, carry) = mac(r0, k, MODULUS.0[0], 0);
781 let (r1, carry) = mac(r1, k, MODULUS.0[1], carry);
782 let (r2, carry) = mac(r2, k, MODULUS.0[2], carry);
783 let (r3, carry) = mac(r3, k, MODULUS.0[3], carry);
784 let (r4, carry2) = adc(r4, 0, carry);
785
786 let k = r1.wrapping_mul(INV);
787 let (_, carry) = mac(r1, k, MODULUS.0[0], 0);
788 let (r2, carry) = mac(r2, k, MODULUS.0[1], carry);
789 let (r3, carry) = mac(r3, k, MODULUS.0[2], carry);
790 let (r4, carry) = mac(r4, k, MODULUS.0[3], carry);
791 let (r5, carry2) = adc(r5, carry2, carry);
792
793 let k = r2.wrapping_mul(INV);
794 let (_, carry) = mac(r2, k, MODULUS.0[0], 0);
795 let (r3, carry) = mac(r3, k, MODULUS.0[1], carry);
796 let (r4, carry) = mac(r4, k, MODULUS.0[2], carry);
797 let (r5, carry) = mac(r5, k, MODULUS.0[3], carry);
798 let (r6, carry2) = adc(r6, carry2, carry);
799
800 let k = r3.wrapping_mul(INV);
801 let (_, carry) = mac(r3, k, MODULUS.0[0], 0);
802 let (r4, carry) = mac(r4, k, MODULUS.0[1], carry);
803 let (r5, carry) = mac(r5, k, MODULUS.0[2], carry);
804 let (r6, carry) = mac(r6, k, MODULUS.0[3], carry);
805 let (r7, _) = adc(r7, carry2, carry);
806
807 (&Scalar([r4, r5, r6, r7])).sub(&MODULUS)
808 }
809
810 #[inline]
812 pub const fn mul(&self, rhs: &Self) -> Self {
813 let (r0, carry) = mac(0, self.0[0], rhs.0[0], 0);
814 let (r1, carry) = mac(0, self.0[0], rhs.0[1], carry);
815 let (r2, carry) = mac(0, self.0[0], rhs.0[2], carry);
816 let (r3, r4) = mac(0, self.0[0], rhs.0[3], carry);
817
818 let (r1, carry) = mac(r1, self.0[1], rhs.0[0], 0);
819 let (r2, carry) = mac(r2, self.0[1], rhs.0[1], carry);
820 let (r3, carry) = mac(r3, self.0[1], rhs.0[2], carry);
821 let (r4, r5) = mac(r4, self.0[1], rhs.0[3], carry);
822
823 let (r2, carry) = mac(r2, self.0[2], rhs.0[0], 0);
824 let (r3, carry) = mac(r3, self.0[2], rhs.0[1], carry);
825 let (r4, carry) = mac(r4, self.0[2], rhs.0[2], carry);
826 let (r5, r6) = mac(r5, self.0[2], rhs.0[3], carry);
827
828 let (r3, carry) = mac(r3, self.0[3], rhs.0[0], 0);
829 let (r4, carry) = mac(r4, self.0[3], rhs.0[1], carry);
830 let (r5, carry) = mac(r5, self.0[3], rhs.0[2], carry);
831 let (r6, r7) = mac(r6, self.0[3], rhs.0[3], carry);
832
833 Scalar::montgomery_reduce(r0, r1, r2, r3, r4, r5, r6, r7)
834 }
835
836 #[inline]
838 pub const fn sub(&self, rhs: &Self) -> Self {
839 let (d0, borrow) = sbb(self.0[0], rhs.0[0], 0);
840 let (d1, borrow) = sbb(self.0[1], rhs.0[1], borrow);
841 let (d2, borrow) = sbb(self.0[2], rhs.0[2], borrow);
842 let (d3, borrow) = sbb(self.0[3], rhs.0[3], borrow);
843
844 let (d0, carry) = adc(d0, MODULUS.0[0] & borrow, 0);
845 let (d1, carry) = adc(d1, MODULUS.0[1] & borrow, carry);
846 let (d2, carry) = adc(d2, MODULUS.0[2] & borrow, carry);
847 let (d3, _) = adc(d3, MODULUS.0[3] & borrow, carry);
848
849 Scalar([d0, d1, d2, d3])
850 }
851
852 #[inline]
854 pub const fn add(&self, rhs: &Self) -> Self {
855 let (d0, carry) = adc(self.0[0], rhs.0[0], 0);
856 let (d1, carry) = adc(self.0[1], rhs.0[1], carry);
857 let (d2, carry) = adc(self.0[2], rhs.0[2], carry);
858 let (d3, _) = adc(self.0[3], rhs.0[3], carry);
859
860 (&Scalar([d0, d1, d2, d3])).sub(&MODULUS)
861 }
862
863 #[inline]
865 pub const fn neg(&self) -> Self {
866 let (d0, borrow) = sbb(MODULUS.0[0], self.0[0], 0);
867 let (d1, borrow) = sbb(MODULUS.0[1], self.0[1], borrow);
868 let (d2, borrow) = sbb(MODULUS.0[2], self.0[2], borrow);
869 let (d3, _) = sbb(MODULUS.0[3], self.0[3], borrow);
870
871 let mask = (((self.0[0] | self.0[1] | self.0[2] | self.0[3]) == 0) as u64).wrapping_sub(1);
872
873 Scalar([d0 & mask, d1 & mask, d2 & mask, d3 & mask])
874 }
875}
876
877impl From<Scalar> for [u8; 32] {
878 fn from(value: Scalar) -> [u8; 32] {
879 value.to_bytes()
880 }
881}
882
883impl<'a> From<&'a Scalar> for [u8; 32] {
884 fn from(value: &'a Scalar) -> [u8; 32] {
885 value.to_bytes()
886 }
887}
888
889impl<T> core::iter::Sum<T> for Scalar
890where
891 T: core::borrow::Borrow<Scalar>,
892{
893 fn sum<I>(iter: I) -> Self
894 where
895 I: Iterator<Item = T>,
896 {
897 iter.fold(Self::zero(), |acc, item| acc + item.borrow())
898 }
899}
900
901impl<T> core::iter::Product<T> for Scalar
902where
903 T: core::borrow::Borrow<Scalar>,
904{
905 fn product<I>(iter: I) -> Self
906 where
907 I: Iterator<Item = T>,
908 {
909 iter.fold(Self::one(), |acc, item| acc * item.borrow())
910 }
911}
912
913#[test]
915fn test_inv() {
916 let mut inv = 1u64;
918 for _ in 0..63 {
919 inv = inv.wrapping_mul(inv);
920 inv = inv.wrapping_mul(MODULUS.0[0]);
921 }
922 inv = inv.wrapping_neg();
923 assert_eq!(inv, INV);
924}
925
926#[cfg(feature = "std")]
927#[test]
928fn test_debug() {
929 assert_eq!(
930 format!("{:?}", Scalar::zero()),
931 "0x0000000000000000000000000000000000000000000000000000000000000000"
932 );
933 assert_eq!(
934 format!("{:?}", Scalar::one()),
935 "0x0000000000000000000000000000000000000000000000000000000000000001"
936 );
937 assert_eq!(
940 format!("{:?}", R),
941 "0x0000000000000000000000000000000000000000000000000000000000000001"
942 );
943}
944
945#[test]
946fn test_equality() {
947 assert_eq!(Scalar::zero(), Scalar::zero());
948 assert_eq!(Scalar::one(), Scalar::one());
949 #[allow(clippy::eq_op)]
950 {
951 assert_eq!(R2, R2);
952 }
953
954 assert!(Scalar::zero() != Scalar::one());
955 assert!(Scalar::one() != R2);
956}
957
958#[test]
959fn test_to_bytes() {
960 assert_eq!(
961 Scalar::zero().to_bytes(),
962 [
963 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,
964 0, 0, 0
965 ]
966 );
967
968 assert_eq!(
969 Scalar::one().to_bytes(),
970 [
971 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,
972 0, 0, 0
973 ]
974 );
975
976 assert_eq!(
979 R.to_bytes(),
980 [
981 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,
982 0, 0, 0
983 ]
984 );
985
986 assert_eq!(
987 (-&Scalar::one()).to_bytes(),
988 [
989 0, 0, 0, 0, 255, 255, 255, 255, 254, 91, 254, 255, 2, 164, 189, 83, 5, 216, 161, 9, 8,
990 216, 57, 51, 72, 125, 157, 41, 83, 167, 237, 115
991 ]
992 );
993}
994
995#[test]
996fn test_from_bytes() {
997 let mut a = R2;
998
999 for _ in 0..100 {
1000 let bytes = a.to_bytes();
1001 let b = Scalar::from_bytes(&bytes).unwrap();
1002 assert_eq!(a, b);
1003
1004 let bytes = (-a).to_bytes();
1006 let b = Scalar::from_bytes(&bytes).unwrap();
1007 assert_eq!(-a, b);
1008
1009 a = a.square();
1010 }
1011}
1012
1013#[test]
1014fn test_from_bytes_enforces_canonical_scalar_encoding() {
1015 let mut modulus =
1016 hex::decode("73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001").unwrap();
1017 modulus.reverse();
1018 let modulus: [u8; 32] = modulus.try_into().unwrap();
1019 assert!(bool::from(Scalar::from_bytes(&modulus).is_none()));
1020 assert!(<Scalar as ByteSerializable>::from_bytes(&modulus).is_err());
1021
1022 let mut largest =
1023 hex::decode("73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000").unwrap();
1024 largest.reverse();
1025 let largest: [u8; 32] = largest.try_into().unwrap();
1026 assert!(bool::from(Scalar::from_bytes(&largest).is_some()));
1027
1028 assert!(bool::from(Scalar::from_bytes(&[0u8; 32]).is_some()));
1029 assert!(bool::from(Scalar::from_bytes(&[0xff; 32]).is_none()));
1030
1031 let mut modulus_be = modulus;
1032 modulus_be.reverse();
1033 assert!(bool::from(Scalar::from_be_bytes(&modulus_be).is_none()));
1034 assert!(bool::from(
1035 Scalar::from_be_bytes_mod_order(&modulus_be)
1036 .unwrap()
1037 .is_zero()
1038 ));
1039 assert!(Scalar::from_be_bytes_mod_order(&[0u8; 65]).is_err());
1040 let forty_two = Scalar::from(42u64);
1041 assert_eq!(
1042 Scalar::from_be_bytes(&forty_two.to_be_bytes()).unwrap(),
1043 forty_two
1044 );
1045}
1046
1047#[test]
1048fn borrowed_secret_validation_matches_canonical_scalar_decoder() {
1049 let mut bytes = [0u8; 32];
1050 for counter in 0u16..2048 {
1051 for (index, byte) in bytes.iter_mut().enumerate() {
1052 *byte = (counter as u8)
1053 .wrapping_mul(73)
1054 .wrapping_add((counter >> 8) as u8)
1055 .wrapping_add((index as u8).wrapping_mul(19));
1056 }
1057
1058 let decoded = Scalar::from_be_bytes(&bytes).into_option();
1059 let expected = decoded
1060 .as_ref()
1061 .map(|scalar| !bool::from(scalar.is_zero()))
1062 .unwrap_or(false);
1063 assert_eq!(
1064 bool::from(Scalar::secret_key_bytes_are_valid(&bytes)),
1065 expected,
1066 "mismatch at corpus item {counter}",
1067 );
1068 }
1069}
1070
1071#[cfg(test)]
1072const LARGEST: Scalar = Scalar([
1073 0xffff_ffff_0000_0000,
1074 0x53bd_a402_fffe_5bfe,
1075 0x3339_d808_09a1_d805,
1076 0x73ed_a753_299d_7d48,
1077]);
1078
1079#[test]
1080fn test_addition() {
1081 let mut tmp = LARGEST;
1082 tmp += &LARGEST;
1083
1084 assert_eq!(
1085 tmp,
1086 Scalar([
1087 0xffff_fffe_ffff_ffff,
1088 0x53bd_a402_fffe_5bfe,
1089 0x3339_d808_09a1_d805,
1090 0x73ed_a753_299d_7d48,
1091 ])
1092 );
1093
1094 let mut tmp = LARGEST;
1095 tmp += &Scalar([1, 0, 0, 0]);
1096
1097 assert_eq!(tmp, Scalar::zero());
1098}
1099
1100#[test]
1101fn test_inversion() {
1102 assert!(bool::from(Scalar::zero().invert().is_none()));
1103 assert_eq!(Scalar::one().invert().unwrap(), Scalar::one());
1104 assert_eq!((-&Scalar::one()).invert().unwrap(), -&Scalar::one());
1105
1106 let mut tmp = R2;
1107
1108 for _ in 0..100 {
1109 let mut tmp2 = tmp.invert().unwrap();
1110 tmp2.mul_assign(&tmp);
1111
1112 assert_eq!(tmp2, Scalar::one());
1113
1114 tmp.add_assign(&R2);
1115 }
1116}
1117
1118#[test]
1119fn test_sqrt() {
1120 assert_eq!(Scalar::zero().sqrt().unwrap(), Scalar::zero());
1122
1123 assert_eq!(Scalar::one().sqrt().unwrap(), Scalar::one());
1125
1126 let four = Scalar::from(4u64);
1128 let two = Scalar::from(2u64);
1129 let neg_two = -two;
1130
1131 let sqrt_four = four.sqrt().unwrap();
1132 assert!(sqrt_four == two || sqrt_four == neg_two);
1133 assert_eq!(sqrt_four.square(), four);
1134
1135 let s = Scalar::from(123456789u64);
1137 let s_sq = s.square();
1138 let s_sqrt = s_sq.sqrt().unwrap();
1139 assert!(s_sqrt == s || s_sqrt == -s);
1140 assert_eq!(s_sqrt.square(), s_sq);
1141
1142 let five = Scalar::from(5u64);
1145 assert!(bool::from(five.sqrt().is_none()));
1146
1147 let neg_one = -Scalar::one();
1150 let neg_one_sqrt = neg_one.sqrt().unwrap();
1151 assert_eq!(neg_one_sqrt.square(), neg_one);
1152
1153 let mut val = R2;
1155 for _ in 0..100 {
1156 let sq = val.square();
1157 let sqrt = sq.sqrt().unwrap();
1158 assert!(sqrt == val || sqrt == -val);
1159 val += R;
1160 }
1161}
1162
1163#[test]
1164fn test_from_raw() {
1165 assert_eq!(
1166 Scalar::from_raw([
1167 0x0001_ffff_fffd,
1168 0x5884_b7fa_0003_4802,
1169 0x998c_4fef_ecbc_4ff5,
1170 0x1824_b159_acc5_056f,
1171 ]),
1172 Scalar::from_raw([0xffff_ffff_ffff_ffff; 4])
1173 );
1174
1175 assert_eq!(Scalar::from_raw(MODULUS.0), Scalar::zero());
1176
1177 assert_eq!(Scalar::from_raw([1, 0, 0, 0]), R);
1178}
1179
1180#[test]
1181fn test_scalar_hash_to_field() {
1182 let data1 = b"some input data";
1183 let data2 = b"different input data";
1184 let dst1 = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_"; let dst2 = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
1186
1187 let s1 = Scalar::hash_to_field(data1, dst1).unwrap();
1189 let s2 = Scalar::hash_to_field(data2, dst1).unwrap();
1190 assert_ne!(s1, s2);
1191
1192 let s3 = Scalar::hash_to_field(data1, dst1).unwrap();
1194 let s4 = Scalar::hash_to_field(data1, dst2).unwrap();
1195 assert_ne!(s3, s4);
1196
1197 let s5 = Scalar::hash_to_field(data1, dst1).unwrap();
1199 assert_eq!(s3, s5);
1200
1201 for test_case in &[b"" as &[u8], b"a", b"test", &[0xFF; 100], &[0x00; 64]] {
1203 let scalar = Scalar::hash_to_field(test_case, dst1).unwrap();
1204 let bytes = scalar.to_bytes();
1206 let scalar2 = Scalar::from_bytes(&bytes).unwrap();
1207 assert_eq!(scalar, scalar2, "Output should be a valid reduced scalar");
1208 }
1209
1210 let mut scalars = Vec::new();
1213 for i in 0u32..100 {
1214 let data = i.to_le_bytes();
1215 let s = Scalar::hash_to_field(&data, dst1).unwrap();
1216 scalars.push(s);
1217 }
1218 for i in 0..scalars.len() {
1220 for j in i + 1..scalars.len() {
1221 assert_ne!(
1222 scalars[i], scalars[j],
1223 "Unexpected collision at {} and {}",
1224 i, j
1225 );
1226 }
1227 }
1228
1229 let s_empty = Scalar::hash_to_field(b"", b"").unwrap();
1231 let s_empty2 = Scalar::hash_to_field(b"", b"").unwrap();
1232 assert_eq!(
1233 s_empty, s_empty2,
1234 "Empty input should still be deterministic"
1235 );
1236
1237 let dst_short = b"A";
1239 let dst_long = b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; let s_short = Scalar::hash_to_field(data1, dst_short).unwrap();
1241 let s_long = Scalar::hash_to_field(data1, dst_long).unwrap();
1242 assert_ne!(s_short, s_long, "DST length should affect output");
1243
1244 let mut has_odd = false;
1247 let mut has_even = false;
1248 for i in 0u8..20 {
1249 let s = Scalar::hash_to_field(&[i], dst1).unwrap();
1250 if s.to_bytes()[0] & 1 == 0 {
1252 has_even = true;
1253 } else {
1254 has_odd = true;
1255 }
1256 }
1257 assert!(
1258 has_odd && has_even,
1259 "Hash output should have both odd and even values"
1260 );
1261}
1262
1263#[test]
1264fn test_zeroize() {
1265 use dcrypt_internal::zeroing::Zeroize;
1266
1267 let mut a = Scalar::from_raw([
1268 0x1fff_3231_233f_fffd,
1269 0x4884_b7fa_0003_4802,
1270 0x998c_4fef_ecbc_4ff3,
1271 0x1824_b159_acc5_0562,
1272 ]);
1273 a.zeroize();
1274 assert!(bool::from(
1275 dcrypt_internal::constant_time::ConstantTimeEq::ct_eq(&a, &Scalar::zero())
1276 ));
1277}