1use std::cmp::Ordering;
2use rand::Rng;
3use core::fmt;
4use byteorder::{ByteOrder, BigEndian, WriteBytesExt};
5use std::iter::FromIterator;
6#[cfg(feature = "borsh")]
7use borsh::{BorshSerialize, BorshDeserialize};
8#[cfg(feature = "serde")]
9use serde::{Serialize, Deserialize};
10
11#[derive(Copy, Clone, PartialEq, Eq, Debug)]
14#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
15#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
16#[repr(C)]
17pub struct U256(pub [u64; 4]);
18
19impl From<[u64; 4]> for U256 {
20 fn from(d: [u64; 4]) -> Self {
21 U256(d)
22 }
23}
24
25#[derive(Copy, Clone, PartialEq, Eq, Debug)]
28#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
29#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
30#[repr(C)]
31pub struct U512(pub [u64; 8]);
32
33impl U512 {
34 #[allow(dead_code)]
36 pub fn from(c1: &U256, c0: &U256, modulo: &U256) -> U512 {
37 let mut res = [0; 8];
38
39 for (i, xi) in c1.0.iter().enumerate() {
40 mac_digit(&mut res[i..], &modulo.0, *xi);
41 }
42
43 let mut c0_iter = c0.0.iter();
44 let mut carry = 0;
45
46 for ai in res.iter_mut() {
47 if let Some(bi) = c0_iter.next() {
48 *ai = adc(*ai, *bi, &mut carry);
49 } else if carry != 0 {
50 *ai = adc(*ai, 0, &mut carry);
51 } else {
52 break;
53 }
54 }
55
56 debug_assert!(0 == carry);
57
58 U512(res)
59 }
60
61 pub fn random<R: Rng + ?Sized>(rng: &mut R) -> U512 {
63 U512(rng.gen())
64 }
65
66 pub fn get_bit(&self, n: usize) -> Option<bool> {
67 if n >= 512 {
68 None
69 } else {
70 let part = n / 64;
71 let bit = n - (64 * part);
72
73 Some(self.0[part] & (1 << bit) > 0)
74 }
75 }
76
77 pub fn divrem(&self, modulo: &U256) -> (Option<U256>, U256) {
80 let mut q = Some(U256::zero());
81 let mut r = U256::zero();
82
83 for i in (0..512).rev() {
84 mul2(&mut r.0);
87 assert!(r.set_bit(0, self.get_bit(i).unwrap()));
88 if &r >= modulo {
89 sub_noborrow(&mut r.0, &modulo.0);
90 if q.is_some() && !q.as_mut().unwrap().set_bit(i, true) {
91 q = None
92 }
93 }
94 }
95
96 if q.is_some() && (q.as_ref().unwrap() >= modulo) {
97 (None, r)
98 } else {
99 (q, r)
100 }
101 }
102
103 pub fn interpret(buf: &[u8; 64]) -> U512 {
104 let mut n = [0; 8];
105 for (l, i) in (0..8).rev().zip((0..8).map(|i| i * 8)) {
106 n[l] = BigEndian::read_u64(&buf[i..]);
107 }
108
109 U512(n)
110 }
111}
112
113impl fmt::Display for U512 {
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 let mut str = String::new();
116 for tup in self.0.iter() {
117 str.push_str(format!("{:#X?}", tup).as_ref())
118 }
119 write!(f, "{:?}", str)
120 }
121}
122
123impl FromIterator<u64> for U512 {
124 fn from_iter<I: IntoIterator<Item=u64>>(iter: I) -> Self {
125 let mut barry: Vec<u8> = Vec::new();
126 for word in iter {
127 for v in word.to_le_bytes() {
128 barry.push(v)
129 }
130 }
131 let mut array = [0u8; 64];
132 for (&x, p) in barry.iter().zip(array.iter_mut()) {
133 *p = x;
134 }
135 U512::interpret(&array)
136 }
137}
138
139impl fmt::Display for U256 {
140 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141 let mut str = String::new();
142 for tup in self.0.iter() {
143 str.push_str(format!("{:#X?}", tup).as_ref())
144 }
145 write!(f, "{:?}", str)
146 }
147}
148
149impl Ord for U256 {
150 #[inline]
151 fn cmp(&self, other: &U256) -> Ordering {
152 for (a, b) in self.0.iter().zip(other.0.iter()).rev() {
153 if *a < *b {
154 return Ordering::Less;
155 } else if *a > *b {
156 return Ordering::Greater;
157 }
158 }
159
160 return Ordering::Equal;
161 }
162}
163
164impl PartialOrd for U256 {
165 #[inline]
166 fn partial_cmp(&self, other: &U256) -> Option<Ordering> {
167 Some(self.cmp(other))
168 }
169}
170
171#[derive(Debug)]
173pub enum Error {
174 InvalidLength { expected: usize, actual: usize },
175}
176
177impl U256 {
178 pub fn from_slice(s: &[u8]) -> Result<U256, Error> {
180 if s.len() != 32 {
181 return Err(Error::InvalidLength {
182 expected: 32,
183 actual: s.len(),
184 });
185 }
186
187 let mut n = [0; 4];
188 for (l, i) in (0..4).rev().zip((0..4).map(|i| i * 8)) {
189 n[l] = BigEndian::read_u64(&s[i..]);
190 }
191
192 Ok(U256(n))
193 }
194 #[inline]
195 pub fn zero() -> U256 {
196 U256([0, 0, 0, 0])
197 }
198
199 #[inline]
200 pub fn one() -> U256 {
201 U256([1, 0, 0, 0])
202 }
203
204 #[inline]
205 pub fn into_bytes(&self) -> Vec<u8> {
206 let mut wtr = vec![];
207 for elem in self.0 {
208 wtr.write_u64::<BigEndian>(elem).unwrap();
209 }
210 wtr
211 }
212
213 pub fn random<R: Rng + ?Sized>(rng: &mut R, modulo: &U256) -> U256 {
215 U512::random(rng).divrem(modulo).1
216 }
217
218 pub fn is_zero(&self) -> bool {
219 self.0[0] == 0 && self.0[1] == 0 && self.0[2] == 0 && self.0[3] == 0
220 }
221
222 pub fn set_bit(&mut self, n: usize, to: bool) -> bool {
223 if n >= 256 {
224 false
225 } else {
226 let part = n / 64;
227 let bit = n - (64 * part);
228
229 if to {
230 self.0[part] |= 1 << bit;
231 } else {
232 self.0[part] &= !(1 << bit);
233 }
234
235 true
236 }
237 }
238
239 pub fn get_bit(&self, n: usize) -> Option<bool> {
240 if n >= 256 {
241 None
242 } else {
243 let part = n / 64;
244 let bit = n - (64 * part);
245
246 Some(self.0[part] & (1 << bit) > 0)
247 }
248 }
249
250 pub fn add(&mut self, other: &U256, modulo: &U256) {
252 add_nocarry(&mut self.0, &other.0);
253
254 if *self >= *modulo {
255 sub_noborrow(&mut self.0, &modulo.0);
256 }
257 }
258
259 pub fn sub(&mut self, other: &U256, modulo: &U256) {
261 if *self < *other {
262 add_nocarry(&mut self.0, &modulo.0);
263 }
264
265 sub_noborrow(&mut self.0, &other.0);
266 }
267
268 pub fn mul(&mut self, other: &U256, modulo: &U256, inv: u64) {
271 mul_reduce(&mut self.0, &other.0, &modulo.0, inv);
272
273 if *self >= *modulo {
274 sub_noborrow(&mut self.0, &modulo.0);
275 }
276 }
277
278 pub fn neg(&mut self, modulo: &U256) {
280 if *self > Self::zero() {
281 let mut tmp = modulo.0;
282 sub_noborrow(&mut tmp, &self.0);
283
284 self.0 = tmp;
285 }
286 }
287
288 #[inline]
289 pub fn is_even(&self) -> bool {
290 self.0[0] & 1 == 0
291 }
292
293 pub fn invert(&mut self, modulo: &U256) {
295 let mut u = *self;
300 let mut v = *modulo;
301 let mut b = U256::one();
302 let mut c = U256::zero();
303
304 while u != U256::one() && v != U256::one() {
305 while u.is_even() {
306 div2(&mut u.0);
307
308 if b.is_even() {
309 div2(&mut b.0);
310 } else {
311 add_nocarry(&mut b.0, &modulo.0);
312 div2(&mut b.0);
313 }
314 }
315 while v.is_even() {
316 div2(&mut v.0);
317
318 if c.is_even() {
319 div2(&mut c.0);
320 } else {
321 add_nocarry(&mut c.0, &modulo.0);
322 div2(&mut c.0);
323 }
324 }
325
326 if u >= v {
327 sub_noborrow(&mut u.0, &v.0);
328 b.sub(&c, modulo);
329 } else {
330 sub_noborrow(&mut v.0, &u.0);
331 c.sub(&b, modulo);
332 }
333 }
334
335 if u == U256::one() {
336 self.0 = b.0;
337 } else {
338 self.0 = c.0;
339 }
340 }
341
342 pub fn bits(&self) -> BitIterator {
345 BitIterator { int: &self, n: 256 }
346 }
347}
348
349pub struct BitIterator<'a> {
350 int: &'a U256,
351 n: usize,
352}
353
354impl<'a> Iterator for BitIterator<'a> {
355 type Item = bool;
356
357 fn next(&mut self) -> Option<bool> {
358 if self.n == 0 {
359 None
360 } else {
361 self.n -= 1;
362
363 self.int.get_bit(self.n)
364 }
365 }
366}
367
368#[inline]
370fn div2(a: &mut [u64; 4]) {
371 let mut t = a[3] << 63;
372 a[3] = a[3] >> 1;
373 let b = a[2] << 63;
374 a[2] >>= 1;
375 a[2] |= t;
376 t = a[1] << 63;
377 a[1] >>= 1;
378 a[1] |= b;
379 a[0] >>= 1;
380 a[0] |= t;
381}
382
383#[inline]
385fn mul2(a: &mut [u64; 4]) {
386 let mut last = 0;
387 for i in a {
388 let tmp = *i >> 63;
389 *i <<= 1;
390 *i |= last;
391 last = tmp;
392 }
393}
394
395#[inline(always)]
396fn split_u64(i: u64) -> (u64, u64) {
397 (i >> 32, i & 0xFFFFFFFF)
398}
399
400#[inline(always)]
401fn combine_u64(hi: u64, lo: u64) -> u64 {
402 (hi << 32) | lo
403}
404
405#[inline]
406fn adc(a: u64, b: u64, carry: &mut u64) -> u64 {
407 let (a1, a0) = split_u64(a);
408 let (b1, b0) = split_u64(b);
409 let (c, r0) = split_u64(a0 + b0 + *carry);
410 let (c, r1) = split_u64(a1 + b1 + c);
411 *carry = c;
412
413 combine_u64(r1, r0)
414}
415
416#[inline]
417fn add_nocarry(a: &mut [u64; 4], b: &[u64; 4]) {
418 let mut carry = 0;
419
420 for (a, b) in a.into_iter().zip(b.iter()) {
421 *a = adc(*a, *b, &mut carry);
422 }
423
424 debug_assert!(0 == carry);
425}
426
427#[inline]
428fn sub_noborrow(a: &mut [u64; 4], b: &[u64; 4]) {
429 #[inline]
430 fn sbb(a: u64, b: u64, borrow: &mut u64) -> u64 {
431 let (a1, a0) = split_u64(a);
432 let (b1, b0) = split_u64(b);
433 let (b, r0) = split_u64((1 << 32) + a0 - b0 - *borrow);
434 let (b, r1) = split_u64((1 << 32) + a1 - b1 - ((b == 0) as u64));
435
436 *borrow = (b == 0) as u64;
437
438 combine_u64(r1, r0)
439 }
440
441 let mut borrow = 0;
442
443 for (a, b) in a.into_iter().zip(b.iter()) {
444 *a = sbb(*a, *b, &mut borrow);
445 }
446
447 debug_assert!(0 == borrow);
448}
449
450fn mac_digit(acc: &mut [u64], b: &[u64], c: u64) {
451 #[inline]
452 fn mac_with_carry(a: u64, b: u64, c: u64, carry: &mut u64) -> u64 {
453 let (b_hi, b_lo) = split_u64(b);
454 let (c_hi, c_lo) = split_u64(c);
455
456 let (a_hi, a_lo) = split_u64(a);
457 let (carry_hi, carry_lo) = split_u64(*carry);
458 let (x_hi, x_lo) = split_u64(b_lo * c_lo + a_lo + carry_lo);
459 let (y_hi, y_lo) = split_u64(b_lo * c_hi);
460 let (z_hi, z_lo) = split_u64(b_hi * c_lo);
461 let (r_hi, r_lo) = split_u64(x_hi + y_lo + z_lo + a_hi + carry_hi);
462
463 *carry = (b_hi * c_hi) + r_hi + y_hi + z_hi;
464
465 combine_u64(r_lo, x_lo)
466 }
467
468 if c == 0 {
469 return;
470 }
471
472 let mut b_iter = b.iter();
473 let mut carry = 0;
474
475 for ai in acc.iter_mut() {
476 if let Some(bi) = b_iter.next() {
477 *ai = mac_with_carry(*ai, *bi, c, &mut carry);
478 } else if carry != 0 {
479 *ai = mac_with_carry(*ai, 0, c, &mut carry);
480 } else {
481 break;
482 }
483 }
484
485 debug_assert!(carry == 0);
486}
487
488#[inline]
489fn mul_reduce(this: &mut [u64; 4], by: &[u64; 4], modulus: &[u64; 4], inv: u64) {
490 let mut res = [0; 2 * 4];
495 for (i, xi) in this.iter().enumerate() {
496 mac_digit(&mut res[i..], by, *xi);
497 }
498
499 for i in 0..4 {
500 let k = inv.wrapping_mul(res[i]);
501 mac_digit(&mut res[i..], modulus, k);
502 }
503
504 this.copy_from_slice(&res[4..]);
505}
506
507#[test]
508fn setting_bits() {
509 let rng = &mut ::rand::thread_rng();
510 let modulo = U256([0xffffffffffffffff; 4]);
511
512 let a = U256::random(rng, &modulo);
513 let mut e = U256::zero();
514 for (i, b) in a.bits().enumerate() {
515 assert!(e.set_bit(255 - i, b));
516 }
517
518 assert_eq!(a, e);
519}
520
521#[test]
522fn testing_divrem() {
523 let rng = &mut ::rand::thread_rng();
524
525 let modulo = U256(
526 [
527 0x3c208c16d87cfd47,
528 0x97816a916871ca8d,
529 0xb85045b68181585d,
530 0x30644e72e131a029,
531 ],
532 );
533
534 for _ in 0..100 {
535 let c0 = U256::random(rng, &modulo);
536 let c1 = U256::random(rng, &modulo);
537
538 let c1q_plus_c0 = U512::from(&c1, &c0, &modulo);
539
540 let (new_c1, new_c0) = c1q_plus_c0.divrem(&modulo);
541
542 assert_eq!(c1, new_c1.unwrap());
543 assert_eq!(c0, new_c0);
544 }
545
546 {
547 let a = U512(
549 [
550 0x3c208c16d87cfd47,
551 0x97816a916871ca8d,
552 0xb85045b68181585d,
553 0x30644e72e131a029,
554 0,
555 0,
556 0,
557 0,
558 ],
559 );
560
561 let (c1, c0) = a.divrem(&modulo);
562 assert_eq!(c1.unwrap(), U256::one());
563 assert_eq!(c0, U256::zero());
564 }
565
566 {
567 let a = U512(
569 [
570 0x3b5458a2275d69b0,
571 0xa602072d09eac101,
572 0x4a50189c6d96cadc,
573 0x04689e957a1242c8,
574 0x26edfa5c34c6b38d,
575 0xb00b855116375606,
576 0x599a6f7c0348d21c,
577 0x0925c4b8763cbf9c,
578 ],
579 );
580
581 let (c1, c0) = a.divrem(&modulo);
582 assert_eq!(
583 c1.unwrap(),
584 U256(
585 [
586 0x3c208c16d87cfd46,
587 0x97816a916871ca8d,
588 0xb85045b68181585d,
589 0x30644e72e131a029,
590 ],
591 )
592 );
593 assert_eq!(
594 c0,
595 U256(
596 [
597 0x3c208c16d87cfd46,
598 0x97816a916871ca8d,
599 0xb85045b68181585d,
600 0x30644e72e131a029,
601 ],
602 )
603 );
604 }
605
606 {
607 let a = U512(
609 [
610 0x3b5458a2275d69af,
611 0xa602072d09eac101,
612 0x4a50189c6d96cadc,
613 0x04689e957a1242c8,
614 0x26edfa5c34c6b38d,
615 0xb00b855116375606,
616 0x599a6f7c0348d21c,
617 0x0925c4b8763cbf9c,
618 ],
619 );
620
621 let (c1, c0) = a.divrem(&modulo);
622
623 assert_eq!(
624 c1.unwrap(),
625 U256(
626 [
627 0x3c208c16d87cfd46,
628 0x97816a916871ca8d,
629 0xb85045b68181585d,
630 0x30644e72e131a029,
631 ],
632 )
633 );
634 assert_eq!(
635 c0,
636 U256(
637 [
638 0x3c208c16d87cfd45,
639 0x97816a916871ca8d,
640 0xb85045b68181585d,
641 0x30644e72e131a029,
642 ],
643 )
644 );
645 }
646
647 {
648 let a = U512(
650 [
651 0xffffffffffffffff,
652 0xffffffffffffffff,
653 0xffffffffffffffff,
654 0xffffffffffffffff,
655 0xffffffffffffffff,
656 0xffffffffffffffff,
657 0xffffffffffffffff,
658 0xffffffffffffffff,
659 ],
660 );
661
662 let (c1, c0) = a.divrem(&modulo);
663 assert!(c1.is_none());
664 assert_eq!(
665 c0,
666 U256(
667 [
668 0xf32cfc5b538afa88,
669 0xb5e71911d44501fb,
670 0x47ab1eff0a417ff6,
671 0x06d89f71cab8351f,
672 ],
673 )
674 );
675 }
676
677 {
678 let a = U512(
680 [
681 0x3b5458a2275d69b1,
682 0xa602072d09eac101,
683 0x4a50189c6d96cadc,
684 0x04689e957a1242c8,
685 0x26edfa5c34c6b38d,
686 0xb00b855116375606,
687 0x599a6f7c0348d21c,
688 0x0925c4b8763cbf9c,
689 ],
690 );
691
692 let (c1, c0) = a.divrem(&modulo);
693 assert!(c1.is_none());
694 assert_eq!(c0, U256::zero());
695 }
696
697 {
698 let a = U512(
700 [
701 0x3b5458a2275d69b2,
702 0xa602072d09eac101,
703 0x4a50189c6d96cadc,
704 0x04689e957a1242c8,
705 0x26edfa5c34c6b38d,
706 0xb00b855116375606,
707 0x599a6f7c0348d21c,
708 0x0925c4b8763cbf9c,
709 ],
710 );
711
712 let (c1, c0) = a.divrem(&modulo);
713 assert!(c1.is_none());
714 assert_eq!(c0, U256::one());
715 }
716
717 {
718 let modulo = U256(
719 [
720 0x43e1f593f0000001,
721 0x2833e84879b97091,
722 0xb85045b68181585d,
723 0x30644e72e131a029,
724 ],
725 );
726
727 let a = U512(
729 [
730 0xffffffffffffffff,
731 0xffffffffffffffff,
732 0xffffffffffffffff,
733 0xffffffffffffffff,
734 0xffffffffffffffff,
735 0xffffffffffffffff,
736 0xffffffffffffffff,
737 0x07ffffffffffffff,
738 ],
739 );
740
741 let (c1, c0) = a.divrem(&modulo);
742
743 assert!(c1.unwrap() < modulo);
744 assert!(c0 < modulo);
745 }
746}