1macro_rules! construct_uint {
22 ($name:ident, $n_words:expr) => (
23 #[derive(Copy, Clone, PartialEq, Eq, Hash, Default)]
25 pub struct $name(pub [u64; $n_words]);
26 impl_array_newtype!($name, u64, $n_words);
27
28 impl $name {
29 #[inline]
31 pub fn low_u32(&self) -> u32 {
32 let &$name(ref arr) = self;
33 arr[0] as u32
34 }
35
36 #[inline]
38 pub fn low_u64(&self) -> u64 {
39 let &$name(ref arr) = self;
40 arr[0] as u64
41 }
42
43
44 #[inline]
46 pub fn bits(&self) -> usize {
47 let &$name(ref arr) = self;
48 for i in 1..$n_words {
49 if arr[$n_words - i] > 0 { return (0x40 * ($n_words - i + 1)) - arr[$n_words - i].leading_zeros() as usize; }
50 }
51 0x40 - arr[0].leading_zeros() as usize
52 }
53
54 pub fn mul_u32(self, other: u32) -> $name {
56 let $name(ref arr) = self;
57 let mut carry = [0u64; $n_words];
58 let mut ret = [0u64; $n_words];
59 for i in 0..$n_words {
60 let not_last_word = i < $n_words - 1;
61 let upper = other as u64 * (arr[i] >> 32);
62 let lower = other as u64 * (arr[i] & 0xFFFFFFFF);
63 if not_last_word {
64 carry[i + 1] += upper >> 32;
65 }
66 let (sum, overflow) = lower.overflowing_add(upper << 32);
67 ret[i] = sum;
68 if overflow && not_last_word {
69 carry[i + 1] += 1;
70 }
71 }
72 $name(ret) + $name(carry)
73 }
74
75 #[inline]
77 pub fn from_u64(init: u64) -> Option<$name> {
78 let mut ret = [0; $n_words];
79 ret[0] = init;
80 Some($name(ret))
81 }
82
83 #[inline]
85 pub fn from_i64(init: i64) -> Option<$name> {
86 if init >= 0 {
87 $name::from_u64(init as u64)
88 } else {
89 None
90 }
91 }
92
93 pub fn from_be_bytes(bytes: [u8; $n_words * 8]) -> $name {
96 use super::endian::slice_to_u64_be;
97 let mut slice = [0u64; $n_words];
98 slice.iter_mut()
99 .rev()
100 .zip(bytes.chunks(8))
101 .for_each(|(word, bytes)| *word = slice_to_u64_be(bytes));
102 $name(slice)
103 }
104
105 #[inline]
107 fn div_rem(self, other: Self) -> (Self, Self) {
108 let mut sub_copy = self;
109 let mut shift_copy = other;
110 let mut ret = [0u64; $n_words];
111
112 let my_bits = self.bits();
113 let your_bits = other.bits();
114
115 assert!(your_bits != 0);
117
118 if my_bits < your_bits {
120 return ($name(ret), sub_copy);
121 }
122
123 let mut shift = my_bits - your_bits;
125 shift_copy = shift_copy << shift;
126 loop {
127 if sub_copy >= shift_copy {
128 ret[shift / 64] |= 1 << (shift % 64);
129 sub_copy = sub_copy - shift_copy;
130 }
131 shift_copy = shift_copy >> 1;
132 if shift == 0 {
133 break;
134 }
135 shift -= 1;
136 }
137
138 ($name(ret), sub_copy)
139 }
140 }
141
142 impl PartialOrd for $name {
143 #[inline]
144 fn partial_cmp(&self, other: &$name) -> Option<::std::cmp::Ordering> {
145 Some(self.cmp(&other))
146 }
147 }
148
149 impl Ord for $name {
150 #[inline]
151 fn cmp(&self, other: &$name) -> ::std::cmp::Ordering {
152 for i in 0..$n_words {
156 if self[$n_words - 1 - i] < other[$n_words - 1 - i] { return ::std::cmp::Ordering::Less; }
157 if self[$n_words - 1 - i] > other[$n_words - 1 - i] { return ::std::cmp::Ordering::Greater; }
158 }
159 ::std::cmp::Ordering::Equal
160 }
161 }
162
163 impl ::std::ops::Add<$name> for $name {
164 type Output = $name;
165
166 fn add(self, other: $name) -> $name {
167 let $name(ref me) = self;
168 let $name(ref you) = other;
169 let mut ret = [0u64; $n_words];
170 let mut carry = [0u64; $n_words];
171 let mut b_carry = false;
172 for i in 0..$n_words {
173 ret[i] = me[i].wrapping_add(you[i]);
174 if i < $n_words - 1 && ret[i] < me[i] {
175 carry[i + 1] = 1;
176 b_carry = true;
177 }
178 }
179 if b_carry { $name(ret) + $name(carry) } else { $name(ret) }
180 }
181 }
182
183 impl ::std::ops::Sub<$name> for $name {
184 type Output = $name;
185
186 #[inline]
187 fn sub(self, other: $name) -> $name {
188 self + !other + $crate::util::BitArray::one()
189 }
190 }
191
192 impl ::std::ops::Mul<$name> for $name {
193 type Output = $name;
194
195 fn mul(self, other: $name) -> $name {
196 use $crate::util::BitArray;
197 let mut me = $name::zero();
198 for i in 0..(2 * $n_words) {
200 let to_mul = (other >> (32 * i)).low_u32();
201 me = me + (self.mul_u32(to_mul) << (32 * i));
202 }
203 me
204 }
205 }
206
207 impl ::std::ops::Div<$name> for $name {
208 type Output = $name;
209
210 fn div(self, other: $name) -> $name {
211 self.div_rem(other).0
212 }
213 }
214
215 impl ::std::ops::Rem<$name> for $name {
216 type Output = $name;
217
218 fn rem(self, other: $name) -> $name {
219 self.div_rem(other).1
220 }
221 }
222
223 impl $crate::util::BitArray for $name {
224 #[inline]
225 fn bit(&self, index: usize) -> bool {
226 let &$name(ref arr) = self;
227 arr[index / 64] & (1 << (index % 64)) != 0
228 }
229
230 #[inline]
231 fn bit_slice(&self, start: usize, end: usize) -> $name {
232 (*self >> start).mask(end - start)
233 }
234
235 #[inline]
236 fn mask(&self, n: usize) -> $name {
237 let &$name(ref arr) = self;
238 let mut ret = [0; $n_words];
239 for i in 0..$n_words {
240 if n >= 0x40 * (i + 1) {
241 ret[i] = arr[i];
242 } else {
243 ret[i] = arr[i] & ((1 << (n - 0x40 * i)) - 1);
244 break;
245 }
246 }
247 $name(ret)
248 }
249
250 #[inline]
251 fn trailing_zeros(&self) -> usize {
252 let &$name(ref arr) = self;
253 for i in 0..($n_words - 1) {
254 if arr[i] > 0 { return (0x40 * i) + arr[i].trailing_zeros() as usize; }
255 }
256 (0x40 * ($n_words - 1)) + arr[$n_words - 1].trailing_zeros() as usize
257 }
258
259 fn zero() -> $name { Default::default() }
260 fn one() -> $name {
261 $name({ let mut ret = [0; $n_words]; ret[0] = 1; ret })
262 }
263 }
264
265 impl ::std::ops::BitAnd<$name> for $name {
266 type Output = $name;
267
268 #[inline]
269 fn bitand(self, other: $name) -> $name {
270 let $name(ref arr1) = self;
271 let $name(ref arr2) = other;
272 let mut ret = [0u64; $n_words];
273 for i in 0..$n_words {
274 ret[i] = arr1[i] & arr2[i];
275 }
276 $name(ret)
277 }
278 }
279
280 impl ::std::ops::BitXor<$name> for $name {
281 type Output = $name;
282
283 #[inline]
284 fn bitxor(self, other: $name) -> $name {
285 let $name(ref arr1) = self;
286 let $name(ref arr2) = other;
287 let mut ret = [0u64; $n_words];
288 for i in 0..$n_words {
289 ret[i] = arr1[i] ^ arr2[i];
290 }
291 $name(ret)
292 }
293 }
294
295 impl ::std::ops::BitOr<$name> for $name {
296 type Output = $name;
297
298 #[inline]
299 fn bitor(self, other: $name) -> $name {
300 let $name(ref arr1) = self;
301 let $name(ref arr2) = other;
302 let mut ret = [0u64; $n_words];
303 for i in 0..$n_words {
304 ret[i] = arr1[i] | arr2[i];
305 }
306 $name(ret)
307 }
308 }
309
310 impl ::std::ops::Not for $name {
311 type Output = $name;
312
313 #[inline]
314 fn not(self) -> $name {
315 let $name(ref arr) = self;
316 let mut ret = [0u64; $n_words];
317 for i in 0..$n_words {
318 ret[i] = !arr[i];
319 }
320 $name(ret)
321 }
322 }
323
324 impl ::std::ops::Shl<usize> for $name {
325 type Output = $name;
326
327 fn shl(self, shift: usize) -> $name {
328 let $name(ref original) = self;
329 let mut ret = [0u64; $n_words];
330 let word_shift = shift / 64;
331 let bit_shift = shift % 64;
332 for i in 0..$n_words {
333 if bit_shift < 64 && i + word_shift < $n_words {
335 ret[i + word_shift] += original[i] << bit_shift;
336 }
337 if bit_shift > 0 && i + word_shift + 1 < $n_words {
339 ret[i + word_shift + 1] += original[i] >> (64 - bit_shift);
340 }
341 }
342 $name(ret)
343 }
344 }
345
346 impl ::std::ops::Shr<usize> for $name {
347 type Output = $name;
348
349 fn shr(self, shift: usize) -> $name {
350 let $name(ref original) = self;
351 let mut ret = [0u64; $n_words];
352 let word_shift = shift / 64;
353 let bit_shift = shift % 64;
354 for i in word_shift..$n_words {
355 ret[i - word_shift] += original[i] >> bit_shift;
357 if bit_shift > 0 && i < $n_words - 1 {
359 ret[i - word_shift] += original[i + 1] << (64 - bit_shift);
360 }
361 }
362 $name(ret)
363 }
364 }
365
366 impl ::std::fmt::Debug for $name {
367 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
368 let &$name(ref data) = self;
369 write!(f, "0x")?;
370 for ch in data.iter().rev() {
371 write!(f, "{:016x}", ch)?;
372 }
373 Ok(())
374 }
375 }
376
377 display_from_debug!($name);
378
379 impl $crate::consensus::Encodable for $name {
380 #[inline]
381 fn consensus_encode<S: ::std::io::Write>(
382 &self,
383 mut s: S,
384 ) -> Result<usize, ::std::io::Error> {
385 let &$name(ref data) = self;
386 let mut len = 0;
387 for word in data.iter() {
388 len += word.consensus_encode(&mut s)?;
389 }
390 Ok(len)
391 }
392 }
393
394 impl $crate::consensus::Decodable for $name {
395 fn consensus_decode<D: ::std::io::Read>(
396 mut d: D,
397 ) -> Result<$name, $crate::consensus::encode::Error> {
398 use $crate::consensus::Decodable;
399 let mut ret: [u64; $n_words] = [0; $n_words];
400 for i in 0..$n_words {
401 ret[i] = Decodable::consensus_decode(&mut d)?;
402 }
403 Ok($name(ret))
404 }
405 }
406 );
407}
408
409construct_uint!(Uint256, 4);
410construct_uint!(Uint128, 2);
411
412impl Uint256 {
413 #[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 #[inline]
431 pub fn low_128(&self) -> Uint128 {
432 let &Uint256(data) = self;
433 Uint128([data[0], data[1]])
434 }
435}
436
437#[cfg(test)]
438mod tests {
439 use consensus::{deserialize, serialize};
440 use util::uint::{Uint256, Uint128};
441 use util::BitArray;
442
443 #[test]
444 pub fn uint256_bits_test() {
445 assert_eq!(Uint256::from_u64(255).unwrap().bits(), 8);
446 assert_eq!(Uint256::from_u64(256).unwrap().bits(), 9);
447 assert_eq!(Uint256::from_u64(300).unwrap().bits(), 9);
448 assert_eq!(Uint256::from_u64(60000).unwrap().bits(), 16);
449 assert_eq!(Uint256::from_u64(70000).unwrap().bits(), 17);
450
451 let mut shl = Uint256::from_u64(70000).unwrap();
453 shl = shl << 100;
454 assert_eq!(shl.bits(), 117);
455 shl = shl << 100;
456 assert_eq!(shl.bits(), 217);
457 shl = shl << 100;
458 assert_eq!(shl.bits(), 0);
459
460 assert!(!Uint256::from_u64(10).unwrap().bit(0));
462 assert!(Uint256::from_u64(10).unwrap().bit(1));
463 assert!(!Uint256::from_u64(10).unwrap().bit(2));
464 assert!(Uint256::from_u64(10).unwrap().bit(3));
465 assert!(!Uint256::from_u64(10).unwrap().bit(4));
466 }
467
468 #[test]
469 pub fn uint256_display_test() {
470 assert_eq!(format!("{}", Uint256::from_u64(0xDEADBEEF).unwrap()),
471 "0x00000000000000000000000000000000000000000000000000000000deadbeef");
472 assert_eq!(format!("{}", Uint256::from_u64(u64::max_value()).unwrap()),
473 "0x000000000000000000000000000000000000000000000000ffffffffffffffff");
474
475 let max_val = Uint256([0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
476 0xFFFFFFFFFFFFFFFF]);
477 assert_eq!(format!("{}", max_val),
478 "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
479 }
480
481 #[test]
482 pub fn uint256_comp_test() {
483 let small = Uint256([10u64, 0, 0, 0]);
484 let big = Uint256([0x8C8C3EE70C644118u64, 0x0209E7378231E632, 0, 0]);
485 let bigger = Uint256([0x9C8C3EE70C644118u64, 0x0209E7378231E632, 0, 0]);
486 let biggest = Uint256([0x5C8C3EE70C644118u64, 0x0209E7378231E632, 0, 1]);
487
488 assert!(small < big);
489 assert!(big < bigger);
490 assert!(bigger < biggest);
491 assert!(bigger <= biggest);
492 assert!(biggest <= biggest);
493 assert!(bigger >= big);
494 assert!(bigger >= small);
495 assert!(small <= small);
496 }
497
498 #[test]
499 pub fn uint_from_be_bytes() {
500 assert_eq!(Uint128::from_be_bytes([0x1b, 0xad, 0xca, 0xfe, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xaf, 0xba, 0xbe, 0x2b, 0xed, 0xfe, 0xed]),
501 Uint128([0xdeafbabe2bedfeed, 0x1badcafedeadbeef]));
502
503 assert_eq!(Uint256::from_be_bytes([0x1b, 0xad, 0xca, 0xfe, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xaf, 0xba, 0xbe, 0x2b, 0xed, 0xfe, 0xed,
504 0xba, 0xad, 0xf0, 0x0d, 0xde, 0xfa, 0xce, 0xda, 0x11, 0xfe, 0xd2, 0xba, 0xd1, 0xc0, 0xff, 0xe0]),
505 Uint256([0x11fed2bad1c0ffe0, 0xbaadf00ddefaceda, 0xdeafbabe2bedfeed, 0x1badcafedeadbeef]));
506 }
507
508 #[test]
509 pub fn uint256_arithmetic_test() {
510 let init = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
511 let copy = init;
512
513 let add = init + copy;
514 assert_eq!(add, Uint256([0xBD5B7DDFBD5B7DDEu64, 1, 0, 0]));
515 let shl = add << 88;
517 assert_eq!(shl, Uint256([0u64, 0xDFBD5B7DDE000000, 0x1BD5B7D, 0]));
518 let shr = shl >> 40;
519 assert_eq!(shr, Uint256([0x7DDE000000000000u64, 0x0001BD5B7DDFBD5B, 0, 0]));
520 let mut incr = shr;
522 incr.increment();
523 assert_eq!(incr, Uint256([0x7DDE000000000001u64, 0x0001BD5B7DDFBD5B, 0, 0]));
524 let sub = incr - init;
526 assert_eq!(sub, Uint256([0x9F30411021524112u64, 0x0001BD5B7DDFBD5A, 0, 0]));
527 let mult = sub.mul_u32(300);
529 assert_eq!(mult, Uint256([0x8C8C3EE70C644118u64, 0x0209E7378231E632, 0, 0]));
530 assert_eq!(Uint256::from_u64(105).unwrap() /
532 Uint256::from_u64(5).unwrap(),
533 Uint256::from_u64(21).unwrap());
534 let div = mult / Uint256::from_u64(300).unwrap();
535 assert_eq!(div, Uint256([0x9F30411021524112u64, 0x0001BD5B7DDFBD5A, 0, 0]));
536
537 assert_eq!(Uint256::from_u64(105).unwrap() % Uint256::from_u64(5).unwrap(),
538 Uint256::from_u64(0).unwrap());
539 assert_eq!(Uint256::from_u64(35498456).unwrap() % Uint256::from_u64(3435).unwrap(),
540 Uint256::from_u64(1166).unwrap());
541 let rem_src = mult * Uint256::from_u64(39842).unwrap() + Uint256::from_u64(9054).unwrap();
542 assert_eq!(rem_src % Uint256::from_u64(39842).unwrap(),
543 Uint256::from_u64(9054).unwrap());
544 }
546
547 #[test]
548 pub fn mul_u32_test() {
549 let u64_val = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
550
551 let u96_res = u64_val.mul_u32(0xFFFFFFFF);
552 let u128_res = u96_res.mul_u32(0xFFFFFFFF);
553 let u160_res = u128_res.mul_u32(0xFFFFFFFF);
554 let u192_res = u160_res.mul_u32(0xFFFFFFFF);
555 let u224_res = u192_res.mul_u32(0xFFFFFFFF);
556 let u256_res = u224_res.mul_u32(0xFFFFFFFF);
557
558 assert_eq!(u96_res, Uint256([0xffffffff21524111u64, 0xDEADBEEE, 0, 0]));
559 assert_eq!(u128_res, Uint256([0x21524111DEADBEEFu64, 0xDEADBEEE21524110, 0, 0]));
560 assert_eq!(u160_res, Uint256([0xBD5B7DDD21524111u64, 0x42A4822200000001, 0xDEADBEED, 0]));
561 assert_eq!(u192_res, Uint256([0x63F6C333DEADBEEFu64, 0xBD5B7DDFBD5B7DDB, 0xDEADBEEC63F6C334, 0]));
562 assert_eq!(u224_res, Uint256([0x7AB6FBBB21524111u64, 0xFFFFFFFBA69B4558, 0x854904485964BAAA, 0xDEADBEEB]));
563 assert_eq!(u256_res, Uint256([0xA69B4555DEADBEEFu64, 0xA69B455CD41BB662, 0xD41BB662A69B4550, 0xDEADBEEAA69B455C]));
564 }
565
566 #[test]
567 pub fn multiplication_test() {
568 let u64_val = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
569
570 let u128_res = u64_val * u64_val;
571
572 assert_eq!(u128_res, Uint256([0x048D1354216DA321u64, 0xC1B1CD13A4D13D46, 0, 0]));
573
574 let u256_res = u128_res * u128_res;
575
576 assert_eq!(u256_res, Uint256([0xF4E166AAD40D0A41u64, 0xF5CF7F3618C2C886u64,
577 0x4AFCFF6F0375C608u64, 0x928D92B4D7F5DF33u64]));
578 }
579
580 #[test]
581 pub fn uint256_bitslice_test() {
582 let init = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
583 let add = init + (init << 64);
584 assert_eq!(add.bit_slice(64, 128), init);
585 assert_eq!(add.mask(64), init);
586 }
587
588 #[test]
589 pub fn uint256_extreme_bitshift_test() {
590 let init = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
593
594 assert_eq!(init << 64, Uint256([0, 0xDEADBEEFDEADBEEF, 0, 0]));
595 let add = (init << 64) + init;
596 assert_eq!(add, Uint256([0xDEADBEEFDEADBEEF, 0xDEADBEEFDEADBEEF, 0, 0]));
597 assert_eq!(add >> 0, Uint256([0xDEADBEEFDEADBEEF, 0xDEADBEEFDEADBEEF, 0, 0]));
598 assert_eq!(add << 0, Uint256([0xDEADBEEFDEADBEEF, 0xDEADBEEFDEADBEEF, 0, 0]));
599 assert_eq!(add >> 64, Uint256([0xDEADBEEFDEADBEEF, 0, 0, 0]));
600 assert_eq!(add << 64, Uint256([0, 0xDEADBEEFDEADBEEF, 0xDEADBEEFDEADBEEF, 0]));
601 }
602
603 #[test]
604 pub fn uint256_serialize_test() {
605 let start1 = Uint256([0x8C8C3EE70C644118u64, 0x0209E7378231E632, 0, 0]);
606 let start2 = Uint256([0x8C8C3EE70C644118u64, 0x0209E7378231E632, 0xABCD, 0xFFFF]);
607 let serial1 = serialize(&start1);
608 let serial2 = serialize(&start2);
609 let end1: Result<Uint256, _> = deserialize(&serial1);
610 let end2: Result<Uint256, _> = deserialize(&serial2);
611
612 assert_eq!(end1.ok(), Some(start1));
613 assert_eq!(end2.ok(), Some(start2));
614 }
615}