1
1
use alloc:: vec:: Vec ;
2
+ use core:: cmp:: Ordering ;
2
3
use core:: fmt;
3
4
use core:: hash:: { Hash , Hasher } ;
4
5
@@ -325,6 +326,9 @@ impl RsaPrivateKey {
325
326
_ => { }
326
327
}
327
328
329
+ // The primes may come in padded with zeros, so we need to shorten them.
330
+ let primes = primes. iter ( ) . map ( |p| p. shorten ( p. bits ( ) ) ) . collect ( ) ;
331
+
328
332
let mut k = RsaPrivateKey {
329
333
pubkey_components : RsaPublicKey {
330
334
n : n_c,
@@ -408,9 +412,8 @@ impl RsaPrivateKey {
408
412
}
409
413
410
414
let d = & self . d ;
411
- let bits = d. bits_precision ( ) ;
412
- let p = self . primes [ 0 ] . widen ( bits) ;
413
- let q = self . primes [ 1 ] . widen ( bits) ;
415
+ let p = self . primes [ 0 ] . clone ( ) ;
416
+ let q = self . primes [ 1 ] . clone ( ) ;
414
417
415
418
let p_odd = Odd :: new ( p. clone ( ) )
416
419
. into_option ( )
@@ -431,14 +434,23 @@ impl RsaPrivateKey {
431
434
. ok_or ( Error :: InvalidPrime ) ?;
432
435
let dq = d. rem_vartime ( & x) ;
433
436
434
- let qinv = BoxedMontyForm :: new ( q. clone ( ) , p_params. clone ( ) ) ;
435
- let qinv = qinv. invert ( ) . into_option ( ) . ok_or ( Error :: InvalidPrime ) ?;
437
+ // Note that since `p` and `q` may have different `bits_precision`,
438
+ // so we have to equalize them to calculate the remainder.
439
+ let q_mod_p = match p. bits_precision ( ) . cmp ( & q. bits_precision ( ) ) {
440
+ Ordering :: Less => ( & q % & NonZero :: new ( p. widen ( q. bits_precision ( ) ) ) . unwrap ( ) )
441
+ . shorten ( p. bits_precision ( ) ) ,
442
+ Ordering :: Greater => q. widen ( p. bits_precision ( ) ) % & NonZero :: new ( p. clone ( ) ) . unwrap ( ) ,
443
+ Ordering :: Equal => & q % NonZero :: new ( p. clone ( ) ) . unwrap ( ) ,
444
+ } ;
445
+
446
+ let q_mod_p = BoxedMontyForm :: new ( q_mod_p, p_params. clone ( ) ) ;
447
+ let qinv = q_mod_p. invert ( ) . into_option ( ) . ok_or ( Error :: InvalidPrime ) ?;
436
448
437
- debug_assert_eq ! ( dp. bits_precision( ) , bits ) ;
438
- debug_assert_eq ! ( dq. bits_precision( ) , bits ) ;
439
- debug_assert_eq ! ( qinv. bits_precision( ) , bits ) ;
440
- debug_assert_eq ! ( p_params. bits_precision( ) , bits ) ;
441
- debug_assert_eq ! ( q_params. bits_precision( ) , bits ) ;
449
+ debug_assert_eq ! ( dp. bits_precision( ) , p . bits_precision ( ) ) ;
450
+ debug_assert_eq ! ( dq. bits_precision( ) , q . bits_precision ( ) ) ;
451
+ debug_assert_eq ! ( qinv. bits_precision( ) , p . bits_precision ( ) ) ;
452
+ debug_assert_eq ! ( p_params. bits_precision( ) , p . bits_precision ( ) ) ;
453
+ debug_assert_eq ! ( q_params. bits_precision( ) , q . bits_precision ( ) ) ;
442
454
443
455
self . precomputed = Some ( PrecomputedValues {
444
456
dp,
@@ -742,8 +754,7 @@ mod tests {
742
754
743
755
key_generation ! ( key_generation_multi_5_64, 5 , 64 ) ;
744
756
key_generation ! ( key_generation_multi_8_576, 8 , 576 ) ;
745
- // TODO: reenable, currently slow
746
- // key_generation!(key_generation_multi_16_1024, 16, 1024);
757
+ key_generation ! ( key_generation_multi_16_1024, 16 , 1024 ) ;
747
758
748
759
#[ test]
749
760
fn test_negative_decryption_value ( ) {
@@ -768,8 +779,8 @@ mod tests {
768
779
)
769
780
. unwrap ( ) ,
770
781
vec ! [
771
- BoxedUint :: from_le_slice( & [ 105 , 101 , 60 , 173 , 19 , 153 , 3 , 192 ] , bits) . unwrap( ) ,
772
- BoxedUint :: from_le_slice( & [ 235 , 65 , 160 , 134 , 32 , 136 , 6 , 241 ] , bits) . unwrap( ) ,
782
+ BoxedUint :: from_le_slice( & [ 105 , 101 , 60 , 173 , 19 , 153 , 3 , 192 ] , bits / 2 ) . unwrap( ) ,
783
+ BoxedUint :: from_le_slice( & [ 235 , 65 , 160 , 134 , 32 , 136 , 6 , 241 ] , bits / 2 ) . unwrap( ) ,
773
784
] ,
774
785
)
775
786
. unwrap ( ) ;
0 commit comments