extended_primitives/
uint256.rs

1// Rust Bitcoin Library
2// Written in 2014 by
3//     Andrew Poelstra <apoelstra@wpsoftware.net>
4//
5// To the extent possible under law, the author(s) have dedicated all
6// copyright and related and neighboring rights to this software to
7// the public domain worldwide. This software is distributed without
8// any warranty.
9//
10// You should have received a copy of the CC0 Public Domain Dedication
11// along with this software.
12// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
13//
14
15//! Big unsigned integer types
16//!
17//! Implementation of a various large-but-fixed sized unsigned integer types.
18//! The functions here are designed to be fast.
19//!
20//!
21//!Edits to the original Implementation -> We don't use the u128 type at all so I see no need for a
22//!macro. I'd rather have the code easier to understand for a newcomer, then have a macro that is
23//!only used for one thing.
24
25use encodings::hex::{FromHex, FromHexError, ToHex};
26use std::fmt;
27
28#[cfg(feature = "rng")]
29use rand::{thread_rng, Rng};
30
31// When Std::iter::Step is finished being implemented add it to this type. That would allow us to
32// use for loops much more easily. Right now it's on nightly only -> https://github.com/rust-lang/rust/issues/42168
33//TODO expose a zero() function on Uint256 -> Right now the only way to get a 0 is to use default()
34//which doesn't feel very natural to how other rust is written.
35//
36/// A trait which allows numbers to act as fixed-size bit arrays
37pub trait BitArray {
38    /// Is bit set?
39    fn bit(&self, idx: usize) -> bool;
40
41    /// Returns an array which is just the bits from start to end
42    fn bit_slice(&self, start: usize, end: usize) -> Self;
43
44    /// Bitwise and with `n` ones
45    fn mask(&self, n: usize) -> Self;
46
47    /// Trailing zeros
48    fn trailing_zeros(&self) -> usize;
49
50    /// Create all-zeros value
51    fn zero() -> Self;
52
53    /// Create value representing one
54    fn one() -> Self;
55}
56
57// use consensus::encode;
58// use util::BitArray;
59//TODO what is repr actually used for?
60//https://doc.rust-lang.org/nomicon/other-reprs.html -> I'm not sure we are going to be transfering
61//this through FFI, so this could probably be removed, but I'll leave this for review.
62#[repr(C)]
63pub struct Uint256(pub [u64; 4]);
64
65//thing = Uint256
66//ty = u64
67//expr = 4
68
69//DO we need these lifetimes here? TODO
70impl<'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        //TODO this might have to be reversed
99        (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            //@todo this should not return this error here. It should actually return invalid
117            //Uint256 something like that. The Hex isn't invalid length, the result from the hex
118            //is.
119            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        // manually implement comparison to get little-endian ordering
194        // (we need this for our numeric types; non-numeric ones shouldn't
195        // be ordered anyway except to put them in BTrees or whatever, and
196        // they don't care how we order as long as we're consistent).
197        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))] // we don't define the `struct`, we have to explicitly impl
210impl 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    /// Converts the object to a raw pointer
232    pub fn as_ptr(&self) -> *const u64 {
233        let &Uint256(ref dat) = self;
234        dat.as_ptr()
235    }
236
237    #[inline]
238    /// Converts the object to a mutable raw pointer
239    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    /// Returns the length of the object as an array
246    pub fn len(&self) -> usize {
247        4
248    }
249
250    #[inline]
251    /// Returns whether the object, as an array, is empty. Always false.
252    pub fn is_empty(&self) -> bool {
253        false
254    }
255
256    //@todo
257    // #[inline]
258    // pub fn to_hex(&self) -> String {
259    //     hex::encode(self.to_le_bytes())
260    // }
261
262    #[inline]
263    /// Returns the underlying bytes.
264    pub fn as_bytes(&self) -> &[u64; 4] {
265        &self.0
266    }
267
268    #[inline]
269    //Remove old Bytes functions TODO move them to returning u8
270    //XXX Giant todo, do not forget these, or we will have unstandarized function returns.
271    /// Returns the underlying bytes.
272    pub fn to_bytes(&self) -> [u64; 4] {
273        self.0
274    }
275
276    #[inline]
277    //Returns little endian bytes
278    pub fn to_le_bytes(&self) -> [u8; 32] {
279        let mut bytes = [0; 32];
280        for i in 0..4 {
281            //Ugly rewrite this code to be more efficient...
282            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            //Second half
290            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    /// The maximum value which can be inhabited by this type.
300    #[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    /// Returns the underlying bytes.
311    pub fn into_bytes(self) -> [u64; 4] {
312        self.0
313    }
314
315    /// Conversion to u32
316    #[inline]
317    pub fn low_u32(&self) -> u32 {
318        let &Uint256(ref arr) = self;
319        arr[0] as u32
320    }
321
322    /// Conversion to u64
323    #[inline]
324    pub fn low_u64(&self) -> u64 {
325        let &Uint256(ref arr) = self;
326        arr[0]
327    }
328
329    /// Return the least number of bits needed to represent the number
330    #[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    /// Multiplication by u32
342    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    /// Create an object from a given unsigned 64-bit integer
363    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    /// Create an object from a given signed 64-bit integer
370    pub fn from_i64(init: i64) -> Option<Uint256> {
371        assert!(init >= 0);
372        Uint256::from_u64(init as u64)
373    }
374
375    /// Converts from big endian representation bytes in memory.
376    // TODO write a test for this please.
377    pub fn from_big_endian(slice: &[u8]) -> Self {
378        assert!(4 * 8 >= slice.len());
379        assert!(slice.len() % 8 == 0);
380        //TODO this may need to be reworked for various size arrays, test this.
381        let mut ret = [0; 4];
382        let length = slice.len() / 8;
383        //TODO this might have to be reversed
384        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    //TODO this might or might not work. Needs a lot of testing here.
396    pub fn from_bytes(slice: &[u8]) -> Self {
397        assert!(4 * 8 >= slice.len());
398        assert!(slice.len() % 8 == 0);
399        //TODO this may need to be reworked for various size arrays, test this.
400        let mut ret = [0; 4];
401        let length = slice.len() / 8;
402        //TODO this might have to be reversed
403        (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        //TODO should this be Uint256::one()?
460        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        // TODO: be more efficient about this
470        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        // Check for division by 0
490        assert!(your_bits != 0);
491
492        // Early return in case we are dividing by a larger number than us
493        if my_bits < your_bits {
494            return Uint256(ret);
495        }
496
497        // Bitwise long division
498        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
516/// Little-endian large integer type
517// impl_array_newtype!($name, u64, $n_words);
518
519impl 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            // Shift
645            if bit_shift < 64 && i + word_shift < 4 {
646                ret[i + word_shift] += original[i] << bit_shift;
647            }
648            // Carry
649            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            // Shift
667            ret[i - word_shift] += original[i] >> bit_shift;
668            // Carry
669            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
677//@todo I'm going to preface this with a huge @todo and @smells. We need to thoroughly review the
678//fcuntionality and the endianness of this struct. I've been experiencing weird issues with how we
679//are printing out these strings, and it's even more relevant now that we are playing w/ Targets
680//and block hashes quite often. So Im going to have this fuction work for LE, but I want to come
681//back and review extensively.
682impl 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
693//TODO convert these to hex?
694impl 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        // Try to read the following lines out loud quickly
797        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        // Bit set check
806        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        // Bitshifts
861        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        // Increment
869        let mut incr = shr;
870        incr.increment();
871        assert_eq!(
872            incr,
873            Uint256([0x7DDE000000000001u64, 0x0001BD5B7DDFBD5B, 0, 0])
874        );
875        // Subtraction
876        let sub = incr - init;
877        assert_eq!(
878            sub,
879            Uint256([0x9F30411021524112u64, 0x0001BD5B7DDFBD5A, 0, 0])
880        );
881        // Multiplication
882        let mult = sub.mul_u32(300);
883        assert_eq!(
884            mult,
885            Uint256([0x8C8C3EE70C644118u64, 0x0209E7378231E632, 0, 0])
886        );
887        // Division
888        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        // TODO: bit inversion
898    }
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        // Shifting a u64 by 64 bits gives an undefined value, so make sure that
984        // we're doing the Right Thing here
985        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//TODO add tests for serialization here.