Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions willow/proto/willow/messages.proto
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import "willow/proto/zk/proofs.proto";
option java_multiple_files = true;
option java_outer_classname = "MessagesProto";


message ClientMessage {
ShellKaheCiphertext kahe_ciphertext = 1;
ShellAheCiphertext ahe_ciphertext = 2;
Expand All @@ -47,3 +48,20 @@ message DecryptionRequestContribution {
RlweRelationProofListProto proof = 2;
bytes nonce = 3;
}

message DecryptorStateProto {
ShellAheSecretKeyShare sk_share = 1;
}

message ServerStateProto {
map<string, ShellAhePublicKeyShare> decryptor_public_key_shares = 1;
ShellKaheCiphertext client_sum_kahe = 2;
ShellAheRecoverCiphertext client_sum_ahe_recover = 3;
ShellAhePartialDecryption partial_decryption_sum = 4;
}

message VerifierStateProto {
ShellAhePartialDecCiphertext partial_dec_ciphertext_sum = 1;
bytes nonce_lower_bound = 2;
bytes nonce_upper_bound = 3;
}
52 changes: 52 additions & 0 deletions willow/src/willow_v1/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -51,30 +51,76 @@ rust_test(
],
)

rust_test(
name = "willow_v1_decryptor_test",
crate = ":willow_v1_decryptor",
deps = [
"@crate_index//:googletest",
"//willow/src/shell:parameters_shell",
"//willow/src/shell:single_thread_hkdf",
"//willow/src/shell:vahe_shell",
"//willow/src/traits:ahe_traits",
"//willow/src/traits:decryptor_traits",
"//willow/src/traits:prng_traits",
"//willow/src/traits:proto_serialization_traits",
],
)

rust_library(
name = "willow_v1_decryptor",
srcs = [
"decryptor.rs",
],
deps = [
"@protobuf//rust:protobuf",
"//shell_wrapper:status",
"//willow/proto/shell:shell_ciphertexts_rust_proto",
"//willow/proto/willow:messages_rust_proto",
"//willow/src/traits:ahe_traits",
"//willow/src/traits:decryptor_traits",
"//willow/src/traits:messages",
"//willow/src/traits:proto_serialization_traits",
"//willow/src/traits:vahe_traits",
],
)

rust_test(
name = "willow_v1_server_test",
crate = ":willow_v1_server",
deps = [
":willow_v1_client",
":willow_v1_decryptor",
":willow_v1_verifier",
"@crate_index//:googletest",
"//willow/src/shell:kahe_shell",
"//willow/src/shell:parameters_shell",
"//willow/src/shell:single_thread_hkdf",
"//willow/src/shell:vahe_shell",
"//willow/src/testing_utils",
"//willow/src/traits:ahe_traits",
"//willow/src/traits:client_traits",
"//willow/src/traits:decryptor_traits",
"//willow/src/traits:prng_traits",
"//willow/src/traits:proto_serialization_traits",
"//willow/src/traits:server_traits",
"//willow/src/traits:verifier_traits",
],
)

