1#[macro_use]
2pub(crate) mod macros;
3pub(crate) mod traits;
4
5#[macro_export]
6macro_rules! construct_uint {
7 ($(#[$attr:meta])* $visibility:vis struct $name:ident ( $n_words:tt );) => {
8 $crate::concat_idents!(wrapped_mod = wrapped_mod, _, $name {
9 $visibility use wrapped_mod::$name;
10 mod wrapped_mod {
11 use $crate::unroll;
12 use $crate::Uint;
13 #[cfg(feature = "borsh_support")]
14 use $crate::borsh::{BorshSerialize, BorshDeserialize};
15 #[cfg(feature = "scale_support")]
16 use $crate::parity_scale_codec_derive::{Encode, Decode};
17 #[cfg(feature = "scale_support")]
18 use $crate::scale_info::TypeInfo;
19 use $crate::maybestd::{vec, vec::Vec};
20
21 #[repr(C)]
22 $(#[$attr])*
23 #[derive(Copy, Clone, Default, Debug)]
24 #[cfg_attr(feature = "borsh_support", derive(BorshSerialize, BorshDeserialize))]
25 #[cfg_attr(feature = "scale_support", derive(Encode, Decode, TypeInfo))]
26 pub struct $name (pub [u64; $n_words]);
27
28 #[inline]
29 const fn uint_from_u64(v:u64) -> $name {
30 let mut ret = [0;$n_words];
31 ret[0]=v;
32 $name(ret)
33 }
34
35 impl $name {
36 const WORD_BITS:usize = 64;
37 const NUM_WORDS : usize = $n_words;
38
39 const MAX : Self = Self([u64::max_value(); $n_words]);
40 const ZERO : Self = Self([0u64; $n_words]);
41 const ONE : Self = uint_from_u64(1);
42
43 #[inline]
44 pub const fn new(v:[u64; $n_words]) -> Self {
45 Self(v)
46 }
47
48 #[inline]
50 fn fits_word(&self) -> bool {
51 let &$name(ref arr) = self;
52 for i in 1..$n_words { if arr[i] != 0 { return false; } }
53 return true;
54 }
55
56
57 #[inline]
58 fn full_shl(self, shift: u32) -> [u64; $n_words + 1] {
59 debug_assert!(shift < Self::WORD_BITS as u32);
60 let mut u = [064; $n_words + 1];
61 let u_lo = self.0[0] << shift;
62 let u_hi = self.overflowing_shr(Self::WORD_BITS as u32 - shift).0;
63 u[0] = u_lo;
64 u[1..].copy_from_slice(&u_hi.0[..]);
65 u
66 }
67
68 #[inline]
69 fn full_shr(u: [u64; $n_words + 1], shift: u32) -> Self {
70 debug_assert!(shift < Self::WORD_BITS as u32);
71 let mut res = Self::ZERO;
72 for i in 0..$n_words {
73 res.0[i] = u[i] >> shift;
74 }
75 if shift > 0 {
77 for i in 1..=$n_words {
78 res.0[i - 1] |= u[i] << (Self::WORD_BITS as u32 - shift);
79 }
80 }
81 res
82 }
83
84 #[inline]
85 fn full_mul_u64(self, by: u64) -> [u64; $n_words + 1] {
86 let (prod, carry) = self.overflowing_mul_u64(by);
87 let mut res = [0u64; $n_words + 1];
88 res[..$n_words].copy_from_slice(&prod.0[..]);
89 res[$n_words] = carry;
90 res
91 }
92
93 #[inline]
94 fn div_mod_small(mut self, other: u64) -> (Self, Self) {
95 let mut rem = 0u64;
96 self.0.iter_mut().rev().for_each(|d| {
97 let (q, r) = Self::div_mod_word(rem, *d, other);
98 *d = q;
99 rem = r;
100 });
101 (self, Self::from_u64(rem))
102 }
103
104 #[inline]
106 fn div_mod_knuth(self, mut v: Self, n: usize, m: usize) -> (Self, Self) {
107 debug_assert!(self.bits() >= v.bits() && !v.fits_word());
108 debug_assert!(n + m <= $n_words);
109 let shift = v.0[n - 1].leading_zeros();
114 v = v.overflowing_shl(shift).0;
115 let mut u = self.full_shl(shift);
117
118 let mut q = Self::ZERO;
120 let v_n_1 = v.0[n - 1];
121 let v_n_2 = v.0[n - 2];
122
123 for j in (0..=m).rev() {
126 let u_jn = u[j + n];
127
128 let mut q_hat = if u_jn < v_n_1 {
134 let (mut q_hat, mut r_hat) = Self::div_mod_word(u_jn, u[j + n - 1], v_n_1);
135 loop {
137 let (hi, lo) = Self::split_u128(u128::from(q_hat) * u128::from(v_n_2));
139 if (hi, lo) <= (r_hat, u[j + n - 2]) {
140 break;
141 }
142 q_hat -= 1;
144 let (new_r_hat, overflow) = r_hat.overflowing_add(v_n_1);
145 r_hat = new_r_hat;
146 if overflow {
148 break;
149 }
150 }
151 q_hat
152 } else {
153 u64::max_value()
155 };
156
157 let q_hat_v = v.full_mul_u64(q_hat);
165 let c = Self::sub_slice(&mut u[j..], &q_hat_v[..n + 1]);
167
168 if c {
172 q_hat -= 1;
173 let c = Self::add_slice(&mut u[j..], &v.0[..n]);
175 u[j + n] = u[j + n].wrapping_add(u64::from(c));
176 }
177
178 q.0[j] = q_hat;
180 }
181
182 let remainder = Self::full_shr(u, shift);
184
185 (q, remainder)
186 }
187
188 #[inline]
190 fn words(bits: usize) -> usize {
191 debug_assert!(bits > 0);
192 (bits + Self::WORD_BITS - 1) / Self::WORD_BITS
193 }
194
195 #[inline(always)]
196 fn div_mod_word(hi: u64, lo: u64, y: u64) -> (u64, u64) {
197 debug_assert!(hi < y);
198 const TWO32: u64 = 1 << 32;
204 let s = y.leading_zeros();
205 let y = y << s;
206 let (yn1, yn0) = Self::split(y);
207 let un32 = (hi << s) | lo.checked_shr(64 - s).unwrap_or(0);
208 let un10 = lo << s;
209 let (un1, un0) = Self::split(un10);
210 let mut q1 = un32.wrapping_div(yn1);
211 let mut rhat = un32 - q1 * yn1;
212
213 while q1 >= TWO32 || q1 * yn0 > TWO32 * rhat + un1 {
214 q1 -= 1;
215 rhat += yn1;
216 if rhat >= TWO32 {
217 break;
218 }
219 }
220
221 let un21 = un32.wrapping_mul(TWO32).wrapping_add(un1).wrapping_sub(q1.wrapping_mul(y));
222 let mut q0 = un21.wrapping_div(yn1);
223 rhat = un21.wrapping_sub(q0.wrapping_mul(yn1));
224
225 while q0 >= TWO32 || q0 * yn0 > TWO32 * rhat + un0 {
226 q0 -= 1;
227 rhat += yn1;
228 if rhat >= TWO32 {
229 break;
230 }
231 }
232
233 let rem = un21.wrapping_mul(TWO32).wrapping_add(un0).wrapping_sub(y.wrapping_mul(q0));
234 (q1 * TWO32 + q0, rem >> s)
235 }
236
237 #[inline]
238 fn add_slice(a: &mut [u64], b: &[u64]) -> bool {
239 Self::binop_slice(a, b, u64::overflowing_add)
240 }
241
242 #[inline]
243 fn sub_slice(a: &mut [u64], b: &[u64]) -> bool {
244 Self::binop_slice(a, b, u64::overflowing_sub)
245 }
246
247 #[inline]
248 fn binop_slice(a: &mut [u64], b: &[u64], binop: impl Fn(u64, u64) -> (u64, bool) + Copy) -> bool {
249 let mut c = false;
250 a.iter_mut().zip(b.iter()).for_each(|(x, y)| {
251 let (res, carry) = Self::binop_carry(*x, *y, c, binop);
252 *x = res;
253 c = carry;
254 });
255 c
256 }
257
258 #[inline]
259 fn binop_carry(a: u64, b: u64, c: bool, binop: impl Fn(u64, u64) -> (u64, bool)) -> (u64, bool) {
260 let (res1, overflow1) = b.overflowing_add(u64::from(c));
261 let (res2, overflow2) = binop(a, res1);
262 (res2, overflow1 || overflow2)
263 }
264
265 #[inline]
266 const fn mul_u64(a: u64, b: u64, carry: u64) -> (u64, u64) {
267 let (hi, lo) = Self::split_u128(a as u128 * b as u128 + carry as u128);
268 (lo, hi)
269 }
270
271 #[inline]
272 const fn split(a: u64) -> (u64, u64) {
273 (a >> 32, a & 0xFFFF_FFFF)
274 }
275
276 #[inline]
277 const fn split_u128(a: u128) -> (u64, u64) {
278 ((a >> 64) as _, (a & 0xFFFFFFFFFFFFFFFF) as _)
279 }
280
281 }
282
283 $crate::impl_map_from!($name, bool, u64);
284 $crate::impl_map_from!($name, u8, u64);
285 $crate::impl_map_from!($name, u16, u64);
286 $crate::impl_map_from!($name, u32, u64);
287 $crate::impl_map_from!($name, usize, u64);
288 $crate::impl_map_from!($name, i8, i64);
289 $crate::impl_map_from!($name, i16, i64);
290 $crate::impl_map_from!($name, i32, i64);
291 $crate::impl_map_from!($name, isize, i64);
292
293
294 impl core::convert::TryFrom<$name> for bool {
295 type Error = &'static str;
296
297 #[inline]
298 fn try_from(u: $name) -> core::result::Result<bool, &'static str> {
299 let $name(arr) = u;
300 if !u.fits_word() || arr[0] > 2 {
301 Err("integer overflow when casting to bool",)
302 } else {
303 Ok(arr[0] == 1)
304 }
305 }
306 }
307
308 $crate::impl_try_from_for_primitive!($name, u8);
309 $crate::impl_try_from_for_primitive!($name, u16);
310 $crate::impl_try_from_for_primitive!($name, u32);
311 $crate::impl_try_from_for_primitive!($name, usize);
312 $crate::impl_try_from_for_primitive!($name, u64);
313 $crate::impl_try_from_for_primitive!($name, i8);
314 $crate::impl_try_from_for_primitive!($name, i16);
315 $crate::impl_try_from_for_primitive!($name, i32);
316 $crate::impl_try_from_for_primitive!($name, isize);
317 $crate::impl_try_from_for_primitive!($name, i64);
318
319
320
321 $crate::impl_typecast_128!($name, $n_words);
322
323 impl core::cmp::Ord for $name {
324 #[inline]
325 fn cmp(&self, other: &$name) -> core::cmp::Ordering {
326 self.wrapping_cmp(other)
327 }
328 }
329
330 impl core::cmp::PartialOrd for $name {
331 #[inline]
332 fn partial_cmp(&self, other: &$name) -> Option<core::cmp::Ordering> {
333 Some(self.cmp(other))
334 }
335 }
336
337 impl core::cmp::PartialEq for $name {
338 #[inline]
339 fn eq(&self, other: &$name) -> bool {
340 let &$name(ref a) = self;
341 let &$name(ref b) = other;
342 unroll!{
343 for i in 0 .. $n_words {
344 if a[i] != b[i] { return false; }
345 }
346 }
347 true
348 }
349 }
350
351 impl core::cmp::Eq for $name {}
352
353 impl core::hash::Hash for $name {
354 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
355 self.as_inner().as_ref().hash(state);
356 }
357 }
358
359 #[cfg(feature = "rand_support")]
360 impl $crate::rand::distributions::Distribution<$name> for $crate::rand::distributions::Standard {
361 #[inline]
362 fn sample<R: $crate::rand::Rng + ?Sized>(&self, rng: &mut R) -> $name {
363 $name(rng.gen())
364 }
365 }
366
367 impl core::str::FromStr for $name {
368 type Err = &'static str;
369
370 fn from_str(value: &str) -> core::result::Result<$name, Self::Err> {
371 if !value.bytes().all(|b| b >= 48 && b <= 57) {
372 return Err("Invalid character")
373 }
374
375 let mut res = Self::default();
376 for b in value.bytes().map(|b| b - 48) {
377 let (r, overflow) = res.overflowing_mul_u64(10);
378 if overflow > 0 {
379 return Err("Invalid length");
380 }
381 let (r, overflow) = r.overflowing_add(uint_from_u64(b as u64));
382 if overflow {
383 return Err("Invalid length");
384 }
385 res = r;
386 }
387 Ok(res)
388 }
389 }
390
391 impl core::convert::From<&'static str> for $name {
392 fn from(s: &'static str) -> Self {
393 s.parse().unwrap()
394 }
395 }
396
397 impl core::convert::From<u64> for $name {
398 fn from(value: u64) -> $name {
399 let mut ret = [0; $n_words];
400 ret[0] = value;
401 $name(ret)
402 }
403 }
404
405 impl core::convert::From<i64> for $name {
406 fn from(value: i64) -> $name {
407 match value >= 0 {
408 true => From::from(value as u64),
409 false => { panic!("Unsigned integer can't be created from negative value"); }
410 }
411 }
412 }
413
414 impl core::fmt::Display for $name {
415 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
416 if self.is_zero() {
417 return core::write!(f, "0");
418 }
419
420 let mut buf = [0_u8; $n_words * 20];
421 let mut i = buf.len() - 1;
422 let mut current = *self;
423 let ten = $name::from(10);
424
425 loop {
426 let rem = current.div_mod(ten).1;
427 let digit = rem.low_u64() as u8;
428 buf[i] = digit + b'0';
429 current = current.div_mod(ten).0;
430 if current.is_zero() {
431 break;
432 }
433 i -= 1;
434 }
435
436 let s = unsafe {
438 core::str::from_utf8_unchecked(&buf[i..])
439 };
440 f.write_str(s)
441 }
442 }
443
444 impl Uint for $name {
445 type Inner = [u64; $n_words];
446
447 const MAX : Self = Self::MAX;
448 const ZERO : Self = Self::ZERO;
449 const ONE : Self = Self::ONE;
450
451 const NUM_WORDS : usize = Self::NUM_WORDS;
452 const WORD_BITS : usize = Self::WORD_BITS;
453
454 #[cfg(feature = "rand_support")]
455 #[inline]
456 fn random<R: $crate::rand::Rng + ?Sized>(rng: &mut R) -> Self {
457 rng.gen()
458 }
459
460 #[inline]
461 fn into_inner(self) -> Self::Inner {
462 self.0
463 }
464
465 #[inline]
466 fn as_inner(&self) -> &Self::Inner {
467 let &Self(ref res) = self;
468 res
469 }
470
471 #[inline]
472 fn as_inner_mut(&mut self) -> &mut Self::Inner {
473 let &mut Self(ref mut res) = self;
474 res
475 }
476
477 #[inline]
478 fn as_u64(&self) -> u64 {
479 if !self.fits_word() {
480 panic!("Integer overflow when casting to u64")
481 } else {
482 self.low_u64()
483 }
484 }
485
486 #[inline]
487 fn low_u64(&self) -> u64 {
488 self.0[0]
489 }
490
491 #[inline]
492 fn from_u64(v:u64) -> Self {
493 uint_from_u64(v)
494 }
495
496 #[inline]
498 fn is_zero(&self) -> bool {
499 let &Self(ref arr) = self;
500 for i in 0..$n_words { if arr[i] != 0 { return false; } }
501 return true;
502 }
503
504 #[inline]
506 fn leading_zeros(&self) -> u32 {
507 let mut r = 0;
508 for i in 0..$n_words {
509 let w = self.0[$n_words - i - 1];
510 if w == 0 {
511 r += 64;
512 } else {
513 r += w.leading_zeros();
514 break;
515 }
516 }
517 r
518 }
519
520 #[inline]
522 fn trailing_zeros(&self) -> u32 {
523 let mut r = 0;
524 for i in 0..$n_words {
525 let w = self.0[i];
526 if w == 0 {
527 r += 64;
528 } else {
529 r += w.trailing_zeros();
530 break;
531 }
532 }
533 r
534 }
535
536 #[inline]
537 fn bits(&self) -> usize {
538 let &Self(ref arr) = self;
539 for i in 1..$n_words {
540 if arr[$n_words - i] > 0 { return (0x40 * ($n_words - i + 1)) - arr[$n_words - i].leading_zeros() as usize; }
541 }
542 0x40 - arr[0].leading_zeros() as usize
543 }
544
545
546 #[inline]
552 fn div_mod(mut self, mut other: Self) -> (Self, Self) {
553 use core::cmp::Ordering;
554
555 let my_bits = self.bits();
556 let your_bits = other.bits();
557
558 assert!(your_bits != 0, "division by zero");
559
560 if my_bits < your_bits {
562 return (Self::ZERO, self);
563 }
564
565 if your_bits <= Self::WORD_BITS {
566 return self.div_mod_small(other.low_u64());
567 }
568
569 let (n, m) = {
570 let my_words = Self::words(my_bits);
571 let your_words = Self::words(your_bits);
572 (your_words, my_words - your_words)
573 };
574
575 self.div_mod_knuth(other, n, m)
576 }
577
578 #[inline]
579 fn overflowing_add(self, other: Self) -> (Self, bool) {
580 $crate::uint_overflowing_binop!(
581 $name,
582 $n_words,
583 self,
584 other,
585 u64::overflowing_add
586 )
587 }
588
589 #[inline]
590 fn overflowing_sub(self, other: Self) -> (Self, bool) {
591 $crate::uint_overflowing_binop!(
592 $name,
593 $n_words,
594 self,
595 other,
596 u64::overflowing_sub
597 )
598 }
599
600 #[inline]
603 fn overflowing_mul_u64(mut self, other: u64) -> (Self, u64) {
604 let mut carry = 0u64;
605
606 for d in self.0.iter_mut() {
607 let (res, c) = Self::mul_u64(*d, other, carry);
608 *d = res;
609 carry = c;
610 }
611
612 (self, carry)
613 }
614
615 #[inline]
616 fn overflowing_mul(self, other: Self) -> (Self, bool) {
617 $crate::uint_overflowing_mul!($name, $n_words, self, other)
618 }
619
620 #[inline]
621 fn overflowing_neg(self) -> (Self, bool) {
622 (self.overflowing_not().0.wrapping_add(Self::from_u64(1)), !self.is_zero())
623 }
624
625 #[inline]
626 fn overflowing_shl(self, lhs: u32) -> (Self, bool) {
627 let shift = lhs as usize;
628 let $name(ref original) = self;
629 let mut ret = [0u64; $n_words];
630 let word_shift = shift / 64;
631 let bit_shift = shift % 64;
632
633 for i in word_shift..$n_words {
635 ret[i] = original[i - word_shift] << bit_shift;
636 }
637 if bit_shift > 0 {
639 for i in word_shift+1..$n_words {
640 ret[i] += original[i - 1 - word_shift] >> (64 - bit_shift);
641 }
642 }
643 ($name(ret), (lhs > ($n_words*64 - 1)))
644 }
645
646 #[inline]
647 fn overflowing_shr(self, rhs: u32) -> ($name, bool) {
648 let shift = rhs as usize;
649 let $name(ref original) = self;
650 let mut ret = [0u64; $n_words];
651 let word_shift = shift / 64;
652 let bit_shift = shift % 64;
653
654 for i in word_shift..$n_words {
656 ret[i - word_shift] = original[i] >> bit_shift;
657 }
658
659 if bit_shift > 0 {
661 for i in word_shift+1..$n_words {
662 ret[i - word_shift - 1] += original[i] << (64 - bit_shift);
663 }
664 }
665 ($name(ret), (rhs > ($n_words*64 - 1)))
666 }
667
668 #[inline]
669 fn overflowing_not(self) -> (Self, bool) {
670 let mut ret = [0u64; $n_words];
671 $crate::unroll! {
672 for i in 0..$n_words {
673 ret[i]=!self.0[i];
674 }
675 }
676 (Self(ret), false)
677 }
678
679 #[inline]
680 fn overflowing_bitand(self, other:Self) -> (Self, bool) {
681 let mut ret = [0u64; $n_words];
682 $crate::unroll! {
683 for i in 0..$n_words {
684 ret[i]=self.0[i] & other.0[i];
685 }
686 }
687 (Self(ret), false)
688 }
689
690 #[inline]
691 fn overflowing_bitor(self, other:Self) -> (Self, bool) {
692 let mut ret = [0u64; $n_words];
693 $crate::unroll! {
694 for i in 0..$n_words {
695 ret[i]=self.0[i] | other.0[i];
696 }
697 }
698 (Self(ret), false)
699 }
700
701 #[inline]
702 fn overflowing_bitxor(self, other:Self) -> (Self, bool) {
703 let mut ret = [0u64; $n_words];
704 $crate::unroll! {
705 for i in 0..$n_words {
706 ret[i]=self.0[i] ^ other.0[i];
707 }
708 }
709 (Self(ret), false)
710 }
711
712
713
714 #[inline]
716 fn put_big_endian(&self, bytes: &mut [u8]) {
717 use $crate::byteorder::{ByteOrder, BigEndian};
718 debug_assert!($n_words * 8 == bytes.len());
719 for i in 0..$n_words {
720 BigEndian::write_u64(&mut bytes[8 * i..], self.0[$n_words - i - 1]);
721 }
722 }
723
724 #[inline]
726 fn put_little_endian(&self, bytes: &mut [u8]) {
727 use $crate::byteorder::{ByteOrder, LittleEndian};
728 debug_assert!($n_words * 8 == bytes.len());
729 for i in 0..$n_words {
730 LittleEndian::write_u64(&mut bytes[8 * i..], self.0[i]);
731 }
732 }
733
734 #[inline]
735 fn to_big_endian(&self) -> Vec<u8> {
736 let mut res = vec![0u8;$n_words*8];
737 self.put_big_endian(&mut res);
738 res
739 }
740
741 #[inline]
742 fn to_little_endian(&self) -> Vec<u8> {
743 let mut res = vec![0u8;$n_words*8];
744 self.put_little_endian(&mut res);
745 res
746 }
747
748 #[inline]
749 fn from_big_endian(slice: &[u8]) -> Self {
750 use $crate::byteorder::{ByteOrder, BigEndian};
751 assert!($n_words * 8 >= slice.len());
752
753 let mut padded = [0u8; $n_words * 8];
754 padded[$n_words * 8 - slice.len() .. $n_words * 8].copy_from_slice(&slice);
755
756 let mut ret = [0; $n_words];
757 for i in 0..$n_words {
758 ret[$n_words - i - 1] = BigEndian::read_u64(&padded[8 * i..]);
759 }
760
761 $name(ret)
762 }
763
764 #[inline]
765 fn from_little_endian(slice: &[u8]) -> Self {
766 use $crate::byteorder::{ByteOrder, LittleEndian};
767 assert!($n_words * 8 >= slice.len());
768
769 let mut padded = [0u8; $n_words * 8];
770 padded[0..slice.len()].copy_from_slice(&slice);
771
772 let mut ret = [0; $n_words];
773 for i in 0..$n_words {
774 ret[i] = LittleEndian::read_u64(&padded[8 * i..]);
775 }
776
777 $name(ret)
778 }
779
780 #[inline]
781 fn wrapping_cmp(&self, other: &$name) -> core::cmp::Ordering {
782 let &$name(ref a) = self;
783 let &$name(ref b) = other;
784 let mut i = $n_words;
785
786 for i in (0 .. $n_words).rev() {
787 if a[i] < b[i] { return core::cmp::Ordering::Less; }
788 if a[i] > b[i] { return core::cmp::Ordering::Greater; }
789 }
790
791 core::cmp::Ordering::Equal
792 }
793
794
795 }
796 }
797 });
798 };
799}