1use crate::error::{Error, Result};
4use crate::types::{
5 ByteSerializable, ConstantTimeEq as DcryptConstantTimeEq, SecureZeroingType,
6};
7use core::fmt;
8use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
9use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
10
11#[inline(always)]
14const fn adc(a: u64, b: u64, carry: u64) -> (u64, u64) {
15 let ret = (a as u128) + (b as u128) + (carry as u128);
16 (ret as u64, (ret >> 64) as u64)
17}
18
19#[inline(always)]
21const fn sbb(a: u64, b: u64, borrow: u64) -> (u64, u64) {
22 let ret = (a as u128).wrapping_sub((b as u128) + ((borrow >> 63) as u128));
23 (ret as u64, (ret >> 64) as u64)
24}
25
26#[inline(always)]
28const fn mac(a: u64, b: u64, c: u64, carry: u64) -> (u64, u64) {
29 let ret = (a as u128) + ((b as u128) * (c as u128)) + (carry as u128);
30 (ret as u64, (ret >> 64) as u64)
31}
32
33#[derive(Clone, Copy, Eq)]
36pub struct Scalar(pub(crate) [u64; 4]);
37
38impl fmt::Debug for Scalar {
39 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
40 let tmp = self.to_bytes();
41 write!(f, "0x")?;
42 for &b in tmp.iter().rev() {
43 write!(f, "{:02x}", b)?;
44 }
45 Ok(())
46 }
47}
48
49impl fmt::Display for Scalar {
50 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51 write!(f, "{:?}", self)
52 }
53}
54
55impl From<u64> for Scalar {
56 fn from(val: u64) -> Scalar {
57 Scalar([val, 0, 0, 0]) * R2
58 }
59}
60
61impl ConstantTimeEq for Scalar {
62 fn ct_eq(&self, other: &Self) -> Choice {
63 self.0[0].ct_eq(&other.0[0])
64 & self.0[1].ct_eq(&other.0[1])
65 & self.0[2].ct_eq(&other.0[2])
66 & self.0[3].ct_eq(&other.0[3])
67 }
68}
69
70impl PartialEq for Scalar {
71 #[inline]
72 fn eq(&self, other: &Self) -> bool {
73 bool::from(subtle::ConstantTimeEq::ct_eq(self, other))
74 }
75}
76
77impl ConditionallySelectable for Scalar {
78 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
79 Scalar([
80 u64::conditional_select(&a.0[0], &b.0[0], choice),
81 u64::conditional_select(&a.0[1], &b.0[1], choice),
82 u64::conditional_select(&a.0[2], &b.0[2], choice),
83 u64::conditional_select(&a.0[3], &b.0[3], choice),
84 ])
85 }
86}
87
88const MODULUS: Scalar = Scalar([
90 0xffff_ffff_0000_0001,
91 0x53bd_a402_fffe_5bfe,
92 0x3339_d808_09a1_d805,
93 0x73ed_a753_299d_7d48,
94]);
95
96const INV: u64 = 0xffff_fffe_ffff_ffff;
98
99const R: Scalar = Scalar([
101 0x0000_0001_ffff_fffe,
102 0x5884_b7fa_0003_4802,
103 0x998c_4fef_ecbc_4ff5,
104 0x1824_b159_acc5_056f,
105]);
106
107const R2: Scalar = Scalar([
109 0xc999_e990_f3f2_9c6d,
110 0x2b6c_edcb_8792_5c23,
111 0x05d3_1496_7254_398f,
112 0x0748_d9d9_9f59_ff11,
113]);
114
115const R3: Scalar = Scalar([
117 0xc62c_1807_439b_73af,
118 0x1b3e_0d18_8cf0_6990,
119 0x73d1_3c71_c7b5_f418,
120 0x6e2a_5bb9_c8db_33e9,
121]);
122
123impl<'a> Neg for &'a Scalar {
124 type Output = Scalar;
125
126 #[inline]
127 fn neg(self) -> Scalar {
128 self.neg()
129 }
130}
131
132impl Neg for Scalar {
133 type Output = Scalar;
134
135 #[inline]
136 fn neg(self) -> Scalar {
137 -&self
138 }
139}
140
141impl<'a, 'b> Sub<&'b Scalar> for &'a Scalar {
142 type Output = Scalar;
143
144 #[inline]
145 fn sub(self, rhs: &'b Scalar) -> Scalar {
146 self.sub(rhs)
147 }
148}
149
150impl<'a, 'b> Add<&'b Scalar> for &'a Scalar {
151 type Output = Scalar;
152
153 #[inline]
154 fn add(self, rhs: &'b Scalar) -> Scalar {
155 self.add(rhs)
156 }
157}
158
159impl<'a, 'b> Mul<&'b Scalar> for &'a Scalar {
160 type Output = Scalar;
161
162 #[inline]
163 fn mul(self, rhs: &'b Scalar) -> Scalar {
164 self.mul(rhs)
165 }
166}
167
168impl<'b> Add<&'b Scalar> for Scalar {
170 type Output = Scalar;
171 #[inline]
172 fn add(self, rhs: &'b Scalar) -> Scalar {
173 &self + rhs
174 }
175}
176
177impl<'a> Add<Scalar> for &'a Scalar {
178 type Output = Scalar;
179 #[inline]
180 fn add(self, rhs: Scalar) -> Scalar {
181 self + &rhs
182 }
183}
184
185impl Add<Scalar> for Scalar {
186 type Output = Scalar;
187 #[inline]
188 fn add(self, rhs: Scalar) -> Scalar {
189 &self + &rhs
190 }
191}
192
193impl<'b> Sub<&'b Scalar> for Scalar {
194 type Output = Scalar;
195 #[inline]
196 fn sub(self, rhs: &'b Scalar) -> Scalar {
197 &self - rhs
198 }
199}
200
201impl<'a> Sub<Scalar> for &'a Scalar {
202 type Output = Scalar;
203 #[inline]
204 fn sub(self, rhs: Scalar) -> Scalar {
205 self - &rhs
206 }
207}
208
209impl Sub<Scalar> for Scalar {
210 type Output = Scalar;
211 #[inline]
212 fn sub(self, rhs: Scalar) -> Scalar {
213 &self - &rhs
214 }
215}
216
217impl SubAssign<Scalar> for Scalar {
218 #[inline]
219 fn sub_assign(&mut self, rhs: Scalar) {
220 *self = &*self - &rhs;
221 }
222}
223
224impl AddAssign<Scalar> for Scalar {
225 #[inline]
226 fn add_assign(&mut self, rhs: Scalar) {
227 *self = &*self + &rhs;
228 }
229}
230
231impl<'b> SubAssign<&'b Scalar> for Scalar {
232 #[inline]
233 fn sub_assign(&mut self, rhs: &'b Scalar) {
234 *self = &*self - rhs;
235 }
236}
237
238impl<'b> AddAssign<&'b Scalar> for Scalar {
239 #[inline]
240 fn add_assign(&mut self, rhs: &'b Scalar) {
241 *self = &*self + rhs;
242 }
243}
244
245impl<'b> Mul<&'b Scalar> for Scalar {
246 type Output = Scalar;
247 #[inline]
248 fn mul(self, rhs: &'b Scalar) -> Scalar {
249 &self * rhs
250 }
251}
252
253impl<'a> Mul<Scalar> for &'a Scalar {
254 type Output = Scalar;
255 #[inline]
256 fn mul(self, rhs: Scalar) -> Scalar {
257 self * &rhs
258 }
259}
260
261impl Mul<Scalar> for Scalar {
262 type Output = Scalar;
263 #[inline]
264 fn mul(self, rhs: Scalar) -> Scalar {
265 &self * &rhs
266 }
267}
268
269impl MulAssign<Scalar> for Scalar {
270 #[inline]
271 fn mul_assign(&mut self, rhs: Scalar) {
272 *self = &*self * &rhs;
273 }
274}
275
276impl<'b> MulAssign<&'b Scalar> for Scalar {
277 #[inline]
278 fn mul_assign(&mut self, rhs: &'b Scalar) {
279 *self = &*self * rhs;
280 }
281}
282
283impl Default for Scalar {
284 #[inline]
285 fn default() -> Self {
286 Self::zero()
287 }
288}
289
290#[cfg(feature = "zeroize")]
291impl zeroize::DefaultIsZeroes for Scalar {}
292impl ByteSerializable for Scalar {
293 fn to_bytes(&self) -> Vec<u8> {
294 self.to_bytes().to_vec()
295 }
296
297 fn from_bytes(bytes: &[u8]) -> Result<Self> {
298 if bytes.len() != 32 {
299 return Err(Error::Length {
300 context: "Scalar::from_bytes",
301 expected: 32,
302 actual: bytes.len(),
303 });
304 }
305
306 let mut array = [0u8; 32];
307 array.copy_from_slice(bytes);
308
309 Scalar::from_bytes(&array)
310 .into_option() .ok_or_else(|| Error::param("scalar_bytes", "non-canonical scalar"))
312 }
313}
314
315impl DcryptConstantTimeEq for Scalar {
316 fn ct_eq(&self, other: &Self) -> bool {
317 bool::from(subtle::ConstantTimeEq::ct_eq(self, other))
318 }
319}
320
321impl SecureZeroingType for Scalar {
322 fn zeroed() -> Self {
323 Self::zero()
324 }
325}
326
327impl Scalar {
328 #[inline]
330 pub const fn zero() -> Scalar {
331 Scalar([0, 0, 0, 0])
332 }
333
334 #[inline]
336 pub const fn one() -> Scalar {
337 R
338 }
339
340 #[inline]
342 pub const fn double(&self) -> Scalar {
343 self.add(self)
344 }
345
346 pub fn from_bytes(bytes: &[u8; 32]) -> CtOption<Scalar> {
348 let mut tmp = Scalar([0, 0, 0, 0]);
349
350 tmp.0[0] = u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[0..8]).unwrap());
351 tmp.0[1] = u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[8..16]).unwrap());
352 tmp.0[2] = u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[16..24]).unwrap());
353 tmp.0[3] = u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[24..32]).unwrap());
354
355 let (_, borrow) = sbb(tmp.0[0], MODULUS.0[0], 0);
357 let (_, borrow) = sbb(tmp.0[1], MODULUS.0[1], borrow);
358 let (_, borrow) = sbb(tmp.0[2], MODULUS.0[2], borrow);
359 let (_, borrow) = sbb(tmp.0[3], MODULUS.0[3], borrow);
360
361 let is_some = (borrow as u8) & 1;
362
363 tmp *= &R2;
365
366 CtOption::new(tmp, Choice::from(is_some))
367 }
368
369 pub fn to_bytes(&self) -> [u8; 32] {
371 let tmp = Scalar::montgomery_reduce(self.0[0], self.0[1], self.0[2], self.0[3], 0, 0, 0, 0);
373
374 let mut res = [0; 32];
375 res[0..8].copy_from_slice(&tmp.0[0].to_le_bytes());
376 res[8..16].copy_from_slice(&tmp.0[1].to_le_bytes());
377 res[16..24].copy_from_slice(&tmp.0[2].to_le_bytes());
378 res[24..32].copy_from_slice(&tmp.0[3].to_le_bytes());
379
380 res
381 }
382
383 pub fn from_bytes_wide(bytes: &[u8; 64]) -> Scalar {
385 Scalar::from_u512([
386 u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[0..8]).unwrap()),
387 u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[8..16]).unwrap()),
388 u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[16..24]).unwrap()),
389 u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[24..32]).unwrap()),
390 u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[32..40]).unwrap()),
391 u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[40..48]).unwrap()),
392 u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[48..56]).unwrap()),
393 u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[56..64]).unwrap()),
394 ])
395 }
396
397 fn from_u512(limbs: [u64; 8]) -> Scalar {
398 let d0 = Scalar([limbs[0], limbs[1], limbs[2], limbs[3]]);
399 let d1 = Scalar([limbs[4], limbs[5], limbs[6], limbs[7]]);
400 d0 * R2 + d1 * R3
401 }
402
403 pub const fn from_raw(val: [u64; 4]) -> Self {
405 (&Scalar(val)).mul(&R2)
406 }
407
408 #[inline]
410 pub const fn square(&self) -> Scalar {
411 let (r1, carry) = mac(0, self.0[0], self.0[1], 0);
412 let (r2, carry) = mac(0, self.0[0], self.0[2], carry);
413 let (r3, r4) = mac(0, self.0[0], self.0[3], carry);
414
415 let (r3, carry) = mac(r3, self.0[1], self.0[2], 0);
416 let (r4, r5) = mac(r4, self.0[1], self.0[3], carry);
417
418 let (r5, r6) = mac(r5, self.0[2], self.0[3], 0);
419
420 let r7 = r6 >> 63;
421 let r6 = (r6 << 1) | (r5 >> 63);
422 let r5 = (r5 << 1) | (r4 >> 63);
423 let r4 = (r4 << 1) | (r3 >> 63);
424 let r3 = (r3 << 1) | (r2 >> 63);
425 let r2 = (r2 << 1) | (r1 >> 63);
426 let r1 = r1 << 1;
427
428 let (r0, carry) = mac(0, self.0[0], self.0[0], 0);
429 let (r1, carry) = adc(0, r1, carry);
430 let (r2, carry) = mac(r2, self.0[1], self.0[1], carry);
431 let (r3, carry) = adc(0, r3, carry);
432 let (r4, carry) = mac(r4, self.0[2], self.0[2], carry);
433 let (r5, carry) = adc(0, r5, carry);
434 let (r6, carry) = mac(r6, self.0[3], self.0[3], carry);
435 let (r7, _) = adc(0, r7, carry);
436
437 Scalar::montgomery_reduce(r0, r1, r2, r3, r4, r5, r6, r7)
438 }
439
440 pub fn invert(&self) -> CtOption<Self> {
442 #[inline(always)]
443 fn square_assign_multi(n: &mut Scalar, num_times: usize) {
444 for _ in 0..num_times {
445 *n = n.square();
446 }
447 }
448 let mut t0 = self.square();
450 let mut t1 = t0 * self;
451 let mut t16 = t0.square();
452 let mut t6 = t16.square();
453 let mut t5 = t6 * t0;
454 t0 = t6 * t16;
455 let mut t12 = t5 * t16;
456 let mut t2 = t6.square();
457 let mut t7 = t5 * t6;
458 let mut t15 = t0 * t5;
459 let mut t17 = t12.square();
460 t1 *= t17;
461 let mut t3 = t7 * t2;
462 let t8 = t1 * t17;
463 let t4 = t8 * t2;
464 let t9 = t8 * t7;
465 t7 = t4 * t5;
466 let t11 = t4 * t17;
467 t5 = t9 * t17;
468 let t14 = t7 * t15;
469 let t13 = t11 * t12;
470 t12 = t11 * t17;
471 t15 *= &t12;
472 t16 *= &t15;
473 t3 *= &t16;
474 t17 *= &t3;
475 t0 *= &t17;
476 t6 *= &t0;
477 t2 *= &t6;
478 square_assign_multi(&mut t0, 8);
479 t0 *= &t17;
480 square_assign_multi(&mut t0, 9);
481 t0 *= &t16;
482 square_assign_multi(&mut t0, 9);
483 t0 *= &t15;
484 square_assign_multi(&mut t0, 9);
485 t0 *= &t15;
486 square_assign_multi(&mut t0, 7);
487 t0 *= &t14;
488 square_assign_multi(&mut t0, 7);
489 t0 *= &t13;
490 square_assign_multi(&mut t0, 10);
491 t0 *= &t12;
492 square_assign_multi(&mut t0, 9);
493 t0 *= &t11;
494 square_assign_multi(&mut t0, 8);
495 t0 *= &t8;
496 square_assign_multi(&mut t0, 8);
497 t0 *= self;
498 square_assign_multi(&mut t0, 14);
499 t0 *= &t9;
500 square_assign_multi(&mut t0, 10);
501 t0 *= &t8;
502 square_assign_multi(&mut t0, 15);
503 t0 *= &t7;
504 square_assign_multi(&mut t0, 10);
505 t0 *= &t6;
506 square_assign_multi(&mut t0, 8);
507 t0 *= &t5;
508 square_assign_multi(&mut t0, 16);
509 t0 *= &t3;
510 square_assign_multi(&mut t0, 8);
511 t0 *= &t2;
512 square_assign_multi(&mut t0, 7);
513 t0 *= &t4;
514 square_assign_multi(&mut t0, 9);
515 t0 *= &t2;
516 square_assign_multi(&mut t0, 8);
517 t0 *= &t3;
518 square_assign_multi(&mut t0, 8);
519 t0 *= &t2;
520 square_assign_multi(&mut t0, 8);
521 t0 *= &t2;
522 square_assign_multi(&mut t0, 8);
523 t0 *= &t2;
524 square_assign_multi(&mut t0, 8);
525 t0 *= &t3;
526 square_assign_multi(&mut t0, 8);
527 t0 *= &t2;
528 square_assign_multi(&mut t0, 8);
529 t0 *= &t2;
530 square_assign_multi(&mut t0, 5);
531 t0 *= &t1;
532 square_assign_multi(&mut t0, 5);
533 t0 *= &t1;
534
535 CtOption::new(t0, !subtle::ConstantTimeEq::ct_eq(self, &Self::zero()))
536 }
537
538 #[inline(always)]
539 const fn montgomery_reduce(
540 r0: u64,
541 r1: u64,
542 r2: u64,
543 r3: u64,
544 r4: u64,
545 r5: u64,
546 r6: u64,
547 r7: u64,
548 ) -> Self {
549 let k = r0.wrapping_mul(INV);
550 let (_, carry) = mac(r0, k, MODULUS.0[0], 0);
551 let (r1, carry) = mac(r1, k, MODULUS.0[1], carry);
552 let (r2, carry) = mac(r2, k, MODULUS.0[2], carry);
553 let (r3, carry) = mac(r3, k, MODULUS.0[3], carry);
554 let (r4, carry2) = adc(r4, 0, carry);
555
556 let k = r1.wrapping_mul(INV);
557 let (_, carry) = mac(r1, k, MODULUS.0[0], 0);
558 let (r2, carry) = mac(r2, k, MODULUS.0[1], carry);
559 let (r3, carry) = mac(r3, k, MODULUS.0[2], carry);
560 let (r4, carry) = mac(r4, k, MODULUS.0[3], carry);
561 let (r5, carry2) = adc(r5, carry2, carry);
562
563 let k = r2.wrapping_mul(INV);
564 let (_, carry) = mac(r2, k, MODULUS.0[0], 0);
565 let (r3, carry) = mac(r3, k, MODULUS.0[1], carry);
566 let (r4, carry) = mac(r4, k, MODULUS.0[2], carry);
567 let (r5, carry) = mac(r5, k, MODULUS.0[3], carry);
568 let (r6, carry2) = adc(r6, carry2, carry);
569
570 let k = r3.wrapping_mul(INV);
571 let (_, carry) = mac(r3, k, MODULUS.0[0], 0);
572 let (r4, carry) = mac(r4, k, MODULUS.0[1], carry);
573 let (r5, carry) = mac(r5, k, MODULUS.0[2], carry);
574 let (r6, carry) = mac(r6, k, MODULUS.0[3], carry);
575 let (r7, _) = adc(r7, carry2, carry);
576
577 (&Scalar([r4, r5, r6, r7])).sub(&MODULUS)
578 }
579
580 #[inline]
582 pub const fn mul(&self, rhs: &Self) -> Self {
583 let (r0, carry) = mac(0, self.0[0], rhs.0[0], 0);
584 let (r1, carry) = mac(0, self.0[0], rhs.0[1], carry);
585 let (r2, carry) = mac(0, self.0[0], rhs.0[2], carry);
586 let (r3, r4) = mac(0, self.0[0], rhs.0[3], carry);
587
588 let (r1, carry) = mac(r1, self.0[1], rhs.0[0], 0);
589 let (r2, carry) = mac(r2, self.0[1], rhs.0[1], carry);
590 let (r3, carry) = mac(r3, self.0[1], rhs.0[2], carry);
591 let (r4, r5) = mac(r4, self.0[1], rhs.0[3], carry);
592
593 let (r2, carry) = mac(r2, self.0[2], rhs.0[0], 0);
594 let (r3, carry) = mac(r3, self.0[2], rhs.0[1], carry);
595 let (r4, carry) = mac(r4, self.0[2], rhs.0[2], carry);
596 let (r5, r6) = mac(r5, self.0[2], rhs.0[3], carry);
597
598 let (r3, carry) = mac(r3, self.0[3], rhs.0[0], 0);
599 let (r4, carry) = mac(r4, self.0[3], rhs.0[1], carry);
600 let (r5, carry) = mac(r5, self.0[3], rhs.0[2], carry);
601 let (r6, r7) = mac(r6, self.0[3], rhs.0[3], carry);
602
603 Scalar::montgomery_reduce(r0, r1, r2, r3, r4, r5, r6, r7)
604 }
605
606 #[inline]
608 pub const fn sub(&self, rhs: &Self) -> Self {
609 let (d0, borrow) = sbb(self.0[0], rhs.0[0], 0);
610 let (d1, borrow) = sbb(self.0[1], rhs.0[1], borrow);
611 let (d2, borrow) = sbb(self.0[2], rhs.0[2], borrow);
612 let (d3, borrow) = sbb(self.0[3], rhs.0[3], borrow);
613
614 let (d0, carry) = adc(d0, MODULUS.0[0] & borrow, 0);
615 let (d1, carry) = adc(d1, MODULUS.0[1] & borrow, carry);
616 let (d2, carry) = adc(d2, MODULUS.0[2] & borrow, carry);
617 let (d3, _) = adc(d3, MODULUS.0[3] & borrow, carry);
618
619 Scalar([d0, d1, d2, d3])
620 }
621
622 #[inline]
624 pub const fn add(&self, rhs: &Self) -> Self {
625 let (d0, carry) = adc(self.0[0], rhs.0[0], 0);
626 let (d1, carry) = adc(self.0[1], rhs.0[1], carry);
627 let (d2, carry) = adc(self.0[2], rhs.0[2], carry);
628 let (d3, _) = adc(self.0[3], rhs.0[3], carry);
629
630 (&Scalar([d0, d1, d2, d3])).sub(&MODULUS)
631 }
632
633 #[inline]
635 pub const fn neg(&self) -> Self {
636 let (d0, borrow) = sbb(MODULUS.0[0], self.0[0], 0);
637 let (d1, borrow) = sbb(MODULUS.0[1], self.0[1], borrow);
638 let (d2, borrow) = sbb(MODULUS.0[2], self.0[2], borrow);
639 let (d3, _) = sbb(MODULUS.0[3], self.0[3], borrow);
640
641 let mask = (((self.0[0] | self.0[1] | self.0[2] | self.0[3]) == 0) as u64).wrapping_sub(1);
642
643 Scalar([d0 & mask, d1 & mask, d2 & mask, d3 & mask])
644 }
645}
646
647impl From<Scalar> for [u8; 32] {
648 fn from(value: Scalar) -> [u8; 32] {
649 value.to_bytes()
650 }
651}
652
653impl<'a> From<&'a Scalar> for [u8; 32] {
654 fn from(value: &'a Scalar) -> [u8; 32] {
655 value.to_bytes()
656 }
657}
658
659impl<T> core::iter::Sum<T> for Scalar
660where
661 T: core::borrow::Borrow<Scalar>,
662{
663 fn sum<I>(iter: I) -> Self
664 where
665 I: Iterator<Item = T>,
666 {
667 iter.fold(Self::zero(), |acc, item| acc + item.borrow())
668 }
669}
670
671impl<T> core::iter::Product<T> for Scalar
672where
673 T: core::borrow::Borrow<Scalar>,
674{
675 fn product<I>(iter: I) -> Self
676 where
677 I: Iterator<Item = T>,
678 {
679 iter.fold(Self::one(), |acc, item| acc * item.borrow())
680 }
681}
682
683#[test]
685fn test_inv() {
686 let mut inv = 1u64;
688 for _ in 0..63 {
689 inv = inv.wrapping_mul(inv);
690 inv = inv.wrapping_mul(MODULUS.0[0]);
691 }
692 inv = inv.wrapping_neg();
693 assert_eq!(inv, INV);
694}
695
696#[cfg(feature = "std")]
697#[test]
698fn test_debug() {
699 assert_eq!(
700 format!("{:?}", Scalar::zero()),
701 "0x0000000000000000000000000000000000000000000000000000000000000000"
702 );
703 assert_eq!(
704 format!("{:?}", Scalar::one()),
705 "0x0000000000000000000000000000000000000000000000000000000000000001"
706 );
707 assert_eq!(
708 format!("{:?}", R2),
709 "0x1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffe"
710 );
711}
712
713#[test]
714fn test_equality() {
715 assert_eq!(Scalar::zero(), Scalar::zero());
716 assert_eq!(Scalar::one(), Scalar::one());
717 #[allow(clippy::eq_op)]
718 {
719 assert_eq!(R2, R2);
720 }
721
722 assert!(Scalar::zero() != Scalar::one());
723 assert!(Scalar::one() != R2);
724}
725
726#[test]
727fn test_to_bytes() {
728 assert_eq!(
729 Scalar::zero().to_bytes(),
730 [
731 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,
732 0, 0, 0
733 ]
734 );
735
736 assert_eq!(
737 Scalar::one().to_bytes(),
738 [
739 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,
740 0, 0, 0
741 ]
742 );
743
744 assert_eq!(
745 R2.to_bytes(),
746 [
747 254, 255, 255, 255, 1, 0, 0, 0, 2, 72, 3, 0, 250, 183, 132, 88, 245, 79, 188, 236, 239,
748 79, 140, 153, 111, 5, 197, 172, 89, 177, 36, 24
749 ]
750 );
751
752 assert_eq!(
753 (-&Scalar::one()).to_bytes(),
754 [
755 0, 0, 0, 0, 255, 255, 255, 255, 254, 91, 254, 255, 2, 164, 189, 83, 5, 216, 161, 9, 8,
756 216, 57, 51, 72, 125, 157, 41, 83, 167, 237, 115
757 ]
758 );
759}
760
761#[test]
762fn test_from_bytes() {
763 let mut a = R2;
764
765 for _ in 0..100 {
766 let bytes = a.to_bytes();
767 let b = Scalar::from_bytes(&bytes).unwrap();
768 assert_eq!(a, b);
769
770 let bytes = (-a).to_bytes();
772 let b = Scalar::from_bytes(&bytes).unwrap();
773 assert_eq!(-a, b);
774
775 a = a.square();
776 }
777}
778
779#[cfg(test)]
780const LARGEST: Scalar = Scalar([
781 0xffff_ffff_0000_0000,
782 0x53bd_a402_fffe_5bfe,
783 0x3339_d808_09a1_d805,
784 0x73ed_a753_299d_7d48,
785]);
786
787#[test]
788fn test_addition() {
789 let mut tmp = LARGEST;
790 tmp += &LARGEST;
791
792 assert_eq!(
793 tmp,
794 Scalar([
795 0xffff_fffe_ffff_ffff,
796 0x53bd_a402_fffe_5bfe,
797 0x3339_d808_09a1_d805,
798 0x73ed_a753_299d_7d48,
799 ])
800 );
801
802 let mut tmp = LARGEST;
803 tmp += &Scalar([1, 0, 0, 0]);
804
805 assert_eq!(tmp, Scalar::zero());
806}
807
808#[test]
809fn test_inversion() {
810 assert!(bool::from(Scalar::zero().invert().is_none()));
811 assert_eq!(Scalar::one().invert().unwrap(), Scalar::one());
812 assert_eq!((-&Scalar::one()).invert().unwrap(), -&Scalar::one());
813
814 let mut tmp = R2;
815
816 for _ in 0..100 {
817 let mut tmp2 = tmp.invert().unwrap();
818 tmp2.mul_assign(&tmp);
819
820 assert_eq!(tmp2, Scalar::one());
821
822 tmp.add_assign(&R2);
823 }
824}
825
826#[test]
827fn test_from_raw() {
828 assert_eq!(
829 Scalar::from_raw([
830 0x0001_ffff_fffd,
831 0x5884_b7fa_0003_4802,
832 0x998c_4fef_ecbc_4ff5,
833 0x1824_b159_acc5_056f,
834 ]),
835 Scalar::from_raw([0xffff_ffff_ffff_ffff; 4])
836 );
837
838 assert_eq!(Scalar::from_raw(MODULUS.0), Scalar::zero());
839
840 assert_eq!(Scalar::from_raw([1, 0, 0, 0]), R);
841}
842
843#[cfg(feature = "zeroize")]
844#[test]
845fn test_zeroize() {
846 use zeroize::Zeroize;
847
848 let mut a = Scalar::from_raw([
849 0x1fff_3231_233f_fffd,
850 0x4884_b7fa_0003_4802,
851 0x998c_4fef_ecbc_4ff3,
852 0x1824_b159_acc5_0562,
853 ]);
854 a.zeroize();
855 assert!(bool::from(subtle::ConstantTimeEq::ct_eq(&a, &Scalar::zero())));
857}