@@ -200,11 +200,13 @@ impl RsaPublicKey {
200
200
201
201
/// Create a new public key from its components.
202
202
pub fn new_with_max_size ( n : BigUint , e : BigUint , max_size : usize ) -> Result < Self > {
203
- let k = Self {
204
- n : NonZero :: new ( to_uint ( n) ) . unwrap ( ) ,
205
- e : to_uint ( e) ,
206
- } ;
207
- check_public_with_max_size ( & k, max_size) ?;
203
+ check_public_with_max_size ( & n, & e, max_size) ?;
204
+
205
+ let n = NonZero :: new ( to_uint ( n) ) . unwrap ( ) ;
206
+ // widen to 64bit
207
+ let e = to_uint_exact ( e, 64 ) ;
208
+ let k = Self { n, e } ;
209
+
208
210
Ok ( k)
209
211
}
210
212
@@ -215,10 +217,30 @@ impl RsaPublicKey {
215
217
/// Most applications should use [`RsaPublicKey::new`] or
216
218
/// [`RsaPublicKey::new_with_max_size`] instead.
217
219
pub fn new_unchecked ( n : BigUint , e : BigUint ) -> Self {
218
- Self {
219
- n : NonZero :: new ( to_uint ( n) ) . unwrap ( ) ,
220
- e : to_uint ( e) ,
221
- }
220
+ // TODO: widen?
221
+ let n = NonZero :: new ( to_uint ( n) ) . unwrap ( ) ;
222
+ let e = to_uint_exact ( e, 64 ) ;
223
+ Self { n, e }
224
+ }
225
+ }
226
+
227
+ fn needed_bits ( n : & BigUint ) -> usize {
228
+ // widen to the max size bits
229
+ let n_bits = n. bits ( ) ;
230
+
231
+ // TODO: better algorithm/more sizes
232
+ if n_bits <= 512 {
233
+ 512
234
+ } else if n_bits <= 1024 {
235
+ 1024
236
+ } else if n_bits <= 2048 {
237
+ 2048
238
+ } else if n_bits <= 4096 {
239
+ 4096
240
+ } else if n_bits <= 8192 {
241
+ 8192
242
+ } else {
243
+ 16384
222
244
}
223
245
}
224
246
@@ -274,8 +296,16 @@ impl RsaPrivateKey {
274
296
d : BigUint ,
275
297
primes : Vec < BigUint > ,
276
298
) -> Result < RsaPrivateKey > {
299
+ let n_c = NonZero :: new ( to_uint ( n. clone ( ) ) ) . unwrap ( ) ;
300
+ let nbits = n_c. bits_precision ( ) ;
301
+
302
+ std:: dbg!( nbits) ;
303
+
277
304
let mut should_validate = false ;
278
- let mut primes: Vec < _ > = primes. into_iter ( ) . map ( to_uint) . collect ( ) ;
305
+ let mut primes: Vec < _ > = primes
306
+ . into_iter ( )
307
+ . map ( |p| to_uint_exact ( p, nbits) )
308
+ . collect ( ) ;
279
309
280
310
if primes. len ( ) < 2 {
281
311
if !primes. is_empty ( ) {
@@ -284,17 +314,15 @@ impl RsaPrivateKey {
284
314
// Recover `p` and `q` from `d`.
285
315
// See method in Appendix C.2: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Br2.pdf
286
316
let ( p, q) = recover_primes ( & n, & e, & d) ?;
287
- primes. push ( to_uint ( p ) ) ;
288
- primes. push ( to_uint ( q ) ) ;
317
+ primes. push ( to_uint_exact ( p , nbits ) ) ;
318
+ primes. push ( to_uint_exact ( q , nbits ) ) ;
289
319
should_validate = true ;
290
320
}
291
321
322
+ let e = to_uint_exact ( e, 64 ) ;
292
323
let mut k = RsaPrivateKey {
293
- pubkey_components : RsaPublicKey {
294
- n : NonZero :: new ( to_uint ( n) ) . unwrap ( ) ,
295
- e : to_uint ( e) ,
296
- } ,
297
- d : to_uint ( d) ,
324
+ pubkey_components : RsaPublicKey { n : n_c, e } ,
325
+ d : to_uint_exact ( d, nbits) ,
298
326
primes,
299
327
precomputed : None ,
300
328
} ;
@@ -363,6 +391,10 @@ impl RsaPrivateKey {
363
391
if self . precomputed . is_some ( ) {
364
392
return Ok ( ( ) ) ;
365
393
}
394
+
395
+ // already widened to what we need
396
+ let nbits = self . pubkey_components . n . bits_precision ( ) ;
397
+
366
398
let d = to_biguint ( & self . d ) ;
367
399
let dp = & d % ( & to_biguint ( & self . primes [ 0 ] ) - BigUint :: one ( ) ) ;
368
400
let dq = & d % ( & to_biguint ( & self . primes [ 1 ] ) - BigUint :: one ( ) ) ;
@@ -378,14 +410,15 @@ impl RsaPrivateKey {
378
410
for prime in & self . primes [ 2 ..] {
379
411
let prime = to_biguint ( prime) ;
380
412
let res = CrtValueNew {
381
- exp : to_uint ( & d % ( & prime - BigUint :: one ( ) ) ) ,
382
- r : to_uint ( r. clone ( ) ) ,
383
- coeff : to_uint (
413
+ exp : to_uint_exact ( & d % ( & prime - BigUint :: one ( ) ) , nbits ) ,
414
+ r : to_uint_exact ( r. clone ( ) , nbits ) ,
415
+ coeff : to_uint_exact (
384
416
r. clone ( )
385
417
. mod_inverse ( & prime)
386
418
. ok_or ( Error :: InvalidCoefficient ) ?
387
419
. to_biguint ( )
388
420
. unwrap ( ) ,
421
+ nbits,
389
422
) ,
390
423
} ;
391
424
r *= prime;
@@ -400,8 +433,8 @@ impl RsaPrivateKey {
400
433
BoxedResidueParams :: new ( self . pubkey_components . n . clone ( ) . get ( ) ) . unwrap ( ) ;
401
434
402
435
self . precomputed = Some ( PrecomputedValues {
403
- dp : to_uint ( dp) ,
404
- dq : to_uint ( dq) ,
436
+ dp : to_uint_exact ( dp, nbits ) ,
437
+ dq : to_uint_exact ( dq, nbits ) ,
405
438
qinv,
406
439
crt_values,
407
440
residue_params,
@@ -539,34 +572,31 @@ impl PrivateKeyPartsNew for RsaPrivateKey {
539
572
/// Check that the public key is well formed and has an exponent within acceptable bounds.
540
573
#[ inline]
541
574
pub fn check_public ( public_key : & impl PublicKeyParts ) -> Result < ( ) > {
542
- check_public_with_max_size ( public_key, RsaPublicKey :: MAX_SIZE )
575
+ check_public_with_max_size ( & public_key. n ( ) , & public_key . e ( ) , RsaPublicKey :: MAX_SIZE )
543
576
}
544
577
545
578
/// Check that the public key is well formed and has an exponent within acceptable bounds.
546
579
#[ inline]
547
- fn check_public_with_max_size ( public_key : & impl PublicKeyParts , max_size : usize ) -> Result < ( ) > {
548
- if public_key . n ( ) . bits ( ) > max_size {
580
+ fn check_public_with_max_size ( n : & BigUint , e : & BigUint , max_size : usize ) -> Result < ( ) > {
581
+ if n . bits ( ) > max_size {
549
582
return Err ( Error :: ModulusTooLarge ) ;
550
583
}
551
584
552
- let e = public_key
553
- . e ( )
554
- . to_u64 ( )
555
- . ok_or ( Error :: PublicExponentTooLarge ) ?;
585
+ let eu64 = e. to_u64 ( ) . ok_or ( Error :: PublicExponentTooLarge ) ?;
556
586
557
- if public_key . e ( ) >= public_key . n ( ) || public_key . n ( ) . is_even ( ) {
587
+ if e >= n || n . is_even ( ) {
558
588
return Err ( Error :: InvalidModulus ) ;
559
589
}
560
590
561
- if public_key . e ( ) . is_even ( ) {
591
+ if e . is_even ( ) {
562
592
return Err ( Error :: InvalidExponent ) ;
563
593
}
564
594
565
- if e < RsaPublicKey :: MIN_PUB_EXPONENT {
595
+ if eu64 < RsaPublicKey :: MIN_PUB_EXPONENT {
566
596
return Err ( Error :: PublicExponentTooSmall ) ;
567
597
}
568
598
569
- if e > RsaPublicKey :: MAX_PUB_EXPONENT {
599
+ if eu64 > RsaPublicKey :: MAX_PUB_EXPONENT {
570
600
return Err ( Error :: PublicExponentTooLarge ) ;
571
601
}
572
602
@@ -577,12 +607,35 @@ pub(crate) fn to_biguint(uint: &BoxedUint) -> BigUint {
577
607
BigUint :: from_bytes_be ( & uint. to_be_bytes ( ) )
578
608
}
579
609
610
+ pub ( crate ) fn to_uint_exact ( big_uint : BigUint , nbits : usize ) -> BoxedUint {
611
+ let bytes = big_uint. to_bytes_be ( ) ;
612
+ let pad_count = Limb :: BYTES - ( bytes. len ( ) % Limb :: BYTES ) ;
613
+ let mut padded_bytes = vec ! [ 0u8 ; pad_count] ;
614
+ padded_bytes. extend_from_slice ( & bytes) ;
615
+
616
+ let res = BoxedUint :: from_be_slice ( & padded_bytes, padded_bytes. len ( ) * 8 ) . unwrap ( ) ;
617
+
618
+ match res. bits_precision ( ) . cmp ( & nbits) {
619
+ Ordering :: Equal => res,
620
+ Ordering :: Greater => panic ! ( "too large: {} > {}" , res. bits_precision( ) , nbits) ,
621
+ Ordering :: Less => res. widen ( nbits) ,
622
+ }
623
+ }
624
+
580
625
pub ( crate ) fn to_uint ( big_uint : BigUint ) -> BoxedUint {
626
+ let nbits = needed_bits ( & big_uint) ;
627
+
581
628
let bytes = big_uint. to_bytes_be ( ) ;
582
629
let pad_count = Limb :: BYTES - ( bytes. len ( ) % Limb :: BYTES ) ;
583
630
let mut padded_bytes = vec ! [ 0u8 ; pad_count] ;
584
631
padded_bytes. extend_from_slice ( & bytes) ;
585
- BoxedUint :: from_be_slice ( & padded_bytes, padded_bytes. len ( ) * 8 ) . unwrap ( )
632
+
633
+ let res = BoxedUint :: from_be_slice ( & padded_bytes, padded_bytes. len ( ) * 8 ) . unwrap ( ) ;
634
+
635
+ if res. bits ( ) < nbits {
636
+ return res. widen ( nbits) ;
637
+ }
638
+ res
586
639
}
587
640
588
641
pub ( crate ) fn reduce ( n : & BoxedUint , p : BoxedResidueParams ) -> BoxedResidue {
@@ -614,10 +667,10 @@ mod tests {
614
667
fn test_from_into ( ) {
615
668
let private_key = RsaPrivateKey {
616
669
pubkey_components : RsaPublicKey {
617
- n : NonZero :: new ( to_uint ( BigUint :: from_u64 ( 100 ) . unwrap ( ) ) ) . unwrap ( ) ,
618
- e : to_uint ( BigUint :: from_u64 ( 200 ) . unwrap ( ) ) ,
670
+ n : NonZero :: new ( to_uint ( BigUint :: from_u64 ( 100 ) . unwrap ( ) ) . widen ( 64 ) ) . unwrap ( ) ,
671
+ e : to_uint ( BigUint :: from_u64 ( 200 ) . unwrap ( ) ) . widen ( 64 ) ,
619
672
} ,
620
- d : to_uint ( BigUint :: from_u64 ( 123 ) . unwrap ( ) ) ,
673
+ d : to_uint ( BigUint :: from_u64 ( 123 ) . unwrap ( ) ) . widen ( 64 ) ,
621
674
primes : vec ! [ ] ,
622
675
precomputed : None ,
623
676
} ;
@@ -654,7 +707,8 @@ mod tests {
654
707
let mut rng = ChaCha8Rng :: from_seed( [ 42 ; 32 ] ) ;
655
708
let exp = BigUint :: from_u64( RsaPrivateKey :: EXP ) . expect( "invalid static exponent" ) ;
656
709
657
- for _ in 0 ..10 {
710
+ for i in 0 ..10 {
711
+ std:: dbg!( i, $size) ;
658
712
let components =
659
713
generate_multi_prime_key_with_exp( & mut rng, $multi, $size, & exp) . unwrap( ) ;
660
714
let private_key = RsaPrivateKey :: from_components(
0 commit comments