1use std::{
2 cmp::Ordering,
3 fmt, io,
4 mem::transmute,
5 ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Not, Shl, Shr, Sub},
6};
7
8use serde::{Deserialize, Serialize};
9
10use crate::{
11 codec::Codec,
12 crypto::{
13 sha256::{DoubleSha256Hasher, SHA256_LENGTH},
14 Hashing,
15 },
16 StacksError, StacksResult,
17};
18
19#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Copy)]
23#[serde(try_from = "Vec<u64>")]
24#[serde(into = "Vec<u64>")]
25#[repr(C)]
26pub struct Uint<const N: usize>([u64; N]);
27
28impl<const N: usize> Uint<N> {
29 pub const MAX: Self = Self([0xffffffffffffffff; N]);
31 pub const MIN: Self = Self([0; N]);
33
34 pub fn from_u64_array(data: [u64; N]) -> Self {
36 Self(data)
37 }
38
39 pub fn low_u32(&self) -> u32 {
41 self.0[0] as u32
42 }
43
44 pub fn low_u64(&self) -> u64 {
46 self.0[0]
47 }
48
49 pub fn bits(&self) -> usize {
51 for i in 1..N {
52 if self.0[N - i] > 0 {
53 return (0x40 * (N - i + 1))
54 - self.0[N - i].leading_zeros() as usize;
55 }
56 }
57
58 0x40 - self.0[0].leading_zeros() as usize
59 }
60
61 pub fn mul_u32(self, other: u32) -> Self {
63 let mut carry = [0u64; N];
64 let mut ret = [0u64; N];
65
66 for i in 0..N {
67 let not_last_word = i < N - 1;
68 let upper = other as u64 * (self.0[i] >> 32);
69 let lower = other as u64 * (self.0[i] & 0xFFFFFFFF);
70
71 if not_last_word {
72 carry[i + 1] += upper >> 32;
73 }
74
75 let (sum, overflow) = lower.overflowing_add(upper << 32);
76 ret[i] = sum;
77
78 if overflow && not_last_word {
79 carry[i + 1] += 1;
80 }
81 }
82
83 Self(ret) + Self(carry)
84 }
85
86 pub fn to_le_bytes(&self) -> Vec<u8> {
88 let mut buffer = vec![0; N * 8];
89
90 self.0
91 .iter()
92 .flat_map(|part| part.to_le_bytes())
93 .enumerate()
94 .for_each(|(i, byte)| buffer[i] = byte);
95
96 buffer
97 }
98
99 pub fn to_be_bytes(&self) -> Vec<u8> {
101 let mut ret = vec![0; N * 8];
102
103 for i in 0..N {
104 let word_end = N * 8 - (i * 8);
105 let word_start = word_end - 8;
106
107 ret[word_start..word_end].copy_from_slice(&self.0[i].to_be_bytes());
108 }
109
110 ret
111 }
112
113 pub fn from_le_bytes(bytes: impl AsRef<[u8]>) -> StacksResult<Self> {
115 let bytes = bytes.as_ref();
116
117 if bytes.len() % 8 != 0 {
118 return Err(StacksError::InvalidUintBytes(bytes.len()));
119 }
120
121 if bytes.len() / 8 != N {
122 return Err(StacksError::InvalidUintBytes(bytes.len()));
123 }
124
125 let mut ret = [0u64; N];
126 for i in 0..(bytes.len() / 8) {
127 let mut next_bytes = [0u8; 8];
128 next_bytes.copy_from_slice(&bytes[8 * i..(8 * (i + 1))]);
129
130 let next = u64::from_le_bytes(next_bytes);
131
132 ret[i] = next;
133 }
134
135 Ok(Self(ret))
136 }
137
138 pub fn from_be_bytes(bytes: impl AsRef<[u8]>) -> StacksResult<Self> {
140 let bytes = bytes.as_ref();
141
142 if bytes.len() % 8 != 0 {
143 return Err(StacksError::InvalidUintBytes(bytes.len()));
144 }
145
146 if bytes.len() / 8 != N {
147 return Err(StacksError::InvalidUintBytes(bytes.len()));
148 }
149
150 let mut ret = [0u64; N];
151 for i in 0..(bytes.len() / 8) {
152 let mut next_bytes = [0u8; 8];
153 next_bytes.copy_from_slice(&bytes[8 * i..(8 * (i + 1))]);
154
155 let next = u64::from_be_bytes(next_bytes);
156
157 ret[(bytes.len() / 8) - 1 - i] = next;
158 }
159
160 Ok(Self(ret))
161 }
162
163 pub fn to_le_hex(&self) -> String {
165 hex::encode(self.to_le_bytes())
166 }
167
168 pub fn to_be_hex(&self) -> String {
170 hex::encode(self.to_be_bytes())
171 }
172
173 pub fn from_le_hex(data: impl AsRef<str>) -> StacksResult<Self> {
175 Self::from_le_bytes(hex::decode(data.as_ref())?)
176 }
177
178 pub fn from_be_hex(data: impl AsRef<str>) -> StacksResult<Self> {
180 Self::from_be_bytes(hex::decode(data.as_ref())?)
181 }
182
183 pub fn increment(&mut self) {
185 let &mut Uint(ref mut arr) = self;
186
187 for item in arr.iter_mut().take(N) {
188 *item = item.wrapping_add(1);
189
190 if *item != 0 {
191 break;
192 }
193 }
194 }
195
196 pub fn from_uint<const M: usize>(source: impl AsRef<Uint<M>>) -> Self {
198 assert!(M < N, "Cannot convert larger Uint to smaller");
199
200 let source = source.as_ref();
201 let mut dest = [0u64; N];
202
203 dest[..M].copy_from_slice(&source.0[..M]);
204
205 Uint(dest)
206 }
207
208 pub fn from_uint_lossy<const M: usize>(
210 source: impl AsRef<Uint<M>>,
211 ) -> Self {
212 let source = source.as_ref();
213 let mut dest = [0u64; N];
214 let bytes_shared = M.min(N);
215
216 dest[..bytes_shared].copy_from_slice(&source.0[..bytes_shared]);
217
218 Uint(dest)
219 }
220
221 pub fn to_uint<const M: usize>(&self) -> Uint<M> {
223 assert!(M >= N, "Cannot convert larger Uint to smaller");
224
225 let mut dest = [0u64; M];
226
227 dest[..M].copy_from_slice(&self.0[..M]);
228
229 Uint(dest)
230 }
231
232 pub fn to_uint_lossy<const M: usize>(&self) -> Uint<M> {
234 let mut dest = [0u64; M];
235 let bytes_shared = M.min(N);
236
237 dest[..bytes_shared].copy_from_slice(&self.0[..bytes_shared]);
238
239 Uint(dest)
240 }
241
242 fn one() -> Self {
243 let mut ret = [0; N];
244 ret[0] = 1;
245
246 Uint(ret)
247 }
248}
249
250impl<const N: usize> Add<Uint<N>> for Uint<N> {
251 type Output = Self;
252
253 fn add(self, other: Self) -> Self {
254 let Self(ref me) = self;
255 let Self(ref you) = other;
256
257 let mut ret = [0u64; N];
258 let mut carry = [0u64; N];
259 let mut b_carry = false;
260
261 for i in 0..N {
262 ret[i] = me[i].wrapping_add(you[i]);
263 if i < N - 1 && ret[i] < me[i] {
264 carry[i + 1] = 1;
265 b_carry = true;
266 }
267 }
268
269 if b_carry {
270 Self(ret) + Self(carry)
271 } else {
272 Self(ret)
273 }
274 }
275}
276
277impl<const N: usize> Sub<Uint<N>> for Uint<N> {
278 type Output = Self;
279
280 fn sub(self, other: Self) -> Self {
281 self + !other + Self::one()
282 }
283}
284
285impl<const N: usize> Mul<Uint<N>> for Uint<N> {
286 type Output = Self;
287
288 fn mul(self, other: Self) -> Self {
289 let mut me = Self::MIN;
290
291 for i in 0..(2 * N) {
292 let to_mul = (other >> (32 * i)).low_u32();
293 me = me + (self.mul_u32(to_mul) << (32 * i));
294 }
295 me
296 }
297}
298
299impl<const N: usize> Div<Uint<N>> for Uint<N> {
300 type Output = Self;
301
302 fn div(self, other: Self) -> Self {
303 let mut sub_copy = self;
304 let mut shift_copy = other;
305 let mut ret = [0u64; N];
306
307 let my_bits = self.bits();
308 let your_bits = other.bits();
309
310 assert!(your_bits != 0);
312
313 if my_bits < your_bits {
315 return Self(ret);
316 }
317
318 let mut shift = my_bits - your_bits;
320 shift_copy = shift_copy << shift;
321
322 loop {
323 if sub_copy >= shift_copy {
324 ret[shift / 64] |= 1 << (shift % 64);
325 sub_copy = sub_copy - shift_copy;
326 }
327 shift_copy = shift_copy >> 1;
328
329 if shift == 0 {
330 break;
331 }
332
333 shift -= 1;
334 }
335
336 Self(ret)
337 }
338}
339
340impl<const N: usize> Ord for Uint<N> {
341 fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
342 for i in 0..N {
347 if self.0[N - 1 - i] < other.0[N - 1 - i] {
348 return Ordering::Less;
349 }
350
351 if self.0[N - 1 - i] > other.0[N - 1 - i] {
352 return Ordering::Greater;
353 }
354 }
355
356 Ordering::Equal
357 }
358}
359
360impl<const N: usize> PartialOrd for Uint<N> {
361 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
362 Some(self.cmp(other))
363 }
364}
365
366impl<const N: usize> Default for Uint<N> {
367 fn default() -> Self {
368 Self::MIN
369 }
370}
371
372impl<const N: usize> BitAnd<Uint<N>> for Uint<N> {
373 type Output = Uint<N>;
374
375 fn bitand(self, other: Uint<N>) -> Self {
376 let Uint(ref arr1) = self;
377 let Uint(ref arr2) = other;
378
379 let mut ret = [0u64; N];
380 for i in 0..N {
381 ret[i] = arr1[i] & arr2[i];
382 }
383
384 Uint(ret)
385 }
386}
387
388impl<const N: usize> BitXor<Uint<N>> for Uint<N> {
389 type Output = Uint<N>;
390
391 fn bitxor(self, other: Uint<N>) -> Self {
392 let Uint(ref arr1) = self;
393 let Uint(ref arr2) = other;
394
395 let mut ret = [0u64; N];
396 for i in 0..N {
397 ret[i] = arr1[i] ^ arr2[i];
398 }
399
400 Uint(ret)
401 }
402}
403
404impl<const N: usize> BitOr<Uint<N>> for Uint<N> {
405 type Output = Uint<N>;
406
407 fn bitor(self, other: Uint<N>) -> Self {
408 let Uint(ref arr1) = self;
409 let Uint(ref arr2) = other;
410
411 let mut ret = [0u64; N];
412 for i in 0..N {
413 ret[i] = arr1[i] | arr2[i];
414 }
415
416 Uint(ret)
417 }
418}
419
420impl<const N: usize> Not for Uint<N> {
421 type Output = Uint<N>;
422
423 fn not(self) -> Self {
424 let Uint(ref arr) = self;
425
426 let mut ret = [0u64; N];
427 for i in 0..N {
428 ret[i] = !arr[i];
429 }
430
431 Uint(ret)
432 }
433}
434
435impl<const N: usize> Shl<usize> for Uint<N> {
436 type Output = Uint<N>;
437
438 fn shl(self, shift: usize) -> Self {
439 let Uint(ref original) = self;
440 let word_shift = shift / 64;
441 let bit_shift = shift % 64;
442
443 let mut ret = [0u64; N];
444 for i in 0..N {
445 if bit_shift < 64 && i + word_shift < N {
447 ret[i + word_shift] += original[i] << bit_shift;
448 }
449
450 if bit_shift > 0 && i + word_shift + 1 < N {
452 ret[i + word_shift + 1] += original[i] >> (64 - bit_shift);
453 }
454 }
455
456 Uint(ret)
457 }
458}
459
460impl<const N: usize> Shr<usize> for Uint<N> {
461 type Output = Uint<N>;
462
463 fn shr(self, shift: usize) -> Self {
464 let Uint(ref original) = self;
465 let word_shift = shift / 64;
466 let bit_shift = shift % 64;
467
468 let mut ret = [0u64; N];
469 for i in word_shift..N {
470 ret[i - word_shift] += original[i] >> bit_shift;
472
473 if bit_shift > 0 && i < N - 1 {
475 ret[i - word_shift] += original[i + 1] << (64 - bit_shift);
476 }
477 }
478
479 Uint(ret)
480 }
481}
482
483impl<const N: usize> AsRef<Uint<N>> for Uint<N> {
484 fn as_ref(&self) -> &Uint<N> {
485 self
486 }
487}
488
489impl<const N: usize> fmt::Debug for Uint<N> {
490 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
491 let Uint(data) = self;
492
493 write!(f, "0x")?;
494
495 for ch in data.iter().rev() {
496 write!(f, "{:016x}", ch)?;
497 }
498
499 Ok(())
500 }
501}
502
503impl<const N: usize> fmt::Display for Uint<N> {
504 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
505 <dyn fmt::Debug>::fmt(self, f)
506 }
507}
508
509impl<const N: usize> From<u8> for Uint<N> {
510 fn from(value: u8) -> Self {
511 (value as u64).into()
512 }
513}
514
515impl<const N: usize> From<u16> for Uint<N> {
516 fn from(value: u16) -> Self {
517 (value as u64).into()
518 }
519}
520
521impl<const N: usize> From<u32> for Uint<N> {
522 fn from(value: u32) -> Self {
523 (value as u64).into()
524 }
525}
526
527impl<const N: usize> From<u64> for Uint<N> {
528 fn from(value: u64) -> Self {
529 let mut ret = [0; N];
530 ret[0] = value;
531
532 Self(ret)
533 }
534}
535
536impl<const N: usize> From<u128> for Uint<N> {
537 fn from(value: u128) -> Self {
538 let mut ret = [0u64; N];
539
540 ret[0] = value as u64;
541 ret[1] = (value >> 64) as u64;
542
543 Self(ret)
544 }
545}
546
547impl<const N: usize> Codec for Uint<N> {
548 fn codec_serialize<W: io::Write>(&self, dest: &mut W) -> io::Result<()> {
549 dest.write_all(&self.to_be_bytes())
550 }
551
552 fn codec_deserialize<R: io::Read>(data: &mut R) -> io::Result<Self>
553 where
554 Self: Sized,
555 {
556 let mut buffer = vec![0u8; N * 8];
557 data.read_exact(&mut buffer)?;
558
559 Self::from_be_bytes(buffer).map_err(|_| {
560 io::Error::new(
561 io::ErrorKind::InvalidData,
562 "Could not deserialize Uint",
563 )
564 })
565 }
566}
567
568impl From<DoubleSha256Hasher> for Uint256 {
569 fn from(value: DoubleSha256Hasher) -> Self {
570 let buffer: [u8; SHA256_LENGTH] = value.as_bytes().try_into().unwrap();
571
572 let mut ret: [u64; 4] = unsafe { transmute(buffer) };
573 for x in ret.iter_mut() {
574 *x = x.to_le();
575 }
576
577 Uint256::from_u64_array(ret)
578 }
579}
580
581#[allow(clippy::from_over_into)]
583impl<const N: usize> Into<Vec<u64>> for Uint<N> {
584 fn into(self) -> Vec<u64> {
585 self.0.to_vec()
586 }
587}
588
589impl<const N: usize> TryFrom<Vec<u64>> for Uint<N> {
590 type Error = StacksError;
591
592 fn try_from(value: Vec<u64>) -> Result<Self, Self::Error> {
593 Ok(Self(value.as_slice().try_into()?))
594 }
595}
596
597pub type Uint256 = Uint<4>;
599pub type Uint512 = Uint<8>;
601
602#[cfg(test)]
603mod tests {
604 use super::*;
605
606 impl<const N: usize> Uint<N> {
607 fn bit(&self, index: usize) -> bool {
608 let Uint(arr) = self;
609
610 arr[index / 64] & (1 << (index % 64)) != 0
611 }
612
613 fn bit_slice(&self, start: usize, end: usize) -> Self {
614 (*self >> start).mask(end - start)
615 }
616
617 fn mask(&self, n: usize) -> Self {
618 let Uint(arr) = self;
619
620 let mut ret = [0; N];
621 for i in 0..N {
622 if n >= 0x40 * (i + 1) {
623 ret[i] = arr[i];
624 } else {
625 ret[i] = arr[i] & ((1 << (n - 0x40 * i)) - 1);
626 break;
627 }
628 }
629
630 Uint(ret)
631 }
632 }
633
634 #[test]
635 fn should_convert_from_u32() {
636 assert_eq!(Uint256::from(1337u32), Uint256::from(1337u64));
637 }
638
639 #[test]
640 pub fn uint256_bits_test() {
641 assert_eq!(Uint256::from(255u64).bits(), 8);
642 assert_eq!(Uint256::from(256u64).bits(), 9);
643 assert_eq!(Uint256::from(300u64).bits(), 9);
644 assert_eq!(Uint256::from(60000u64).bits(), 16);
645 assert_eq!(Uint256::from(70000u64).bits(), 17);
646
647 let mut shl = Uint256::from(70000u64);
649 shl = shl << 100;
650 assert_eq!(shl.bits(), 117);
651 shl = shl << 100;
652 assert_eq!(shl.bits(), 217);
653 shl = shl << 100;
654 assert_eq!(shl.bits(), 0);
655
656 assert!(!Uint256::from(10u64).bit(0));
658 assert!(Uint256::from(10u64).bit(1));
659 assert!(!Uint256::from(10u64).bit(2));
660 assert!(Uint256::from(10u64).bit(3));
661 assert!(!Uint256::from(10u64).bit(4));
662 }
663
664 #[test]
665 pub fn uint256_display_test() {
666 assert_eq!(
667 format!("{}", Uint256::from(0xDEADBEEFu64)),
668 "0x00000000000000000000000000000000000000000000000000000000deadbeef"
669 );
670 assert_eq!(
671 format!("{}", Uint256::from(u64::MAX)),
672 "0x000000000000000000000000000000000000000000000000ffffffffffffffff"
673 );
674
675 let max_val = Uint256::from_u64_array([
676 0xFFFFFFFFFFFFFFFF,
677 0xFFFFFFFFFFFFFFFF,
678 0xFFFFFFFFFFFFFFFF,
679 0xFFFFFFFFFFFFFFFF,
680 ]);
681
682 assert_eq!(
683 format!("{}", max_val),
684 "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
685 );
686 }
687
688 #[test]
689 pub fn uint256_comp_test() {
690 let small = Uint256::from_u64_array([10u64, 0, 0, 0]);
691 let big = Uint256::from_u64_array([
692 0x8C8C3EE70C644118u64,
693 0x0209E7378231E632,
694 0,
695 0,
696 ]);
697 let bigger = Uint256::from_u64_array([
698 0x9C8C3EE70C644118u64,
699 0x0209E7378231E632,
700 0,
701 0,
702 ]);
703 let biggest = Uint256::from_u64_array([
704 0x5C8C3EE70C644118u64,
705 0x0209E7378231E632,
706 0,
707 1,
708 ]);
709
710 dbg!(&bigger, &biggest);
711
712 assert!(small < big);
713 assert!(big < bigger);
714 assert!(bigger < biggest);
715 assert!(bigger <= biggest);
716 assert!(biggest <= biggest);
717 assert!(bigger >= big);
718 assert!(bigger >= small);
719 assert!(small <= small);
720 }
721
722 #[test]
723 pub fn uint256_arithmetic_test() {
724 let init = Uint256::from(0xDEADBEEFDEADBEEFu64);
725 let copy = init;
726
727 let add = init + copy;
728 assert_eq!(
729 add,
730 Uint256::from_u64_array([0xBD5B7DDFBD5B7DDEu64, 1, 0, 0])
731 );
732 let shl = add << 88;
734 assert_eq!(
735 shl,
736 Uint256::from_u64_array([0u64, 0xDFBD5B7DDE000000, 0x1BD5B7D, 0])
737 );
738 let shr = shl >> 40;
739 assert_eq!(
740 shr,
741 Uint256::from_u64_array([
742 0x7DDE000000000000u64,
743 0x0001BD5B7DDFBD5B,
744 0,
745 0
746 ])
747 );
748 let mut incr = shr;
750 incr.increment();
751 assert_eq!(
752 incr,
753 Uint256::from_u64_array([
754 0x7DDE000000000001u64,
755 0x0001BD5B7DDFBD5B,
756 0,
757 0
758 ])
759 );
760 let sub = incr - init;
762 assert_eq!(
763 sub,
764 Uint256::from_u64_array([
765 0x9F30411021524112u64,
766 0x0001BD5B7DDFBD5A,
767 0,
768 0
769 ])
770 );
771 let mult = sub.mul_u32(300);
773 assert_eq!(
774 mult,
775 Uint256::from_u64_array([
776 0x8C8C3EE70C644118u64,
777 0x0209E7378231E632,
778 0,
779 0
780 ])
781 );
782 assert_eq!(
784 Uint256::from(105u64) / Uint256::from(5u64),
785 Uint256::from(21u64)
786 );
787 let div = mult / Uint256::from(300u64);
788
789 dbg!(mult, Uint256::from(300u64), div);
790
791 assert_eq!(
792 div,
793 Uint256::from_u64_array([
794 0x9F30411021524112u64,
795 0x0001BD5B7DDFBD5A,
796 0,
797 0
798 ])
799 );
800 }
802
803 #[test]
804 pub fn mul_u32_test() {
805 let u64_val = Uint256::from(0xDEADBEEFDEADBEEFu64);
806
807 let u96_res = u64_val.mul_u32(0xFFFFFFFF);
808 let u128_res = u96_res.mul_u32(0xFFFFFFFF);
809 let u160_res = u128_res.mul_u32(0xFFFFFFFF);
810 let u192_res = u160_res.mul_u32(0xFFFFFFFF);
811 let u224_res = u192_res.mul_u32(0xFFFFFFFF);
812 let u256_res = u224_res.mul_u32(0xFFFFFFFF);
813
814 assert_eq!(
815 u96_res,
816 Uint256::from_u64_array([0xffffffff21524111u64, 0xDEADBEEE, 0, 0])
817 );
818 assert_eq!(
819 u128_res,
820 Uint256::from_u64_array([
821 0x21524111DEADBEEFu64,
822 0xDEADBEEE21524110,
823 0,
824 0
825 ])
826 );
827 assert_eq!(
828 u160_res,
829 Uint256::from_u64_array([
830 0xBD5B7DDD21524111u64,
831 0x42A4822200000001,
832 0xDEADBEED,
833 0
834 ])
835 );
836 assert_eq!(
837 u192_res,
838 Uint256::from_u64_array([
839 0x63F6C333DEADBEEFu64,
840 0xBD5B7DDFBD5B7DDB,
841 0xDEADBEEC63F6C334,
842 0
843 ])
844 );
845 assert_eq!(
846 u224_res,
847 Uint256::from_u64_array([
848 0x7AB6FBBB21524111u64,
849 0xFFFFFFFBA69B4558,
850 0x854904485964BAAA,
851 0xDEADBEEB
852 ])
853 );
854 assert_eq!(
855 u256_res,
856 Uint256::from_u64_array([
857 0xA69B4555DEADBEEFu64,
858 0xA69B455CD41BB662,
859 0xD41BB662A69B4550,
860 0xDEADBEEAA69B455C
861 ])
862 );
863 }
864
865 #[test]
866 pub fn multiplication_test() {
867 let u64_val = Uint256::from(0xDEADBEEFDEADBEEFu64);
868
869 let u128_res = u64_val * u64_val;
870
871 assert_eq!(
872 u128_res,
873 Uint256::from_u64_array([
874 0x048D1354216DA321u64,
875 0xC1B1CD13A4D13D46,
876 0,
877 0
878 ])
879 );
880
881 let u256_res = u128_res * u128_res;
882
883 assert_eq!(
884 u256_res,
885 Uint256::from_u64_array([
886 0xF4E166AAD40D0A41u64,
887 0xF5CF7F3618C2C886u64,
888 0x4AFCFF6F0375C608u64,
889 0x928D92B4D7F5DF33u64
890 ])
891 );
892 }
893
894 #[test]
895 pub fn uint256_bitslice_test() {
896 let init = Uint256::from(0xDEADBEEFDEADBEEFu64);
897 let add = init + (init << 64);
898 assert_eq!(add.bit_slice(64, 128), init);
899 assert_eq!(add.mask(64), init);
900 }
901
902 #[test]
903 pub fn uint256_extreme_bitshift_test() {
904 let init = Uint256::from(0xDEADBEEFDEADBEEFu64);
907
908 assert_eq!(
909 init << 64,
910 Uint256::from_u64_array([0, 0xDEADBEEFDEADBEEF, 0, 0])
911 );
912 let add = (init << 64) + init;
913 assert_eq!(
914 add,
915 Uint256::from_u64_array([
916 0xDEADBEEFDEADBEEF,
917 0xDEADBEEFDEADBEEF,
918 0,
919 0
920 ])
921 );
922 assert_eq!(
923 add >> 0,
924 Uint256::from_u64_array([
925 0xDEADBEEFDEADBEEF,
926 0xDEADBEEFDEADBEEF,
927 0,
928 0
929 ])
930 );
931 assert_eq!(
932 add << 0,
933 Uint256::from_u64_array([
934 0xDEADBEEFDEADBEEF,
935 0xDEADBEEFDEADBEEF,
936 0,
937 0
938 ])
939 );
940 assert_eq!(
941 add >> 64,
942 Uint256::from_u64_array([0xDEADBEEFDEADBEEF, 0, 0, 0])
943 );
944 assert_eq!(
945 add << 64,
946 Uint256::from_u64_array([
947 0,
948 0xDEADBEEFDEADBEEF,
949 0xDEADBEEFDEADBEEF,
950 0
951 ])
952 );
953 }
954
955 #[test]
956 pub fn hex_codec() {
957 let init = Uint256::from(0xDEADBEEFDEADBEEFu64) << 64
958 | Uint256::from(0x0102030405060708u64);
959
960 let hex_init =
962 "0807060504030201efbeaddeefbeadde00000000000000000000000000000000";
963 assert_eq!(
964 Uint256::from_le_bytes(hex::decode(hex_init).unwrap()).unwrap(),
965 init
966 );
967 assert_eq!(hex::encode(init.to_le_bytes()), hex_init);
968 assert_eq!(Uint256::from_le_bytes(init.to_le_bytes()).unwrap(), init);
969
970 let hex_init =
972 "00000000000000000000000000000000deadbeefdeadbeef0102030405060708";
973 assert_eq!(
974 Uint256::from_be_bytes(hex::decode(hex_init).unwrap()).unwrap(),
975 init
976 );
977 assert_eq!(hex::encode(init.to_be_bytes()), hex_init);
978 assert_eq!(Uint256::from_be_bytes(init.to_be_bytes()).unwrap(), init);
979 }
980
981 #[test]
982 pub fn uint_increment_test() {
983 let mut value = Uint256::from_u64_array([0xffffffffffffffff, 0, 0, 0]);
984 value.increment();
985 assert_eq!(value, Uint256::from_u64_array([0, 1, 0, 0]));
986
987 value = Uint256::from_u64_array([
988 0xffffffffffffffff,
989 0xffffffffffffffff,
990 0,
991 0,
992 ]);
993 value.increment();
994 assert_eq!(value, Uint256::from_u64_array([0, 0, 1, 0]));
995
996 value = Uint256::from_u64_array([
997 0xffffffffffffffff,
998 0xffffffffffffffff,
999 0xffffffffffffffff,
1000 0,
1001 ]);
1002 value.increment();
1003 assert_eq!(value, Uint256::from_u64_array([0, 0, 0, 1]));
1004
1005 value = Uint256::from_u64_array([
1006 0xffffffffffffffff,
1007 0xffffffffffffffff,
1008 0xffffffffffffffff,
1009 0xffffffffffffffff,
1010 ]);
1011 value.increment();
1012 assert_eq!(value, Uint256::from_u64_array([0, 0, 0, 0]));
1013 }
1014}