1#[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#[derive(Debug, PartialEq)]
54pub enum FromDecStrErr {
55 InvalidCharacter,
57 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) : "{rdi}"(&result[4] as *const u64) "{rsi}"(&other_t[4] as *const u64) "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 "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]) : "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) : "{rdi}"(&result[4] as *const u64) "{rsi}"(&self_t[4] as *const u64) "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 "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]) : "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 : "={r8}"(result[0]), "={r9}"(result[1]), "={r10}"(result[2]),
379 "={r11}"(result[3]), "={rcx}"(overflow)
380
381 : "m"(self_t[0]), "m"(self_t[1]), "m"(self_t[2]),
382 "m"(self_t[3]), "m"(other_t[0]), "m"(other_t[1]),
383 "m"(other_t[2]), "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 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 let res = (c_u >> 32) + (overflow_u << 32);
431 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 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 #[repr(C)]
501 #[derive(Copy, Clone, Eq, PartialEq, Hash)]
502 pub struct $name(pub [u64; $n_words]);
503
504 impl $name {
505 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 #[inline]
528 pub fn low_u32(&self) -> u32 {
529 let &$name(ref arr) = self;
530 arr[0] as u32
531 }
532
533 #[inline]
535 pub fn low_u64(&self) -> u64 {
536 let &$name(ref arr) = self;
537 arr[0]
538 }
539
540 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline]
639 pub fn index(&self, index: usize) -> u8 {
640 let index = $n_words * 8 - 1 - index;
641 self.byte(index)
642 }
643
644 #[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 #[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 #[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 #[inline]
677 pub fn zero() -> Self {
678 From::from(0u64)
679 }
680
681 #[inline]
683 pub fn one() -> Self {
684 From::from(1u64)
685 }
686
687 #[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 #[inline]
699 pub fn min_value() -> Self {
700 $name([0; $n_words])
701 }
702
703 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 n.0[$n_words-1] = n.0[$n_words-1] & ((!0u64)>>1);
728 n = n >> 1;
729 }
730 }
731 x * y
732 }
733
734 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 #[inline(always)]
763 pub fn overflowing_add(self, other: $name) -> ($name, bool) {
764 uint_overflowing_add!($name, $n_words, self, other)
765 }
766
767 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 #[inline(always)]
777 pub fn overflowing_sub(self, other: $name) -> ($name, bool) {
778 uint_overflowing_sub!($name, $n_words, self, other)
779 }
780
781 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 #[inline(always)]
791 pub fn overflowing_mul(self, other: $name) -> ($name, bool) {
792 uint_overflowing_mul!($name, $n_words, self, other)
793 }
794
795 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 pub fn overflowing_div(self, other: $name) -> ($name, bool) {
805 (self / other, false)
806 }
807
808 pub fn overflowing_rem(self, other: $name) -> ($name, bool) {
810 (self % other, false)
811 }
812
813 pub fn overflowing_neg(self) -> ($name, bool) {
815 (!self, true)
816 }
817 }
818
819 impl $name {
820 #[allow(dead_code)] 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 #[allow(dead_code)] 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 assert!(your_bits != 0);
950
951 if my_bits < your_bits {
953 return $name(ret);
954 }
955
956 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 for i in word_shift..$n_words {
1052 ret[i] = original[i - word_shift] << bit_shift;
1053 }
1054 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 for i in word_shift..$n_words {
1075 ret[i - word_shift] = original[i] >> bit_shift;
1076 }
1077
1078 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 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 #[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 : "={r8}"(result[0]), "={r9}"(result[1]), "={r10}"(result[2]),
1334 "={r11}"(result[3]), "={r12}"(result[4]), "={r13}"(result[5]),
1335 "={r14}"(result[6]), "={r15}"(result[7])
1336
1337 : "m"(self_t[0]), "m"(self_t[1]), "m"(self_t[2]),
1338 "m"(self_t[3]), "m"(other_t[0]), "m"(other_t[1]),
1339 "m"(other_t[2]), "m"(other_t[3])
1340 : "rax", "rdx"
1341 :
1342 );
1343 }
1344 U512(result)
1345 }
1346
1347 #[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 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 let res = (c_u >> 32) + (overflow_u << 32);
1377 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 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;