Skip to content

Commit

Permalink
Added tests around ThresholdDecryptionRequest/Response and their encr…
Browse files Browse the repository at this point in the history
…ypted counterparts.
  • Loading branch information
derekpierre committed May 12, 2023
1 parent 1a25ce9 commit 28f72b1
Show file tree
Hide file tree
Showing 3 changed files with 185 additions and 3 deletions.
10 changes: 10 additions & 0 deletions nucypher-core-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,16 @@ impl E2EThresholdDecryptionRequest {
pub fn to_bytes(&self) -> Box<[u8]> {
to_bytes(self)
}

#[wasm_bindgen(getter, js_name=decryption_request)]
pub fn decryption_request(&self) -> ThresholdDecryptionRequest {
ThresholdDecryptionRequest::from(self.0.decryption_request.clone())
}

#[wasm_bindgen(getter, js_name=responseEncryptingKey)]
pub fn response_encrypting_key(&self) -> PublicKey {
PublicKey::from(self.0.response_encrypting_key)
}
}

//
Expand Down
81 changes: 81 additions & 0 deletions nucypher-core-wasm/tests/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -663,3 +663,84 @@ fn metadata_response() {
"MetadataResponse does not roundtrip"
);
}

//
// ThresholdDecryptionRequestResponse
//

#[wasm_bindgen_test]
fn threshold_decryption_request() {
let request_secret = SecretKey::random();
let request_encrypting_key = request_secret.public_key();

let response_secret = SecretKey::random();
let response_encrypting_key = response_secret.public_key();

let conditions: JsValue = Some(Conditions::new("{'some': 'condition'}")).into();
let context: JsValue = Some(Context::new("{'user': 'context'}")).into();

let request = ThresholdDecryptionRequest::new(
0,
0,
b"fake ciphertext",
&conditions.unchecked_into::<OptionConditions>(),
&context.unchecked_into::<OptionContext>(),
)
.unwrap();

let encrypted_request = request.encrypt(&request_encrypting_key, &response_encrypting_key);

let encrypted_request_bytes = encrypted_request.to_bytes();
let encrypted_request_from_bytes =
EncryptedThresholdDecryptionRequest::from_bytes(&encrypted_request_bytes).unwrap();

let e2e_request = encrypted_request_from_bytes
.decrypt(&request_secret)
.unwrap();
assert_eq!(
response_encrypting_key.to_compressed_bytes(),
e2e_request.response_encrypting_key().to_compressed_bytes()
);
assert_eq!(request, e2e_request.decryption_request());

// wrong secret key used
assert!(encrypted_request_from_bytes
.decrypt(&response_secret)
.is_err());

let random_secret_key = SecretKey::random();
assert!(encrypted_request_from_bytes
.decrypt(&random_secret_key)
.is_err());
}

#[wasm_bindgen_test]
fn threshold_decryption_response() {
let response_secret = SecretKey::random();
let response_encrypting_key = response_secret.public_key();

let decryption_share = b"The Tyranny of Merit";

let response = ThresholdDecryptionResponse::new(decryption_share).unwrap();

let encrypted_response = response.encrypt(&response_encrypting_key);
let encrypted_response_bytes = encrypted_response.to_bytes();

let encrypted_response_from_bytes =
EncryptedThresholdDecryptionResponse::from_bytes(&encrypted_response_bytes).unwrap();

let decrypted_response = encrypted_response_from_bytes
.decrypt(&response_secret)
.unwrap();
assert_eq!(response, decrypted_response);
assert_eq!(
response.decryption_share(),
decrypted_response.decryption_share()
);

// wrong secret key used
let random_secret_key = SecretKey::random();
assert!(encrypted_response_from_bytes
.decrypt(&random_secret_key)
.is_err());
}
97 changes: 94 additions & 3 deletions nucypher-core/src/dkg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,15 @@ impl<'a> ProtocolObject<'a> for ThresholdDecryptionRequest {}
/// A request for an Ursula to derive a decryption share that specifies the key to encrypt Ursula's response.
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
pub struct E2EThresholdDecryptionRequest {
decryption_request: ThresholdDecryptionRequest,
response_encrypting_key: PublicKey,
/// The decryption request.
pub decryption_request: ThresholdDecryptionRequest,
/// The key to encrypt the corresponding decryption response.
pub response_encrypting_key: PublicKey,
}

impl E2EThresholdDecryptionRequest {
/// Create E2E decryption request.
fn new(
pub fn new(
decryption_request: &ThresholdDecryptionRequest,
response_encrypting_key: &PublicKey,
) -> Self {
Expand Down Expand Up @@ -323,3 +325,92 @@ impl<'a> ProtocolObjectInner<'a> for EncryptedThresholdDecryptionResponse {
}

impl<'a> ProtocolObject<'a> for EncryptedThresholdDecryptionResponse {}

#[cfg(test)]
mod tests {
use umbral_pre::encrypt;
use umbral_pre::SecretKey;

use crate::{
Conditions, Context, EncryptedThresholdDecryptionRequest,
EncryptedThresholdDecryptionResponse, FerveoVariant, ProtocolObject,
ThresholdDecryptionRequest, ThresholdDecryptionResponse,
};

#[test]
fn threshold_decryption_request() {
let ritual_id = 0;

let request_secret = SecretKey::random();
let request_encrypting_key = request_secret.public_key();

let response_secret = SecretKey::random();
let response_encrypting_key = response_secret.public_key();

let random_secret_key = SecretKey::random();

let encryption_result = encrypt(&random_secret_key.public_key(), b"The Tyranny of Merit");

let (_capsule, _ciphertext) = encryption_result.unwrap();

let request = ThresholdDecryptionRequest::new(
ritual_id,
&_ciphertext,
Some(&Conditions::new("abcd")),
Some(&Context::new("efgh")),
FerveoVariant::SIMPLE,
);

let encrypted_request = request.encrypt(&request_encrypting_key, &response_encrypting_key);

let encrypted_request_bytes = encrypted_request.to_bytes();
let encrypted_request_from_bytes =
EncryptedThresholdDecryptionRequest::from_bytes(&encrypted_request_bytes).unwrap();

let e2e_request = encrypted_request_from_bytes
.decrypt(&request_secret)
.unwrap();
assert_eq!(response_encrypting_key, e2e_request.response_encrypting_key);
assert_eq!(request, e2e_request.decryption_request);

// wrong secret key used
assert!(encrypted_request_from_bytes
.decrypt(&response_secret)
.is_err());

assert!(encrypted_request_from_bytes
.decrypt(&random_secret_key)
.is_err());
}

#[test]
fn threshold_decryption_response() {
let response_secret = SecretKey::random();
let response_encrypting_key = response_secret.public_key();

let decryption_share = b"The Tyranny of Merit";

let response = ThresholdDecryptionResponse::new(decryption_share);

let encrypted_response = response.encrypt(&response_encrypting_key);

let encrypted_response_bytes = encrypted_response.to_bytes();
let encrypted_response_from_bytes =
EncryptedThresholdDecryptionResponse::from_bytes(&encrypted_response_bytes).unwrap();

let decrypted_response = encrypted_response_from_bytes
.decrypt(&response_secret)
.unwrap();
assert_eq!(response, decrypted_response);
assert_eq!(
response.decryption_share,
decrypted_response.decryption_share
);

// wrong secret key used
let random_secret_key = SecretKey::random();
assert!(encrypted_response_from_bytes
.decrypt(&random_secret_key)
.is_err());
}
}

0 comments on commit 28f72b1

Please sign in to comment.