rust_library(
name = "willow_v1_server",
srcs = [
"server.rs",
],
deps = [
"@protobuf//rust:protobuf",
"//shell_wrapper:status",
"//willow/proto/shell:shell_ciphertexts_rust_proto",
"//willow/proto/willow:messages_rust_proto",
"//willow/src/traits:ahe_traits",
"//willow/src/traits:kahe_traits",
"//willow/src/traits:messages",
"//willow/src/traits:proto_serialization_traits",
"//willow/src/traits:server_traits",
"//willow/src/traits:vahe_traits",
],
Expand All @@ -86,10 +132,14 @@ rust_library(
"verifier.rs",
],
deps = [
"@protobuf//rust:protobuf",
"//shell_wrapper:status",
"//willow/proto/shell:shell_ciphertexts_rust_proto",
"//willow/proto/willow:messages_rust_proto",
"//willow/src/traits:ahe_traits",
"//willow/src/traits:kahe_traits",
"//willow/src/traits:messages",
"//willow/src/traits:proto_serialization_traits",
"//willow/src/traits:vahe_traits",
"//willow/src/traits:verifier_traits",
],
Expand All @@ -105,6 +155,7 @@ rust_test(
"@crate_index//:googletest",
"//shell_wrapper:status_matchers_rs",
"//willow/src/shell:kahe_shell",
"//willow/src/shell:parameters_shell",
"//willow/src/shell:single_thread_hkdf",
"//willow/src/shell:vahe_shell",
"//willow/src/testing_utils",
Expand All @@ -114,6 +165,7 @@ rust_test(
"//willow/src/traits:decryptor_traits",
"//willow/src/traits:kahe_traits",
"//willow/src/traits:prng_traits",
"//willow/src/traits:proto_serialization_traits",
"//willow/src/traits:server_traits",
"//willow/src/traits:vahe_traits",
],
Expand Down
85 changes: 85 additions & 0 deletions willow/src/willow_v1/decryptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
use ahe_traits::{AheKeygen, PartialDec};
use decryptor_traits::SecureAggregationDecryptor;
use messages::{DecryptorPublicKeyShare, PartialDecryptionRequest, PartialDecryptionResponse};
use messages_rust_proto::DecryptorStateProto;
use proto_serialization_traits::{FromProto, ToProto};
use protobuf::{proto, AsView};
use shell_ciphertexts_rust_proto::ShellAheSecretKeyShare;
use status::StatusError;
use vahe_traits::{EncryptVerify, HasVahe, VaheBase};

/// Lightweight decryptor directly exposing KAHE/VAHE types. It verifies only the client proofs,
Expand All @@ -41,6 +46,45 @@ impl<Vahe: VaheBase> Default for DecryptorState<Vahe> {
}
}

impl<'a, C, Vahe> ToProto<&'a C> for DecryptorState<Vahe>
where
C: HasVahe<Vahe = Vahe>,
Vahe: VaheBase + 'a,
Vahe::SecretKeyShare: ToProto<&'a Vahe, Proto = ShellAheSecretKeyShare>,
{
type Proto = DecryptorStateProto;

fn to_proto(&self, context: &'a C) -> Result<Self::Proto, StatusError> {
let mut proto = DecryptorStateProto::new();
if let Some(sk) = &self.sk_share {
proto.set_sk_share(sk.to_proto(context.vahe())?);
}
Ok(proto)
}
}

impl<'a, C, Vahe> FromProto<&'a C> for DecryptorState<Vahe>
where
C: HasVahe<Vahe = Vahe>,
Vahe: VaheBase + 'a,
Vahe::SecretKeyShare: FromProto<&'a Vahe, Proto = ShellAheSecretKeyShare>,
{
type Proto = DecryptorStateProto;

fn from_proto(
proto: impl AsView<Proxied = Self::Proto>,
context: &'a C,
) -> Result<Self, StatusError> {
let proto = proto.as_view();
let sk_share = if proto.has_sk_share() {
Some(Vahe::SecretKeyShare::from_proto(proto.sk_share(), context.vahe())?)
} else {
None
};
Ok(DecryptorState { sk_share })
}
}

/// Implementation of the `SecureAggregationDecryptor` trait for the generic
/// KAHE/AHE decryptor, using WillowCommon as the common types (e.g. protocol
/// messages are directly the AHE public key and ciphertexts).
Expand Down Expand Up @@ -82,3 +126,44 @@ where
Ok(PartialDecryptionResponse { partial_decryption: pd })
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::{DecryptorState, WillowV1Decryptor};
use ahe_traits::AheBase;
use decryptor_traits::SecureAggregationDecryptor;
use googletest::{gtest, verify_true};
use parameters_shell::create_shell_ahe_config;
use prng_traits::SecurePrng;
use proto_serialization_traits::{FromProto, ToProto};
use single_thread_hkdf::SingleThreadHkdfPrng;
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 seed = SingleThreadHkdfPrng::generate_seed()?;
let prng = SingleThreadHkdfPrng::create(&seed)?;
let mut decryptor = WillowV1Decryptor { vahe, prng };
let mut decryptor_state = DecryptorState::default();

// Check empty state serialization.
let decryptor_state_proto = decryptor_state.to_proto(&decryptor)?;
let decryptor_state_roundtrip =
DecryptorState::from_proto(decryptor_state_proto, &decryptor)?;
verify_true!(decryptor_state_roundtrip.sk_share.is_none())?;

// Check populated state serialization.
decryptor.create_public_key_share(&mut decryptor_state)?;
verify_true!(decryptor_state.sk_share.is_some())?;
let decryptor_state_proto = decryptor_state.to_proto(&decryptor)?;
let decryptor_state_roundtrip =
DecryptorState::from_proto(decryptor_state_proto, &decryptor)?;
verify_true!(decryptor_state_roundtrip.sk_share.is_some())?;

Ok(())
}
}
Loading