1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use crate::UInt;
use core::ops::{Add, AddAssign, Deref, Mul, MulAssign, Sub, SubAssign};
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
#[derive(Copy, Clone, Debug)]
pub struct Checked<T>(pub CtOption<T>);
impl<T> Checked<T> {
pub fn new(val: T) -> Self {
Self(CtOption::new(val, Choice::from(1)))
}
}
impl<T> Default for Checked<T>
where
T: Default,
{
fn default() -> Self {
Self::new(T::default())
}
}
impl<T> Deref for Checked<T> {
type Target = CtOption<T>;
fn deref(&self) -> &CtOption<T> {
&self.0
}
}
impl<T: ConditionallySelectable> ConditionallySelectable for Checked<T> {
#[inline]
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
Self(CtOption::conditional_select(&a.0, &b.0, choice))
}
}
impl<T: ConstantTimeEq> ConstantTimeEq for Checked<T> {
#[inline]
fn ct_eq(&self, rhs: &Self) -> Choice {
self.0.ct_eq(&rhs.0)
}
}
impl<const LIMBS: usize> Add for Checked<UInt<LIMBS>> {
type Output = Self;
fn add(self, rhs: Self) -> Checked<UInt<LIMBS>> {
Checked(self.0.and_then(|a| rhs.0.and_then(|b| a.checked_add(&b))))
}
}
impl<const LIMBS: usize> AddAssign for Checked<UInt<LIMBS>> {
fn add_assign(&mut self, other: Self) {
*self = *self + other;
}
}
impl<const LIMBS: usize> Sub for Checked<UInt<LIMBS>> {
type Output = Self;
fn sub(self, rhs: Self) -> Checked<UInt<LIMBS>> {
Checked(self.0.and_then(|a| rhs.0.and_then(|b| a.checked_sub(&b))))
}
}
impl<const LIMBS: usize> SubAssign for Checked<UInt<LIMBS>> {
fn sub_assign(&mut self, other: Self) {
*self = *self - other;
}
}
impl<const LIMBS: usize> Mul for Checked<UInt<LIMBS>> {
type Output = Self;
fn mul(self, rhs: Self) -> Checked<UInt<LIMBS>> {
Checked(self.0.and_then(|a| rhs.0.and_then(|b| a.checked_mul(&b))))
}
}
impl<const LIMBS: usize> MulAssign for Checked<UInt<LIMBS>> {
fn mul_assign(&mut self, other: Self) {
*self = *self * other;
}
}