1use alloc::string::{String, ToString};
2use core::fmt;
3use core::ops::{
4 Add, AddAssign, Div, DivAssign, Mul, MulAssign, Not, Rem, RemAssign, Shl, ShlAssign, Shr,
5 ShrAssign, Sub, SubAssign,
6};
7use core::str::FromStr;
8use serde::{de, ser, Deserialize, Deserializer, Serialize};
9
10use crate::errors::{
11 ConversionOverflowError, DivideByZeroError, OverflowError, OverflowOperation, StdError,
12};
13use crate::forward_ref::{forward_ref_binop, forward_ref_op_assign};
14use crate::{
15 Int128, Int256, Int512, Int64, Uint128, Uint256, Uint64, __internal::forward_ref_partial_eq,
16};
17
18use bnum::types::U512;
21
22use super::conversion::{forward_try_from, try_from_int_to_uint};
23use super::num_consts::NumConsts;
24
25#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, schemars::JsonSchema)]
50pub struct Uint512(#[schemars(with = "String")] pub(crate) U512);
51
52forward_ref_partial_eq!(Uint512, Uint512);
53
54impl Uint512 {
55 pub const MAX: Uint512 = Uint512(U512::MAX);
56 pub const MIN: Uint512 = Uint512(U512::ZERO);
57
58 pub const fn new(value: [u8; 64]) -> Self {
61 Self::from_be_bytes(value)
62 }
63
64 #[inline]
66 pub const fn zero() -> Self {
67 Uint512(U512::ZERO)
68 }
69
70 #[inline]
72 pub const fn one() -> Self {
73 Self(U512::ONE)
74 }
75
76 #[must_use]
77 pub const fn from_be_bytes(data: [u8; 64]) -> Self {
78 let words: [u64; 8] = [
79 u64::from_le_bytes([
80 data[63], data[62], data[61], data[60], data[59], data[58], data[57], data[56],
81 ]),
82 u64::from_le_bytes([
83 data[55], data[54], data[53], data[52], data[51], data[50], data[49], data[48],
84 ]),
85 u64::from_le_bytes([
86 data[47], data[46], data[45], data[44], data[43], data[42], data[41], data[40],
87 ]),
88 u64::from_le_bytes([
89 data[39], data[38], data[37], data[36], data[35], data[34], data[33], data[32],
90 ]),
91 u64::from_le_bytes([
92 data[31], data[30], data[29], data[28], data[27], data[26], data[25], data[24],
93 ]),
94 u64::from_le_bytes([
95 data[23], data[22], data[21], data[20], data[19], data[18], data[17], data[16],
96 ]),
97 u64::from_le_bytes([
98 data[15], data[14], data[13], data[12], data[11], data[10], data[9], data[8],
99 ]),
100 u64::from_le_bytes([
101 data[7], data[6], data[5], data[4], data[3], data[2], data[1], data[0],
102 ]),
103 ];
104 Self(U512::from_digits(words))
105 }
106
107 #[must_use]
108 pub const fn from_le_bytes(data: [u8; 64]) -> Self {
109 let words: [u64; 8] = [
110 u64::from_le_bytes([
111 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
112 ]),
113 u64::from_le_bytes([
114 data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15],
115 ]),
116 u64::from_le_bytes([
117 data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23],
118 ]),
119 u64::from_le_bytes([
120 data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31],
121 ]),
122 u64::from_le_bytes([
123 data[32], data[33], data[34], data[35], data[36], data[37], data[38], data[39],
124 ]),
125 u64::from_le_bytes([
126 data[40], data[41], data[42], data[43], data[44], data[45], data[46], data[47],
127 ]),
128 u64::from_le_bytes([
129 data[48], data[49], data[50], data[51], data[52], data[53], data[54], data[55],
130 ]),
131 u64::from_le_bytes([
132 data[56], data[57], data[58], data[59], data[60], data[61], data[62], data[63],
133 ]),
134 ];
135 Self(U512::from_digits(words))
136 }
137
138 #[must_use]
141 pub const fn from_uint256(num: Uint256) -> Self {
142 let bytes = num.to_le_bytes();
143 Self::from_le_bytes([
144 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
145 bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
146 bytes[16], bytes[17], bytes[18], bytes[19], bytes[20], bytes[21], bytes[22], bytes[23],
147 bytes[24], bytes[25], bytes[26], bytes[27], bytes[28], bytes[29], bytes[30], bytes[31],
148 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,
149 0, 0, 0,
150 ])
151 }
152
153 #[must_use = "this returns the result of the operation, without modifying the original"]
155 pub const fn to_be_bytes(self) -> [u8; 64] {
156 let words = self.0.digits();
157 let words = [
158 words[7].to_be_bytes(),
159 words[6].to_be_bytes(),
160 words[5].to_be_bytes(),
161 words[4].to_be_bytes(),
162 words[3].to_be_bytes(),
163 words[2].to_be_bytes(),
164 words[1].to_be_bytes(),
165 words[0].to_be_bytes(),
166 ];
167 unsafe { core::mem::transmute::<[[u8; 8]; 8], [u8; 64]>(words) }
168 }
169
170 #[must_use = "this returns the result of the operation, without modifying the original"]
172 pub const fn to_le_bytes(self) -> [u8; 64] {
173 let words = self.0.digits();
174 let words = [
175 words[0].to_le_bytes(),
176 words[1].to_le_bytes(),
177 words[2].to_le_bytes(),
178 words[3].to_le_bytes(),
179 words[4].to_le_bytes(),
180 words[5].to_le_bytes(),
181 words[6].to_le_bytes(),
182 words[7].to_le_bytes(),
183 ];
184 unsafe { core::mem::transmute::<[[u8; 8]; 8], [u8; 64]>(words) }
185 }
186
187 #[must_use]
188 pub const fn is_zero(&self) -> bool {
189 self.0.is_zero()
190 }
191
192 #[must_use = "this returns the result of the operation, without modifying the original"]
193 pub const fn pow(self, exp: u32) -> Self {
194 match self.0.checked_pow(exp) {
195 Some(val) => Self(val),
196 None => panic!("attempt to exponentiate with overflow"),
197 }
198 }
199
200 #[must_use = "this returns the result of the operation, without modifying the original"]
206 pub fn ilog2(self) -> u32 {
207 self.0.checked_ilog2().unwrap()
208 }
209
210 pub fn checked_add(self, other: Self) -> Result<Self, OverflowError> {
211 self.0
212 .checked_add(other.0)
213 .map(Self)
214 .ok_or_else(|| OverflowError::new(OverflowOperation::Add))
215 }
216
217 pub fn checked_sub(self, other: Self) -> Result<Self, OverflowError> {
218 self.0
219 .checked_sub(other.0)
220 .map(Self)
221 .ok_or_else(|| OverflowError::new(OverflowOperation::Sub))
222 }
223
224 pub fn checked_mul(self, other: Self) -> Result<Self, OverflowError> {
225 self.0
226 .checked_mul(other.0)
227 .map(Self)
228 .ok_or_else(|| OverflowError::new(OverflowOperation::Mul))
229 }
230
231 pub fn checked_pow(self, exp: u32) -> Result<Self, OverflowError> {
232 self.0
233 .checked_pow(exp)
234 .map(Self)
235 .ok_or_else(|| OverflowError::new(OverflowOperation::Pow))
236 }
237
238 pub fn checked_div(self, other: Self) -> Result<Self, DivideByZeroError> {
239 self.0
240 .checked_div(other.0)
241 .map(Self)
242 .ok_or(DivideByZeroError)
243 }
244
245 pub fn checked_div_euclid(self, other: Self) -> Result<Self, DivideByZeroError> {
246 self.checked_div(other)
247 }
248
249 pub fn checked_rem(self, other: Self) -> Result<Self, DivideByZeroError> {
250 self.0
251 .checked_rem(other.0)
252 .map(Self)
253 .ok_or(DivideByZeroError)
254 }
255
256 pub fn checked_shr(self, other: u32) -> Result<Self, OverflowError> {
257 self.0
258 .checked_shr(other)
259 .map(Self)
260 .ok_or_else(|| OverflowError::new(OverflowOperation::Shr))
261 }
262
263 pub fn checked_shl(self, other: u32) -> Result<Self, OverflowError> {
264 if other >= 512 {
265 return Err(OverflowError::new(OverflowOperation::Shl));
266 }
267
268 Ok(Self(self.0.shl(other)))
269 }
270
271 #[must_use = "this returns the result of the operation, without modifying the original"]
272 #[inline]
273 pub fn wrapping_add(self, other: Self) -> Self {
274 Self(self.0.wrapping_add(other.0))
275 }
276
277 #[must_use = "this returns the result of the operation, without modifying the original"]
278 #[inline]
279 pub fn wrapping_sub(self, other: Self) -> Self {
280 Self(self.0.wrapping_sub(other.0))
281 }
282
283 #[must_use = "this returns the result of the operation, without modifying the original"]
284 #[inline]
285 pub fn wrapping_mul(self, other: Self) -> Self {
286 Self(self.0.wrapping_mul(other.0))
287 }
288
289 #[must_use = "this returns the result of the operation, without modifying the original"]
290 #[inline]
291 pub fn wrapping_pow(self, other: u32) -> Self {
292 Self(self.0.wrapping_pow(other))
293 }
294
295 #[must_use = "this returns the result of the operation, without modifying the original"]
296 pub fn saturating_add(self, other: Self) -> Self {
297 Self(self.0.saturating_add(other.0))
298 }
299
300 #[must_use = "this returns the result of the operation, without modifying the original"]
301 pub fn saturating_sub(self, other: Self) -> Self {
302 Self(self.0.saturating_sub(other.0))
303 }
304
305 #[must_use = "this returns the result of the operation, without modifying the original"]
306 pub fn saturating_mul(self, other: Self) -> Self {
307 Self(self.0.saturating_mul(other.0))
308 }
309
310 #[must_use = "this returns the result of the operation, without modifying the original"]
311 pub fn saturating_pow(self, exp: u32) -> Self {
312 Self(self.0.saturating_pow(exp))
313 }
314
315 #[must_use = "this returns the result of the operation, without modifying the original"]
319 pub const fn strict_add(self, rhs: Self) -> Self {
320 match self.0.checked_add(rhs.0) {
321 None => panic!("attempt to add with overflow"),
322 Some(sum) => Self(sum),
323 }
324 }
325
326 #[must_use = "this returns the result of the operation, without modifying the original"]
330 pub const fn strict_sub(self, other: Self) -> Self {
331 match self.0.checked_sub(other.0) {
332 None => panic!("attempt to subtract with overflow"),
333 Some(diff) => Self(diff),
334 }
335 }
336
337 #[must_use = "this returns the result of the operation, without modifying the original"]
338 pub const fn abs_diff(self, other: Self) -> Self {
339 Self(self.0.abs_diff(other.0))
340 }
341}
342
343impl NumConsts for Uint512 {
344 const ZERO: Self = Self::zero();
345 const ONE: Self = Self::one();
346 const MAX: Self = Self::MAX;
347 const MIN: Self = Self::MIN;
348}
349
350impl From<Uint256> for Uint512 {
351 fn from(val: Uint256) -> Self {
352 let mut bytes = [0u8; 64];
353 bytes[32..].copy_from_slice(&val.to_be_bytes());
354
355 Self::from_be_bytes(bytes)
356 }
357}
358
359impl From<Uint128> for Uint512 {
360 fn from(val: Uint128) -> Self {
361 val.u128().into()
362 }
363}
364
365impl From<Uint64> for Uint512 {
366 fn from(val: Uint64) -> Self {
367 val.u64().into()
368 }
369}
370
371impl From<u128> for Uint512 {
372 fn from(val: u128) -> Self {
373 Uint512(val.into())
374 }
375}
376
377impl From<u64> for Uint512 {
378 fn from(val: u64) -> Self {
379 Uint512(val.into())
380 }
381}
382
383impl From<u32> for Uint512 {
384 fn from(val: u32) -> Self {
385 Uint512(val.into())
386 }
387}
388
389impl From<u16> for Uint512 {
390 fn from(val: u16) -> Self {
391 Uint512(val.into())
392 }
393}
394
395impl From<u8> for Uint512 {
396 fn from(val: u8) -> Self {
397 Uint512(val.into())
398 }
399}
400
401impl TryFrom<Uint512> for Uint256 {
402 type Error = ConversionOverflowError;
403
404 fn try_from(value: Uint512) -> Result<Self, Self::Error> {
405 let bytes = value.to_be_bytes();
406 let (first_bytes, last_bytes) = bytes.split_at(32);
407
408 if first_bytes != [0u8; 32] {
409 return Err(ConversionOverflowError::new("Uint512", "Uint256"));
410 }
411
412 Ok(Self::from_be_bytes(last_bytes.try_into().unwrap()))
413 }
414}
415
416forward_try_from!(Uint512, Uint128);
417forward_try_from!(Uint512, Uint64);
418
419try_from_int_to_uint!(Int64, Uint512);
421try_from_int_to_uint!(Int128, Uint512);
422try_from_int_to_uint!(Int256, Uint512);
423try_from_int_to_uint!(Int512, Uint512);
424
425impl TryFrom<&str> for Uint512 {
426 type Error = StdError;
427
428 fn try_from(val: &str) -> Result<Self, Self::Error> {
429 Self::from_str(val)
430 }
431}
432
433impl FromStr for Uint512 {
434 type Err = StdError;
435
436 fn from_str(s: &str) -> Result<Self, Self::Err> {
437 match U512::from_str_radix(s, 10) {
438 Ok(u) => Ok(Self(u)),
439 Err(e) => Err(StdError::generic_err(format!("Parsing u512: {e}"))),
440 }
441 }
442}
443
444impl From<Uint512> for String {
445 fn from(original: Uint512) -> Self {
446 original.to_string()
447 }
448}
449
450impl fmt::Display for Uint512 {
451 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
452 self.0.fmt(f)
453 }
454}
455
456impl Add<Uint512> for Uint512 {
457 type Output = Self;
458
459 fn add(self, rhs: Self) -> Self {
460 self.strict_add(rhs)
461 }
462}
463forward_ref_binop!(impl Add, add for Uint512, Uint512);
464
465impl Sub<Uint512> for Uint512 {
466 type Output = Self;
467
468 fn sub(self, rhs: Self) -> Self {
469 self.strict_sub(rhs)
470 }
471}
472forward_ref_binop!(impl Sub, sub for Uint512, Uint512);
473
474impl SubAssign<Uint512> for Uint512 {
475 fn sub_assign(&mut self, rhs: Uint512) {
476 self.0 = self.0.checked_sub(rhs.0).unwrap();
477 }
478}
479forward_ref_op_assign!(impl SubAssign, sub_assign for Uint512, Uint512);
480
481impl Div<Uint512> for Uint512 {
482 type Output = Self;
483
484 fn div(self, rhs: Self) -> Self::Output {
485 Self(self.0.checked_div(rhs.0).unwrap())
486 }
487}
488
489impl<'a> Div<&'a Uint512> for Uint512 {
490 type Output = Self;
491
492 fn div(self, rhs: &'a Uint512) -> Self::Output {
493 Self(self.0.checked_div(rhs.0).unwrap())
494 }
495}
496
497impl Rem for Uint512 {
498 type Output = Self;
499
500 #[inline]
504 fn rem(self, rhs: Self) -> Self {
505 Self(self.0.rem(rhs.0))
506 }
507}
508forward_ref_binop!(impl Rem, rem for Uint512, Uint512);
509
510impl Not for Uint512 {
511 type Output = Self;
512
513 fn not(self) -> Self::Output {
514 Self(!self.0)
515 }
516}
517
518impl RemAssign<Uint512> for Uint512 {
519 fn rem_assign(&mut self, rhs: Uint512) {
520 *self = *self % rhs;
521 }
522}
523forward_ref_op_assign!(impl RemAssign, rem_assign for Uint512, Uint512);
524
525impl Mul<Uint512> for Uint512 {
526 type Output = Self;
527
528 fn mul(self, rhs: Self) -> Self::Output {
529 Self(self.0.checked_mul(rhs.0).unwrap())
530 }
531}
532forward_ref_binop!(impl Mul, mul for Uint512, Uint512);
533
534impl MulAssign<Uint512> for Uint512 {
535 fn mul_assign(&mut self, rhs: Self) {
536 self.0 = self.0.checked_mul(rhs.0).unwrap();
537 }
538}
539forward_ref_op_assign!(impl MulAssign, mul_assign for Uint512, Uint512);
540
541impl Shr<u32> for Uint512 {
542 type Output = Self;
543
544 fn shr(self, rhs: u32) -> Self::Output {
545 self.checked_shr(rhs).unwrap_or_else(|_| {
546 panic!(
547 "right shift error: {rhs} is larger or equal than the number of bits in Uint512",
548 )
549 })
550 }
551}
552
553impl<'a> Shr<&'a u32> for Uint512 {
554 type Output = Self;
555
556 fn shr(self, rhs: &'a u32) -> Self::Output {
557 Shr::<u32>::shr(self, *rhs)
558 }
559}
560
561impl Shl<u32> for Uint512 {
562 type Output = Self;
563
564 fn shl(self, rhs: u32) -> Self::Output {
565 self.checked_shl(rhs)
566 .expect("attempt to shift left with overflow")
567 }
568}
569
570impl<'a> Shl<&'a u32> for Uint512 {
571 type Output = Self;
572
573 fn shl(self, rhs: &'a u32) -> Self::Output {
574 self.shl(*rhs)
575 }
576}
577
578impl AddAssign<Uint512> for Uint512 {
579 fn add_assign(&mut self, rhs: Uint512) {
580 self.0 = self.0.checked_add(rhs.0).unwrap();
581 }
582}
583
584impl<'a> AddAssign<&'a Uint512> for Uint512 {
585 fn add_assign(&mut self, rhs: &'a Uint512) {
586 self.0 = self.0.checked_add(rhs.0).unwrap();
587 }
588}
589
590impl DivAssign<Uint512> for Uint512 {
591 fn div_assign(&mut self, rhs: Self) {
592 self.0 = self.0.checked_div(rhs.0).unwrap();
593 }
594}
595
596impl<'a> DivAssign<&'a Uint512> for Uint512 {
597 fn div_assign(&mut self, rhs: &'a Uint512) {
598 self.0 = self.0.checked_div(rhs.0).unwrap();
599 }
600}
601
602impl ShrAssign<u32> for Uint512 {
603 fn shr_assign(&mut self, rhs: u32) {
604 *self = Shr::<u32>::shr(*self, rhs);
605 }
606}
607
608impl<'a> ShrAssign<&'a u32> for Uint512 {
609 fn shr_assign(&mut self, rhs: &'a u32) {
610 *self = Shr::<u32>::shr(*self, *rhs);
611 }
612}
613
614impl ShlAssign<u32> for Uint512 {
615 fn shl_assign(&mut self, rhs: u32) {
616 *self = self.shl(rhs);
617 }
618}
619
620impl<'a> ShlAssign<&'a u32> for Uint512 {
621 fn shl_assign(&mut self, rhs: &'a u32) {
622 *self = self.shl(*rhs);
623 }
624}
625
626impl Serialize for Uint512 {
627 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
629 where
630 S: ser::Serializer,
631 {
632 serializer.serialize_str(&self.to_string())
633 }
634}
635
636impl<'de> Deserialize<'de> for Uint512 {
637 fn deserialize<D>(deserializer: D) -> Result<Uint512, D::Error>
639 where
640 D: Deserializer<'de>,
641 {
642 deserializer.deserialize_str(Uint512Visitor)
643 }
644}
645
646struct Uint512Visitor;
647
648impl<'de> de::Visitor<'de> for Uint512Visitor {
649 type Value = Uint512;
650
651 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
652 formatter.write_str("string-encoded integer")
653 }
654
655 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
656 where
657 E: de::Error,
658 {
659 Uint512::try_from(v).map_err(|e| E::custom(format_args!("invalid Uint512 '{v}' - {e}")))
660 }
661}
662
663impl<A> core::iter::Sum<A> for Uint512
664where
665 Self: Add<A, Output = Self>,
666{
667 fn sum<I: Iterator<Item = A>>(iter: I) -> Self {
668 iter.fold(Self::zero(), Add::add)
669 }
670}
671
672#[cfg(test)]
673mod tests {
674 use super::*;
675 use crate::math::conversion::test_try_from_int_to_uint;
676
677 #[test]
678 fn size_of_works() {
679 assert_eq!(core::mem::size_of::<Uint512>(), 64);
680 }
681
682 #[test]
683 fn uint512_new_works() {
684 let num = Uint512::new([1; 64]);
685 let a: [u8; 64] = num.to_be_bytes();
686 assert_eq!(a, [1; 64]);
687
688 let be_bytes = [
689 0u8, 222u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
690 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
691 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
692 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8,
693 ];
694 let num = Uint512::new(be_bytes);
695 let resulting_bytes: [u8; 64] = num.to_be_bytes();
696 assert_eq!(be_bytes, resulting_bytes);
697 }
698
699 #[test]
700 fn uint512_not_works() {
701 let num = Uint512::new([1; 64]);
702 let a = (!num).to_be_bytes();
703 assert_eq!(a, [254; 64]);
704
705 assert_eq!(!Uint512::MAX, Uint512::MIN);
706 assert_eq!(!Uint512::MIN, Uint512::MAX);
707 }
708
709 #[test]
710 fn uint512_zero_works() {
711 let zero = Uint512::zero();
712 assert_eq!(
713 zero.to_be_bytes(),
714 [
715 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,
716 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,
717 0, 0, 0, 0, 0, 0, 0, 0
718 ]
719 );
720 }
721
722 #[test]
723 fn uin512_one_works() {
724 let one = Uint512::one();
725 assert_eq!(
726 one.to_be_bytes(),
727 [
728 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,
729 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,
730 0, 0, 0, 0, 0, 0, 0, 1
731 ]
732 );
733 }
734
735 #[test]
736 fn uint512_endianness() {
737 let be_bytes = [
738 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
739 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
740 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
741 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8,
742 ];
743 let le_bytes = [
744 3u8, 2u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
745 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
746 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
747 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
748 ];
749
750 let num1 = Uint512::new(be_bytes);
752 let num2 = Uint512::from_be_bytes(be_bytes);
753 let num3 = Uint512::from_le_bytes(le_bytes);
754 assert_eq!(num1, Uint512::from(65536u32 + 512 + 3));
755 assert_eq!(num1, num2);
756 assert_eq!(num1, num3);
757 }
758
759 #[test]
760 fn uint512_convert_from() {
761 let a = Uint512::from(5u128);
762 assert_eq!(a.0, U512::from(5u32));
763
764 let a = Uint512::from(5u64);
765 assert_eq!(a.0, U512::from(5u32));
766
767 let a = Uint512::from(5u32);
768 assert_eq!(a.0, U512::from(5u32));
769
770 let a = Uint512::from(5u16);
771 assert_eq!(a.0, U512::from(5u32));
772
773 let a = Uint512::from(5u8);
774 assert_eq!(a.0, U512::from(5u32));
775
776 let result = Uint512::try_from("34567");
777 assert_eq!(
778 result.unwrap().0,
779 U512::from_str_radix("34567", 10).unwrap()
780 );
781
782 let result = Uint512::try_from("1.23");
783 assert!(result.is_err());
784 }
785
786 #[test]
787 fn uint512_try_from_signed_works() {
788 test_try_from_int_to_uint::<Int64, Uint512>("Int64", "Uint512");
789 test_try_from_int_to_uint::<Int128, Uint512>("Int128", "Uint512");
790 test_try_from_int_to_uint::<Int256, Uint512>("Int256", "Uint512");
791 test_try_from_int_to_uint::<Int512, Uint512>("Int512", "Uint512");
792 }
793
794 #[test]
795 fn uint512_try_into() {
796 assert!(Uint64::try_from(Uint512::MAX).is_err());
797 assert!(Uint128::try_from(Uint512::MAX).is_err());
798 assert!(Uint256::try_from(Uint512::MAX).is_err());
799
800 assert_eq!(Uint64::try_from(Uint512::zero()), Ok(Uint64::zero()));
801 assert_eq!(Uint128::try_from(Uint512::zero()), Ok(Uint128::zero()));
802 assert_eq!(Uint256::try_from(Uint512::zero()), Ok(Uint256::zero()));
803
804 assert_eq!(
805 Uint64::try_from(Uint512::from(42u64)),
806 Ok(Uint64::from(42u64))
807 );
808 assert_eq!(
809 Uint128::try_from(Uint512::from(42u128)),
810 Ok(Uint128::from(42u128))
811 );
812 assert_eq!(
813 Uint256::try_from(Uint512::from(42u128)),
814 Ok(Uint256::from(42u128))
815 );
816 }
817
818 #[test]
819 fn uint512_convert_to_uint128() {
820 let source = Uint512::from(42u128);
821 let target = Uint128::try_from(source);
822 assert_eq!(target, Ok(Uint128::new(42u128)));
823
824 let source = Uint512::MAX;
825 let target = Uint128::try_from(source);
826 assert_eq!(
827 target,
828 Err(ConversionOverflowError::new("Uint512", "Uint128"))
829 );
830 }
831
832 #[test]
833 fn uint512_from_uint256() {
834 assert_eq!(
835 Uint512::from_uint256(Uint256::from_str("123").unwrap()),
836 Uint512::from_str("123").unwrap()
837 );
838
839 assert_eq!(
840 Uint512::from_uint256(Uint256::from_str("9785746283745").unwrap()),
841 Uint512::from_str("9785746283745").unwrap()
842 );
843
844 assert_eq!(
845 Uint512::from_uint256(
846 Uint256::from_str(
847 "97857462837575757832978493758398593853985452378423874623874628736482736487236"
848 )
849 .unwrap()
850 ),
851 Uint512::from_str(
852 "97857462837575757832978493758398593853985452378423874623874628736482736487236"
853 )
854 .unwrap()
855 );
856 }
857
858 #[test]
859 fn uint512_implements_display() {
860 let a = Uint512::from(12345u32);
861 assert_eq!(format!("Embedded: {a}"), "Embedded: 12345");
862 assert_eq!(a.to_string(), "12345");
863
864 let a = Uint512::zero();
865 assert_eq!(format!("Embedded: {a}"), "Embedded: 0");
866 assert_eq!(a.to_string(), "0");
867 }
868
869 #[test]
870 fn uint512_display_padding_works() {
871 let a = Uint512::from(123u64);
873 assert_eq!(format!("Embedded: {a:05}"), "Embedded: 00123");
874
875 let a = Uint512::from(123u64);
877 assert_eq!(format!("Embedded: {a:02}"), "Embedded: 123");
878 }
879
880 #[test]
881 fn uint512_to_be_bytes_works() {
882 assert_eq!(
883 Uint512::zero().to_be_bytes(),
884 [
885 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,
886 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,
887 0, 0, 0, 0, 0, 0, 0, 0,
888 ]
889 );
890 assert_eq!(
891 Uint512::MAX.to_be_bytes(),
892 [
893 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
894 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
895 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
896 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
897 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
898 ]
899 );
900 assert_eq!(
901 Uint512::from(1u128).to_be_bytes(),
902 [
903 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,
904 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,
905 0, 0, 0, 0, 0, 0, 0, 1
906 ]
907 );
908 assert_eq!(
910 Uint512::from(240282366920938463463374607431768124608u128).to_be_bytes(),
911 [
912 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,
913 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 196, 179, 87, 165,
914 121, 59, 133, 246, 117, 221, 191, 255, 254, 172, 192
915 ]
916 );
917 assert_eq!(
918 Uint512::from_be_bytes([
919 17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54,
920 211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240, 218, 88, 106, 45, 208, 134,
921 238, 119, 85, 22, 14, 88, 166, 195, 154, 73, 64, 10, 44, 59, 13, 22, 47, 12, 99, 8,
922 252, 96, 230, 187, 38, 29
923 ])
924 .to_be_bytes(),
925 [
926 17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54,
927 211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240, 218, 88, 106, 45, 208, 134,
928 238, 119, 85, 22, 14, 88, 166, 195, 154, 73, 64, 10, 44, 59, 13, 22, 47, 12, 99, 8,
929 252, 96, 230, 187, 38, 29
930 ]
931 );
932 }
933
934 #[test]
935 fn uint512_to_le_bytes_works() {
936 assert_eq!(
937 Uint512::zero().to_le_bytes(),
938 [
939 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,
940 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,
941 0, 0, 0, 0, 0, 0, 0, 0
942 ]
943 );
944 assert_eq!(
945 Uint512::MAX.to_le_bytes(),
946 [
947 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
948 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
949 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
950 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
951 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
952 ]
953 );
954 assert_eq!(
955 Uint512::from(1u128).to_le_bytes(),
956 [
957 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,
958 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,
959 0, 0, 0, 0, 0, 0, 0, 0
960 ]
961 );
962 assert_eq!(
964 Uint512::from(240282366920938463463374607431768124608u128).to_le_bytes(),
965 [
966 192, 172, 254, 255, 191, 221, 117, 246, 133, 59, 121, 165, 87, 179, 196, 180, 0, 0,
967 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,
968 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
969 ]
970 );
971 assert_eq!(
972 Uint512::from_be_bytes([
973 17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54,
974 211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240, 218, 88, 106, 45, 208, 134,
975 238, 119, 85, 22, 14, 88, 166, 195, 154, 73, 64, 10, 44, 59, 13, 22, 47, 12, 99, 8,
976 252, 96, 230, 187, 38, 29
977 ])
978 .to_le_bytes(),
979 [
980 29, 38, 187, 230, 96, 252, 8, 99, 12, 47, 22, 13, 59, 44, 10, 64, 73, 154, 195,
981 166, 88, 14, 22, 85, 119, 238, 134, 208, 45, 106, 88, 218, 240, 150, 115, 200, 240,
982 2, 233, 42, 7, 192, 201, 211, 54, 65, 76, 87, 78, 67, 21, 33, 38, 0, 91, 58, 200,
983 123, 67, 87, 32, 23, 4, 17
984 ]
985 );
986 }
987
988 #[test]
989 fn uint512_is_zero_works() {
990 assert!(Uint512::zero().is_zero());
991 assert!(Uint512(U512::from(0u32)).is_zero());
992
993 assert!(!Uint512::from(1u32).is_zero());
994 assert!(!Uint512::from(123u32).is_zero());
995 }
996
997 #[test]
998 fn uint512_wrapping_methods() {
999 assert_eq!(
1001 Uint512::from(2u32).wrapping_add(Uint512::from(2u32)),
1002 Uint512::from(4u32)
1003 ); assert_eq!(
1005 Uint512::MAX.wrapping_add(Uint512::from(1u32)),
1006 Uint512::from(0u32)
1007 ); assert_eq!(
1011 Uint512::from(7u32).wrapping_sub(Uint512::from(5u32)),
1012 Uint512::from(2u32)
1013 ); assert_eq!(
1015 Uint512::from(0u32).wrapping_sub(Uint512::from(1u32)),
1016 Uint512::MAX
1017 ); assert_eq!(
1021 Uint512::from(3u32).wrapping_mul(Uint512::from(2u32)),
1022 Uint512::from(6u32)
1023 ); assert_eq!(
1025 Uint512::MAX.wrapping_mul(Uint512::from(2u32)),
1026 Uint512::MAX - Uint512::one()
1027 ); assert_eq!(Uint512::from(2u32).wrapping_pow(3), Uint512::from(8u32)); assert_eq!(Uint512::MAX.wrapping_pow(2), Uint512::from(1u32)); }
1033
1034 #[test]
1035 fn uint512_json() {
1036 let orig = Uint512::from(1234567890987654321u128);
1037 let serialized = serde_json::to_vec(&orig).unwrap();
1038 assert_eq!(serialized.as_slice(), b"\"1234567890987654321\"");
1039 let parsed: Uint512 = serde_json::from_slice(&serialized).unwrap();
1040 assert_eq!(parsed, orig);
1041 }
1042
1043 #[test]
1044 fn uint512_compare() {
1045 let a = Uint512::from(12345u32);
1046 let b = Uint512::from(23456u32);
1047
1048 assert!(a < b);
1049 assert!(b > a);
1050 assert_eq!(a, Uint512::from(12345u32));
1051 }
1052
1053 #[test]
1054 #[allow(clippy::op_ref)]
1055 fn uint512_math() {
1056 let a = Uint512::from(12345u32);
1057 let b = Uint512::from(23456u32);
1058
1059 let mut c = Uint512::from(300000u32);
1061 c += b;
1062 assert_eq!(c, Uint512::from(323456u32));
1063 let mut d = Uint512::from(300000u32);
1064 d += &b;
1065 assert_eq!(d, Uint512::from(323456u32));
1066
1067 let mut c = Uint512::from(300000u32);
1069 c -= b;
1070 assert_eq!(c, Uint512::from(276544u32));
1071 let mut d = Uint512::from(300000u32);
1072 d -= &b;
1073 assert_eq!(d, Uint512::from(276544u32));
1074
1075 let underflow_result = a.checked_sub(b);
1077 let OverflowError { operation } = underflow_result.unwrap_err();
1078 assert_eq!(operation, OverflowOperation::Sub);
1079 }
1080
1081 #[test]
1082 #[allow(clippy::op_ref)]
1083 fn uint512_add_works() {
1084 assert_eq!(
1085 Uint512::from(2u32) + Uint512::from(1u32),
1086 Uint512::from(3u32)
1087 );
1088 assert_eq!(
1089 Uint512::from(2u32) + Uint512::from(0u32),
1090 Uint512::from(2u32)
1091 );
1092
1093 let a = Uint512::from(10u32);
1095 let b = Uint512::from(3u32);
1096 let expected = Uint512::from(13u32);
1097 assert_eq!(a + b, expected);
1098 assert_eq!(a + &b, expected);
1099 assert_eq!(&a + b, expected);
1100 assert_eq!(&a + &b, expected);
1101 }
1102
1103 #[test]
1104 #[should_panic(expected = "attempt to add with overflow")]
1105 fn uint512_add_overflow_panics() {
1106 let max = Uint512::MAX;
1107 let _ = max + Uint512::from(12u32);
1108 }
1109
1110 #[test]
1111 #[allow(clippy::op_ref)]
1112 fn uint512_sub_works() {
1113 assert_eq!(
1114 Uint512::from(2u32) - Uint512::from(1u32),
1115 Uint512::from(1u32)
1116 );
1117 assert_eq!(
1118 Uint512::from(2u32) - Uint512::from(0u32),
1119 Uint512::from(2u32)
1120 );
1121 assert_eq!(
1122 Uint512::from(2u32) - Uint512::from(2u32),
1123 Uint512::from(0u32)
1124 );
1125
1126 let a = Uint512::from(10u32);
1128 let b = Uint512::from(3u32);
1129 let expected = Uint512::from(7u32);
1130 assert_eq!(a - b, expected);
1131 assert_eq!(a - &b, expected);
1132 assert_eq!(&a - b, expected);
1133 assert_eq!(&a - &b, expected);
1134 }
1135
1136 #[test]
1137 #[should_panic]
1138 fn uint512_sub_overflow_panics() {
1139 let _ = Uint512::from(1u32) - Uint512::from(2u32);
1140 }
1141
1142 #[test]
1143 fn uint512_sub_assign_works() {
1144 let mut a = Uint512::from(14u32);
1145 a -= Uint512::from(2u32);
1146 assert_eq!(a, Uint512::from(12u32));
1147
1148 let mut a = Uint512::from(10u32);
1150 let b = Uint512::from(3u32);
1151 let expected = Uint512::from(7u32);
1152 a -= &b;
1153 assert_eq!(a, expected);
1154 }
1155
1156 #[test]
1157 #[allow(clippy::op_ref)]
1158 fn uint512_mul_works() {
1159 assert_eq!(
1160 Uint512::from(2u32) * Uint512::from(3u32),
1161 Uint512::from(6u32)
1162 );
1163 assert_eq!(Uint512::from(2u32) * Uint512::zero(), Uint512::zero());
1164
1165 let a = Uint512::from(11u32);
1167 let b = Uint512::from(3u32);
1168 let expected = Uint512::from(33u32);
1169 assert_eq!(a * b, expected);
1170 assert_eq!(a * &b, expected);
1171 assert_eq!(&a * b, expected);
1172 assert_eq!(&a * &b, expected);
1173 }
1174
1175 #[test]
1176 fn uint512_mul_assign_works() {
1177 let mut a = Uint512::from(14u32);
1178 a *= Uint512::from(2u32);
1179 assert_eq!(a, Uint512::from(28u32));
1180
1181 let mut a = Uint512::from(10u32);
1183 let b = Uint512::from(3u32);
1184 a *= &b;
1185 assert_eq!(a, Uint512::from(30u32));
1186 }
1187
1188 #[test]
1189 fn uint512_pow_works() {
1190 assert_eq!(Uint512::from(2u32).pow(2), Uint512::from(4u32));
1191 assert_eq!(Uint512::from(2u32).pow(10), Uint512::from(1024u32));
1192 }
1193
1194 #[test]
1195 #[should_panic]
1196 fn uint512_pow_overflow_panics() {
1197 _ = Uint512::MAX.pow(2u32);
1198 }
1199
1200 #[test]
1201 fn uint512_shr_works() {
1202 let original = Uint512::new([
1203 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1204 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1205 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1206 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 4u8, 2u8,
1207 ]);
1208
1209 let shifted = Uint512::new([
1210 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1211 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1212 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1213 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 128u8, 1u8, 0u8,
1214 ]);
1215
1216 assert_eq!(original >> 2u32, shifted);
1217 }
1218
1219 #[test]
1220 #[should_panic]
1221 fn uint512_shr_overflow_panics() {
1222 let _ = Uint512::from(1u32) >> 512u32;
1223 }
1224
1225 #[test]
1226 fn uint512_shl_works() {
1227 let original = Uint512::new([
1228 64u8, 128u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1229 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1230 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1231 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1232 ]);
1233
1234 let shifted = Uint512::new([
1235 2u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1236 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1237 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1238 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
1239 ]);
1240
1241 assert_eq!(original << 2u32, shifted);
1242 }
1243
1244 #[test]
1245 #[should_panic]
1246 fn uint512_shl_overflow_panics() {
1247 let _ = Uint512::from(1u32) << 512u32;
1248 }
1249
1250 #[test]
1251 fn sum_works() {
1252 let nums = vec![
1253 Uint512::from(17u32),
1254 Uint512::from(123u32),
1255 Uint512::from(540u32),
1256 Uint512::from(82u32),
1257 ];
1258 let expected = Uint512::from(762u32);
1259
1260 let sum_as_ref: Uint512 = nums.iter().sum();
1261 assert_eq!(expected, sum_as_ref);
1262
1263 let sum_as_owned: Uint512 = nums.into_iter().sum();
1264 assert_eq!(expected, sum_as_owned);
1265 }
1266
1267 #[test]
1268 fn uint512_methods() {
1269 assert!(matches!(
1271 Uint512::MAX.checked_add(Uint512::from(1u32)),
1272 Err(OverflowError { .. })
1273 ));
1274 assert_eq!(
1275 Uint512::from(1u32).checked_add(Uint512::from(1u32)),
1276 Ok(Uint512::from(2u32)),
1277 );
1278 assert!(matches!(
1279 Uint512::from(0u32).checked_sub(Uint512::from(1u32)),
1280 Err(OverflowError { .. })
1281 ));
1282 assert_eq!(
1283 Uint512::from(2u32).checked_sub(Uint512::from(1u32)),
1284 Ok(Uint512::from(1u32)),
1285 );
1286 assert!(matches!(
1287 Uint512::MAX.checked_mul(Uint512::from(2u32)),
1288 Err(OverflowError { .. })
1289 ));
1290 assert_eq!(
1291 Uint512::from(2u32).checked_mul(Uint512::from(2u32)),
1292 Ok(Uint512::from(4u32)),
1293 );
1294 assert!(matches!(
1295 Uint512::MAX.checked_pow(2u32),
1296 Err(OverflowError { .. })
1297 ));
1298 assert_eq!(
1299 Uint512::from(2u32).checked_pow(3u32),
1300 Ok(Uint512::from(8u32)),
1301 );
1302 assert!(matches!(
1303 Uint512::MAX.checked_div(Uint512::from(0u32)),
1304 Err(DivideByZeroError { .. })
1305 ));
1306 assert_eq!(
1307 Uint512::from(6u32).checked_div(Uint512::from(2u32)),
1308 Ok(Uint512::from(3u32)),
1309 );
1310 assert!(matches!(
1311 Uint512::MAX.checked_div_euclid(Uint512::from(0u32)),
1312 Err(DivideByZeroError { .. })
1313 ));
1314 assert_eq!(
1315 Uint512::from(6u32).checked_div_euclid(Uint512::from(2u32)),
1316 Ok(Uint512::from(3u32)),
1317 );
1318 assert_eq!(
1319 Uint512::from(7u32).checked_div_euclid(Uint512::from(2u32)),
1320 Ok(Uint512::from(3u32)),
1321 );
1322 assert!(matches!(
1323 Uint512::MAX.checked_rem(Uint512::from(0u32)),
1324 Err(DivideByZeroError { .. })
1325 ));
1326
1327 assert_eq!(
1329 Uint512::MAX.saturating_add(Uint512::from(1u32)),
1330 Uint512::MAX
1331 );
1332 assert_eq!(
1333 Uint512::from(0u32).saturating_sub(Uint512::from(1u32)),
1334 Uint512::from(0u32)
1335 );
1336 assert_eq!(
1337 Uint512::MAX.saturating_mul(Uint512::from(2u32)),
1338 Uint512::MAX
1339 );
1340 assert_eq!(
1341 Uint512::from(4u32).saturating_pow(2u32),
1342 Uint512::from(16u32)
1343 );
1344 assert_eq!(Uint512::MAX.saturating_pow(2u32), Uint512::MAX);
1345 }
1346
1347 #[test]
1348 #[allow(clippy::op_ref)]
1349 fn uint512_implements_rem() {
1350 let a = Uint512::from(10u32);
1351 assert_eq!(a % Uint512::from(10u32), Uint512::zero());
1352 assert_eq!(a % Uint512::from(2u32), Uint512::zero());
1353 assert_eq!(a % Uint512::from(1u32), Uint512::zero());
1354 assert_eq!(a % Uint512::from(3u32), Uint512::from(1u32));
1355 assert_eq!(a % Uint512::from(4u32), Uint512::from(2u32));
1356
1357 let a = Uint512::from(10u32);
1359 let b = Uint512::from(3u32);
1360 let expected = Uint512::from(1u32);
1361 assert_eq!(a % b, expected);
1362 assert_eq!(a % &b, expected);
1363 assert_eq!(&a % b, expected);
1364 assert_eq!(&a % &b, expected);
1365 }
1366
1367 #[test]
1368 #[should_panic(expected = "divisor of zero")]
1369 fn uint512_rem_panics_for_zero() {
1370 let _ = Uint512::from(10u32) % Uint512::zero();
1371 }
1372
1373 #[test]
1374 #[allow(clippy::op_ref)]
1375 fn uint512_rem_works() {
1376 assert_eq!(
1377 Uint512::from(12u32) % Uint512::from(10u32),
1378 Uint512::from(2u32)
1379 );
1380 assert_eq!(Uint512::from(50u32) % Uint512::from(5u32), Uint512::zero());
1381
1382 let a = Uint512::from(42u32);
1384 let b = Uint512::from(5u32);
1385 let expected = Uint512::from(2u32);
1386 assert_eq!(a % b, expected);
1387 assert_eq!(a % &b, expected);
1388 assert_eq!(&a % b, expected);
1389 assert_eq!(&a % &b, expected);
1390 }
1391
1392 #[test]
1393 fn uint512_rem_assign_works() {
1394 let mut a = Uint512::from(30u32);
1395 a %= Uint512::from(4u32);
1396 assert_eq!(a, Uint512::from(2u32));
1397
1398 let mut a = Uint512::from(25u32);
1400 let b = Uint512::from(6u32);
1401 a %= &b;
1402 assert_eq!(a, Uint512::from(1u32));
1403 }
1404
1405 #[test]
1406 fn uint512_strict_add_works() {
1407 let a = Uint512::from(5u32);
1408 let b = Uint512::from(3u32);
1409 assert_eq!(a.strict_add(b), Uint512::from(8u32));
1410 assert_eq!(b.strict_add(a), Uint512::from(8u32));
1411 }
1412
1413 #[test]
1414 #[should_panic(expected = "attempt to add with overflow")]
1415 fn uint512_strict_add_panics_on_overflow() {
1416 let a = Uint512::MAX;
1417 let b = Uint512::ONE;
1418 let _ = a.strict_add(b);
1419 }
1420
1421 #[test]
1422 fn uint512_strict_sub_works() {
1423 let a = Uint512::from(5u32);
1424 let b = Uint512::from(3u32);
1425 assert_eq!(a.strict_sub(b), Uint512::from(2u32));
1426 }
1427
1428 #[test]
1429 #[should_panic(expected = "attempt to subtract with overflow")]
1430 fn uint512_strict_sub_panics_on_overflow() {
1431 let a = Uint512::ZERO;
1432 let b = Uint512::ONE;
1433 let _ = a.strict_sub(b);
1434 }
1435
1436 #[test]
1437 fn uint512_abs_diff_works() {
1438 let a = Uint512::from(42u32);
1439 let b = Uint512::from(5u32);
1440 let expected = Uint512::from(37u32);
1441 assert_eq!(a.abs_diff(b), expected);
1442 assert_eq!(b.abs_diff(a), expected);
1443 }
1444
1445 #[test]
1446 fn uint512_partial_eq() {
1447 let test_cases = [(1, 1, true), (42, 42, true), (42, 24, false), (0, 0, true)]
1448 .into_iter()
1449 .map(|(lhs, rhs, expected): (u64, u64, bool)| {
1450 (Uint512::from(lhs), Uint512::from(rhs), expected)
1451 });
1452
1453 #[allow(clippy::op_ref)]
1454 for (lhs, rhs, expected) in test_cases {
1455 assert_eq!(lhs == rhs, expected);
1456 assert_eq!(&lhs == rhs, expected);
1457 assert_eq!(lhs == &rhs, expected);
1458 assert_eq!(&lhs == &rhs, expected);
1459 }
1460 }
1461}