diff --git a/willow/benches/shell_benchmarks.rs b/willow/benches/shell_benchmarks.rs index d9fc07d..2836eef 100644 --- a/willow/benches/shell_benchmarks.rs +++ b/willow/benches/shell_benchmarks.rs @@ -15,6 +15,7 @@ use clap::Parser; use std::collections::HashMap; use std::hint::black_box; +use std::rc::Rc; use std::time::Duration; use aggregation_config::AggregationConfig; @@ -126,25 +127,25 @@ fn setup_base(args: &Args) -> BaseInputs { let ahe_config = create_shell_ahe_config(aggregation_config.max_number_of_decryptors).unwrap(); let kahe_config = create_shell_kahe_config(&aggregation_config).unwrap(); + // Create common KAHE/VAHE instances. + let kahe = Rc::new(ShellKahe::new(kahe_config.clone(), CONTEXT_STRING).unwrap()); + let vahe = Rc::new(ShellVahe::new(ahe_config.clone(), CONTEXT_STRING).unwrap()); + // Create client. - let kahe = ShellKahe::new(kahe_config.clone(), CONTEXT_STRING).unwrap(); - let vahe = ShellVahe::new(ahe_config.clone(), CONTEXT_STRING).unwrap(); - let client = WillowV1Client::new_with_randomly_generated_seed(kahe, vahe).unwrap(); + let client = + WillowV1Client::new_with_randomly_generated_seed(Rc::clone(&kahe), Rc::clone(&vahe)) + .unwrap(); // Create decryptor. - let vahe = ShellVahe::new(ahe_config.clone(), CONTEXT_STRING).unwrap(); let mut decryptor_state = DecryptorState::default(); - let decryptor = WillowV1Decryptor::new_with_randomly_generated_seed(vahe).unwrap(); + let decryptor = WillowV1Decryptor::new_with_randomly_generated_seed(Rc::clone(&vahe)).unwrap(); // Create server. - let kahe = ShellKahe::new(kahe_config.clone(), CONTEXT_STRING).unwrap(); - let vahe = ShellVahe::new(ahe_config.clone(), CONTEXT_STRING).unwrap(); - let server = WillowV1Server { kahe, vahe }; + let server = WillowV1Server { kahe: Rc::clone(&kahe), vahe: Rc::clone(&vahe) }; let mut server_state = ServerState::default(); // Create verifier. - let vahe = ShellVahe::new(ahe_config.clone(), CONTEXT_STRING).unwrap(); - let verifier = WillowV1Verifier { vahe }; + let verifier = WillowV1Verifier { vahe: Rc::clone(&vahe) }; let verifier_state = VerifierState::default(); // Decryptor generates public key share. diff --git a/willow/src/api/client.rs b/willow/src/api/client.rs index c6f505b..fdcb128 100644 --- a/willow/src/api/client.rs +++ b/willow/src/api/client.rs @@ -28,6 +28,7 @@ use shell_ciphertexts_rust_proto::ShellAhePublicKey; use status::ffi::FfiStatus; use status::StatusError; use std::collections::HashMap; +use std::rc::Rc; use vahe_shell::ShellVahe; use willow_v1_client::WillowV1Client; @@ -82,8 +83,8 @@ impl WillowShellClient { let aggregation_config = AggregationConfig::from_proto(aggregation_config_proto, ())?; let (kahe_config, ahe_config) = create_shell_configs(&aggregation_config)?; let context_bytes = &aggregation_config.key_id; - let kahe = ShellKahe::new(kahe_config, &context_bytes)?; - let vahe = ShellVahe::new(ahe_config, &context_bytes)?; + let kahe = Rc::new(ShellKahe::new(kahe_config, &context_bytes)?); + let vahe = Rc::new(ShellVahe::new(ahe_config, &context_bytes)?); let client = WillowV1Client::new_with_randomly_generated_seed(kahe, vahe)?; Ok(WillowShellClient(client)) } @@ -102,7 +103,7 @@ impl WillowShellClient { } let public_key_proto = ShellAhePublicKey::parse(public_key.as_bytes()) .map_err(|e| status::internal(format!("Failed to parse ShellAhePublicKey: {}", e)))?; - let public_key_rust = PublicKey::from_proto(public_key_proto, &self.0.vahe)?; + let public_key_rust = PublicKey::from_proto(public_key_proto, self.0.vahe.as_ref())?; let message = self.0.create_client_message(&plaintext_slice, &public_key_rust, nonce)?; Ok(message .to_proto(&self.0)? diff --git a/willow/src/api/server_accumulator.rs b/willow/src/api/server_accumulator.rs index f98776a..ae62b8f 100644 --- a/willow/src/api/server_accumulator.rs +++ b/willow/src/api/server_accumulator.rs @@ -31,6 +31,7 @@ use server_traits::SecureAggregationServer; use status::StatusError; use std::collections::BTreeMap; use std::ops::Range; +use std::rc::Rc; use vahe_shell::ShellVahe; use verifier_traits::SecureAggregationVerifier; use willow_v1_server::{ServerState, WillowV1Server}; @@ -147,11 +148,10 @@ impl ServerAccumulator { fn new(aggregation_config: AggregationConfig) -> Result { let (kahe_config, vahe_config) = create_shell_configs(&aggregation_config)?; let context_bytes = &aggregation_config.key_id; - let server_kahe = ShellKahe::new(kahe_config, context_bytes)?; - let server_vahe = ShellVahe::new(vahe_config.clone(), context_bytes)?; - let verifier_vahe = ShellVahe::new(vahe_config, context_bytes)?; - let server = WillowV1Server { kahe: server_kahe, vahe: server_vahe }; - let verifier = WillowV1Verifier { vahe: verifier_vahe }; + let kahe = Rc::new(ShellKahe::new(kahe_config, &context_bytes)?); + let vahe = Rc::new(ShellVahe::new(vahe_config, &context_bytes)?); + let server = WillowV1Server { kahe: Rc::clone(&kahe), vahe: Rc::clone(&vahe) }; + let verifier = WillowV1Verifier { vahe }; Ok(Self { server: server, server_state: Default::default(), @@ -661,8 +661,8 @@ impl FinalResultDecryptor { let aggregation_config = AggregationConfig::from_proto(aggregation_config_proto, ())?; let (kahe_config, vahe_config) = create_shell_configs(&aggregation_config)?; let context_bytes = &aggregation_config.key_id; - let kahe = ShellKahe::new(kahe_config, context_bytes)?; - let vahe = ShellVahe::new(vahe_config, context_bytes)?; + let kahe = Rc::new(ShellKahe::new(kahe_config, context_bytes)?); + let vahe = Rc::new(ShellVahe::new(vahe_config, context_bytes)?); let server = WillowV1Server { kahe, vahe }; let server_state = ServerState::from_proto(server_state_proto, &server)?; diff --git a/willow/src/willow_v1/client.rs b/willow/src/willow_v1/client.rs index 4716c0c..089b854 100644 --- a/willow/src/willow_v1/client.rs +++ b/willow/src/willow_v1/client.rs @@ -17,33 +17,34 @@ use kahe_traits::{HasKahe, KaheBase, KaheEncrypt, KaheKeygen, TrySecretKeyInto}; use messages::{ClientMessage, DecryptorPublicKey}; use prng_traits::SecurePrng; use std::cell::RefCell; +use std::rc::Rc; use vahe_traits::{HasVahe, VaheBase, VerifiableEncrypt}; /// Lightweight client directly exposing KAHE/VAHE types. pub struct WillowV1Client { - pub kahe: Kahe, - pub vahe: Vahe, + pub kahe: Rc, + pub vahe: Rc, pub prng: RefCell, // Using a single PRNG for both VAHE and KAHE. } impl HasKahe for WillowV1Client { type Kahe = Kahe; fn kahe(&self) -> &Self::Kahe { - &self.kahe + self.kahe.as_ref() } } impl HasVahe for WillowV1Client { type Vahe = Vahe; fn vahe(&self) -> &Self::Vahe { - &self.vahe + self.vahe.as_ref() } } impl WillowV1Client { pub fn new_with_randomly_generated_seed( - kahe: Kahe, - vahe: Vahe, + kahe: Rc, + vahe: Rc, ) -> Result { let seed = Kahe::Rng::generate_seed()?; let prng = RefCell::new(Kahe::Rng::create(&seed)?); @@ -122,8 +123,8 @@ mod test { // Create a client. let (kahe_config, ahe_config) = create_shell_configs(&aggregation_config)?; - let kahe = ShellKahe::new(kahe_config, CONTEXT_STRING)?; - let vahe = ShellVahe::new(ahe_config, CONTEXT_STRING)?; + let kahe = Rc::new(ShellKahe::new(kahe_config, CONTEXT_STRING)?); + let vahe = Rc::new(ShellVahe::new(ahe_config, CONTEXT_STRING)?); let client = WillowV1Client::new_with_randomly_generated_seed(kahe, vahe)?; // Generate AHE keys. @@ -159,16 +160,14 @@ mod test { key_id: b"test".to_vec(), }; - // Create a client. + // Create common KAHE/VAHE instances. let (kahe_config, ahe_config) = create_shell_configs(&aggregation_config)?; - let kahe = ShellKahe::new(kahe_config, CONTEXT_STRING)?; - let vahe = ShellVahe::new(ahe_config, CONTEXT_STRING)?; - let client1 = WillowV1Client::new_with_randomly_generated_seed(kahe, vahe)?; + let kahe = Rc::new(ShellKahe::new(kahe_config, CONTEXT_STRING)?); + let vahe = Rc::new(ShellVahe::new(ahe_config, CONTEXT_STRING)?); - // Create a second client. - let (kahe_config, ahe_config) = create_shell_configs(&aggregation_config)?; - let kahe = ShellKahe::new(kahe_config, CONTEXT_STRING)?; - let vahe = ShellVahe::new(ahe_config, CONTEXT_STRING)?; + // Create clients. + let client1 = + WillowV1Client::new_with_randomly_generated_seed(Rc::clone(&kahe), Rc::clone(&vahe))?; let client2 = WillowV1Client::new_with_randomly_generated_seed(kahe, vahe)?; // Generate AHE keys. diff --git a/willow/src/willow_v1/decryptor.rs b/willow/src/willow_v1/decryptor.rs index 81b023e..b911c7d 100644 --- a/willow/src/willow_v1/decryptor.rs +++ b/willow/src/willow_v1/decryptor.rs @@ -22,12 +22,13 @@ use protobuf::AsView; use shell_ciphertexts_rust_proto::ShellAheSecretKeyShare; use status::StatusError; use std::cell::RefCell; +use std::rc::Rc; use vahe_traits::{EncryptVerify, HasVahe, VaheBase}; /// Lightweight decryptor directly exposing KAHE/VAHE types. It verifies only the client proofs, /// does not provide verifiable partial decryptions. pub struct WillowV1Decryptor { - pub vahe: Vahe, + pub vahe: Rc, pub prng: RefCell, } @@ -39,7 +40,7 @@ impl HasVahe for WillowV1Decryptor { } impl WillowV1Decryptor { - pub fn new_with_randomly_generated_seed(vahe: Vahe) -> Result { + pub fn new_with_randomly_generated_seed(vahe: Rc) -> Result { let seed = Vahe::Rng::generate_seed()?; let prng = RefCell::new(Vahe::Rng::create(&seed)?); Ok(Self { vahe, prng }) @@ -145,13 +146,15 @@ mod tests { use googletest::{gtest, verify_true}; use parameters_shell::create_shell_ahe_config; use proto_serialization_traits::{FromProto, ToProto}; + use std::rc::Rc; use vahe_shell::ShellVahe; const CONTEXT_STRING: &[u8] = b"testing_context_string"; #[gtest] fn decryptor_state_serialization_roundtrip() -> googletest::Result<()> { - let vahe = ShellVahe::new(create_shell_ahe_config(1).unwrap(), CONTEXT_STRING).unwrap(); + let vahe = + Rc::new(ShellVahe::new(create_shell_ahe_config(1).unwrap(), CONTEXT_STRING).unwrap()); let decryptor = WillowV1Decryptor::new_with_randomly_generated_seed(vahe)?; let mut decryptor_state = DecryptorState::default(); diff --git a/willow/src/willow_v1/server.rs b/willow/src/willow_v1/server.rs index d2110aa..85f3138 100644 --- a/willow/src/willow_v1/server.rs +++ b/willow/src/willow_v1/server.rs @@ -28,14 +28,15 @@ use shell_ciphertexts_rust_proto::{ }; use status::StatusError; use std::collections::HashMap; +use std::rc::Rc; use vahe_traits::{EncryptVerify, HasVahe, Recover, VaheBase}; /// Implements the `server` role in the Willow protocol. This includes aggregating public key shares /// from the decryptors, aggregating client ciphertexts, and recovering the aggregation result after /// receiving partial decryption responses from the decryptors. pub struct WillowV1Server { - pub kahe: Kahe, - pub vahe: Vahe, + pub kahe: Rc, + pub vahe: Rc, } impl HasKahe for WillowV1Server { @@ -381,45 +382,33 @@ mod tests { generate_aggregation_config(DEFAULT_VECTOR_ID.to_string(), 16, 10, 1, 1); let max_number_of_decryptors = aggregation_config.max_number_of_decryptors; - // Create client. - let kahe = + // Create common KAHE/VAHE instances. + let kahe = Rc::new( ShellKahe::new(create_shell_kahe_config(&aggregation_config).unwrap(), CONTEXT_STRING) - .unwrap(); - let vahe = ShellVahe::new( - create_shell_ahe_config(max_number_of_decryptors).unwrap(), - CONTEXT_STRING, - ) - .unwrap(); - let client = WillowV1Client::new_with_randomly_generated_seed(kahe, vahe)?; + .unwrap(), + ); + let vahe = Rc::new( + ShellVahe::new( + create_shell_ahe_config(max_number_of_decryptors).unwrap(), + CONTEXT_STRING, + ) + .unwrap(), + ); + + // Create client. + let client = WillowV1Client::new_with_randomly_generated_seed(kahe.clone(), vahe.clone())?; // Create decryptor. - let vahe = ShellVahe::new( - create_shell_ahe_config(max_number_of_decryptors).unwrap(), - CONTEXT_STRING, - ) - .unwrap(); + let mut decryptor_state = DecryptorState::default(); - let decryptor = WillowV1Decryptor::new_with_randomly_generated_seed(vahe)?; + let decryptor = WillowV1Decryptor::new_with_randomly_generated_seed(Rc::clone(&vahe))?; // Create server. - let kahe = - ShellKahe::new(create_shell_kahe_config(&aggregation_config).unwrap(), CONTEXT_STRING) - .unwrap(); - let vahe = ShellVahe::new( - create_shell_ahe_config(max_number_of_decryptors).unwrap(), - CONTEXT_STRING, - ) - .unwrap(); - let server = WillowV1Server { kahe, vahe }; + let server = WillowV1Server { kahe: kahe.clone(), vahe: Rc::clone(&vahe) }; let mut server_state = ServerState::default(); // Create verifier. - let vahe = ShellVahe::new( - create_shell_ahe_config(max_number_of_decryptors).unwrap(), - CONTEXT_STRING, - ) - .unwrap(); - let verifier = WillowV1Verifier { vahe }; + let verifier = WillowV1Verifier { vahe: vahe.clone() }; let mut verifier_state = VerifierState::default(); // Check empty state serialization diff --git a/willow/src/willow_v1/verifier.rs b/willow/src/willow_v1/verifier.rs index c887bc0..db63717 100644 --- a/willow/src/willow_v1/verifier.rs +++ b/willow/src/willow_v1/verifier.rs @@ -19,12 +19,13 @@ use protobuf::{proto, AsView}; use shell_ciphertexts_rust_proto::ShellAhePartialDecCiphertext; use status::StatusError; use std::fmt::Debug; +use std::rc::Rc; use vahe_traits::{EncryptVerify, HasVahe, VaheBase}; use verifier_traits::SecureAggregationVerifier; /// The verifier struct, containing a WillowCommon instance. pub struct WillowV1Verifier { - pub vahe: Vahe, + pub vahe: Rc, } impl HasVahe for WillowV1Verifier { @@ -294,46 +295,34 @@ mod tests { generate_aggregation_config(DEFAULT_VECTOR_ID.to_string(), 16, 10, 1, 1); let max_number_of_decryptors = aggregation_config.max_number_of_decryptors; - // Create client. - let kahe = + // Create common KAHE/VAHE instances. + let kahe = Rc::new( ShellKahe::new(create_shell_kahe_config(&aggregation_config).unwrap(), CONTEXT_STRING) + .unwrap(), + ); + let vahe = Rc::new( + ShellVahe::new( + create_shell_ahe_config(max_number_of_decryptors).unwrap(), + CONTEXT_STRING, + ) + .unwrap(), + ); + + // Create client. + let client = + WillowV1Client::new_with_randomly_generated_seed(Rc::clone(&kahe), Rc::clone(&vahe)) .unwrap(); - let vahe = ShellVahe::new( - create_shell_ahe_config(max_number_of_decryptors).unwrap(), - CONTEXT_STRING, - ) - .unwrap(); - let client = WillowV1Client::new_with_randomly_generated_seed(kahe, vahe)?; - - // Create decryptor, which needs its own `vahe` (with same public polynomials - // generated from the seeds) and `prng`. - let vahe = ShellVahe::new( - create_shell_ahe_config(max_number_of_decryptors).unwrap(), - CONTEXT_STRING, - ) - .unwrap(); + + // Create decryptor. let mut decryptor_state = DecryptorState::default(); - let decryptor = WillowV1Decryptor::new_with_randomly_generated_seed(vahe)?; + let decryptor = WillowV1Decryptor::new_with_randomly_generated_seed(Rc::clone(&vahe))?; // Create server. - let kahe = - ShellKahe::new(create_shell_kahe_config(&aggregation_config).unwrap(), CONTEXT_STRING) - .unwrap(); - let vahe = ShellVahe::new( - create_shell_ahe_config(max_number_of_decryptors).unwrap(), - CONTEXT_STRING, - ) - .unwrap(); - let server = WillowV1Server { kahe, vahe }; + let server = WillowV1Server { kahe: Rc::clone(&kahe), vahe: Rc::clone(&vahe) }; let mut server_state = ServerState::default(); // Create verifier. - let vahe = ShellVahe::new( - create_shell_ahe_config(max_number_of_decryptors).unwrap(), - CONTEXT_STRING, - ) - .unwrap(); - let verifier = WillowV1Verifier { vahe }; + let verifier = WillowV1Verifier { vahe: Rc::clone(&vahe) }; // Decryptor generates public key share. let public_key_share = decryptor.create_public_key_share(&mut decryptor_state)?; diff --git a/willow/tests/willow_v1_shell.rs b/willow/tests/willow_v1_shell.rs index 56ff8c9..7a36630 100644 --- a/willow/tests/willow_v1_shell.rs +++ b/willow/tests/willow_v1_shell.rs @@ -29,6 +29,7 @@ use server_traits::SecureAggregationServer; use status::StatusErrorCode; use status_matchers_rs::status_is; use std::collections::HashMap; +use std::rc::Rc; use testing_utils::{ generate_aggregation_config, generate_random_nonce, generate_random_unsigned_vector, }; @@ -48,38 +49,30 @@ fn encrypt_decrypt_one() -> googletest::Result<()> { let aggregation_config = generate_aggregation_config(default_id.clone(), 16, 10, 1, 1); let max_number_of_decryptors = aggregation_config.max_number_of_decryptors; - // Create client. - let vahe = + // Create common KAHE/VAHE instances. + let vahe = Rc::new( ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) - .unwrap(); - let kahe = + .unwrap(), + ); + let kahe = Rc::new( ShellKahe::new(create_shell_kahe_config(&aggregation_config).unwrap(), CONTEXT_STRING) - .unwrap(); - let client = WillowV1Client::new_with_randomly_generated_seed(kahe, vahe).unwrap(); + .unwrap(), + ); - // Create decryptor, which needs its own `vahe` (with same public polynomials - // generated from the seeds) and `prng`. - let vahe = - ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) + // Create client. + let client = + WillowV1Client::new_with_randomly_generated_seed(Rc::clone(&kahe), Rc::clone(&vahe)) .unwrap(); + let mut decryptor_state = DecryptorState::default(); - let decryptor = WillowV1Decryptor::new_with_randomly_generated_seed(vahe).unwrap(); + let decryptor = WillowV1Decryptor::new_with_randomly_generated_seed(Rc::clone(&vahe)).unwrap(); // Create server. - let vahe = - ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) - .unwrap(); - let kahe = - ShellKahe::new(create_shell_kahe_config(&aggregation_config).unwrap(), CONTEXT_STRING) - .unwrap(); - let server = WillowV1Server { kahe, vahe }; + let server = WillowV1Server { kahe: Rc::clone(&kahe), vahe: Rc::clone(&vahe) }; let mut server_state = ServerState::default(); // Create verifier. - let vahe = - ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) - .unwrap(); - let verifier = WillowV1Verifier { vahe }; + let verifier = WillowV1Verifier { vahe: Rc::clone(&vahe) }; let mut verifier_state = VerifierState::default(); // Decryptor generates public key share. @@ -134,47 +127,43 @@ fn encrypt_decrypt_one_serialized() -> googletest::Result<()> { let aggregation_config = generate_aggregation_config(default_id.clone(), 16, 10, 1, 1); let max_number_of_decryptors = aggregation_config.max_number_of_decryptors; - // Create client. - let kahe = + // Create common KAHE/VAHE instances. + let kahe = Rc::new( ShellKahe::new(create_shell_kahe_config(&aggregation_config).unwrap(), CONTEXT_STRING) - .unwrap(); - let vahe = + .unwrap(), + ); + let vahe = Rc::new( ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) - .unwrap(); - let client = WillowV1Client::new_with_randomly_generated_seed(kahe, vahe).unwrap(); + .unwrap(), + ); - // Create decryptor, which needs its own `vahe` (with same public polynomials - // generated from the seeds) and `prng`. - let vahe = - ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) + // Create client. + let client = + WillowV1Client::new_with_randomly_generated_seed(Rc::clone(&kahe), Rc::clone(&vahe)) .unwrap(); + + // Create decryptor. let mut decryptor_state = DecryptorState::default(); - let decryptor = WillowV1Decryptor::new_with_randomly_generated_seed(vahe).unwrap(); + let decryptor = WillowV1Decryptor::new_with_randomly_generated_seed(Rc::clone(&vahe)).unwrap(); // Create server. - let kahe = - ShellKahe::new(create_shell_kahe_config(&aggregation_config).unwrap(), CONTEXT_STRING) - .unwrap(); - let vahe = - ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) - .unwrap(); - let server = WillowV1Server { kahe, vahe }; + let server = WillowV1Server { kahe: Rc::clone(&kahe), vahe: Rc::clone(&vahe) }; let mut server_state = ServerState::default(); // Create verifier. - let vahe = - ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) - .unwrap(); - let verifier = WillowV1Verifier { vahe }; + let verifier = WillowV1Verifier { vahe: Rc::clone(&vahe) }; let mut verifier_state = VerifierState::default(); // Decryptor generates public key share. let public_key_share = decryptor.create_public_key_share(&mut decryptor_state).unwrap(); // Serialize and deserialize the public key share. - let public_key_share_proto = public_key_share.to_proto(&decryptor.vahe)?; + let public_key_share_proto = public_key_share.to_proto(decryptor.vahe.as_ref())?; let public_key_share: DecryptorPublicKeyShare = - DecryptorPublicKeyShare::::from_proto(public_key_share_proto, &server.vahe)?; + DecryptorPublicKeyShare::::from_proto( + public_key_share_proto, + server.vahe.as_ref(), + )?; // Server handles the public key share. server @@ -185,9 +174,11 @@ fn encrypt_decrypt_one_serialized() -> googletest::Result<()> { let public_key = server.create_decryptor_public_key(&server_state).unwrap(); // Serialize and deserialize the public key. - let public_key_proto = public_key.to_proto(&server.vahe)?; - let public_key = - messages::DecryptorPublicKey::::from_proto(public_key_proto, &client.vahe)?; + let public_key_proto = public_key.to_proto(server.vahe.as_ref())?; + let public_key = messages::DecryptorPublicKey::::from_proto( + public_key_proto, + client.vahe.as_ref(), + )?; // Client encrypts. let client_plaintext = @@ -266,44 +257,35 @@ fn encrypt_decrypt_multiple_clients() -> googletest::Result<()> { generate_aggregation_config(default_id.clone(), 16, 10, 1, NUM_CLIENTS); let max_number_of_decryptors = aggregation_config.max_number_of_decryptors; + // Create common KAHE/VAHE instances. + let vahe = Rc::new( + ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) + .unwrap(), + ); + let kahe = Rc::new( + ShellKahe::new(create_shell_kahe_config(&aggregation_config).unwrap(), CONTEXT_STRING) + .unwrap(), + ); + // Create clients. let mut clients = vec![]; for _ in 0..NUM_CLIENTS { - let vahe = ShellVahe::new( - create_shell_ahe_config(max_number_of_decryptors).unwrap(), - CONTEXT_STRING, - ) - .unwrap(); - let kahe = - ShellKahe::new(create_shell_kahe_config(&aggregation_config).unwrap(), CONTEXT_STRING) + let client = + WillowV1Client::new_with_randomly_generated_seed(Rc::clone(&kahe), Rc::clone(&vahe)) .unwrap(); - let client = WillowV1Client::new_with_randomly_generated_seed(kahe, vahe).unwrap(); clients.push(client); } - // Create decryptor, which needs its own `vahe` (with same public polynomials - // generated from the seeds) and `prng`. - let vahe = - ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) - .unwrap(); + // Create decryptor. let mut decryptor_state = DecryptorState::default(); - let decryptor = WillowV1Decryptor::new_with_randomly_generated_seed(vahe).unwrap(); + let decryptor = WillowV1Decryptor::new_with_randomly_generated_seed(Rc::clone(&vahe)).unwrap(); // Create server. - let vahe = - ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) - .unwrap(); - let kahe = - ShellKahe::new(create_shell_kahe_config(&aggregation_config).unwrap(), CONTEXT_STRING) - .unwrap(); - let server = WillowV1Server { kahe, vahe }; + let server = WillowV1Server { kahe: Rc::clone(&kahe), vahe: Rc::clone(&vahe) }; let mut server_state = ServerState::default(); // Create verifier. - let vahe = - ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) - .unwrap(); - let verifier = WillowV1Verifier { vahe }; + let verifier = WillowV1Verifier { vahe: Rc::clone(&vahe) }; let mut verifier_state = VerifierState::default(); // Decryptor generates public key share. @@ -395,59 +377,44 @@ fn encrypt_decrypt_multiple_clients_including_invalid_proofs() -> googletest::Re generate_aggregation_config(default_id.clone(), 16, 10, 1, NUM_MAX_CLIENTS); let max_number_of_decryptors = aggregation_config.max_number_of_decryptors; + // Create common KAHE/VAHE instances. + let vahe = Rc::new( + ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) + .unwrap(), + ); + let kahe = Rc::new( + ShellKahe::new(create_shell_kahe_config(&aggregation_config).unwrap(), CONTEXT_STRING) + .unwrap(), + ); + // Create clients. let mut good_clients = vec![]; for _ in 0..NUM_GOOD_CLIENTS { - let vahe = ShellVahe::new( - create_shell_ahe_config(max_number_of_decryptors).unwrap(), - CONTEXT_STRING, - ) - .unwrap(); - let kahe = - ShellKahe::new(create_shell_kahe_config(&aggregation_config).unwrap(), CONTEXT_STRING) + let client = + WillowV1Client::new_with_randomly_generated_seed(Rc::clone(&kahe), Rc::clone(&vahe)) .unwrap(); - let client = WillowV1Client::new_with_randomly_generated_seed(kahe, vahe).unwrap(); good_clients.push(client); } // Create bad clients. let mut bad_clients = vec![]; for _ in 0..NUM_BAD_CLIENTS { - let vahe = ShellVahe::new( - create_shell_ahe_config(max_number_of_decryptors).unwrap(), - CONTEXT_STRING, - ) - .unwrap(); - let kahe = - ShellKahe::new(create_shell_kahe_config(&aggregation_config).unwrap(), CONTEXT_STRING) + let client = + WillowV1Client::new_with_randomly_generated_seed(Rc::clone(&kahe), Rc::clone(&vahe)) .unwrap(); - let client = WillowV1Client::new_with_randomly_generated_seed(kahe, vahe).unwrap(); bad_clients.push(client); } - // Create decryptor, which needs its own `vahe` (with same public polynomials - // generated from the seeds) and `prng`. - let vahe = - ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) - .unwrap(); + // Create decryptor. let mut decryptor_state = DecryptorState::default(); - let decryptor = WillowV1Decryptor::new_with_randomly_generated_seed(vahe).unwrap(); + let decryptor = WillowV1Decryptor::new_with_randomly_generated_seed(Rc::clone(&vahe)).unwrap(); // Create server. - let vahe = - ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) - .unwrap(); - let kahe = - ShellKahe::new(create_shell_kahe_config(&aggregation_config).unwrap(), CONTEXT_STRING) - .unwrap(); - let server = WillowV1Server { kahe, vahe }; + let server = WillowV1Server { kahe: Rc::clone(&kahe), vahe: Rc::clone(&vahe) }; let mut server_state = ServerState::default(); // Create verifier. - let vahe = - ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) - .unwrap(); - let verifier = WillowV1Verifier { vahe }; + let verifier = WillowV1Verifier { vahe: Rc::clone(&vahe) }; let mut verifier_state = VerifierState::default(); // Decryptor generates public key share. @@ -569,35 +536,31 @@ fn encrypt_decrypt_many_clients_decryptors() -> googletest::Result<()> { // here anyway, we set `max_number_of_decryptors` to 1 just to obtain the AHE parameters. let max_number_of_decryptors = 1; - // Create server. - let vahe = + // Create common KAHE/VAHE instances. + let vahe = Rc::new( ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) - .unwrap(); - let kahe = + .unwrap(), + ); + let kahe = Rc::new( ShellKahe::new(create_shell_kahe_config(&aggregation_config).unwrap(), CONTEXT_STRING) - .unwrap(); - let server = WillowV1Server { kahe, vahe }; + .unwrap(), + ); + + // Create server. + let server = WillowV1Server { kahe: Rc::clone(&kahe), vahe: Rc::clone(&vahe) }; let mut server_state = ServerState::default(); // Create verifier. - let vahe = - ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) - .unwrap(); - let verifier = WillowV1Verifier { vahe }; + let verifier = WillowV1Verifier { vahe: Rc::clone(&vahe) }; let mut verifier_state = VerifierState::default(); - // Create decryptors, which needs their own `vahe` (with same public - // polynomials generated from the seeds) and `prng`. + // Create decryptors. let mut decryptors = vec![]; let mut decryptor_states = vec![]; for i in 0..NUM_DECRYPTORS { - let vahe = ShellVahe::new( - create_shell_ahe_config(max_number_of_decryptors).unwrap(), - CONTEXT_STRING, - ) - .unwrap(); let mut decryptor_state = DecryptorState::default(); - let decryptor = WillowV1Decryptor::new_with_randomly_generated_seed(vahe).unwrap(); + let decryptor = + WillowV1Decryptor::new_with_randomly_generated_seed(Rc::clone(&vahe)).unwrap(); // Decryptor generates public key share. let public_key_share = decryptor.create_public_key_share(&mut decryptor_state).unwrap(); @@ -622,15 +585,9 @@ fn encrypt_decrypt_many_clients_decryptors() -> googletest::Result<()> { let mut expected_output = vec![0; INPUT_LENGTH as usize]; let mut client_messages = vec![]; for _ in 0..NUM_CLIENTS { - let vahe = ShellVahe::new( - create_shell_ahe_config(max_number_of_decryptors).unwrap(), - CONTEXT_STRING, - ) - .unwrap(); - let kahe = - ShellKahe::new(create_shell_kahe_config(&aggregation_config).unwrap(), CONTEXT_STRING) + let client = + WillowV1Client::new_with_randomly_generated_seed(Rc::clone(&kahe), Rc::clone(&vahe)) .unwrap(); - let client = WillowV1Client::new_with_randomly_generated_seed(kahe, vahe).unwrap(); let client_input_values = generate_random_unsigned_vector(INPUT_LENGTH as usize, INPUT_DOMAIN as u64); @@ -695,52 +652,42 @@ fn encrypt_decrypt_no_dropout() -> googletest::Result<()> { // here anyway, we set `max_number_of_decryptors` to 1 just to obtain the AHE parameters. let max_number_of_decryptors = 1; + // Create common KAHE/VAHE instances. + let vahe = Rc::new( + ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) + .unwrap(), + ); + let kahe = Rc::new( + ShellKahe::new(create_shell_kahe_config(&aggregation_config).unwrap(), CONTEXT_STRING) + .unwrap(), + ); + // Create clients. let mut clients = vec![]; for _ in 0..NUM_CLIENTS { - let vahe = ShellVahe::new( - create_shell_ahe_config(max_number_of_decryptors).unwrap(), - CONTEXT_STRING, - ) - .unwrap(); - let kahe = - ShellKahe::new(create_shell_kahe_config(&aggregation_config).unwrap(), CONTEXT_STRING) + let client = + WillowV1Client::new_with_randomly_generated_seed(Rc::clone(&kahe), Rc::clone(&vahe)) .unwrap(); - let client = WillowV1Client::new_with_randomly_generated_seed(kahe, vahe).unwrap(); clients.push(client); } - // Create decryptors, which need their own `vahe` (with same public polynomials - // generated from the seeds) and `prng`. + // Create decryptors. let mut decryptor_states = vec![]; let mut decryptors = vec![]; for _ in 0..NUM_DECRYPTORS { - let vahe = ShellVahe::new( - create_shell_ahe_config(max_number_of_decryptors).unwrap(), - CONTEXT_STRING, - ) - .unwrap(); let decryptor_state = DecryptorState::default(); - let decryptor = WillowV1Decryptor::new_with_randomly_generated_seed(vahe).unwrap(); + let decryptor = + WillowV1Decryptor::new_with_randomly_generated_seed(Rc::clone(&vahe)).unwrap(); decryptor_states.push(decryptor_state); decryptors.push(decryptor); } // Create server. - let vahe = - ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) - .unwrap(); - let kahe = - ShellKahe::new(create_shell_kahe_config(&aggregation_config).unwrap(), CONTEXT_STRING) - .unwrap(); - let server = WillowV1Server { kahe, vahe }; + let server = WillowV1Server { kahe: Rc::clone(&kahe), vahe: Rc::clone(&vahe) }; let mut server_state = ServerState::default(); // Create verifier. - let vahe = - ShellVahe::new(create_shell_ahe_config(max_number_of_decryptors).unwrap(), CONTEXT_STRING) - .unwrap(); - let verifier = WillowV1Verifier { vahe }; + let verifier = WillowV1Verifier { vahe: Rc::clone(&vahe) }; let mut verifier_state = VerifierState::default(); // Decryptors generate public key shares.