@@ -2,10 +2,13 @@ use crate::{Choice, CtSelect};
22use cmov:: Cmov ;
33use core:: cmp;
44
5+ #[ cfg( feature = "alloc" ) ]
6+ use alloc:: { boxed:: Box , vec:: Vec } ;
7+
58/// Constant-time conditional assignment: assign a given value to another based on a [`Choice`].
6- pub trait CtAssign {
7- /// Conditionally assign `other ` to `self` if `choice` is [`Choice::TRUE`].
8- fn ct_assign ( & mut self , other : & Self , choice : Choice ) ;
9+ pub trait CtAssign < Rhs : ? Sized = Self > {
10+ /// Conditionally assign `rhs ` to `self` if `choice` is [`Choice::TRUE`].
11+ fn ct_assign ( & mut self , rhs : & Rhs , choice : Choice ) ;
912}
1013
1114/// Impl `CtAssign` using the `CtSelect` trait.
@@ -18,8 +21,8 @@ macro_rules! impl_ct_assign_with_ct_select {
1821 $(
1922 impl CtAssign for $ty {
2023 #[ inline]
21- fn ct_assign( & mut self , other : & Self , choice: Choice ) {
22- * self = Self :: ct_select( self , other , choice) ;
24+ fn ct_assign( & mut self , rhs : & Self , choice: Choice ) {
25+ * self = Self :: ct_select( self , rhs , choice) ;
2326 }
2427 }
2528 ) +
@@ -34,8 +37,8 @@ macro_rules! impl_ct_assign_with_cmov {
3437 $(
3538 impl CtAssign for $ty {
3639 #[ inline]
37- fn ct_assign( & mut self , other : & Self , choice: Choice ) {
38- self . cmovnz( other , choice. into( ) ) ;
40+ fn ct_assign( & mut self , rhs : & Self , choice: Choice ) {
41+ self . cmovnz( rhs , choice. into( ) ) ;
3942 }
4043 }
4144 ) +
@@ -46,33 +49,17 @@ impl_ct_assign_with_cmov!(i8, i16, i32, i64, i128, u8, u16, u32, u64, u128);
4649
4750#[ cfg( any( target_pointer_width = "32" , target_pointer_width = "64" ) ) ]
4851impl CtAssign for isize {
49- #[ cfg( target_pointer_width = "32" ) ]
50- #[ inline]
51- fn ct_assign ( & mut self , other : & Self , choice : Choice ) {
52- * self = Self :: ct_select ( self , other, choice) ;
53- }
54-
55- #[ cfg( target_pointer_width = "64" ) ]
56- #[ allow( clippy:: cast_possible_truncation) ]
5752 #[ inline]
58- fn ct_assign ( & mut self , other : & Self , choice : Choice ) {
59- * self = Self :: ct_select ( self , other , choice) ;
53+ fn ct_assign ( & mut self , rhs : & Self , choice : Choice ) {
54+ * self = Self :: ct_select ( self , rhs , choice) ;
6055 }
6156}
6257
6358#[ cfg( any( target_pointer_width = "32" , target_pointer_width = "64" ) ) ]
6459impl CtAssign for usize {
65- #[ cfg( target_pointer_width = "32" ) ]
66- #[ inline]
67- fn ct_assign ( & mut self , other : & Self , choice : Choice ) {
68- * self = Self :: ct_select ( self , other, choice) ;
69- }
70-
71- #[ cfg( target_pointer_width = "64" ) ]
72- #[ allow( clippy:: cast_possible_truncation) ]
7360 #[ inline]
74- fn ct_assign ( & mut self , other : & Self , choice : Choice ) {
75- * self = Self :: ct_select ( self , other , choice) ;
61+ fn ct_assign ( & mut self , rhs : & Self , choice : Choice ) {
62+ * self = Self :: ct_select ( self , rhs , choice) ;
7663 }
7764}
7865
8269{
8370 #[ inline]
8471 #[ track_caller]
85- fn ct_assign ( & mut self , other : & Self , choice : Choice ) {
72+ fn ct_assign ( & mut self , rhs : & Self , choice : Choice ) {
8673 const {
8774 assert ! (
8875 size_of:: <T >( ) != 1 ,
@@ -92,13 +79,13 @@ where
9279
9380 assert_eq ! (
9481 self . len( ) ,
95- other . len( ) ,
82+ rhs . len( ) ,
9683 "source slice length ({}) does not match destination slice length ({})" ,
97- other . len( ) ,
84+ rhs . len( ) ,
9885 self . len( )
9986 ) ;
10087
101- for ( a, b) in self . iter_mut ( ) . zip ( other ) {
88+ for ( a, b) in self . iter_mut ( ) . zip ( rhs ) {
10289 a. ct_assign ( b, choice)
10390 }
10491 }
@@ -109,16 +96,76 @@ where
10996 T : CtAssign ,
11097{
11198 #[ inline]
112- fn ct_assign ( & mut self , other : & Self , choice : Choice ) {
113- self . as_mut_slice ( ) . ct_assign ( other, choice) ;
99+ fn ct_assign ( & mut self , rhs : & Self , choice : Choice ) {
100+ self . as_mut_slice ( ) . ct_assign ( rhs, choice) ;
101+ }
102+ }
103+
104+ #[ cfg( feature = "alloc" ) ]
105+ impl < T > CtAssign for Box < T >
106+ where
107+ T : CtAssign ,
108+ {
109+ #[ inline]
110+ #[ track_caller]
111+ fn ct_assign ( & mut self , rhs : & Self , choice : Choice ) {
112+ ( * * self ) . ct_assign ( rhs, choice) ;
113+ }
114+ }
115+
116+ #[ cfg( feature = "alloc" ) ]
117+ impl < T > CtAssign for Box < [ T ] >
118+ where
119+ T : CtAssign ,
120+ {
121+ #[ inline]
122+ #[ track_caller]
123+ fn ct_assign ( & mut self , rhs : & Self , choice : Choice ) {
124+ self . ct_assign ( & * * rhs, choice) ;
125+ }
126+ }
127+
128+ #[ cfg( feature = "alloc" ) ]
129+ impl < T > CtAssign < [ T ] > for Box < [ T ] >
130+ where
131+ T : CtAssign ,
132+ {
133+ #[ inline]
134+ #[ track_caller]
135+ fn ct_assign ( & mut self , rhs : & [ T ] , choice : Choice ) {
136+ ( * * self ) . ct_assign ( rhs, choice) ;
137+ }
138+ }
139+
140+ #[ cfg( feature = "alloc" ) ]
141+ impl < T > CtAssign for Vec < T >
142+ where
143+ T : CtAssign ,
144+ {
145+ #[ inline]
146+ #[ track_caller]
147+ fn ct_assign ( & mut self , rhs : & Self , choice : Choice ) {
148+ self . ct_assign ( rhs. as_slice ( ) , choice) ;
149+ }
150+ }
151+
152+ #[ cfg( feature = "alloc" ) ]
153+ impl < T > CtAssign < [ T ] > for Vec < T >
154+ where
155+ T : CtAssign ,
156+ {
157+ #[ inline]
158+ #[ track_caller]
159+ fn ct_assign ( & mut self , rhs : & [ T ] , choice : Choice ) {
160+ self . as_mut_slice ( ) . ct_assign ( rhs, choice) ;
114161 }
115162}
116163
117164#[ cfg( feature = "subtle" ) ]
118165impl CtAssign for subtle:: Choice {
119166 #[ inline]
120- fn ct_assign ( & mut self , other : & Self , choice : Choice ) {
121- * self = Self :: ct_select ( self , other , choice) ;
167+ fn ct_assign ( & mut self , rhs : & Self , choice : Choice ) {
168+ * self = Self :: ct_select ( self , rhs , choice) ;
122169 }
123170}
124171
@@ -128,8 +175,8 @@ where
128175 T : Default + subtle:: ConditionallySelectable ,
129176{
130177 #[ inline]
131- fn ct_assign ( & mut self , other : & Self , choice : Choice ) {
178+ fn ct_assign ( & mut self , rhs : & Self , choice : Choice ) {
132179 use subtle:: ConditionallySelectable as _;
133- self . conditional_assign ( other , choice. into ( ) ) ;
180+ self . conditional_assign ( rhs , choice. into ( ) ) ;
134181 }
135182}
0 commit comments