Skip to content

Commit 74e3520

Browse files
authored
Impl and bound Integer on CtGt/CtLt (#1049)
Replaces the previous bounds on `subtle::ConstantTimeGreater` and `ConstantTimeLess` with `ctutils::{CtGt, CtLt}`. The old `subtle` trait impls are retained but no longer used in bounds. One step closer to making `subtle` optional.
1 parent 2c51c70 commit 74e3520

File tree

6 files changed

+101
-48
lines changed

6 files changed

+101
-48
lines changed

src/int/cmp.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
//!
33
//! By default, these are all constant-time.
44
5-
use crate::{ConstChoice, CtEq, Int, Uint};
5+
use crate::{ConstChoice, CtEq, CtGt, CtLt, Int, Uint};
66
use core::cmp::Ordering;
7-
use subtle::{Choice, ConstantTimeGreater, ConstantTimeLess};
87

98
impl<const LIMBS: usize> Int<LIMBS> {
109
/// Return `b` if `c` is truthy, otherwise return `a`.
@@ -66,23 +65,37 @@ impl<const LIMBS: usize> CtEq for Int<LIMBS> {
6665
}
6766
}
6867

68+
impl<const LIMBS: usize> CtGt for Int<LIMBS> {
69+
#[inline]
70+
fn ct_gt(&self, other: &Self) -> ConstChoice {
71+
Int::gt(self, other)
72+
}
73+
}
74+
75+
impl<const LIMBS: usize> CtLt for Int<LIMBS> {
76+
#[inline]
77+
fn ct_lt(&self, other: &Self) -> ConstChoice {
78+
Int::lt(self, other)
79+
}
80+
}
81+
6982
impl<const LIMBS: usize> subtle::ConstantTimeEq for Int<LIMBS> {
7083
#[inline]
71-
fn ct_eq(&self, other: &Self) -> Choice {
84+
fn ct_eq(&self, other: &Self) -> subtle::Choice {
7285
CtEq::ct_eq(self, other).into()
7386
}
7487
}
7588

76-
impl<const LIMBS: usize> ConstantTimeGreater for Int<LIMBS> {
89+
impl<const LIMBS: usize> subtle::ConstantTimeGreater for Int<LIMBS> {
7790
#[inline]
78-
fn ct_gt(&self, other: &Self) -> Choice {
79-
Int::gt(self, other).into()
91+
fn ct_gt(&self, other: &Self) -> subtle::Choice {
92+
CtGt::ct_gt(self, other).into()
8093
}
8194
}
8295

83-
impl<const LIMBS: usize> ConstantTimeLess for Int<LIMBS> {
96+
impl<const LIMBS: usize> subtle::ConstantTimeLess for Int<LIMBS> {
8497
#[inline]
85-
fn ct_lt(&self, other: &Self) -> Choice {
98+
fn ct_lt(&self, other: &Self) -> subtle::Choice {
8699
Int::lt(self, other).into()
87100
}
88101
}

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ pub use crate::{
193193
};
194194

195195
// TODO(tarcieri): get rid of `Const*` prefix
196-
pub use ctutils::{Choice as ConstChoice, CtEq, CtOption as ConstCtOption, CtSelect};
196+
pub use ctutils::{Choice as ConstChoice, CtOption as ConstCtOption};
197197

198198
#[cfg(feature = "alloc")]
199199
pub use crate::uint::boxed::BoxedUint;

src/limb/cmp.rs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
//! Limb comparisons
22
3-
use crate::{ConstChoice, CtEq, Limb, word};
3+
use crate::{ConstChoice, CtEq, CtGt, CtLt, CtSelect, Limb, word};
44
use core::cmp::Ordering;
5-
use subtle::{Choice, ConditionallySelectable, ConstantTimeGreater, ConstantTimeLess};
65

76
impl Limb {
87
/// Is this limb an odd number?
@@ -58,29 +57,43 @@ impl CtEq for Limb {
5857
}
5958
}
6059

60+
impl CtGt for Limb {
61+
#[inline]
62+
fn ct_gt(&self, other: &Self) -> ConstChoice {
63+
word::choice_from_gt(self.0, other.0)
64+
}
65+
}
66+
67+
impl CtLt for Limb {
68+
#[inline]
69+
fn ct_lt(&self, other: &Self) -> ConstChoice {
70+
word::choice_from_lt(self.0, other.0)
71+
}
72+
}
73+
6174
impl subtle::ConstantTimeEq for Limb {
6275
#[inline]
63-
fn ct_eq(&self, other: &Self) -> Choice {
76+
fn ct_eq(&self, other: &Self) -> subtle::Choice {
6477
CtEq::ct_eq(self, other).into()
6578
}
6679

6780
#[inline]
68-
fn ct_ne(&self, other: &Self) -> Choice {
81+
fn ct_ne(&self, other: &Self) -> subtle::Choice {
6982
CtEq::ct_ne(self, other).into()
7083
}
7184
}
7285

73-
impl ConstantTimeGreater for Limb {
86+
impl subtle::ConstantTimeGreater for Limb {
7487
#[inline]
75-
fn ct_gt(&self, other: &Self) -> Choice {
76-
word::choice_from_gt(self.0, other.0).into()
88+
fn ct_gt(&self, other: &Self) -> subtle::Choice {
89+
CtGt::ct_gt(self, other).into()
7790
}
7891
}
7992

80-
impl ConstantTimeLess for Limb {
93+
impl subtle::ConstantTimeLess for Limb {
8194
#[inline]
82-
fn ct_lt(&self, other: &Self) -> Choice {
83-
word::choice_from_lt(self.0, other.0).into()
95+
fn ct_lt(&self, other: &Self) -> subtle::Choice {
96+
CtLt::ct_lt(self, other).into()
8497
}
8598
}
8699

@@ -89,8 +102,8 @@ impl Eq for Limb {}
89102
impl Ord for Limb {
90103
fn cmp(&self, other: &Self) -> Ordering {
91104
let mut ret = Ordering::Less;
92-
ret.conditional_assign(&Ordering::Equal, self.ct_eq(other).into());
93-
ret.conditional_assign(&Ordering::Greater, self.ct_gt(other));
105+
ret.ct_assign(&Ordering::Equal, self.ct_eq(other));
106+
ret.ct_assign(&Ordering::Greater, self.ct_gt(other));
94107
debug_assert_eq!(ret == Ordering::Less, bool::from(self.ct_lt(other)));
95108
ret
96109
}

src/traits.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
//! Traits provided by this crate
22
3+
pub use ctutils::{CtEq, CtGt, CtLt, CtSelect};
34
pub use num_traits::{
45
ConstOne, ConstZero, WrappingAdd, WrappingMul, WrappingNeg, WrappingShl, WrappingShr,
56
WrappingSub,
67
};
78

8-
use crate::{ConstChoice, CtEq, CtSelect, Limb, NonZero, Odd, Reciprocal, modular::Retrieve};
9+
use crate::{ConstChoice, Limb, NonZero, Odd, Reciprocal, modular::Retrieve};
910
use core::{
1011
fmt::{self, Debug},
1112
ops::{
@@ -14,7 +15,7 @@ use core::{
1415
SubAssign,
1516
},
1617
};
17-
use subtle::{Choice, ConditionallySelectable, ConstantTimeGreater, ConstantTimeLess, CtOption};
18+
use subtle::{Choice, ConditionallySelectable, CtOption};
1819

1920
#[cfg(feature = "rand_core")]
2021
use rand_core::{RngCore, TryRngCore};
@@ -53,9 +54,9 @@ pub trait Integer:
5354
+ CheckedMul
5455
+ CheckedDiv
5556
+ Clone
56-
+ ConstantTimeGreater
57-
+ ConstantTimeLess
5857
+ CtEq
58+
+ CtGt
59+
+ CtLt
5960
+ CtSelect
6061
+ Debug
6162
+ Default
@@ -136,7 +137,7 @@ pub trait Signed:
136137
+ From<i16>
137138
+ From<i32>
138139
+ From<i64>
139-
+ Integer
140+
+ Integer // + CtNeg TODO(tarcieri)
140141
{
141142
/// Corresponding unsigned integer type.
142143
type Unsigned: Unsigned;

src/uint/boxed/cmp.rs

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
pub(super) use core::cmp::{Ordering, max};
66

77
use super::BoxedUint;
8-
use crate::{ConstChoice, CtEq, Limb, Uint, word};
9-
use subtle::{Choice, ConditionallySelectable, ConstantTimeGreater, ConstantTimeLess};
8+
use crate::{ConstChoice, CtEq, CtGt, CtLt, CtSelect, Limb, Uint, word};
109

1110
impl BoxedUint {
1211
/// Returns the Ordering between `self` and `rhs` in variable time.
@@ -53,26 +52,40 @@ impl CtEq for BoxedUint {
5352
}
5453
}
5554

55+
impl CtGt for BoxedUint {
56+
#[inline]
57+
fn ct_gt(&self, other: &Self) -> ConstChoice {
58+
let (_, borrow) = other.borrowing_sub(self, Limb::ZERO);
59+
word::choice_from_mask(borrow.0)
60+
}
61+
}
62+
63+
impl CtLt for BoxedUint {
64+
#[inline]
65+
fn ct_lt(&self, other: &Self) -> ConstChoice {
66+
let (_, borrow) = self.borrowing_sub(other, Limb::ZERO);
67+
word::choice_from_mask(borrow.0)
68+
}
69+
}
70+
5671
impl subtle::ConstantTimeEq for BoxedUint {
5772
#[inline]
58-
fn ct_eq(&self, other: &Self) -> Choice {
73+
fn ct_eq(&self, other: &Self) -> subtle::Choice {
5974
CtEq::ct_eq(self, other).into()
6075
}
6176
}
6277

63-
impl ConstantTimeGreater for BoxedUint {
78+
impl subtle::ConstantTimeGreater for BoxedUint {
6479
#[inline]
65-
fn ct_gt(&self, other: &Self) -> Choice {
66-
let (_, borrow) = other.borrowing_sub(self, Limb::ZERO);
67-
word::choice_from_mask(borrow.0).into()
80+
fn ct_gt(&self, other: &Self) -> subtle::Choice {
81+
CtGt::ct_gt(self, other).into()
6882
}
6983
}
7084

71-
impl ConstantTimeLess for BoxedUint {
85+
impl subtle::ConstantTimeLess for BoxedUint {
7286
#[inline]
73-
fn ct_lt(&self, other: &Self) -> Choice {
74-
let (_, borrow) = self.borrowing_sub(other, Limb::ZERO);
75-
word::choice_from_mask(borrow.0).into()
87+
fn ct_lt(&self, other: &Self) -> subtle::Choice {
88+
CtLt::ct_lt(self, other).into()
7689
}
7790
}
7891

@@ -92,8 +105,8 @@ impl<const LIMBS: usize> PartialEq<Uint<LIMBS>> for BoxedUint {
92105
impl Ord for BoxedUint {
93106
fn cmp(&self, other: &Self) -> Ordering {
94107
let mut ret = Ordering::Equal;
95-
ret.conditional_assign(&Ordering::Greater, self.ct_gt(other));
96-
ret.conditional_assign(&Ordering::Less, self.ct_lt(other));
108+
ret.ct_assign(&Ordering::Greater, self.ct_gt(other));
109+
ret.ct_assign(&Ordering::Less, self.ct_lt(other));
97110

98111
#[cfg(debug_assertions)]
99112
if ret == Ordering::Equal {

src/uint/cmp.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
//! By default, these are all constant-time.
44
55
use super::Uint;
6-
use crate::{ConstChoice, CtEq, Limb, word};
6+
use crate::{ConstChoice, CtEq, CtGt, CtLt, Limb, word};
77
use core::cmp::Ordering;
8-
use subtle::{Choice, ConstantTimeGreater, ConstantTimeLess};
98

109
impl<const LIMBS: usize> Uint<LIMBS> {
1110
/// Return `b` if `c` is truthy, otherwise return `a`.
@@ -156,28 +155,42 @@ impl<const LIMBS: usize> CtEq for Uint<LIMBS> {
156155
}
157156
}
158157

158+
impl<const LIMBS: usize> CtGt for Uint<LIMBS> {
159+
#[inline]
160+
fn ct_gt(&self, other: &Self) -> ConstChoice {
161+
Self::gt(self, other)
162+
}
163+
}
164+
165+
impl<const LIMBS: usize> CtLt for Uint<LIMBS> {
166+
#[inline]
167+
fn ct_lt(&self, other: &Self) -> ConstChoice {
168+
Self::lt(self, other)
169+
}
170+
}
171+
159172
impl<const LIMBS: usize> subtle::ConstantTimeEq for Uint<LIMBS> {
160173
#[inline]
161-
fn ct_eq(&self, other: &Self) -> Choice {
174+
fn ct_eq(&self, other: &Self) -> subtle::Choice {
162175
CtEq::ct_eq(self, other).into()
163176
}
164177

165178
#[inline]
166-
fn ct_ne(&self, other: &Self) -> Choice {
179+
fn ct_ne(&self, other: &Self) -> subtle::Choice {
167180
CtEq::ct_ne(self, other).into()
168181
}
169182
}
170183

171-
impl<const LIMBS: usize> ConstantTimeGreater for Uint<LIMBS> {
184+
impl<const LIMBS: usize> subtle::ConstantTimeGreater for Uint<LIMBS> {
172185
#[inline]
173-
fn ct_gt(&self, other: &Self) -> Choice {
174-
Uint::gt(self, other).into()
186+
fn ct_gt(&self, other: &Self) -> subtle::Choice {
187+
CtGt::ct_gt(self, other).into()
175188
}
176189
}
177190

178-
impl<const LIMBS: usize> ConstantTimeLess for Uint<LIMBS> {
191+
impl<const LIMBS: usize> subtle::ConstantTimeLess for Uint<LIMBS> {
179192
#[inline]
180-
fn ct_lt(&self, other: &Self) -> Choice {
193+
fn ct_lt(&self, other: &Self) -> subtle::Choice {
181194
Uint::lt(self, other).into()
182195
}
183196
}

0 commit comments

Comments
 (0)