11//! Multiple precision integer
22
3- use crate :: { Error , Result } ;
3+ use crate :: { CheckedSum , Decode , Encode , Error , Reader , Result , Writer } ;
44use alloc:: { boxed:: Box , vec:: Vec } ;
55use core:: fmt;
6- use encoding:: { CheckedSum , Decode , Encode , Reader , Writer } ;
6+
7+ #[ cfg( feature = "subtle" ) ]
78use subtle:: { Choice , ConstantTimeEq } ;
8- use zeroize:: Zeroize ;
99
10- #[ cfg( any( feature = "dsa" , feature = "rsa" ) ) ]
10+ #[ cfg( any( feature = "bigint" , feature = "zeroize" ) ) ]
11+ use zeroize:: Zeroize ;
12+ #[ cfg( feature = "bigint" ) ]
1113use zeroize:: Zeroizing ;
1214
13- /// Multiple precision integer, a.k.a. "mpint".
14- ///
15- /// This type is used for representing the big integer components of
16- /// DSA and RSA keys.
15+ /// Multiple precision integer, a.k.a. `mpint`.
1716///
1817/// Described in [RFC4251 § 5](https://datatracker.ietf.org/doc/html/rfc4251#section-5):
1918///
@@ -38,7 +37,8 @@ use zeroize::Zeroizing;
3837/// | 80 | `00 00 00 02 00 80`
3938/// |-1234 | `00 00 00 02 ed cc`
4039/// | -deadbeef | `00 00 00 05 ff 21 52 41 11`
41- #[ derive( Clone , PartialOrd , Ord ) ]
40+ #[ cfg_attr( not( feature = "subtle" ) , derive( Clone ) ) ]
41+ #[ cfg_attr( feature = "subtle" , derive( Clone , Ord , PartialOrd ) ) ] // TODO: constant time (Partial)`Ord`?
4242pub struct Mpint {
4343 /// Inner big endian-serialized integer value
4444 inner : Box < [ u8 ] > ,
@@ -109,14 +109,17 @@ impl AsRef<[u8]> for Mpint {
109109 }
110110}
111111
112+ #[ cfg( feature = "subtle" ) ]
112113impl ConstantTimeEq for Mpint {
113114 fn ct_eq ( & self , other : & Self ) -> Choice {
114115 self . as_ref ( ) . ct_eq ( other. as_ref ( ) )
115116 }
116117}
117118
119+ #[ cfg( feature = "subtle" ) ]
118120impl Eq for Mpint { }
119121
122+ #[ cfg( feature = "subtle" ) ]
120123impl PartialEq for Mpint {
121124 fn eq ( & self , other : & Self ) -> bool {
122125 self . ct_eq ( other) . into ( )
@@ -132,11 +135,11 @@ impl Decode for Mpint {
132135}
133136
134137impl Encode for Mpint {
135- fn encoded_len ( & self ) -> encoding :: Result < usize > {
138+ fn encoded_len ( & self ) -> Result < usize > {
136139 [ 4 , self . as_bytes ( ) . len ( ) ] . checked_sum ( )
137140 }
138141
139- fn encode ( & self , writer : & mut impl Writer ) -> encoding :: Result < ( ) > {
142+ fn encode ( & self , writer : & mut impl Writer ) -> Result < ( ) > {
140143 self . as_bytes ( ) . encode ( writer) ?;
141144 Ok ( ( ) )
142145 }
@@ -156,14 +159,15 @@ impl TryFrom<Box<[u8]>> for Mpint {
156159 fn try_from ( bytes : Box < [ u8 ] > ) -> Result < Self > {
157160 match & * bytes {
158161 // Unnecessary leading 0
159- [ 0x00 ] => Err ( Error :: FormatEncoding ) ,
162+ [ 0x00 ] => Err ( Error :: MpintEncoding ) ,
160163 // Unnecessary leading 0
161- [ 0x00 , n, ..] if * n < 0x80 => Err ( Error :: FormatEncoding ) ,
164+ [ 0x00 , n, ..] if * n < 0x80 => Err ( Error :: MpintEncoding ) ,
162165 _ => Ok ( Self { inner : bytes } ) ,
163166 }
164167 }
165168}
166169
170+ #[ cfg( feature = "zeroize" ) ]
167171impl Zeroize for Mpint {
168172 fn zeroize ( & mut self ) {
169173 self . inner . zeroize ( ) ;
@@ -200,7 +204,7 @@ impl fmt::UpperHex for Mpint {
200204 }
201205}
202206
203- #[ cfg( any ( feature = "dsa" , feature = "rsa" ) ) ]
207+ #[ cfg( feature = "bigint" ) ]
204208impl TryFrom < bigint:: BigUint > for Mpint {
205209 type Error = Error ;
206210
@@ -209,7 +213,7 @@ impl TryFrom<bigint::BigUint> for Mpint {
209213 }
210214}
211215
212- #[ cfg( any ( feature = "dsa" , feature = "rsa" ) ) ]
216+ #[ cfg( feature = "bigint" ) ]
213217impl TryFrom < & bigint:: BigUint > for Mpint {
214218 type Error = Error ;
215219
@@ -219,7 +223,7 @@ impl TryFrom<&bigint::BigUint> for Mpint {
219223 }
220224}
221225
222- #[ cfg( any ( feature = "dsa" , feature = "rsa" ) ) ]
226+ #[ cfg( feature = "bigint" ) ]
223227impl TryFrom < Mpint > for bigint:: BigUint {
224228 type Error = Error ;
225229
@@ -228,15 +232,15 @@ impl TryFrom<Mpint> for bigint::BigUint {
228232 }
229233}
230234
231- #[ cfg( any ( feature = "dsa" , feature = "rsa" ) ) ]
235+ #[ cfg( feature = "bigint" ) ]
232236impl TryFrom < & Mpint > for bigint:: BigUint {
233237 type Error = Error ;
234238
235239 fn try_from ( mpint : & Mpint ) -> Result < bigint:: BigUint > {
236240 mpint
237241 . as_positive_bytes ( )
238242 . map ( bigint:: BigUint :: from_bytes_be)
239- . ok_or ( Error :: Crypto )
243+ . ok_or ( Error :: MpintEncoding )
240244 }
241245}
242246
0 commit comments