@@ -68,14 +68,32 @@ impl RsaPrivateKey {
6868 n : BigUint ,
6969 e : BigUint ,
7070 d : BigUint ,
71- p : BigUint ,
72- q : BigUint ,
73- dp : BigUint ,
74- dq : BigUint ,
75- qinv : BigUint ,
71+ mut p : BigUint ,
72+ mut q : BigUint ,
73+ mut dp : BigUint ,
74+ mut dq : BigUint ,
75+ mut qinv : BigUint ,
7676 ) -> Result < Self > {
7777 let public_key = RsaPublicKey :: new ( n, e) ?;
7878
79+ // Ensure p > q (required for CRT correctness)
80+ // If q > p, swap them and recalculate CRT parameters
81+ if q > p {
82+ core:: mem:: swap ( & mut p, & mut q) ;
83+ core:: mem:: swap ( & mut dp, & mut dq) ;
84+
85+ // Recalculate qinv = q^-1 mod p (since we swapped p and q)
86+ use crate :: primitives:: mod_inverse;
87+ use num_traits:: One ;
88+
89+ qinv = mod_inverse ( & q, & p) . ok_or ( RsaError :: KeyGenerationFailed ) ?;
90+
91+ // Verify the swap is correct
92+ if ( & qinv * & q) % & p != BigUint :: one ( ) {
93+ return Err ( RsaError :: KeyGenerationFailed ) ;
94+ }
95+ }
96+
7997 Ok ( Self {
8098 public_key,
8199 d,
@@ -231,19 +249,11 @@ impl RsaPrivateKey {
231249 let m2 = c_mod_q. modpow ( & self . dq , & self . q ) ;
232250
233251 // h = qinv * (m1 - m2) mod p
234- // Use modular arithmetic to avoid potential underflow
235252 let h = if m1 >= m2 {
236- ( & self . qinv * ( & m1 - & m2) ) % & self . p
253+ ( & self . qinv * ( m1 - & m2) ) % & self . p
237254 } else {
238- // m1 < m2: compute (m1 + p - m2) mod p to avoid underflow
239- // Since m1 < p and m2 < q, and we ensure p >= q during key generation,
240- // (m1 + p) will always be >= m2
241- let sum = & m1 + & self . p ;
242- // Additional safety check to prevent underflow
243- if sum < m2 {
244- return Err ( RsaError :: InvalidCiphertext ) ;
245- }
246- ( & self . qinv * ( sum - & m2) ) % & self . p
255+ // Handle m1 < m2: compute h = qinv * (p + m1 - m2) mod p
256+ ( & self . qinv * ( ( & self . p + m1) - & m2) ) % & self . p
247257 } ;
248258
249259 // m = m2 + h * q
@@ -267,20 +277,11 @@ impl RsaPrivateKey {
267277 let m_mod_q = m % & self . q ;
268278 let s2 = m_mod_q. modpow ( & self . dq , & self . q ) ;
269279
270- // h = qinv * (s1 - s2) mod p
271- // Use modular arithmetic to avoid potential underflow
272280 let h = if s1 >= s2 {
273- ( & self . qinv * ( & s1 - & s2) ) % & self . p
281+ ( & self . qinv * ( s1 - & s2) ) % & self . p
274282 } else {
275- // s1 < s2: compute (s1 + p - s2) mod p to avoid underflow
276- // Since s1 < p and s2 < q, and we ensure p >= q during key generation,
277- // (s1 + p) will always be >= s2
278- let sum = & s1 + & self . p ;
279- // Additional safety check to prevent underflow
280- if sum < s2 {
281- return Err ( RsaError :: MessageTooLong ) ;
282- }
283- ( & self . qinv * ( sum - & s2) ) % & self . p
283+ // Handle s1 < s2: compute h = qinv * (p + s1 - s2) mod p
284+ ( & self . qinv * ( ( & self . p + s1) - & s2) ) % & self . p
284285 } ;
285286
286287 let s = s2 + ( h * & self . q ) ;
0 commit comments