35
35
//!
36
36
//! ```
37
37
//! use curve25519_dalek::scalar::Scalar;
38
+ //! use curve25519_dalek::subtle::CtOption;
38
39
//!
39
40
//! let one_as_bytes: [u8; 32] = Scalar::one().to_bytes();
40
- //! let a: Option <Scalar> = Scalar::from_canonical_bytes(one_as_bytes);
41
+ //! let a: CtOption <Scalar> = Scalar::from_canonical_bytes(one_as_bytes);
41
42
//!
42
- //! assert!(a.is_some());
43
+ //! assert!(bool::from( a.is_some() ));
43
44
//! ```
44
45
//!
45
46
//! However, if we give it bytes representing a scalar larger than \\( \ell \\)
46
47
//! (in this case, \\( \ell + 2 \\)), we'll get `None` back:
47
48
//!
48
49
//! ```
49
50
//! use curve25519_dalek::scalar::Scalar;
51
+ //! use curve25519_dalek::subtle::CtOption;
50
52
//!
51
53
//! let l_plus_two_bytes: [u8; 32] = [
52
54
//! 0xef, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
53
55
//! 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
54
56
//! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55
57
//! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
56
58
//! ];
57
- //! let a: Option <Scalar> = Scalar::from_canonical_bytes(l_plus_two_bytes);
59
+ //! let a: CtOption <Scalar> = Scalar::from_canonical_bytes(l_plus_two_bytes);
58
60
//!
59
- //! assert!(a.is_none());
61
+ //! assert!(bool::from( a.is_none() ));
60
62
//! ```
61
63
//!
62
64
//! Another way to create a `Scalar` is by reducing a \\(256\\)-bit integer mod
132
134
//! let two: Scalar = Scalar::one() + Scalar::one();
133
135
//!
134
136
//! assert!(a != two); // the scalar is not reduced (mod l)…
135
- //! assert!(! a.is_canonical()); // …and therefore is not canonical.
137
+ //! assert!(! bool::from( a.is_canonical() )); // …and therefore is not canonical.
136
138
//! assert!(a.reduce() == two); // if we were to reduce it manually, it would be.
137
139
//! ```
138
140
//!
@@ -157,7 +159,8 @@ use rand_core::{CryptoRng, RngCore};
157
159
use digest:: generic_array:: typenum:: U64 ;
158
160
use digest:: Digest ;
159
161
160
- use subtle:: { Choice , ConstantTimeGreater , ConditionallySelectable , ConstantTimeEq } ;
162
+ use subtle:: { CtOption , Choice } ;
163
+ use subtle:: { ConstantTimeGreater , ConditionallySelectable , ConstantTimeEq } ;
161
164
162
165
use zeroize:: Zeroize ;
163
166
@@ -234,14 +237,9 @@ impl Scalar {
234
237
/// - `Some(s)`, where `s` is the `Scalar` corresponding to `bytes`,
235
238
/// if `bytes` is a canonical byte representation;
236
239
/// - `None` if `bytes` is not a canonical byte representation.
237
- pub fn from_canonical_bytes ( bytes : [ u8 ; 32 ] ) -> Option < Scalar > {
240
+ pub fn from_canonical_bytes ( bytes : [ u8 ; 32 ] ) -> CtOption < Scalar > {
238
241
let candidate = Scalar { bytes} ;
239
-
240
- if candidate. is_canonical ( ) {
241
- Some ( candidate)
242
- } else {
243
- None
244
- }
242
+ CtOption :: new ( candidate, candidate. is_canonical ( ) )
245
243
}
246
244
247
245
/// Construct a `Scalar` from the low 255 bits of a 256-bit integer.
@@ -1106,7 +1104,7 @@ impl Scalar {
1106
1104
1107
1105
/// Check whether this `Scalar` is the canonical representative mod \\(\ell\\).
1108
1106
///
1109
- /// This is intended for uses like input validation, where variable-time code is acceptable .
1107
+ /// This is intended for uses like input validation.
1110
1108
///
1111
1109
/// ```
1112
1110
/// # extern crate curve25519_dalek;
@@ -1116,13 +1114,13 @@ impl Scalar {
1116
1114
/// # fn main() {
1117
1115
/// // 2^255 - 1, since `from_bits` clears the high bit
1118
1116
/// let _2_255_minus_1 = Scalar::from_bits([0xff;32]);
1119
- /// assert!(!_2_255_minus_1.is_canonical());
1117
+ /// assert!(!bool::from( _2_255_minus_1.is_canonical() ));
1120
1118
///
1121
1119
/// let reduced = _2_255_minus_1.reduce();
1122
- /// assert!(reduced.is_canonical());
1120
+ /// assert!(bool::from( reduced.is_canonical() ));
1123
1121
/// # }
1124
1122
/// ```
1125
- pub fn is_canonical ( & self ) -> bool {
1123
+ pub fn is_canonical ( & self ) -> Choice {
1126
1124
let mut over = Choice :: from ( 0 ) ;
1127
1125
let mut under = Choice :: from ( 0 ) ;
1128
1126
for ( this, l) in self . unpack ( ) . 0 . iter ( ) . zip ( & constants:: L . 0 ) . rev ( ) {
@@ -1131,7 +1129,7 @@ impl Scalar {
1131
1129
under |= ( !gt & !eq) & !over;
1132
1130
over |= gt;
1133
1131
}
1134
- under. into ( )
1132
+ under
1135
1133
}
1136
1134
}
1137
1135
@@ -1670,16 +1668,16 @@ mod test {
1670
1668
let non_canonical_full = [ 0xFF ; 32 ] ;
1671
1669
let non_canonical_255_minus_1 = [ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0b0111_1111 ] ;
1672
1670
1673
- assert ! ( Scalar :: from_canonical_bytes( canonical_bytes) . is_some( ) ) ;
1674
- assert ! ( Scalar :: from_canonical_bytes( canonical_l_minus_one) . is_some( ) ) ;
1675
- assert ! ( Scalar :: from_canonical_bytes( canonical_zero) . is_some( ) ) ;
1676
- assert ! ( Scalar :: from_canonical_bytes( canonical_255_minus_1) . is_some( ) ) ;
1677
- assert ! ( Scalar :: from_canonical_bytes( non_canonical_bytes_because_unreduced) . is_none( ) ) ;
1678
- assert ! ( Scalar :: from_canonical_bytes( non_canonical_bytes_because_highbit) . is_none( ) ) ;
1679
- assert ! ( Scalar :: from_canonical_bytes( non_canonical_l) . is_none( ) ) ;
1680
- assert ! ( Scalar :: from_canonical_bytes( non_canonical_l_plus_one) . is_none( ) ) ;
1681
- assert ! ( Scalar :: from_canonical_bytes( non_canonical_full) . is_none( ) ) ;
1682
- assert ! ( Scalar :: from_canonical_bytes( non_canonical_255_minus_1) . is_none( ) ) ;
1671
+ assert ! ( bool :: from ( Scalar :: from_canonical_bytes( canonical_bytes) . is_some( ) ) ) ;
1672
+ assert ! ( bool :: from ( Scalar :: from_canonical_bytes( canonical_l_minus_one) . is_some( ) ) ) ;
1673
+ assert ! ( bool :: from ( Scalar :: from_canonical_bytes( canonical_zero) . is_some( ) ) ) ;
1674
+ assert ! ( bool :: from ( Scalar :: from_canonical_bytes( canonical_255_minus_1) . is_some( ) ) ) ;
1675
+ assert ! ( bool :: from ( Scalar :: from_canonical_bytes( non_canonical_bytes_because_unreduced) . is_none( ) ) ) ;
1676
+ assert ! ( bool :: from ( Scalar :: from_canonical_bytes( non_canonical_bytes_because_highbit) . is_none( ) ) ) ;
1677
+ assert ! ( bool :: from ( Scalar :: from_canonical_bytes( non_canonical_l) . is_none( ) ) ) ;
1678
+ assert ! ( bool :: from ( Scalar :: from_canonical_bytes( non_canonical_l_plus_one) . is_none( ) ) ) ;
1679
+ assert ! ( bool :: from ( Scalar :: from_canonical_bytes( non_canonical_full) . is_none( ) ) ) ;
1680
+ assert ! ( bool :: from ( Scalar :: from_canonical_bytes( non_canonical_255_minus_1) . is_none( ) ) ) ;
1683
1681
}
1684
1682
1685
1683
#[ test]
0 commit comments