@@ -731,6 +731,10 @@ where
731731 . clone ( )
732732 . into_lwe_secret_key ( ) ;
733733
734+ //Computing and opening BK can take a while, so we increase the timeout.
735+ //This must be set before compression key generation, which internally generates a BK.
736+ session. network ( ) . set_timeout_for_bk ( ) . await ;
737+
734738 // Generate compression public keys if compression params exist
735739 let compression_keys =
736740 if let Some ( comp_params) = params_basics_handle. get_compression_decompression_params ( ) {
@@ -767,9 +771,6 @@ where
767771 )
768772 . await ?;
769773 tracing:: info!( "(Party {my_role}) Generating KSK...Done" ) ;
770-
771- //Computing and opening BK can take a while, so we increase the timeout
772- session. network ( ) . set_timeout_for_bk ( ) . await ;
773774 //Compute the bootstrapping keys
774775 let bk = generate_bootstrap_key (
775776 & private_key_set. glwe_secret_key_share ,
@@ -1009,6 +1010,10 @@ where
10091010 . clone ( )
10101011 . into_lwe_secret_key ( ) ;
10111012
1013+ //Computing and opening BK can take a while, so we increase the timeout.
1014+ //This must be set before compression key generation, which internally generates a BK.
1015+ session. network ( ) . set_timeout_for_bk ( ) . await ;
1016+
10121017 // Generate compression public keys if compression params exist
10131018 let compression_keys =
10141019 if let Some ( comp_params) = params_basics_handle. get_compression_decompression_params ( ) {
@@ -1047,9 +1052,6 @@ where
10471052 )
10481053 . await ?;
10491054 tracing:: info!( "(Party {my_role}) Generating KSK...Done" ) ;
1050-
1051- //Computing and opening BK can take a while, so we increase the timeout
1052- session. network ( ) . set_timeout_for_bk ( ) . await ;
10531055 //Compute the bootstrapping keys
10541056 let bk = generate_compressed_bootstrap_key (
10551057 & private_key_set. glwe_secret_key_share ,
@@ -1612,6 +1614,8 @@ pub mod conformance {
16121614#[ cfg( test) ]
16131615pub mod tests {
16141616 use super :: OnlineDistributedKeyGen ;
1617+ #[ cfg( feature = "slow_tests" ) ]
1618+ use crate :: execution:: runtime:: sessions:: base_session:: GenericBaseSessionHandles ;
16151619 use crate :: {
16161620 algebra:: {
16171621 base_ring:: { Z128 , Z64 } ,
@@ -1620,6 +1624,7 @@ pub mod tests {
16201624 } ,
16211625 execution:: {
16221626 endpoints:: keygen:: conformance:: check_drift_technique_key,
1627+ keyset_config:: StandardKeySetConfig ,
16231628 online:: preprocessing:: dummy:: DummyPreprocessing ,
16241629 runtime:: sessions:: {
16251630 large_session:: LargeSession , session_parameters:: GenericParameterHandles ,
@@ -2469,10 +2474,6 @@ pub mod tests {
24692474 use strum:: IntoEnumIterator ;
24702475 use tfhe:: shortint:: parameters:: CompressionParameters ;
24712476
2472- use crate :: execution:: runtime:: sessions:: {
2473- base_session:: GenericBaseSessionHandles ,
2474- session_parameters:: GenericParameterHandles ,
2475- } ;
24762477 for bound in crate :: execution:: tfhe_internals:: parameters:: NoiseBounds :: iter ( ) {
24772478 assert_eq ! ( 0 , dkg_preproc. noise_len( bound) ) ;
24782479 }
@@ -3244,4 +3245,185 @@ pub mod tests {
32443245 assert_eq ! ( clear_a. wrapping_add( clear_b) , dec) ;
32453246 }
32463247 }
3248+
3249+ /// Phase 1: normal keygen to obtain a `PrivateKeySet`, using dummy preproc
3250+ /// Phase 2: keygen from the existing `PrivateKeySet` to regenerate public keys
3251+ /// Saves the results (phase 1 private keys, phase 2 public keys) to file.
3252+ #[ cfg( feature = "slow_tests" ) ]
3253+ async fn run_dkg_from_existing_sk_and_save < const EXTENSION_DEGREE : usize > (
3254+ params : DKGParams ,
3255+ tag : tfhe:: Tag ,
3256+ num_parties : usize ,
3257+ threshold : usize ,
3258+ prefix_path : & Path ,
3259+ run_compressed : bool ,
3260+ ) where
3261+ ResiduePoly < Z128 , EXTENSION_DEGREE > : ErrorCorrect + Invert + Solve ,
3262+ ResiduePoly < Z64 , EXTENSION_DEGREE > : ErrorCorrect + Invert + Solve ,
3263+ {
3264+ let mut task = |mut session : SmallSession < ResiduePoly < Z128 , EXTENSION_DEGREE > > ,
3265+ tag : Option < String > | async move {
3266+ let my_role = session. my_role ( ) ;
3267+ let tag = tag
3268+ . map ( |s| {
3269+ let mut tag = tfhe:: Tag :: default ( ) ;
3270+ tag. set_data ( s. as_bytes ( ) ) ;
3271+ tag
3272+ } )
3273+ . unwrap_or_default ( ) ;
3274+
3275+ // Phase 1: normal keygen to obtain a PrivateKeySet,
3276+ // note that this is *not* compressed
3277+ let mut phase1_preproc = DummyPreprocessing :: new ( DUMMY_PREPROC_SEED , & session) ;
3278+ let ( _pk_phase1, sk) =
3279+ super :: SecureOnlineDistributedKeyGen128 :: < EXTENSION_DEGREE > :: keygen (
3280+ & mut session,
3281+ & mut phase1_preproc,
3282+ params,
3283+ tag. clone ( ) ,
3284+ None ,
3285+ )
3286+ . await
3287+ . unwrap ( ) ;
3288+
3289+ // Phase 2: regenerate public keys from the existing PrivateKeySet
3290+ let keyset_config = KeySetConfig :: Standard ( StandardKeySetConfig :: use_existing_sk ( ) ) ;
3291+ session
3292+ . network ( )
3293+ . set_timeout_for_next_round ( Duration :: from_secs ( 240 ) )
3294+ . await ;
3295+ let mut phase2_preproc =
3296+ generate_preproc_from_params ( & params, keyset_config, & mut session) . await ;
3297+
3298+ assert_ne ! ( 0 , phase2_preproc. bits_len( ) ) ;
3299+ assert_ne ! ( 0 , phase2_preproc. triples_len( ) ) ;
3300+ assert_ne ! ( 0 , phase2_preproc. randoms_len( ) ) ;
3301+ let pk = if run_compressed {
3302+ let compressed_pk =
3303+ super :: SecureOnlineDistributedKeyGen128 :: < EXTENSION_DEGREE > :: compressed_keygen_from_existing_private_keyset (
3304+ & mut session,
3305+ & mut phase2_preproc,
3306+ params,
3307+ tag,
3308+ Some ( & sk) ,
3309+ )
3310+ . await
3311+ . unwrap ( ) ;
3312+ let ( public_key, server_key) = compressed_pk. decompress ( ) . unwrap ( ) . into_raw_parts ( ) ;
3313+ FhePubKeySet {
3314+ public_key,
3315+ server_key,
3316+ }
3317+ } else {
3318+ super :: SecureOnlineDistributedKeyGen128 :: < EXTENSION_DEGREE > :: keygen_from_existing_private_keyset (
3319+ & mut session,
3320+ & mut phase2_preproc,
3321+ params,
3322+ tag,
3323+ Some ( & sk) ,
3324+ )
3325+ . await
3326+ . unwrap ( )
3327+ } ;
3328+
3329+ ( my_role, pk, sk)
3330+ } ;
3331+
3332+ let results =
3333+ execute_protocol_small :: < _ , _ , ResiduePoly < Z128 , EXTENSION_DEGREE > , EXTENSION_DEGREE > (
3334+ num_parties,
3335+ threshold as u8 ,
3336+ None ,
3337+ NetworkMode :: Sync ,
3338+ None ,
3339+ & mut task,
3340+ Some ( std:: str:: from_utf8 ( tag. as_slice ( ) ) . unwrap ( ) . to_string ( ) ) ,
3341+ )
3342+ . await ;
3343+
3344+ let pk_ref = results[ 0 ] . 1 . clone ( ) ;
3345+
3346+ for ( role, pk, sk) in results {
3347+ assert_eq ! ( pk, pk_ref) ;
3348+ write_element (
3349+ prefix_path. join ( format ! ( "sk_p{}.der" , role. one_based( ) ) ) ,
3350+ & sk,
3351+ )
3352+ . unwrap ( ) ;
3353+ }
3354+
3355+ write_element ( prefix_path. join ( "pk.der" ) , & pk_ref) . unwrap ( ) ;
3356+ }
3357+
3358+ /// Tests keygen from an existing private keyset using [`PARAMS_TEST_BK_SNS`].
3359+ /// Runs the two-phase DKG, then verifies the resulting keys with TFHE operations.
3360+ #[ cfg( feature = "slow_tests" ) ]
3361+ async fn integration_keygen_from_existing_test_bk_sns < const EXTENSION_DEGREE : usize > (
3362+ run_compressed : bool ,
3363+ ) where
3364+ ResiduePoly < Z64 , EXTENSION_DEGREE > : ErrorCorrect + Solve + Invert ,
3365+ ResiduePoly < Z128 , EXTENSION_DEGREE > : ErrorCorrect + Solve + Invert ,
3366+ {
3367+ let params = PARAMS_TEST_BK_SNS ;
3368+ let num_parties = 4 ;
3369+ let threshold = 1 ;
3370+ let temp_dir = tempfile:: tempdir ( ) . unwrap ( ) ;
3371+ let tag = {
3372+ let mut tag = tfhe:: Tag :: default ( ) ;
3373+ tag. set_data ( "hello tag" . as_bytes ( ) ) ;
3374+ tag
3375+ } ;
3376+
3377+ run_dkg_from_existing_sk_and_save :: < EXTENSION_DEGREE > (
3378+ params,
3379+ tag. clone ( ) ,
3380+ num_parties,
3381+ threshold,
3382+ temp_dir. path ( ) ,
3383+ run_compressed,
3384+ )
3385+ . await ;
3386+
3387+ run_switch_and_squash :: < EXTENSION_DEGREE > (
3388+ temp_dir. path ( ) ,
3389+ params. try_into ( ) . unwrap ( ) ,
3390+ tag. clone ( ) ,
3391+ num_parties,
3392+ threshold,
3393+ ) ;
3394+
3395+ run_tfhe_computation_shortint :: < EXTENSION_DEGREE , DKGParamsSnS > (
3396+ temp_dir. path ( ) ,
3397+ params,
3398+ num_parties,
3399+ threshold,
3400+ true ,
3401+ ) ;
3402+
3403+ run_tfhe_computation_fheuint :: < EXTENSION_DEGREE > (
3404+ temp_dir. path ( ) ,
3405+ params,
3406+ num_parties,
3407+ threshold,
3408+ true ,
3409+ true ,
3410+ ) ;
3411+
3412+ run_tag_test :: < EXTENSION_DEGREE > ( temp_dir. path ( ) , params, num_parties, threshold, & tag) ;
3413+ }
3414+
3415+ // #[tokio::test]
3416+ // #[serial_test::serial]
3417+ // #[cfg(feature = "slow_tests")]
3418+ // async fn keygen_from_existing_private_keyset_bk_sns_f4() {
3419+ // keygen_from_existing_test_bk_sns::<4>(false).await
3420+ // }
3421+
3422+ #[ tokio:: test]
3423+ #[ serial_test:: serial]
3424+ #[ cfg( feature = "slow_tests" ) ]
3425+ #[ tracing_test:: traced_test]
3426+ async fn integration_compressed_keygen_from_existing_private_keyset_bk_sns_f4 ( ) {
3427+ integration_keygen_from_existing_test_bk_sns :: < 4 > ( true ) . await
3428+ }
32473429}
0 commit comments