1use encodings::hex::{FromHex, FromHexError, ToHex};
26use std::fmt;
27
28#[cfg(feature = "rng")]
29use rand::{thread_rng, Rng};
30
31pub trait BitArray {
38 fn bit(&self, idx: usize) -> bool;
40
41 fn bit_slice(&self, start: usize, end: usize) -> Self;
43
44 fn mask(&self, n: usize) -> Self;
46
47 fn trailing_zeros(&self) -> usize;
49
50 fn zero() -> Self;
52
53 fn one() -> Self;
55}
56
57#[repr(C)]
63pub struct Uint256(pub [u64; 4]);
64
65impl<'a> From<&'a [u64]> for Uint256 {
71 fn from(data: &'a [u64]) -> Uint256 {
72 assert_eq!(data.len(), 4);
73 let mut ret = [0; 4];
74 ret.copy_from_slice(data);
75 Uint256(ret)
76 }
77}
78
79impl From<u32> for Uint256 {
80 fn from(value: u32) -> Uint256 {
81 let mut ret = [0; 4];
82 ret[0] = value as u64;
83 Uint256(ret)
84 }
85}
86
87impl From<u64> for Uint256 {
88 fn from(value: u64) -> Uint256 {
89 let mut ret = [0; 4];
90 ret[0] = value;
91 Uint256(ret)
92 }
93}
94
95impl From<[u8; 32]> for Uint256 {
96 fn from(value: [u8; 32]) -> Uint256 {
97 let mut ret = [0; 4];
98 (0..4).for_each(|i| {
100 let start = i * 8;
101 let end = 8 + i * 8;
102 let mut bytes = [0; 8];
103 bytes.copy_from_slice(&value[start..end]);
104 ret[i] = u64::from_be_bytes(bytes);
105 });
106 Uint256(ret)
107 }
108}
109
110impl FromHex for Uint256 {
111 type Error = FromHexError;
112
113 fn from_hex<T: AsRef<[u8]>>(hex: T) -> std::result::Result<Self, Self::Error> {
114 let bytes = Vec::from_hex(hex)?;
115 if bytes.len() != 32 {
116 Err(FromHexError::InvalidHexLength)
120 } else {
121 let mut ret = [0; 32];
122 ret.copy_from_slice(&bytes);
123 Ok(Uint256::from(ret))
124 }
125 }
126}
127
128impl ::std::ops::Index<usize> for Uint256 {
129 type Output = u64;
130
131 #[inline]
132 fn index(&self, index: usize) -> &u64 {
133 let &Uint256(ref dat) = self;
134 &dat[index]
135 }
136}
137
138impl ::std::ops::Index<::std::ops::Range<usize>> for Uint256 {
139 type Output = [u64];
140
141 #[inline]
142 fn index(&self, index: ::std::ops::Range<usize>) -> &[u64] {
143 &self.0[index]
144 }
145}
146
147impl ::std::ops::Index<::std::ops::RangeTo<usize>> for Uint256 {
148 type Output = [u64];
149
150 #[inline]
151 fn index(&self, index: ::std::ops::RangeTo<usize>) -> &[u64] {
152 &self.0[index]
153 }
154}
155
156impl ::std::ops::Index<::std::ops::RangeFrom<usize>> for Uint256 {
157 type Output = [u64];
158
159 #[inline]
160 fn index(&self, index: ::std::ops::RangeFrom<usize>) -> &[u64] {
161 &self.0[index]
162 }
163}
164
165impl ::std::ops::Index<::std::ops::RangeFull> for Uint256 {
166 type Output = [u64];
167
168 #[inline]
169 fn index(&self, _: ::std::ops::RangeFull) -> &[u64] {
170 &self.0[..]
171 }
172}
173
174impl PartialEq for Uint256 {
175 #[inline]
176 fn eq(&self, other: &Uint256) -> bool {
177 self[..] == other[..]
178 }
179}
180
181impl Eq for Uint256 {}
182
183impl PartialOrd for Uint256 {
184 #[inline]
185 fn partial_cmp(&self, other: &Uint256) -> Option<::std::cmp::Ordering> {
186 Some(self.cmp(other))
187 }
188}
189
190impl Ord for Uint256 {
191 #[inline]
192 fn cmp(&self, other: &Uint256) -> ::std::cmp::Ordering {
193 for i in 0..4 {
198 if self[4 - 1 - i] < other[4 - 1 - i] {
199 return ::std::cmp::Ordering::Less;
200 }
201 if self[4 - 1 - i] > other[4 - 1 - i] {
202 return ::std::cmp::Ordering::Greater;
203 }
204 }
205 ::std::cmp::Ordering::Equal
206 }
207}
208
209#[cfg_attr(feature = "clippy", allow(expl_impl_clone_on_copy))] impl Clone for Uint256 {
211 #[inline]
212 fn clone(&self) -> Uint256 {
213 Uint256::from(&self[..])
214 }
215}
216
217impl Copy for Uint256 {}
218
219impl Uint256 {
220 #[cfg(feature = "rng")]
221 pub fn random() -> Self {
222 let mut rng = thread_rng();
223
224 let mut arr = [0_u64; 4];
225 rng.fill(&mut arr);
226
227 Uint256(arr)
228 }
229
230 #[inline]
231 pub fn as_ptr(&self) -> *const u64 {
233 let &Uint256(ref dat) = self;
234 dat.as_ptr()
235 }
236
237 #[inline]
238 pub fn as_mut_ptr(&mut self) -> *mut u64 {
240 let &mut Uint256(ref mut dat) = self;
241 dat.as_mut_ptr()
242 }
243
244 #[inline]
245 pub fn len(&self) -> usize {
247 4
248 }
249
250 #[inline]
251 pub fn is_empty(&self) -> bool {
253 false
254 }
255
256 #[inline]
263 pub fn as_bytes(&self) -> &[u64; 4] {
265 &self.0
266 }
267
268 #[inline]
269 pub fn to_bytes(&self) -> [u64; 4] {
273 self.0
274 }
275
276 #[inline]
277 pub fn to_le_bytes(&self) -> [u8; 32] {
279 let mut bytes = [0; 32];
280 for i in 0..4 {
281 let le_bytes = self.0[i].to_le_bytes();
283
284 bytes[8 * i] = le_bytes[0];
285 bytes[1 + 8 * i] = le_bytes[1];
286 bytes[2 + 8 * i] = le_bytes[2];
287 bytes[3 + 8 * i] = le_bytes[3];
288
289 bytes[4 + 8 * i] = le_bytes[4];
291 bytes[5 + 8 * i] = le_bytes[5];
292 bytes[6 + 8 * i] = le_bytes[6];
293 bytes[7 + 8 * i] = le_bytes[7];
294 }
295
296 bytes
297 }
298
299 #[inline]
301 pub fn max_value() -> Self {
302 let mut result = [0; 4];
303 (0..4).for_each(|i| {
304 result[i] = u64::max_value();
305 });
306 Uint256(result)
307 }
308
309 #[inline]
310 pub fn into_bytes(self) -> [u64; 4] {
312 self.0
313 }
314
315 #[inline]
317 pub fn low_u32(&self) -> u32 {
318 let &Uint256(ref arr) = self;
319 arr[0] as u32
320 }
321
322 #[inline]
324 pub fn low_u64(&self) -> u64 {
325 let &Uint256(ref arr) = self;
326 arr[0]
327 }
328
329 #[inline]
331 pub fn bits(&self) -> usize {
332 let &Uint256(ref arr) = self;
333 for i in 1..4 {
334 if arr[4 - i] > 0 {
335 return (0x40 * (4 - i + 1)) - arr[4 - i].leading_zeros() as usize;
336 }
337 }
338 0x40 - arr[0].leading_zeros() as usize
339 }
340
341 pub fn mul_u32(self, other: u32) -> Uint256 {
343 let Uint256(ref arr) = self;
344 let mut carry = [0u64; 4];
345 let mut ret = [0u64; 4];
346 for i in 0..4 {
347 let not_last_word = i < 4 - 1;
348 let upper = other as u64 * (arr[i] >> 32);
349 let lower = other as u64 * (arr[i] & 0xFFFFFFFF);
350 if not_last_word {
351 carry[i + 1] += upper >> 32;
352 }
353 let (sum, overflow) = lower.overflowing_add(upper << 32);
354 ret[i] = sum;
355 if overflow && not_last_word {
356 carry[i + 1] += 1;
357 }
358 }
359 Uint256(ret) + Uint256(carry)
360 }
361
362 pub fn from_u64(init: u64) -> Option<Uint256> {
364 let mut ret = [0; 4];
365 ret[0] = init;
366 Some(Uint256(ret))
367 }
368
369 pub fn from_i64(init: i64) -> Option<Uint256> {
371 assert!(init >= 0);
372 Uint256::from_u64(init as u64)
373 }
374
375 pub fn from_big_endian(slice: &[u8]) -> Self {
378 assert!(4 * 8 >= slice.len());
379 assert!(slice.len() % 8 == 0);
380 let mut ret = [0; 4];
382 let length = slice.len() / 8;
383 for i in 0..length {
385 let start = i * 8;
386 let end = 8 + i * 8;
387 let mut bytes = [0; 8];
388 bytes.copy_from_slice(&slice[start..end]);
389 ret[3 - i] = u64::from_be_bytes(bytes);
390 }
391
392 Uint256(ret)
393 }
394
395 pub fn from_bytes(slice: &[u8]) -> Self {
397 assert!(4 * 8 >= slice.len());
398 assert!(slice.len() % 8 == 0);
399 let mut ret = [0; 4];
401 let length = slice.len() / 8;
402 (0..length).for_each(|i| {
404 let start = i * 8;
405 let end = 8 + i * 8;
406 let mut bytes = [0; 8];
407 bytes.copy_from_slice(&slice[start..end]);
408 ret[i] = u64::from_le_bytes(bytes);
409 });
410
411 Uint256(ret)
412 }
413
414 #[inline]
415 pub fn increment(&mut self) {
416 let &mut Uint256(ref mut arr) = self;
417 arr[0] += 1;
418 if arr[0] == 0 {
419 arr[1] += 1;
420 if arr[1] == 0 {
421 arr[2] += 1;
422 if arr[2] == 0 {
423 arr[3] += 1;
424 }
425 }
426 }
427 }
428}
429
430impl ::std::ops::Add<Uint256> for Uint256 {
431 type Output = Uint256;
432
433 fn add(self, other: Uint256) -> Uint256 {
434 let Uint256(ref me) = self;
435 let Uint256(ref you) = other;
436 let mut ret = [0u64; 4];
437 let mut carry = [0u64; 4];
438 let mut b_carry = false;
439 for i in 0..4 {
440 ret[i] = me[i].wrapping_add(you[i]);
441 if i < 4 - 1 && ret[i] < me[i] {
442 carry[i + 1] = 1;
443 b_carry = true;
444 }
445 }
446 if b_carry {
447 Uint256(ret) + Uint256(carry)
448 } else {
449 Uint256(ret)
450 }
451 }
452}
453
454impl ::std::ops::Sub<Uint256> for Uint256 {
455 type Output = Uint256;
456
457 #[inline]
458 fn sub(self, other: Uint256) -> Uint256 {
459 self + !other + BitArray::one()
461 }
462}
463
464impl ::std::ops::Mul<Uint256> for Uint256 {
465 type Output = Uint256;
466
467 fn mul(self, other: Uint256) -> Uint256 {
468 let mut me = Uint256::zero();
469 for i in 0..(2 * 4) {
471 let to_mul = (other >> (32 * i)).low_u32();
472 me = me + (self.mul_u32(to_mul) << (32 * i));
473 }
474 me
475 }
476}
477
478impl ::std::ops::Div<Uint256> for Uint256 {
479 type Output = Uint256;
480
481 fn div(self, other: Uint256) -> Uint256 {
482 let mut sub_copy = self;
483 let mut shift_copy = other;
484 let mut ret = [0u64; 4];
485
486 let my_bits = self.bits();
487 let your_bits = other.bits();
488
489 assert!(your_bits != 0);
491
492 if my_bits < your_bits {
494 return Uint256(ret);
495 }
496
497 let mut shift = my_bits - your_bits;
499 shift_copy = shift_copy << shift;
500 loop {
501 if sub_copy >= shift_copy {
502 ret[shift / 64] |= 1 << (shift % 64);
503 sub_copy = sub_copy - shift_copy;
504 }
505 shift_copy = shift_copy >> 1;
506 if shift == 0 {
507 break;
508 }
509 shift -= 1;
510 }
511
512 Uint256(ret)
513 }
514}
515
516impl BitArray for Uint256 {
520 #[inline]
521 fn bit(&self, index: usize) -> bool {
522 let &Uint256(ref arr) = self;
523 arr[index / 64] & (1 << (index % 64)) != 0
524 }
525
526 #[inline]
527 fn bit_slice(&self, start: usize, end: usize) -> Uint256 {
528 (*self >> start).mask(end - start)
529 }
530
531 #[inline]
532 fn mask(&self, n: usize) -> Uint256 {
533 let &Uint256(ref arr) = self;
534 let mut ret = [0; 4];
535 for i in 0..4 {
536 if n >= 0x40 * (i + 1) {
537 ret[i] = arr[i];
538 } else {
539 ret[i] = arr[i] & ((1 << (n - 0x40 * i)) - 1);
540 break;
541 }
542 }
543 Uint256(ret)
544 }
545
546 #[inline]
547 fn trailing_zeros(&self) -> usize {
548 let &Uint256(ref arr) = self;
549 for i in 0..(4 - 1) {
550 if arr[i] > 0 {
551 return (0x40 * i) + arr[i].trailing_zeros() as usize;
552 }
553 }
554 (0x40 * (4 - 1)) + arr[4 - 1].trailing_zeros() as usize
555 }
556
557 fn zero() -> Uint256 {
558 Uint256([0; 4])
559 }
560
561 fn one() -> Uint256 {
562 Uint256({
563 let mut ret = [0; 4];
564 ret[0] = 1;
565 ret
566 })
567 }
568}
569
570impl ::std::default::Default for Uint256 {
571 fn default() -> Uint256 {
572 BitArray::zero()
573 }
574}
575
576impl ::std::ops::BitAnd<Uint256> for Uint256 {
577 type Output = Uint256;
578
579 #[inline]
580 fn bitand(self, other: Uint256) -> Uint256 {
581 let Uint256(ref arr1) = self;
582 let Uint256(ref arr2) = other;
583 let mut ret = [0u64; 4];
584 for i in 0..4 {
585 ret[i] = arr1[i] & arr2[i];
586 }
587 Uint256(ret)
588 }
589}
590
591impl ::std::ops::BitXor<Uint256> for Uint256 {
592 type Output = Uint256;
593
594 #[inline]
595 fn bitxor(self, other: Uint256) -> Uint256 {
596 let Uint256(ref arr1) = self;
597 let Uint256(ref arr2) = other;
598 let mut ret = [0u64; 4];
599 for i in 0..4 {
600 ret[i] = arr1[i] ^ arr2[i];
601 }
602 Uint256(ret)
603 }
604}
605
606impl ::std::ops::BitOr<Uint256> for Uint256 {
607 type Output = Uint256;
608
609 #[inline]
610 fn bitor(self, other: Uint256) -> Uint256 {
611 let Uint256(ref arr1) = self;
612 let Uint256(ref arr2) = other;
613 let mut ret = [0u64; 4];
614 for i in 0..4 {
615 ret[i] = arr1[i] | arr2[i];
616 }
617 Uint256(ret)
618 }
619}
620
621impl ::std::ops::Not for Uint256 {
622 type Output = Uint256;
623
624 #[inline]
625 fn not(self) -> Uint256 {
626 let Uint256(ref arr) = self;
627 let mut ret = [0u64; 4];
628 for i in 0..4 {
629 ret[i] = !arr[i];
630 }
631 Uint256(ret)
632 }
633}
634
635impl ::std::ops::Shl<usize> for Uint256 {
636 type Output = Uint256;
637
638 fn shl(self, shift: usize) -> Uint256 {
639 let Uint256(ref original) = self;
640 let mut ret = [0u64; 4];
641 let word_shift = shift / 64;
642 let bit_shift = shift % 64;
643 for i in 0..4 {
644 if bit_shift < 64 && i + word_shift < 4 {
646 ret[i + word_shift] += original[i] << bit_shift;
647 }
648 if bit_shift > 0 && i + word_shift + 1 < 4 {
650 ret[i + word_shift + 1] += original[i] >> (64 - bit_shift);
651 }
652 }
653 Uint256(ret)
654 }
655}
656
657impl ::std::ops::Shr<usize> for Uint256 {
658 type Output = Uint256;
659
660 fn shr(self, shift: usize) -> Uint256 {
661 let Uint256(ref original) = self;
662 let mut ret = [0u64; 4];
663 let word_shift = shift / 64;
664 let bit_shift = shift % 64;
665 for i in word_shift..4 {
666 ret[i - word_shift] += original[i] >> bit_shift;
668 if bit_shift > 0 && i < 4 - 1 {
670 ret[i - word_shift] += original[i + 1] << (64 - bit_shift);
671 }
672 }
673 Uint256(ret)
674 }
675}
676
677impl ToHex for Uint256 {
683 fn to_hex(&self) -> String {
684 let mut hex = "".to_owned();
685 for bytes in self.0.iter() {
686 hex.push_str(&bytes.to_le_bytes().to_vec().to_hex());
687 }
688
689 hex
690 }
691}
692
693impl fmt::Debug for Uint256 {
695 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
696 let &Uint256(ref data) = self;
697 write!(f, "0x")?;
698 for ch in data.iter().rev() {
699 write!(f, "{:016x}", ch)?;
700 }
701 Ok(())
702 }
703}
704
705impl fmt::Display for Uint256 {
706 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
707 <dyn fmt::Debug>::fmt(self, f)
708 }
709}
710
711#[cfg(feature = "serialization")]
712impl serde::Serialize for Uint256 {
713 fn serialize<S: serde::Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
714 if s.is_human_readable() {
715 s.serialize_str(&self.to_hex())
716 } else {
717 s.serialize_bytes(&self.to_le_bytes())
718 }
719 }
720}
721
722#[cfg(feature = "serialization")]
723impl<'de> serde::Deserialize<'de> for Uint256 {
724 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> std::result::Result<Uint256, D::Error> {
725 if d.is_human_readable() {
726 struct HexVisitor;
727
728 impl<'de> serde::de::Visitor<'de> for HexVisitor {
729 type Value = Uint256;
730
731 fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
732 formatter.write_str("an ASCII hex string")
733 }
734
735 fn visit_bytes<E>(self, v: &[u8]) -> std::result::Result<Self::Value, E>
736 where
737 E: ::serde::de::Error,
738 {
739 if let Ok(hex) = ::std::str::from_utf8(v) {
740 Uint256::from_hex(hex).map_err(E::custom)
741 } else {
742 return Err(E::invalid_value(serde::de::Unexpected::Bytes(v), &self));
743 }
744 }
745
746 fn visit_str<E>(self, v: &str) -> std::result::Result<Self::Value, E>
747 where
748 E: ::serde::de::Error,
749 {
750 Uint256::from_hex(v).map_err(E::custom)
751 }
752 }
753
754 d.deserialize_str(HexVisitor)
755 } else {
756 struct BytesVisitor;
757
758 impl<'de> ::serde::de::Visitor<'de> for BytesVisitor {
759 type Value = Uint256;
760
761 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
762 formatter.write_str("a bytestring")
763 }
764
765 fn visit_bytes<E>(self, v: &[u8]) -> std::result::Result<Self::Value, E>
766 where
767 E: ::serde::de::Error,
768 {
769 if v.len() != 32 {
770 Err(E::invalid_length(v.len(), &stringify!(32)))
771 } else {
772 let mut ret = [0; 32];
773 ret.copy_from_slice(v);
774 Ok(Uint256::from(ret))
775 }
776 }
777 }
778
779 d.deserialize_bytes(BytesVisitor)
780 }
781 }
782}
783
784#[cfg(test)]
785mod tests {
786 use super::*;
787
788 #[test]
789 pub fn uint256_bits_test() {
790 assert_eq!(Uint256::from_u64(255).unwrap().bits(), 8);
791 assert_eq!(Uint256::from_u64(256).unwrap().bits(), 9);
792 assert_eq!(Uint256::from_u64(300).unwrap().bits(), 9);
793 assert_eq!(Uint256::from_u64(60000).unwrap().bits(), 16);
794 assert_eq!(Uint256::from_u64(70000).unwrap().bits(), 17);
795
796 let mut shl = Uint256::from_u64(70000).unwrap();
798 shl = shl << 100;
799 assert_eq!(shl.bits(), 117);
800 shl = shl << 100;
801 assert_eq!(shl.bits(), 217);
802 shl = shl << 100;
803 assert_eq!(shl.bits(), 0);
804
805 assert!(!Uint256::from_u64(10).unwrap().bit(0));
807 assert!(Uint256::from_u64(10).unwrap().bit(1));
808 assert!(!Uint256::from_u64(10).unwrap().bit(2));
809 assert!(Uint256::from_u64(10).unwrap().bit(3));
810 assert!(!Uint256::from_u64(10).unwrap().bit(4));
811 }
812
813 #[test]
814 pub fn uint256_display_test() {
815 assert_eq!(
816 format!("{}", Uint256::from_u64(0xDEADBEEF).unwrap()),
817 "0x00000000000000000000000000000000000000000000000000000000deadbeef"
818 );
819 assert_eq!(
820 format!("{}", Uint256::from_u64(u64::max_value()).unwrap()),
821 "0x000000000000000000000000000000000000000000000000ffffffffffffffff"
822 );
823
824 let max_val = Uint256([
825 0xFFFFFFFFFFFFFFFF,
826 0xFFFFFFFFFFFFFFFF,
827 0xFFFFFFFFFFFFFFFF,
828 0xFFFFFFFFFFFFFFFF,
829 ]);
830 assert_eq!(
831 format!("{}", max_val),
832 "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
833 );
834 }
835
836 #[test]
837 pub fn uint256_comp_test() {
838 let small = Uint256([10u64, 0, 0, 0]);
839 let big = Uint256([0x8C8C3EE70C644118u64, 0x0209E7378231E632, 0, 0]);
840 let bigger = Uint256([0x9C8C3EE70C644118u64, 0x0209E7378231E632, 0, 0]);
841 let biggest = Uint256([0x5C8C3EE70C644118u64, 0x0209E7378231E632, 0, 1]);
842
843 assert!(small < big);
844 assert!(big < bigger);
845 assert!(bigger < biggest);
846 assert!(bigger <= biggest);
847 assert!(biggest <= biggest);
848 assert!(bigger >= big);
849 assert!(bigger >= small);
850 assert!(small <= small);
851 }
852
853 #[test]
854 pub fn uint256_arithmetic_test() {
855 let init = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
856 let copy = init;
857
858 let add = init + copy;
859 assert_eq!(add, Uint256([0xBD5B7DDFBD5B7DDEu64, 1, 0, 0]));
860 let shl = add << 88;
862 assert_eq!(shl, Uint256([0u64, 0xDFBD5B7DDE000000, 0x1BD5B7D, 0]));
863 let shr = shl >> 40;
864 assert_eq!(
865 shr,
866 Uint256([0x7DDE000000000000u64, 0x0001BD5B7DDFBD5B, 0, 0])
867 );
868 let mut incr = shr;
870 incr.increment();
871 assert_eq!(
872 incr,
873 Uint256([0x7DDE000000000001u64, 0x0001BD5B7DDFBD5B, 0, 0])
874 );
875 let sub = incr - init;
877 assert_eq!(
878 sub,
879 Uint256([0x9F30411021524112u64, 0x0001BD5B7DDFBD5A, 0, 0])
880 );
881 let mult = sub.mul_u32(300);
883 assert_eq!(
884 mult,
885 Uint256([0x8C8C3EE70C644118u64, 0x0209E7378231E632, 0, 0])
886 );
887 assert_eq!(
889 Uint256::from_u64(105).unwrap() / Uint256::from_u64(5).unwrap(),
890 Uint256::from_u64(21).unwrap()
891 );
892 let div = mult / Uint256::from_u64(300).unwrap();
893 assert_eq!(
894 div,
895 Uint256([0x9F30411021524112u64, 0x0001BD5B7DDFBD5A, 0, 0])
896 );
897 }
899
900 #[test]
901 pub fn mul_u32_test() {
902 let u64_val = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
903
904 let u96_res = u64_val.mul_u32(0xFFFFFFFF);
905 let u128_res = u96_res.mul_u32(0xFFFFFFFF);
906 let u160_res = u128_res.mul_u32(0xFFFFFFFF);
907 let u192_res = u160_res.mul_u32(0xFFFFFFFF);
908 let u224_res = u192_res.mul_u32(0xFFFFFFFF);
909 let u256_res = u224_res.mul_u32(0xFFFFFFFF);
910
911 assert_eq!(u96_res, Uint256([0xffffffff21524111u64, 0xDEADBEEE, 0, 0]));
912 assert_eq!(
913 u128_res,
914 Uint256([0x21524111DEADBEEFu64, 0xDEADBEEE21524110, 0, 0])
915 );
916 assert_eq!(
917 u160_res,
918 Uint256([0xBD5B7DDD21524111u64, 0x42A4822200000001, 0xDEADBEED, 0])
919 );
920 assert_eq!(
921 u192_res,
922 Uint256([
923 0x63F6C333DEADBEEFu64,
924 0xBD5B7DDFBD5B7DDB,
925 0xDEADBEEC63F6C334,
926 0
927 ])
928 );
929 assert_eq!(
930 u224_res,
931 Uint256([
932 0x7AB6FBBB21524111u64,
933 0xFFFFFFFBA69B4558,
934 0x854904485964BAAA,
935 0xDEADBEEB
936 ])
937 );
938 assert_eq!(
939 u256_res,
940 Uint256([
941 0xA69B4555DEADBEEFu64,
942 0xA69B455CD41BB662,
943 0xD41BB662A69B4550,
944 0xDEADBEEAA69B455C
945 ])
946 );
947 }
948
949 #[test]
950 pub fn multiplication_test() {
951 let u64_val = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
952
953 let u128_res = u64_val * u64_val;
954
955 assert_eq!(
956 u128_res,
957 Uint256([0x048D1354216DA321u64, 0xC1B1CD13A4D13D46, 0, 0])
958 );
959
960 let u256_res = u128_res * u128_res;
961
962 assert_eq!(
963 u256_res,
964 Uint256([
965 0xF4E166AAD40D0A41u64,
966 0xF5CF7F3618C2C886u64,
967 0x4AFCFF6F0375C608u64,
968 0x928D92B4D7F5DF33u64
969 ])
970 );
971 }
972
973 #[test]
974 pub fn uint256_bitslice_test() {
975 let init = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
976 let add = init + (init << 64);
977 assert_eq!(add.bit_slice(64, 128), init);
978 assert_eq!(add.mask(64), init);
979 }
980
981 #[test]
982 pub fn uint256_extreme_bitshift_test() {
983 let init = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
986
987 assert_eq!(init << 64, Uint256([0, 0xDEADBEEFDEADBEEF, 0, 0]));
988 let add = (init << 64) + init;
989 assert_eq!(add, Uint256([0xDEADBEEFDEADBEEF, 0xDEADBEEFDEADBEEF, 0, 0]));
990 assert_eq!(
991 add >> 0,
992 Uint256([0xDEADBEEFDEADBEEF, 0xDEADBEEFDEADBEEF, 0, 0])
993 );
994 assert_eq!(
995 add << 0,
996 Uint256([0xDEADBEEFDEADBEEF, 0xDEADBEEFDEADBEEF, 0, 0])
997 );
998 assert_eq!(add >> 64, Uint256([0xDEADBEEFDEADBEEF, 0, 0, 0]));
999 assert_eq!(
1000 add << 64,
1001 Uint256([0, 0xDEADBEEFDEADBEEF, 0xDEADBEEFDEADBEEF, 0])
1002 );
1003 }
1004
1005 #[cfg(feature = "rng")]
1006 #[test]
1007 pub fn uint256_random() {
1008 let random = Uint256::random();
1009 dbg!(random);
1010 }
1011}
1012
1013