1use core::cmp::Ordering;
2use rand::Rng;
3
4use byteorder::{BigEndian, ByteOrder};
5#[cfg(feature = "rustc-serialize")]
6use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
7
8#[derive(Copy, Clone, Debug, PartialEq, Eq)]
11#[repr(C)]
12pub struct U256(pub [u128; 2]);
13
14impl From<[u64; 4]> for U256 {
15 fn from(d: [u64; 4]) -> Self {
16 let mut a = [0u128; 2];
17 a[0] = (d[1] as u128) << 64 | d[0] as u128;
18 a[1] = (d[3] as u128) << 64 | d[2] as u128;
19 U256(a)
20 }
21}
22
23impl From<u64> for U256 {
24 fn from(d: u64) -> Self {
25 U256::from([d, 0, 0, 0])
26 }
27}
28
29#[derive(Copy, Clone, Debug, PartialEq, Eq)]
32#[repr(C)]
33pub struct U512(pub [u128; 4]);
34
35impl From<[u64; 8]> for U512 {
36 fn from(d: [u64; 8]) -> Self {
37 let mut a = [0u128; 4];
38 a[0] = (d[1] as u128) << 64 | d[0] as u128;
39 a[1] = (d[3] as u128) << 64 | d[2] as u128;
40 a[2] = (d[5] as u128) << 64 | d[4] as u128;
41 a[3] = (d[7] as u128) << 64 | d[6] as u128;
42 U512(a)
43 }
44}
45
46impl U512 {
47 pub fn new(c1: &U256, c0: &U256, modulo: &U256) -> U512 {
49 let mut res = [0; 4];
50
51 debug_assert_eq!(c1.0.len(), 2);
52 unroll! {
53 for i in 0..2 {
54 mac_digit(i, &mut res, &modulo.0, c1.0[i]);
55 }
56 }
57
58 let mut carry = 0;
59
60 debug_assert_eq!(res.len(), 4);
61 unroll! {
62 for i in 0..2 {
63 res[i] = adc(res[i], c0.0[i], &mut carry);
64 }
65 }
66
67 unroll! {
68 for i in 0..2 {
69 let (a1, a0) = split_u128(res[i + 2]);
70 let (c, r0) = split_u128(a0 + carry);
71 let (c, r1) = split_u128(a1 + c);
72 carry = c;
73
74 res[i + 2] = combine_u128(r1, r0);
75 }
76 }
77
78 debug_assert!(0 == carry);
79
80 U512(res)
81 }
82
83 pub fn from_slice(s: &[u8]) -> Result<U512, Error> {
84 if s.len() != 64 {
85 return Err(Error::InvalidLength {
86 expected: 32,
87 actual: s.len(),
88 });
89 }
90
91 let mut n = [0; 4];
92 for (l, i) in (0..4).rev().zip((0..4).map(|i| i * 16)) {
93 n[l] = BigEndian::read_u128(&s[i..]);
94 }
95
96 Ok(U512(n))
97 }
98
99 pub fn random<R: Rng>(rng: &mut R) -> U512 {
101 U512(rng.random())
102 }
103
104 pub fn get_bit(&self, n: usize) -> Option<bool> {
105 if n >= 512 {
106 None
107 } else {
108 let part = n / 128;
109 let bit = n - (128 * part);
110
111 Some(self.0[part] & (1 << bit) > 0)
112 }
113 }
114
115 pub fn divrem(&self, modulo: &U256) -> (Option<U256>, U256) {
118 let mut q = Some(U256::zero());
119 let mut r = U256::zero();
120
121 for i in (0..512).rev() {
122 mul2(&mut r.0);
125 assert!(r.set_bit(0, self.get_bit(i).unwrap()));
126 if &r >= modulo {
127 sub_noborrow(&mut r.0, &modulo.0);
128 if q.is_some() && !q.as_mut().unwrap().set_bit(i, true) {
129 q = None
130 }
131 }
132 }
133
134 if q.is_some() && (q.as_ref().unwrap() >= modulo) {
135 (None, r)
136 } else {
137 (q, r)
138 }
139 }
140
141 pub fn interpret(buf: &[u8; 64]) -> U512 {
142 let mut n = [0; 4];
143 for (l, i) in (0..4).rev().zip((0..4).map(|i| i * 16)) {
144 n[l] = BigEndian::read_u128(&buf[i..]);
145 }
146
147 U512(n)
148 }
149}
150
151#[cfg(feature = "rustc-serialize")]
152impl Encodable for U512 {
153 fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
154 let mut buf = [0; (4 * 16)];
155
156 for (l, i) in (0..4).rev().zip((0..4).map(|i| i * 16)) {
157 BigEndian::write_u128(&mut buf[i..], self.0[l]);
158 }
159
160 for i in 0..(4 * 16) {
161 s.emit_u8(buf[i])?;
162 }
163
164 Ok(())
165 }
166}
167
168#[cfg(feature = "rustc-serialize")]
169impl Decodable for U512 {
170 fn decode<S: Decoder>(s: &mut S) -> Result<U512, S::Error> {
171 let mut buf = [0; (4 * 16)];
172
173 for i in 0..(4 * 16) {
174 buf[i] = s.read_u8()?;
175 }
176
177 Ok(U512::interpret(&buf))
178 }
179}
180
181#[cfg(feature = "rustc-serialize")]
182impl Encodable for U256 {
183 fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
184 let mut buf = [0; (2 * 16)];
185
186 for (l, i) in (0..2).rev().zip((0..2).map(|i| i * 16)) {
187 BigEndian::write_u128(&mut buf[i..], self.0[l]);
188 }
189
190 for i in 0..(2 * 16) {
191 s.emit_u8(buf[i])?;
192 }
193
194 Ok(())
195 }
196}
197
198#[cfg(feature = "rustc-serialize")]
199impl Decodable for U256 {
200 fn decode<S: Decoder>(s: &mut S) -> Result<U256, S::Error> {
201 let mut buf = [0; (2 * 16)];
202
203 for i in 0..(2 * 16) {
204 buf[i] = s.read_u8()?;
205 }
206
207 U256::from_slice(&buf).map_err(|_| s.error("Invalid input length; Also unreachable;"))
208 }
209}
210
211impl Ord for U512 {
212 #[inline]
213 fn cmp(&self, other: &U512) -> Ordering {
214 for (a, b) in self.0.iter().zip(other.0.iter()).rev() {
215 if *a < *b {
216 return Ordering::Less;
217 } else if *a > *b {
218 return Ordering::Greater;
219 }
220 }
221
222 Ordering::Equal
223 }
224}
225
226impl PartialOrd for U512 {
227 #[inline]
228 fn partial_cmp(&self, other: &U512) -> Option<Ordering> {
229 Some(self.cmp(other))
230 }
231}
232
233impl Ord for U256 {
234 #[inline]
235 fn cmp(&self, other: &U256) -> Ordering {
236 for (a, b) in self.0.iter().zip(other.0.iter()).rev() {
237 if *a < *b {
238 return Ordering::Less;
239 } else if *a > *b {
240 return Ordering::Greater;
241 }
242 }
243
244 Ordering::Equal
245 }
246}
247
248impl PartialOrd for U256 {
249 #[inline]
250 fn partial_cmp(&self, other: &U256) -> Option<Ordering> {
251 Some(self.cmp(other))
252 }
253}
254
255#[derive(Debug)]
257pub enum Error {
258 InvalidLength { expected: usize, actual: usize },
259}
260
261impl U256 {
262 pub fn from_slice(s: &[u8]) -> Result<U256, Error> {
264 if s.len() != 32 {
265 return Err(Error::InvalidLength {
266 expected: 32,
267 actual: s.len(),
268 });
269 }
270
271 let mut n = [0; 2];
272 for (l, i) in (0..2).rev().zip((0..2).map(|i| i * 16)) {
273 n[l] = BigEndian::read_u128(&s[i..]);
274 }
275
276 Ok(U256(n))
277 }
278
279 pub fn to_big_endian(&self, s: &mut [u8]) -> Result<(), Error> {
280 if s.len() != 32 {
281 return Err(Error::InvalidLength {
282 expected: 32,
283 actual: s.len(),
284 });
285 }
286
287 for (l, i) in (0..2).rev().zip((0..2).map(|i| i * 16)) {
288 BigEndian::write_u128(&mut s[i..], self.0[l]);
289 }
290
291 Ok(())
292 }
293
294 #[inline]
295 pub fn zero() -> U256 {
296 U256([0, 0])
297 }
298
299 #[inline]
300 pub fn one() -> U256 {
301 U256([1, 0])
302 }
303
304 pub fn random<R: Rng>(rng: &mut R, modulo: &U256) -> U256 {
306 U512::random(rng).divrem(modulo).1
307 }
308
309 pub fn is_zero(&self) -> bool {
310 self.0[0] == 0 && self.0[1] == 0
311 }
312
313 pub fn set_bit(&mut self, n: usize, to: bool) -> bool {
314 if n >= 256 {
315 false
316 } else {
317 let part = n / 128;
318 let bit = n - (128 * part);
319
320 if to {
321 self.0[part] |= 1 << bit;
322 } else {
323 self.0[part] &= !(1 << bit);
324 }
325
326 true
327 }
328 }
329
330 pub fn get_bit(&self, n: usize) -> Option<bool> {
331 if n >= 256 {
332 None
333 } else {
334 let part = n / 128;
335 let bit = n - (128 * part);
336
337 Some(self.0[part] & (1 << bit) > 0)
338 }
339 }
340
341 pub fn add(&mut self, other: &U256, modulo: &U256) {
343 add_nocarry(&mut self.0, &other.0);
344
345 if *self >= *modulo {
346 sub_noborrow(&mut self.0, &modulo.0);
347 }
348 }
349
350 pub fn sub(&mut self, other: &U256, modulo: &U256) {
352 if *self < *other {
353 add_nocarry(&mut self.0, &modulo.0);
354 }
355
356 sub_noborrow(&mut self.0, &other.0);
357 }
358
359 pub fn mul(&mut self, other: &U256, modulo: &U256, inv: u128) {
362 mul_reduce(&mut self.0, &other.0, &modulo.0, inv);
363
364 if *self >= *modulo {
365 sub_noborrow(&mut self.0, &modulo.0);
366 }
367 }
368
369 pub fn neg(&mut self, modulo: &U256) {
371 if *self > Self::zero() {
372 let mut tmp = modulo.0;
373 sub_noborrow(&mut tmp, &self.0);
374
375 self.0 = tmp;
376 }
377 }
378
379 #[inline]
380 pub fn is_even(&self) -> bool {
381 self.0[0] & 1 == 0
382 }
383
384 pub fn invert(&mut self, modulo: &U256) {
386 let mut u = *self;
391 let mut v = *modulo;
392 let mut b = U256::one();
393 let mut c = U256::zero();
394
395 while u != U256::one() && v != U256::one() {
396 while u.is_even() {
397 div2(&mut u.0);
398
399 if b.is_even() {
400 div2(&mut b.0);
401 } else {
402 add_nocarry(&mut b.0, &modulo.0);
403 div2(&mut b.0);
404 }
405 }
406 while v.is_even() {
407 div2(&mut v.0);
408
409 if c.is_even() {
410 div2(&mut c.0);
411 } else {
412 add_nocarry(&mut c.0, &modulo.0);
413 div2(&mut c.0);
414 }
415 }
416
417 if u >= v {
418 sub_noborrow(&mut u.0, &v.0);
419 b.sub(&c, modulo);
420 } else {
421 sub_noborrow(&mut v.0, &u.0);
422 c.sub(&b, modulo);
423 }
424 }
425
426 if u == U256::one() {
427 self.0 = b.0;
428 } else {
429 self.0 = c.0;
430 }
431 }
432
433 pub fn bits(&self) -> BitIterator {
436 BitIterator { int: self, n: 256 }
437 }
438}
439
440pub struct BitIterator<'a> {
441 int: &'a U256,
442 n: usize,
443}
444
445impl<'a> Iterator for BitIterator<'a> {
446 type Item = bool;
447
448 fn next(&mut self) -> Option<bool> {
449 if self.n == 0 {
450 None
451 } else {
452 self.n -= 1;
453
454 self.int.get_bit(self.n)
455 }
456 }
457}
458
459#[inline]
461fn div2(a: &mut [u128; 2]) {
462 let tmp = a[1] << 127;
463 a[1] >>= 1;
464 a[0] >>= 1;
465 a[0] |= tmp;
466}
467
468#[inline]
470fn mul2(a: &mut [u128; 2]) {
471 let tmp = a[0] >> 127;
472 a[0] <<= 1;
473 a[1] <<= 1;
474 a[1] |= tmp;
475}
476
477#[inline(always)]
478fn split_u128(i: u128) -> (u128, u128) {
479 (i >> 64, i & 0xFFFFFFFFFFFFFFFF)
480}
481
482#[inline(always)]
483fn combine_u128(hi: u128, lo: u128) -> u128 {
484 (hi << 64) | lo
485}
486
487#[inline]
488fn adc(a: u128, b: u128, carry: &mut u128) -> u128 {
489 let (a1, a0) = split_u128(a);
490 let (b1, b0) = split_u128(b);
491 let (c, r0) = split_u128(a0 + b0 + *carry);
492 let (c, r1) = split_u128(a1 + b1 + c);
493 *carry = c;
494
495 combine_u128(r1, r0)
496}
497
498#[inline]
499fn add_nocarry(a: &mut [u128; 2], b: &[u128; 2]) {
500 let mut carry = 0;
501
502 for (a, b) in a.iter_mut().zip(b.iter()) {
503 *a = adc(*a, *b, &mut carry);
504 }
505
506 debug_assert!(0 == carry);
507}
508
509#[inline]
510fn sub_noborrow(a: &mut [u128; 2], b: &[u128; 2]) {
511 #[inline]
512 fn sbb(a: u128, b: u128, borrow: &mut u128) -> u128 {
513 let (a1, a0) = split_u128(a);
514 let (b1, b0) = split_u128(b);
515 let (b, r0) = split_u128((1 << 64) + a0 - b0 - *borrow);
516 let (b, r1) = split_u128((1 << 64) + a1 - b1 - ((b == 0) as u128));
517
518 *borrow = (b == 0) as u128;
519
520 combine_u128(r1, r0)
521 }
522
523 let mut borrow = 0;
524
525 for (a, b) in a.iter_mut().zip(b.iter()) {
526 *a = sbb(*a, *b, &mut borrow);
527 }
528
529 debug_assert!(0 == borrow);
530}
531
532#[inline(always)]
534fn mac_digit(from_index: usize, acc: &mut [u128; 4], b: &[u128; 2], c: u128) {
535 #[inline]
536 fn mac_with_carry(a: u128, b: u128, c: u128, carry: &mut u128) -> u128 {
537 let (b_hi, b_lo) = split_u128(b);
538 let (c_hi, c_lo) = split_u128(c);
539
540 let (a_hi, a_lo) = split_u128(a);
541 let (carry_hi, carry_lo) = split_u128(*carry);
542 let (x_hi, x_lo) = split_u128(b_lo * c_lo + a_lo + carry_lo);
543 let (y_hi, y_lo) = split_u128(b_lo * c_hi);
544 let (z_hi, z_lo) = split_u128(b_hi * c_lo);
545 let (r_hi, r_lo) = split_u128((x_hi + y_lo) + (z_lo + a_hi) + carry_hi);
547
548 *carry = (b_hi * c_hi) + r_hi + y_hi + z_hi;
549
550 combine_u128(r_lo, x_lo)
551 }
552
553 if c == 0 {
554 return;
555 }
556
557 let mut carry = 0;
558
559 debug_assert_eq!(acc.len(), 4);
560 unroll! {
561 for i in 0..2 {
562 let a_index = i + from_index;
563 acc[a_index] = mac_with_carry(acc[a_index], b[i], c, &mut carry);
564 }
565 }
566 unroll! {
567 for i in 0..2 {
568 let a_index = i + from_index + 2;
569 if a_index < 4 {
570 let (a_hi, a_lo) = split_u128(acc[a_index]);
571 let (carry_hi, carry_lo) = split_u128(carry);
572 let (x_hi, x_lo) = split_u128(a_lo + carry_lo);
573 let (r_hi, r_lo) = split_u128(x_hi + a_hi + carry_hi);
574
575 carry = r_hi;
576
577 acc[a_index] = combine_u128(r_lo, x_lo);
578 }
579 }
580 }
581
582 debug_assert!(carry == 0);
583}
584
585#[inline]
586fn mul_reduce(this: &mut [u128; 2], by: &[u128; 2], modulus: &[u128; 2], inv: u128) {
587 let mut res = [0; 2 * 2];
592 unroll! {
593 for i in 0..2 {
594 mac_digit(i, &mut res, by, this[i]);
595 }
596 }
597
598 unroll! {
599 for i in 0..2 {
600 let k = inv.wrapping_mul(res[i]);
601 mac_digit(i, &mut res, modulus, k);
602 }
603 }
604
605 this.copy_from_slice(&res[2..]);
606}
607
608#[test]
609fn setting_bits() {
610 let rng = &mut ::rand::rng();
611 let modulo = U256::from([0xffffffffffffffff; 4]);
612
613 let a = U256::random(rng, &modulo);
614 let mut e = U256::zero();
615 for (i, b) in a.bits().enumerate() {
616 assert!(e.set_bit(255 - i, b));
617 }
618
619 assert_eq!(a, e);
620}
621
622#[test]
623fn from_slice() {
624 let tst = U256::one();
625 let mut s = [0u8; 32];
626 s[31] = 1;
627
628 let num =
629 U256::from_slice(&s).expect("U256 should initialize ok from slice in `from_slice` test");
630 assert_eq!(num, tst);
631}
632
633#[test]
634fn to_big_endian() {
635 let num = U256::one();
636 let mut s = [0u8; 32];
637
638 num.to_big_endian(&mut s)
639 .expect("U256 should convert to bytes ok in `to_big_endian` test");
640 assert_eq!(
641 s,
642 [
643 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
644 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
645 ]
646 );
647}
648
649#[test]
650fn testing_divrem() {
651 let rng = &mut ::rand::rng();
652
653 let modulo = U256::from([
654 0x3c208c16d87cfd47,
655 0x97816a916871ca8d,
656 0xb85045b68181585d,
657 0x30644e72e131a029,
658 ]);
659
660 for _ in 0..100 {
661 let c0 = U256::random(rng, &modulo);
662 let c1 = U256::random(rng, &modulo);
663
664 let c1q_plus_c0 = U512::new(&c1, &c0, &modulo);
665
666 let (new_c1, new_c0) = c1q_plus_c0.divrem(&modulo);
667
668 assert!(c1 == new_c1.unwrap());
669 assert!(c0 == new_c0);
670 }
671
672 {
673 let a = U512::from([
675 0x3c208c16d87cfd47,
676 0x97816a916871ca8d,
677 0xb85045b68181585d,
678 0x30644e72e131a029,
679 0,
680 0,
681 0,
682 0,
683 ]);
684
685 let (c1, c0) = a.divrem(&modulo);
686 assert_eq!(c1.unwrap(), U256::one());
687 assert_eq!(c0, U256::zero());
688 }
689
690 {
691 let a = U512::from([
693 0x3b5458a2275d69b0,
694 0xa602072d09eac101,
695 0x4a50189c6d96cadc,
696 0x04689e957a1242c8,
697 0x26edfa5c34c6b38d,
698 0xb00b855116375606,
699 0x599a6f7c0348d21c,
700 0x0925c4b8763cbf9c,
701 ]);
702
703 let (c1, c0) = a.divrem(&modulo);
704 assert_eq!(
705 c1.unwrap(),
706 U256::from([
707 0x3c208c16d87cfd46,
708 0x97816a916871ca8d,
709 0xb85045b68181585d,
710 0x30644e72e131a029
711 ])
712 );
713 assert_eq!(
714 c0,
715 U256::from([
716 0x3c208c16d87cfd46,
717 0x97816a916871ca8d,
718 0xb85045b68181585d,
719 0x30644e72e131a029
720 ])
721 );
722 }
723
724 {
725 let a = U512::from([
727 0x3b5458a2275d69af,
728 0xa602072d09eac101,
729 0x4a50189c6d96cadc,
730 0x04689e957a1242c8,
731 0x26edfa5c34c6b38d,
732 0xb00b855116375606,
733 0x599a6f7c0348d21c,
734 0x0925c4b8763cbf9c,
735 ]);
736
737 let (c1, c0) = a.divrem(&modulo);
738
739 assert_eq!(
740 c1.unwrap(),
741 U256::from([
742 0x3c208c16d87cfd46,
743 0x97816a916871ca8d,
744 0xb85045b68181585d,
745 0x30644e72e131a029
746 ])
747 );
748 assert_eq!(
749 c0,
750 U256::from([
751 0x3c208c16d87cfd45,
752 0x97816a916871ca8d,
753 0xb85045b68181585d,
754 0x30644e72e131a029
755 ])
756 );
757 }
758
759 {
760 let a = U512::from([
762 0xffffffffffffffff,
763 0xffffffffffffffff,
764 0xffffffffffffffff,
765 0xffffffffffffffff,
766 0xffffffffffffffff,
767 0xffffffffffffffff,
768 0xffffffffffffffff,
769 0xffffffffffffffff,
770 ]);
771
772 let (c1, c0) = a.divrem(&modulo);
773 assert!(c1.is_none());
774 assert_eq!(
775 c0,
776 U256::from([
777 0xf32cfc5b538afa88,
778 0xb5e71911d44501fb,
779 0x47ab1eff0a417ff6,
780 0x06d89f71cab8351f
781 ])
782 );
783 }
784
785 {
786 let a = U512::from([
788 0x3b5458a2275d69b1,
789 0xa602072d09eac101,
790 0x4a50189c6d96cadc,
791 0x04689e957a1242c8,
792 0x26edfa5c34c6b38d,
793 0xb00b855116375606,
794 0x599a6f7c0348d21c,
795 0x0925c4b8763cbf9c,
796 ]);
797
798 let (c1, c0) = a.divrem(&modulo);
799 assert!(c1.is_none());
800 assert_eq!(c0, U256::zero());
801 }
802
803 {
804 let a = U512::from([
806 0x3b5458a2275d69b2,
807 0xa602072d09eac101,
808 0x4a50189c6d96cadc,
809 0x04689e957a1242c8,
810 0x26edfa5c34c6b38d,
811 0xb00b855116375606,
812 0x599a6f7c0348d21c,
813 0x0925c4b8763cbf9c,
814 ]);
815
816 let (c1, c0) = a.divrem(&modulo);
817 assert!(c1.is_none());
818 assert_eq!(c0, U256::one());
819 }
820
821 {
822 let modulo = U256::from([
823 0x43e1f593f0000001,
824 0x2833e84879b97091,
825 0xb85045b68181585d,
826 0x30644e72e131a029,
827 ]);
828
829 let a = U512::from([
831 0xffffffffffffffff,
832 0xffffffffffffffff,
833 0xffffffffffffffff,
834 0xffffffffffffffff,
835 0xffffffffffffffff,
836 0xffffffffffffffff,
837 0xffffffffffffffff,
838 0x07ffffffffffffff,
839 ]);
840
841 let (c1, c0) = a.divrem(&modulo);
842
843 assert!(c1.unwrap() < modulo);
844 assert!(c0 < modulo);
845 }
846}