bigint/uint/
mod.rs

1// Copyright 2015-2017 Parity Technologies
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9// Code derived from original work by Andrew Poelstra <apoelstra@wpsoftware.net>
10
11// Rust Bitcoin Library
12// Written in 2014 by
13//     Andrew Poelstra <apoelstra@wpsoftware.net>
14//
15// To the extent possible under law, the author(s) have dedicated all
16// copyright and related and neighboring rights to this software to
17// the public domain worldwide. This software is distributed without
18// any warranty.
19//
20// You should have received a copy of the CC0 Public Domain Dedication
21// along with this software.
22// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
23//
24
25//! Big unsigned integer types.
26//!
27//! Implementation of a various large-but-fixed sized unsigned integer types.
28//! The functions here are designed to be fast. There are optional `x86_64`
29//! implementations for even more speed, hidden behind the `x64_arithmetic`
30//! feature flag.
31
32#[cfg(feature = "std")] use std::fmt;
33#[cfg(feature = "std")] use std::str::FromStr;
34#[cfg(feature = "std")] use std::ops::{Shr, Shl, BitAnd, BitOr, BitXor, Not, Div, Rem, Mul, Add, Sub};
35#[cfg(feature = "std")] use std::cmp::Ordering;
36
37#[cfg(not(feature = "std"))] use core::fmt;
38#[cfg(not(feature = "std"))] use core::str::FromStr;
39#[cfg(not(feature = "std"))] use core::ops::{Shr, Shl, BitAnd, BitOr, BitXor, Not, Div, Rem, Mul, Add, Sub};
40#[cfg(not(feature = "std"))] use core::cmp::Ordering;
41
42#[cfg(all(not(feature = "std"), feature = "string"))]
43use alloc::string::String;
44
45use byteorder::{ByteOrder, BigEndian, LittleEndian};
46#[cfg(feature = "string")]
47use hexutil::{ParseHexError, read_hex};
48
49#[cfg(feature = "rlp")]
50mod rlp;
51
52/// Conversion from decimal string error
53#[derive(Debug, PartialEq)]
54pub enum FromDecStrErr {
55    /// Char not from range 0-9
56    InvalidCharacter,
57    /// Value does not fit into type
58    InvalidLength,
59}
60
61macro_rules! impl_map_from {
62	($thing:ident, $from:ty, $to:ty) => {
63		impl From<$from> for $thing {
64			fn from(value: $from) -> $thing {
65				From::from(value as $to)
66			}
67		}
68	}
69}
70
71#[cfg(not(all(asm_available, target_arch="x86_64")))]
72macro_rules! uint_overflowing_add {
73	($name:ident, $n_words:expr, $self_expr: expr, $other: expr) => ({
74		uint_overflowing_add_reg!($name, $n_words, $self_expr, $other)
75	})
76}
77
78macro_rules! uint_overflowing_add_reg {
79	($name:ident, $n_words:expr, $self_expr: expr, $other: expr) => ({
80		let $name(ref me) = $self_expr;
81		let $name(ref you) = $other;
82
83		let mut ret = [0u64; $n_words];
84		let mut carry = 0u64;
85
86		for i in 0..$n_words {
87			let (res1, overflow1) = me[i].overflowing_add(you[i]);
88			let (res2, overflow2) = res1.overflowing_add(carry);
89
90			ret[i] = res2;
91			carry = overflow1 as u64 + overflow2 as u64;
92		}
93
94		($name(ret), carry > 0)
95	})
96}
97
98#[cfg(all(asm_available, target_arch="x86_64"))]
99macro_rules! uint_overflowing_add {
100	(U256, $n_words: expr, $self_expr: expr, $other: expr) => ({
101		let mut result: [u64; $n_words] = unsafe { ::std::mem::uninitialized() };
102		let self_t: &[u64; $n_words] = &$self_expr.0;
103		let other_t: &[u64; $n_words] = &$other.0;
104
105		let overflow: u8;
106		unsafe {
107			asm!("
108				add $9, $0
109				adc $10, $1
110				adc $11, $2
111				adc $12, $3
112				setc %al
113				"
114			: "=r"(result[0]), "=r"(result[1]), "=r"(result[2]), "=r"(result[3]), "={al}"(overflow)
115			: "0"(self_t[0]), "1"(self_t[1]), "2"(self_t[2]), "3"(self_t[3]),
116			  "mr"(other_t[0]), "mr"(other_t[1]), "mr"(other_t[2]), "mr"(other_t[3])
117			:
118			:
119			);
120		}
121		(U256(result), overflow != 0)
122	});
123	(U512, $n_words: expr, $self_expr: expr, $other: expr) => ({
124		let mut result: [u64; $n_words] = unsafe { ::std::mem::uninitialized() };
125		let self_t: &[u64; $n_words] = &$self_expr.0;
126		let other_t: &[u64; $n_words] = &$other.0;
127
128		let overflow: u8;
129
130		unsafe {
131			asm!("
132				add $15, $0
133				adc $16, $1
134				adc $17, $2
135				adc $18, $3
136				lodsq
137				adc $11, %rax
138				stosq
139				lodsq
140				adc $12, %rax
141				stosq
142				lodsq
143				adc $13, %rax
144				stosq
145				lodsq
146				adc $14, %rax
147				stosq
148				setc %al
149
150				": "=r"(result[0]), "=r"(result[1]), "=r"(result[2]), "=r"(result[3]),
151
152			  "={al}"(overflow) /* $0 - $4 */
153
154            : "{rdi}"(&result[4] as *const u64) /* $5 */
155			  "{rsi}"(&other_t[4] as *const u64) /* $6 */
156			  "0"(self_t[0]), "1"(self_t[1]), "2"(self_t[2]), "3"(self_t[3]),
157		  	  "m"(self_t[4]), "m"(self_t[5]), "m"(self_t[6]), "m"(self_t[7]),
158			  /* $7 - $14 */
159
160			  "mr"(other_t[0]), "mr"(other_t[1]), "mr"(other_t[2]), "mr"(other_t[3]),
161              "m"(other_t[4]), "m"(other_t[5]), "m"(other_t[6]), "m"(other_t[7]) /* $15 - $22 */
162			: "rdi", "rsi"
163			:
164			);
165		}
166		(U512(result), overflow != 0)
167	});
168
169	($name:ident, $n_words:expr, $self_expr: expr, $other: expr) => (
170		uint_overflowing_add_reg!($name, $n_words, $self_expr, $other)
171	)
172}
173
174#[cfg(not(all(asm_available, target_arch="x86_64")))]
175macro_rules! uint_overflowing_sub {
176	($name:ident, $n_words: expr, $self_expr: expr, $other: expr) => ({
177		uint_overflowing_sub_reg!($name, $n_words, $self_expr, $other)
178	})
179}
180
181macro_rules! uint_overflowing_sub_reg {
182	($name:ident, $n_words: expr, $self_expr: expr, $other: expr) => ({
183		let $name(ref me) = $self_expr;
184		let $name(ref you) = $other;
185
186		let mut ret = [0u64; $n_words];
187		let mut carry = 0u64;
188
189		for i in 0..$n_words {
190			let (res1, overflow1) = me[i].overflowing_sub(you[i]);
191			let (res2, overflow2) = res1.overflowing_sub(carry);
192
193			ret[i] = res2;
194			carry = overflow1 as u64 + overflow2 as u64;
195		}
196
197		($name(ret), carry > 0)
198
199	})
200}
201
202#[cfg(all(asm_available, target_arch="x86_64"))]
203macro_rules! uint_overflowing_sub {
204	(U256, $n_words: expr, $self_expr: expr, $other: expr) => ({
205		let mut result: [u64; $n_words] = unsafe { ::std::mem::uninitialized() };
206		let self_t: &[u64; $n_words] = &$self_expr.0;
207		let other_t: &[u64; $n_words] = &$other.0;
208
209		let overflow: u8;
210		unsafe {
211			asm!("
212				sub $9, $0
213				sbb $10, $1
214				sbb $11, $2
215				sbb $12, $3
216				setb %al
217				"
218				: "=r"(result[0]), "=r"(result[1]), "=r"(result[2]), "=r"(result[3]), "={al}"(overflow)
219				: "0"(self_t[0]), "1"(self_t[1]), "2"(self_t[2]), "3"(self_t[3]), "mr"(other_t[0]), "mr"(other_t[1]), "mr"(other_t[2]), "mr"(other_t[3])
220				:
221				:
222			);
223		}
224		(U256(result), overflow != 0)
225	});
226	(U512, $n_words: expr, $self_expr: expr, $other: expr) => ({
227		let mut result: [u64; $n_words] = unsafe { ::std::mem::uninitialized() };
228		let self_t: &[u64; $n_words] = &$self_expr.0;
229		let other_t: &[u64; $n_words] = &$other.0;
230
231		let overflow: u8;
232
233		unsafe {
234			asm!("
235				sub $15, $0
236				sbb $16, $1
237				sbb $17, $2
238				sbb $18, $3
239				lodsq
240				sbb $19, %rax
241				stosq
242				lodsq
243				sbb $20, %rax
244				stosq
245				lodsq
246				sbb $21, %rax
247				stosq
248				lodsq
249				sbb $22, %rax
250				stosq
251				setb %al
252				"
253			: "=r"(result[0]), "=r"(result[1]), "=r"(result[2]), "=r"(result[3]),
254
255			  "={al}"(overflow) /* $0 - $4 */
256
257			: "{rdi}"(&result[4] as *const u64) /* $5 */
258		 	 "{rsi}"(&self_t[4] as *const u64) /* $6 */
259			  "0"(self_t[0]), "1"(self_t[1]), "2"(self_t[2]), "3"(self_t[3]),
260			  "m"(self_t[4]), "m"(self_t[5]), "m"(self_t[6]), "m"(self_t[7]),
261			  /* $7 - $14 */
262
263			  "m"(other_t[0]), "m"(other_t[1]), "m"(other_t[2]), "m"(other_t[3]),
264			  "m"(other_t[4]), "m"(other_t[5]), "m"(other_t[6]), "m"(other_t[7]) /* $15 - $22 */
265			: "rdi", "rsi"
266			:
267			);
268		}
269		(U512(result), overflow != 0)
270	});
271	($name:ident, $n_words: expr, $self_expr: expr, $other: expr) => ({
272		uint_overflowing_sub_reg!($name, $n_words, $self_expr, $other)
273	})
274}
275
276#[cfg(all(asm_available, target_arch="x86_64"))]
277macro_rules! uint_overflowing_mul {
278	(U256, $n_words: expr, $self_expr: expr, $other: expr) => ({
279		let mut result: [u64; $n_words] = unsafe { ::std::mem::uninitialized() };
280		let self_t: &[u64; $n_words] = &$self_expr.0;
281		let other_t: &[u64; $n_words] = &$other.0;
282
283		let overflow: u64;
284		unsafe {
285			asm!("
286				mov $5, %rax
287				mulq $9
288				mov %rax, $0
289				mov %rdx, $1
290
291				mov $5, %rax
292				mulq $10
293				add %rax, $1
294				adc $$0, %rdx
295				mov %rdx, $2
296
297				mov $5, %rax
298				mulq $11
299				add %rax, $2
300				adc $$0, %rdx
301				mov %rdx, $3
302
303				mov $5, %rax
304				mulq $12
305				add %rax, $3
306				adc $$0, %rdx
307				mov %rdx, %rcx
308
309				mov $6, %rax
310				mulq $9
311				add %rax, $1
312				adc %rdx, $2
313				adc $$0, $3
314				adc $$0, %rcx
315
316				mov $6, %rax
317				mulq $10
318				add %rax, $2
319				adc %rdx, $3
320				adc $$0, %rcx
321				adc $$0, $3
322				adc $$0, %rcx
323
324				mov $6, %rax
325				mulq $11
326				add %rax, $3
327				adc $$0, %rdx
328				or %rdx, %rcx
329
330				mov $7, %rax
331				mulq $9
332				add %rax, $2
333				adc %rdx, $3
334				adc $$0, %rcx
335
336				mov $7, %rax
337				mulq $10
338				add %rax, $3
339				adc $$0, %rdx
340				or %rdx, %rcx
341
342				mov $8, %rax
343				mulq $9
344				add %rax, $3
345				or %rdx, %rcx
346
347				cmpq $$0, %rcx
348				jne 2f
349
350				mov $8, %rcx
351				jrcxz 12f
352
353				mov $12, %rcx
354				mov $11, %rax
355				or %rax, %rcx
356				mov $10, %rax
357				or %rax, %rcx
358				jmp 2f
359
360				12:
361				mov $12, %rcx
362				jrcxz 11f
363
364				mov $7, %rcx
365				mov $6, %rax
366				or %rax, %rcx
367
368				cmpq $$0, %rcx
369				jne 2f
370
371				11:
372				mov $11, %rcx
373				jrcxz 2f
374				mov $7, %rcx
375
376				2:
377				"
378				: /* $0 */ "={r8}"(result[0]), /* $1 */ "={r9}"(result[1]), /* $2 */ "={r10}"(result[2]),
379				  /* $3 */ "={r11}"(result[3]), /* $4 */  "={rcx}"(overflow)
380
381				: /* $5 */ "m"(self_t[0]), /* $6 */ "m"(self_t[1]), /* $7 */  "m"(self_t[2]),
382				  /* $8 */ "m"(self_t[3]), /* $9 */ "m"(other_t[0]), /* $10 */ "m"(other_t[1]),
383				  /* $11 */ "m"(other_t[2]), /* $12 */ "m"(other_t[3])
384           		: "rax", "rdx"
385				:
386
387			);
388		}
389		(U256(result), overflow > 0)
390	});
391	($name:ident, $n_words:expr, $self_expr: expr, $other: expr) => (
392		uint_overflowing_mul_reg!($name, $n_words, $self_expr, $other)
393	)
394}
395
396#[cfg(not(all(asm_available, target_arch="x86_64")))]
397macro_rules! uint_overflowing_mul {
398	($name:ident, $n_words: expr, $self_expr: expr, $other: expr) => ({
399		uint_overflowing_mul_reg!($name, $n_words, $self_expr, $other)
400	})
401}
402
403macro_rules! uint_overflowing_mul_reg {
404	($name:ident, $n_words: expr, $self_expr: expr, $other: expr) => ({
405		let $name(ref me) = $self_expr;
406		let $name(ref you) = $other;
407		let mut ret = [0u64; 2*$n_words];
408
409		for i in 0..$n_words {
410			if you[i] == 0 {
411				continue;
412			}
413
414			let mut carry2 = 0u64;
415			let (b_u, b_l) = split(you[i]);
416
417			for j in 0..$n_words {
418				if me[j] == 0 && carry2 == 0 {
419					continue;
420				}
421
422				let a = split(me[j]);
423
424				// multiply parts
425				let (c_l, overflow_l) = mul_u32(a, b_l, ret[i + j]);
426				let (c_u, overflow_u) = mul_u32(a, b_u, c_l >> 32);
427				ret[i + j] = (c_l & 0xFFFFFFFF) + (c_u << 32);
428
429				// No overflow here
430				let res = (c_u >> 32) + (overflow_u << 32);
431				// possible overflows
432				let (res, o1) = res.overflowing_add(overflow_l);
433				let (res, o2) = res.overflowing_add(carry2);
434				let (res, o3) = res.overflowing_add(ret[i + j + 1]);
435				ret[i + j + 1] = res;
436
437				// Only single overflow possible there
438				carry2 = (o1 | o2 | o3) as u64;
439			}
440		}
441
442		let mut res = [0u64; $n_words];
443		let mut overflow = false;
444		for i in 0..$n_words {
445			res[i] = ret[i];
446		}
447
448		for i in $n_words..2*$n_words {
449			overflow |= ret[i] != 0;
450		}
451
452		($name(res), overflow)
453	})
454}
455
456macro_rules! overflowing {
457	($op: expr, $overflow: expr) => (
458		{
459			let (overflow_x, overflow_overflow) = $op;
460			$overflow |= overflow_overflow;
461			overflow_x
462		}
463	);
464	($op: expr) => (
465		{
466			let (overflow_x, _overflow_overflow) = $op;
467			overflow_x
468		}
469	);
470}
471
472macro_rules! panic_on_overflow {
473	($name: expr) => {
474		if $name {
475			panic!("arithmetic operation overflow")
476		}
477	}
478}
479
480#[inline(always)]
481fn mul_u32(a: (u64, u64), b: u64, carry: u64) -> (u64, u64) {
482    let upper = b * a.0;
483    let lower = b * a.1;
484
485    let (res1, overflow1) = lower.overflowing_add(upper << 32);
486    let (res2, overflow2) = res1.overflowing_add(carry);
487
488    let carry = (upper >> 32) + overflow1 as u64 + overflow2 as u64;
489    (res2, carry)
490}
491
492#[inline(always)]
493fn split(a: u64) -> (u64, u64) {
494    (a >> 32, a & 0xFFFFFFFF)
495}
496
497macro_rules! construct_uint {
498	($name:ident, $n_words:expr) => (
499		/// Little-endian large integer type
500		#[repr(C)]
501		#[derive(Copy, Clone, Eq, PartialEq, Hash)]
502		pub struct $name(pub [u64; $n_words]);
503
504		impl $name {
505			/// Convert from a decimal string.
506			pub fn from_dec_str(value: &str) -> Result<Self, FromDecStrErr> {
507				if !value.bytes().all(|b| b >= 48 && b <= 57) {
508					return Err(FromDecStrErr::InvalidCharacter)
509				}
510
511				let mut res = Self::default();
512				for b in value.bytes().map(|b| b - 48) {
513					let (r, overflow) = res.overflowing_mul_u32(10);
514					if overflow {
515						return Err(FromDecStrErr::InvalidLength);
516					}
517					let (r, overflow) = r.overflowing_add(b.into());
518					if overflow {
519						return Err(FromDecStrErr::InvalidLength);
520					}
521					res = r;
522				}
523				Ok(res)
524			}
525
526			/// Conversion to u32
527			#[inline]
528			pub fn low_u32(&self) -> u32 {
529				let &$name(ref arr) = self;
530				arr[0] as u32
531			}
532
533			/// Conversion to u64
534			#[inline]
535			pub fn low_u64(&self) -> u64 {
536				let &$name(ref arr) = self;
537				arr[0]
538			}
539
540			/// Conversion to u32 with overflow checking
541			///
542			/// # Panics
543			///
544			/// Panics if the number is larger than 2^32.
545			#[inline]
546			pub fn as_u32(&self) -> u32 {
547				let &$name(ref arr) = self;
548				if (arr[0] & (0xffffffffu64 << 32)) != 0 {
549					panic!("Integer overflow when casting U256")
550				}
551				self.as_u64() as u32
552			}
553
554			/// Conversion to u64 with overflow checking
555			///
556			/// # Panics
557			///
558			/// Panics if the number is larger than 2^64.
559			#[inline]
560			pub fn as_u64(&self) -> u64 {
561				let &$name(ref arr) = self;
562				for i in 1..$n_words {
563					if arr[i] != 0 {
564						panic!("Integer overflow when casting U256")
565					}
566				}
567				arr[0]
568			}
569
570		    /// Conversion to usize with overflow checking
571			///
572			/// # Panics
573			///
574			/// Panics if the number is larger than usize::max_value().
575            #[inline]
576            pub fn as_usize(&self) -> usize {
577                #[cfg(feature = "std")]
578                use std::mem::size_of;
579
580                #[cfg(not(feature = "std"))]
581                use core::mem::size_of;
582
583                if size_of::<usize>() > size_of::<u64>() && size_of::<usize>() < size_of::<u32>() {
584                    panic!("Unsupported platform")
585                }
586                if size_of::<usize>() == size_of::<u64>() {
587                    self.as_u64() as usize
588                } else {
589                    self.as_u32() as usize
590                }
591            }
592
593			/// Whether this is zero.
594			#[inline]
595			pub fn is_zero(&self) -> bool {
596				let &$name(ref arr) = self;
597				for i in 0..$n_words { if arr[i] != 0 { return false; } }
598				return true;
599			}
600
601			/// Return the least number of bits needed to represent the number
602			#[inline]
603			pub fn bits(&self) -> usize {
604				let &$name(ref arr) = self;
605				for i in 1..$n_words {
606					if arr[$n_words - i] > 0 { return (0x40 * ($n_words - i + 1)) - arr[$n_words - i].leading_zeros() as usize; }
607				}
608				0x40 - arr[0].leading_zeros() as usize
609			}
610
611			/// Return if specific bit is set.
612			///
613			/// # Panics
614			///
615			/// Panics if `index` exceeds the bit width of the number.
616			#[inline]
617			pub fn bit(&self, index: usize) -> bool {
618				let &$name(ref arr) = self;
619				arr[index / 64] & (1 << (index % 64)) != 0
620			}
621
622			/// Return specific byte.
623			///
624			/// # Panics
625			///
626			/// Panics if `index` exceeds the byte width of the number.
627			#[inline]
628			pub fn byte(&self, index: usize) -> u8 {
629				let &$name(ref arr) = self;
630				(arr[index / 8] >> (((index % 8)) * 8)) as u8
631			}
632
633            /// Return specific byte in big-endian format.
634            ///
635			/// # Panics
636			///
637			/// Panics if `index` exceeds the byte width of the number.
638            #[inline]
639            pub fn index(&self, index: usize) -> u8 {
640                let index = $n_words * 8 - 1 - index;
641                self.byte(index)
642            }
643
644			/// Write to the slice in big-endian format.
645			#[inline]
646			pub fn to_big_endian(&self, bytes: &mut [u8]) {
647				debug_assert!($n_words * 8 == bytes.len());
648				for i in 0..$n_words {
649					BigEndian::write_u64(&mut bytes[8 * i..], self.0[$n_words - i - 1]);
650				}
651			}
652
653			/// Write to the slice in little-endian format.
654			#[inline]
655			pub fn to_little_endian(&self, bytes: &mut [u8]) {
656				debug_assert!($n_words * 8 == bytes.len());
657				for i in 0..$n_words {
658					LittleEndian::write_u64(&mut bytes[8 * i..], self.0[i]);
659				}
660			}
661
662			/// Create `10**n` as this type.
663			///
664			/// # Panics
665			///
666			/// Panics if the result overflows the type.
667			#[inline]
668			pub fn exp10(n: usize) -> Self {
669				match n {
670					0 => Self::from(1u64),
671					_ => Self::exp10(n - 1).mul_u32(10)
672				}
673			}
674
675			/// Zero (additive identity) of this type.
676			#[inline]
677			pub fn zero() -> Self {
678				From::from(0u64)
679			}
680
681			/// One (multiplicative identity) of this type.
682			#[inline]
683			pub fn one() -> Self {
684				From::from(1u64)
685			}
686
687			/// The maximum value which can be inhabited by this type.
688			#[inline]
689			pub fn max_value() -> Self {
690				let mut result = [0; $n_words];
691				for i in 0..$n_words {
692					result[i] = u64::max_value();
693				}
694				$name(result)
695			}
696
697			/// The minimum value which can be inhabited by this type.
698			#[inline]
699			pub fn min_value() -> Self {
700			    $name([0; $n_words])
701			}
702
703			/// Fast exponentation by squaring
704			/// https://en.wikipedia.org/wiki/Exponentiation_by_squaring
705			///
706			/// # Panics
707			///
708			/// Panics if the result overflows the type.
709			pub fn pow(self, expon: Self) -> Self {
710				if expon.is_zero() {
711					return Self::one()
712				}
713				let is_even = |x : &Self| x.low_u64() & 1 == 0;
714
715				let u_one = Self::one();
716				let mut y = u_one;
717				let mut n = expon;
718				let mut x = self;
719				while n > u_one {
720					if is_even(&n) {
721						x = x * x;
722						n = n >> 1;
723					} else {
724						y = x * y;
725						x = x * x;
726						// to reduce odd number by 1 we should just clear the last bit
727						n.0[$n_words-1] = n.0[$n_words-1] & ((!0u64)>>1);
728						n = n >> 1;
729					}
730				}
731				x * y
732			}
733
734			/// Fast exponentation by squaring
735			/// https://en.wikipedia.org/wiki/Exponentiation_by_squaring
736			pub fn overflowing_pow(self, expon: Self) -> (Self, bool) {
737				if expon.is_zero() { return (Self::one(), false) }
738
739				let is_even = |x : &Self| x.low_u64() & 1 == 0;
740
741				let u_one = Self::one();
742				let mut y = u_one;
743				let mut n = expon;
744				let mut x = self;
745				let mut overflow = false;
746
747				while n > u_one {
748					if is_even(&n) {
749						x = overflowing!(x.overflowing_mul(x), overflow);
750						n = n >> 1;
751					} else {
752						y = overflowing!(x.overflowing_mul(y), overflow);
753						x = overflowing!(x.overflowing_mul(x), overflow);
754						n = (n - u_one) >> 1;
755					}
756				}
757				let res = overflowing!(x.overflowing_mul(y), overflow);
758				(res, overflow)
759			}
760
761			/// Optimized instructions
762			#[inline(always)]
763			pub fn overflowing_add(self, other: $name) -> ($name, bool) {
764				uint_overflowing_add!($name, $n_words, self, other)
765			}
766
767			/// Addition which saturates at the maximum value.
768			pub fn saturating_add(self, other: $name) -> $name {
769				match self.overflowing_add(other) {
770					(_, true) => $name::max_value(),
771					(val, false) => val,
772				}
773			}
774
775			/// Subtraction which underflows and returns a flag if it does.
776			#[inline(always)]
777			pub fn overflowing_sub(self, other: $name) -> ($name, bool) {
778				uint_overflowing_sub!($name, $n_words, self, other)
779			}
780
781			/// Subtraction which saturates at zero.
782			pub fn saturating_sub(self, other: $name) -> $name {
783				match self.overflowing_sub(other) {
784					(_, true) => $name::zero(),
785					(val, false) => val,
786				}
787			}
788
789			/// Multiply with overflow, returning a flag if it does.
790			#[inline(always)]
791			pub fn overflowing_mul(self, other: $name) -> ($name, bool) {
792				uint_overflowing_mul!($name, $n_words, self, other)
793			}
794
795			/// Multiplication which saturates at the maximum value..
796			pub fn saturating_mul(self, other: $name) -> $name {
797				match self.overflowing_mul(other) {
798					(_, true) => $name::max_value(),
799					(val, false) => val,
800				}
801			}
802
803			/// Division with overflow
804			pub fn overflowing_div(self, other: $name) -> ($name, bool) {
805				(self / other, false)
806			}
807
808			/// Modulus with overflow.
809			pub fn overflowing_rem(self, other: $name) -> ($name, bool) {
810				(self % other, false)
811			}
812
813			/// Negation with overflow.
814			pub fn overflowing_neg(self) -> ($name, bool) {
815				(!self, true)
816			}
817		}
818
819		impl $name {
820			/// Multiplication by u32
821			#[allow(dead_code)] // not used when multiplied with inline assembly
822			fn mul_u32(self, other: u32) -> Self {
823				let (ret, overflow) = self.overflowing_mul_u32(other);
824				panic_on_overflow!(overflow);
825				ret
826			}
827
828			/// Overflowing multiplication by u32
829			#[allow(dead_code)] // not used when multiplied with inline assembly
830			fn overflowing_mul_u32(self, other: u32) -> (Self, bool) {
831				let $name(ref arr) = self;
832				let mut ret = [0u64; $n_words];
833				let mut carry = 0;
834				let o = other as u64;
835
836				for i in 0..$n_words {
837					let (res, carry2) = mul_u32(split(arr[i]), o, carry);
838					ret[i] = res;
839					carry = carry2;
840				}
841
842				($name(ret), carry > 0)
843			}
844		}
845
846		impl Default for $name {
847			fn default() -> Self {
848				$name::zero()
849			}
850		}
851
852		impl From<u64> for $name {
853			fn from(value: u64) -> $name {
854				let mut ret = [0; $n_words];
855				ret[0] = value;
856				$name(ret)
857			}
858		}
859
860
861		impl_map_from!($name, u8, u64);
862		impl_map_from!($name, u16, u64);
863		impl_map_from!($name, u32, u64);
864		impl_map_from!($name, usize, u64);
865
866		impl From<i64> for $name {
867			fn from(value: i64) -> $name {
868				match value >= 0 {
869					true => From::from(value as u64),
870					false => { panic!("Unsigned integer can't be created from negative value"); }
871				}
872			}
873		}
874
875		impl_map_from!($name, i8, i64);
876		impl_map_from!($name, i16, i64);
877		impl_map_from!($name, i32, i64);
878		impl_map_from!($name, isize, i64);
879
880		impl<'a> From<&'a [u8]> for $name {
881			fn from(bytes: &[u8]) -> $name {
882				assert!($n_words * 8 >= bytes.len());
883
884				let mut ret = [0; $n_words];
885				for i in 0..bytes.len() {
886					let rev = bytes.len() - 1 - i;
887					let pos = rev / 8;
888					ret[pos] += (bytes[i] as u64) << ((rev % 8) * 8);
889				}
890				$name(ret)
891			}
892		}
893
894        #[cfg(feature = "string")]
895		impl FromStr for $name {
896			type Err = ParseHexError;
897
898			fn from_str(value: &str) -> Result<$name, Self::Err> {
899			    read_hex(value).map(|s| {
900			        let z: &[u8] = s.as_ref();
901			        $name::from(z)
902			    })
903			}
904		}
905
906		impl Add<$name> for $name {
907			type Output = $name;
908
909			fn add(self, other: $name) -> $name {
910				let (result, overflow) = self.overflowing_add(other);
911				panic_on_overflow!(overflow);
912				result
913			}
914		}
915
916		impl Sub<$name> for $name {
917			type Output = $name;
918
919			#[inline]
920			fn sub(self, other: $name) -> $name {
921				let (result, overflow) = self.overflowing_sub(other);
922				panic_on_overflow!(overflow);
923				result
924			}
925		}
926
927		impl Mul<$name> for $name {
928			type Output = $name;
929
930			fn mul(self, other: $name) -> $name {
931				let (result, overflow) = self.overflowing_mul(other);
932				panic_on_overflow!(overflow);
933				result
934			}
935		}
936
937		impl Div<$name> for $name {
938			type Output = $name;
939
940			fn div(self, other: $name) -> $name {
941				let mut sub_copy = self;
942				let mut shift_copy = other;
943				let mut ret = [0u64; $n_words];
944
945				let my_bits = self.bits();
946				let your_bits = other.bits();
947
948				// Check for division by 0
949				assert!(your_bits != 0);
950
951				// Early return in case we are dividing by a larger number than us
952				if my_bits < your_bits {
953					return $name(ret);
954				}
955
956				// Bitwise long division
957				let mut shift = my_bits - your_bits;
958				shift_copy = shift_copy << shift;
959				loop {
960					if sub_copy >= shift_copy {
961						ret[shift / 64] |= 1 << (shift % 64);
962						sub_copy = overflowing!(sub_copy.overflowing_sub(shift_copy));
963					}
964					shift_copy = shift_copy >> 1;
965					if shift == 0 { break; }
966					shift -= 1;
967				}
968
969				$name(ret)
970			}
971		}
972
973		impl Rem<$name> for $name {
974			type Output = $name;
975
976			fn rem(self, other: $name) -> $name {
977				let times = self / other;
978				self - (times * other)
979			}
980		}
981
982		impl BitAnd<$name> for $name {
983			type Output = $name;
984
985			#[inline]
986			fn bitand(self, other: $name) -> $name {
987				let $name(ref arr1) = self;
988				let $name(ref arr2) = other;
989				let mut ret = [0u64; $n_words];
990				for i in 0..$n_words {
991					ret[i] = arr1[i] & arr2[i];
992				}
993				$name(ret)
994			}
995		}
996
997		impl BitXor<$name> for $name {
998			type Output = $name;
999
1000			#[inline]
1001			fn bitxor(self, other: $name) -> $name {
1002				let $name(ref arr1) = self;
1003				let $name(ref arr2) = other;
1004				let mut ret = [0u64; $n_words];
1005				for i in 0..$n_words {
1006					ret[i] = arr1[i] ^ arr2[i];
1007				}
1008				$name(ret)
1009			}
1010		}
1011
1012		impl BitOr<$name> for $name {
1013			type Output = $name;
1014
1015			#[inline]
1016			fn bitor(self, other: $name) -> $name {
1017				let $name(ref arr1) = self;
1018				let $name(ref arr2) = other;
1019				let mut ret = [0u64; $n_words];
1020				for i in 0..$n_words {
1021					ret[i] = arr1[i] | arr2[i];
1022				}
1023				$name(ret)
1024			}
1025		}
1026
1027		impl Not for $name {
1028			type Output = $name;
1029
1030			#[inline]
1031			fn not(self) -> $name {
1032				let $name(ref arr) = self;
1033				let mut ret = [0u64; $n_words];
1034				for i in 0..$n_words {
1035					ret[i] = !arr[i];
1036				}
1037				$name(ret)
1038			}
1039		}
1040
1041		impl Shl<usize> for $name {
1042			type Output = $name;
1043
1044			fn shl(self, shift: usize) -> $name {
1045				let $name(ref original) = self;
1046				let mut ret = [0u64; $n_words];
1047				let word_shift = shift / 64;
1048				let bit_shift = shift % 64;
1049
1050				// shift
1051				for i in word_shift..$n_words {
1052					ret[i] = original[i - word_shift] << bit_shift;
1053				}
1054				// carry
1055				if bit_shift > 0 {
1056					for i in word_shift+1..$n_words {
1057						ret[i] += original[i - 1 - word_shift] >> (64 - bit_shift);
1058					}
1059				}
1060				$name(ret)
1061			}
1062		}
1063
1064		impl Shr<usize> for $name {
1065			type Output = $name;
1066
1067			fn shr(self, shift: usize) -> $name {
1068				let $name(ref original) = self;
1069				let mut ret = [0u64; $n_words];
1070				let word_shift = shift / 64;
1071				let bit_shift = shift % 64;
1072
1073				// shift
1074				for i in word_shift..$n_words {
1075					ret[i - word_shift] = original[i] >> bit_shift;
1076				}
1077
1078				// Carry
1079				if bit_shift > 0 {
1080					for i in word_shift+1..$n_words {
1081						ret[i - word_shift - 1] += original[i] << (64 - bit_shift);
1082					}
1083				}
1084
1085				$name(ret)
1086			}
1087		}
1088
1089		impl Ord for $name {
1090			fn cmp(&self, other: &$name) -> Ordering {
1091				let &$name(ref me) = self;
1092				let &$name(ref you) = other;
1093				let mut i = $n_words;
1094				while i > 0 {
1095					i -= 1;
1096					if me[i] < you[i] { return Ordering::Less; }
1097					if me[i] > you[i] { return Ordering::Greater; }
1098				}
1099				Ordering::Equal
1100			}
1101		}
1102
1103		impl PartialOrd for $name {
1104			fn partial_cmp(&self, other: &$name) -> Option<Ordering> {
1105				Some(self.cmp(other))
1106			}
1107		}
1108
1109		impl fmt::Debug for $name {
1110			fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1111				fmt::Display::fmt(self, f)
1112			}
1113		}
1114
1115		impl fmt::Display for $name {
1116			fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1117				if self.is_zero() {
1118					return write!(f, "0");
1119				}
1120
1121                let mut s = [0u8; $n_words * 20];
1122                let mut i = $n_words * 20;
1123				let mut current = *self;
1124				let ten = $name::from(10);
1125
1126				while !current.is_zero() {
1127                    i = i - 1;
1128                    s[i] = (current % ten).low_u32() as u8;
1129					current = current / ten;
1130				}
1131
1132                for i in i..($n_words * 20) {
1133                    write!(f, "{}", s[i])?;
1134                }
1135
1136                Ok(())
1137			}
1138		}
1139
1140		impl fmt::LowerHex for $name {
1141			fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1142				let &$name(ref data) = self;
1143				let mut latch = false;
1144				for ch in data.iter().rev() {
1145					for x in 0..16 {
1146						let nibble = (ch & (15u64 << ((15 - x) * 4) as u64)) >> (((15 - x) * 4) as u64);
1147						if !latch { latch = nibble != 0 }
1148						if latch {
1149							try!(write!(f, "{:x}", nibble));
1150						}
1151					}
1152				}
1153				Ok(())
1154			}
1155		}
1156
1157		impl fmt::UpperHex for $name {
1158		    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1159		        let &$name(ref data) = self;
1160				let mut latch = false;
1161				for ch in data.iter().rev() {
1162					for x in 0..16 {
1163						let nibble = (ch & (15u64 << ((15 - x) * 4) as u64)) >> (((15 - x) * 4) as u64);
1164						if !latch { latch = nibble != 0 }
1165						if latch {
1166							try!(write!(f, "{:X}", nibble));
1167						}
1168					}
1169				}
1170				Ok(())
1171		    }
1172		}
1173
1174        #[cfg(feature = "string")]
1175		impl From<&'static str> for $name {
1176			fn from(s: &'static str) -> Self {
1177				s.parse().unwrap()
1178			}
1179		}
1180	);
1181}
1182
1183construct_uint!(U512, 8);
1184construct_uint!(U256, 4);
1185construct_uint!(U128, 2);
1186
1187impl U256 {
1188    /// Equals `floor(log2(*))`. This is always an integer.
1189    pub fn log2floor(&self) -> usize {
1190        assert!(*self != U256::zero());
1191        let mut l: usize = 256;
1192        for i in 0..4 {
1193            let i = 3 - i;
1194            if self.0[i] == 0u64 {
1195                l -= 64;
1196            } else {
1197                l -= self.0[i].leading_zeros() as usize;
1198                if l == 0 {
1199                    return l
1200                } else {
1201                    return l - 1;
1202                }
1203            }
1204        }
1205        return l;
1206    }
1207
1208    /// Multiplies two 256-bit integers to produce full 512-bit integer
1209    /// No overflow possible
1210    #[cfg(all(asm_available, target_arch="x86_64"))]
1211    pub fn full_mul(self, other: U256) -> U512 {
1212        let self_t: &[u64; 4] = &self.0;
1213        let other_t: &[u64; 4] = &other.0;
1214        let mut result: [u64; 8] = unsafe { ::std::mem::uninitialized() };
1215        unsafe {
1216            asm!("
1217				mov $8, %rax
1218				mulq $12
1219				mov %rax, $0
1220				mov %rdx, $1
1221
1222				mov $8, %rax
1223				mulq $13
1224				add %rax, $1
1225				adc $$0, %rdx
1226				mov %rdx, $2
1227
1228				mov $8, %rax
1229				mulq $14
1230				add %rax, $2
1231				adc $$0, %rdx
1232				mov %rdx, $3
1233
1234				mov $8, %rax
1235				mulq $15
1236				add %rax, $3
1237				adc $$0, %rdx
1238				mov %rdx, $4
1239
1240				mov $9, %rax
1241				mulq $12
1242				add %rax, $1
1243				adc %rdx, $2
1244				adc $$0, $3
1245				adc $$0, $4
1246				xor $5, $5
1247				adc $$0, $5
1248				xor $6, $6
1249				adc $$0, $6
1250				xor $7, $7
1251				adc $$0, $7
1252
1253				mov $9, %rax
1254				mulq $13
1255				add %rax, $2
1256				adc %rdx, $3
1257				adc $$0, $4
1258				adc $$0, $5
1259				adc $$0, $6
1260				adc $$0, $7
1261
1262				mov $9, %rax
1263				mulq $14
1264				add %rax, $3
1265				adc %rdx, $4
1266				adc $$0, $5
1267				adc $$0, $6
1268				adc $$0, $7
1269
1270				mov $9, %rax
1271				mulq $15
1272				add %rax, $4
1273				adc %rdx, $5
1274				adc $$0, $6
1275				adc $$0, $7
1276
1277				mov $10, %rax
1278				mulq $12
1279				add %rax, $2
1280				adc %rdx, $3
1281				adc $$0, $4
1282				adc $$0, $5
1283				adc $$0, $6
1284				adc $$0, $7
1285
1286				mov $10, %rax
1287				mulq $13
1288				add %rax, $3
1289				adc %rdx, $4
1290				adc $$0, $5
1291				adc $$0, $6
1292				adc $$0, $7
1293
1294				mov $10, %rax
1295				mulq $14
1296				add %rax, $4
1297				adc %rdx, $5
1298				adc $$0, $6
1299				adc $$0, $7
1300
1301				mov $10, %rax
1302				mulq $15
1303				add %rax, $5
1304				adc %rdx, $6
1305				adc $$0, $7
1306
1307				mov $11, %rax
1308				mulq $12
1309				add %rax, $3
1310				adc %rdx, $4
1311				adc $$0, $5
1312				adc $$0, $6
1313				adc $$0, $7
1314
1315				mov $11, %rax
1316				mulq $13
1317				add %rax, $4
1318				adc %rdx, $5
1319				adc $$0, $6
1320				adc $$0, $7
1321
1322				mov $11, %rax
1323				mulq $14
1324				add %rax, $5
1325				adc %rdx, $6
1326				adc $$0, $7
1327
1328				mov $11, %rax
1329				mulq $15
1330				add %rax, $6
1331				adc %rdx, $7
1332				"
1333            : /* $0 */ "={r8}"(result[0]), /* $1 */ "={r9}"(result[1]), /* $2 */ "={r10}"(result[2]),
1334			  /* $3 */ "={r11}"(result[3]), /* $4 */ "={r12}"(result[4]), /* $5 */ "={r13}"(result[5]),
1335			  /* $6 */ "={r14}"(result[6]), /* $7 */ "={r15}"(result[7])
1336
1337            : /* $8 */ "m"(self_t[0]), /* $9 */ "m"(self_t[1]), /* $10 */  "m"(self_t[2]),
1338			  /* $11 */ "m"(self_t[3]), /* $12 */ "m"(other_t[0]), /* $13 */ "m"(other_t[1]),
1339			  /* $14 */ "m"(other_t[2]), /* $15 */ "m"(other_t[3])
1340			: "rax", "rdx"
1341			:
1342			);
1343        }
1344        U512(result)
1345    }
1346
1347    /// Multiplies two 256-bit integers to produce full 512-bit integer
1348    /// No overflow possible
1349    #[cfg(not(all(asm_available, target_arch="x86_64")))]
1350    pub fn full_mul(self, other: U256) -> U512 {
1351        let U256(ref me) = self;
1352        let U256(ref you) = other;
1353        let mut ret = [0u64; 8];
1354
1355        for i in 0..4 {
1356            if you[i] == 0 {
1357                continue;
1358            }
1359
1360            let mut carry2 = 0u64;
1361            let (b_u, b_l) = split(you[i]);
1362
1363            for j in 0..4 {
1364                if me[j] == 0 && carry2 == 0 {
1365                    continue;
1366                }
1367
1368                let a = split(me[j]);
1369
1370                // multiply parts
1371                let (c_l, overflow_l) = mul_u32(a, b_l, ret[i + j]);
1372                let (c_u, overflow_u) = mul_u32(a, b_u, c_l >> 32);
1373                ret[i + j] = (c_l & 0xFFFFFFFF) + (c_u << 32);
1374
1375                // No overflow here
1376                let res = (c_u >> 32) + (overflow_u << 32);
1377                // possible overflows
1378                let (res, o1) = res.overflowing_add(overflow_l);
1379                let (res, o2) = res.overflowing_add(carry2);
1380                let (res, o3) = res.overflowing_add(ret[i + j + 1]);
1381                ret[i + j + 1] = res;
1382
1383                // Only single overflow possible there
1384                carry2 = (o1 | o2 | o3) as u64;
1385            }
1386        }
1387
1388        U512(ret)
1389    }
1390}
1391
1392impl From<U256> for U512 {
1393    fn from(value: U256) -> U512 {
1394        let U256(ref arr) = value;
1395        let mut ret = [0; 8];
1396        ret[0] = arr[0];
1397        ret[1] = arr[1];
1398        ret[2] = arr[2];
1399        ret[3] = arr[3];
1400        U512(ret)
1401    }
1402}
1403
1404impl From<U512> for U256 {
1405    fn from(value: U512) -> U256 {
1406        let U512(ref arr) = value;
1407        if arr[4] | arr[5] | arr[6] | arr[7] != 0 {
1408            panic!("Overflow");
1409        }
1410        let mut ret = [0; 4];
1411        ret[0] = arr[0];
1412        ret[1] = arr[1];
1413        ret[2] = arr[2];
1414        ret[3] = arr[3];
1415        U256(ret)
1416    }
1417}
1418
1419impl<'a> From<&'a U256> for U512 {
1420    fn from(value: &'a U256) -> U512 {
1421        let U256(ref arr) = *value;
1422        let mut ret = [0; 8];
1423        ret[0] = arr[0];
1424        ret[1] = arr[1];
1425        ret[2] = arr[2];
1426        ret[3] = arr[3];
1427        U512(ret)
1428    }
1429}
1430
1431impl<'a> From<&'a U512> for U256 {
1432    fn from(value: &'a U512) -> U256 {
1433        let U512(ref arr) = *value;
1434        if arr[4] | arr[5] | arr[6] | arr[7] != 0 {
1435            panic!("Overflow");
1436        }
1437        let mut ret = [0; 4];
1438        ret[0] = arr[0];
1439        ret[1] = arr[1];
1440        ret[2] = arr[2];
1441        ret[3] = arr[3];
1442        U256(ret)
1443    }
1444}
1445
1446impl From<U256> for U128 {
1447    fn from(value: U256) -> U128 {
1448        let U256(ref arr) = value;
1449        if arr[2] | arr[3] != 0 {
1450            panic!("Overflow");
1451        }
1452        let mut ret = [0; 2];
1453        ret[0] = arr[0];
1454        ret[1] = arr[1];
1455        U128(ret)
1456    }
1457}
1458
1459impl From<U512> for U128 {
1460    fn from(value: U512) -> U128 {
1461        let U512(ref arr) = value;
1462        if arr[2] | arr[3] | arr[4] | arr[5] | arr[6] | arr[7] != 0 {
1463            panic!("Overflow");
1464        }
1465        let mut ret = [0; 2];
1466        ret[0] = arr[0];
1467        ret[1] = arr[1];
1468        U128(ret)
1469    }
1470}
1471
1472impl From<U128> for U512 {
1473    fn from(value: U128) -> U512 {
1474        let U128(ref arr) = value;
1475        let mut ret = [0; 8];
1476        ret[0] = arr[0];
1477        ret[1] = arr[1];
1478        U512(ret)
1479    }
1480}
1481
1482impl From<U128> for U256 {
1483    fn from(value: U128) -> U256 {
1484        let U128(ref arr) = value;
1485        let mut ret = [0; 4];
1486        ret[0] = arr[0];
1487        ret[1] = arr[1];
1488        U256(ret)
1489    }
1490}
1491
1492impl From<U256> for u64 {
1493    fn from(value: U256) -> u64 {
1494        value.as_u64()
1495    }
1496}
1497
1498impl From<U256> for u32 {
1499    fn from(value: U256) -> u32 {
1500        value.as_u32()
1501    }
1502}
1503
1504#[cfg(feature="heapsizeof")]
1505known_heap_size!(0, U128, U256);
1506
1507#[cfg(test)] mod tests;