// needed to remove wasm_bindgen warnings
#![allow(non_upper_case_globals)]
#![allow(clippy::unused_unit)]
// Wait for `wasm-bindgen` issue 2774: https://github.com/rustwasm/wasm-bindgen/issues/2774
use super::{
generate_gpsw_keys::{webassembly_generate_master_keys, webassembly_generate_user_private_key},
hybrid_gpsw_aes_decryption::{
webassembly_decrypt_hybrid_block, webassembly_decrypt_hybrid_header,
},
hybrid_gpsw_aes_encryption::{
webassembly_encrypt_hybrid_block, webassembly_encrypt_hybrid_header, MAX_CLEAR_TEXT_SIZE,
},
};
use crate::{
core::{
bilinear_map::bls12_381::Bls12_381,
gpsw::{
scheme::{GpswMasterPrivateKey, GpswMasterPublicKey},
AbeScheme, AsBytes, Gpsw,
},
},
interfaces::hybrid_crypto::{
decrypt_hybrid_block, decrypt_hybrid_header, encrypt_hybrid_header, ClearTextHeader,
EncryptedHeader,
},
};
use abe_policy::{Attributes, Policy, PolicyAxis};
use cosmian_crypto_base::{
symmetric_crypto::{aes_256_gcm_pure::Aes256GcmCrypto, Metadata, SymmetricCrypto},
KeyTrait,
};
use js_sys::Uint8Array;
use serde_json::Value;
use std::convert::{TryFrom, TryInto};
use wasm_bindgen::JsValue;
use wasm_bindgen_test::wasm_bindgen_test;
type UserDecryptionKey = <Gpsw<Bls12_381> as AbeScheme>::UserDecryptionKey;
type PublicKey = <Gpsw<Bls12_381> as AbeScheme>::MasterPublicKey;
fn create_test_policy() -> Policy {
//
// Policy settings
//
let mut policy = Policy::new(100);
policy
.add_axis(&PolicyAxis::new(
"Security Level",
&["Protected", "Confidential", "Top Secret"],
true,
))
.unwrap();
policy
.add_axis(&PolicyAxis::new(
"Department",
&["R&D", "HR", "MKG", "FIN"],
false,
))
.unwrap();
policy
}
#[wasm_bindgen_test]
fn test_generate_keys() {
//
// Policy settings
//
let policy = create_test_policy();
let serialized_policy = serde_json::to_vec(&policy).unwrap();
//
// Generate master keys
let master_keys =
webassembly_generate_master_keys(Uint8Array::from(serialized_policy.as_slice())).unwrap();
let master_keys_vec = master_keys.to_vec();
let private_key_size = u32::from_be_bytes(master_keys_vec[0..4].try_into().unwrap());
let private_key_bytes = &master_keys_vec[4..4 + private_key_size as usize];
//
// Check deserialization
GpswMasterPrivateKey::<Bls12_381>::try_from_bytes(private_key_bytes).unwrap();
GpswMasterPublicKey::<Bls12_381>::try_from_bytes(
&master_keys_vec[4 + private_key_size as usize..],
)
.unwrap();
//
// Generate user private key
webassembly_generate_user_private_key(
Uint8Array::from(private_key_bytes),
"Department::FIN && Security Level::Top Secret",
Uint8Array::from(serialized_policy.as_slice()),
)
.unwrap();
}
#[wasm_bindgen_test]
pub fn test_decrypt_hybrid_header() {
let public_key_json: Value = serde_json::from_str(include_str!(
"../hybrid_crypto/tests/public_master_key.json"
))
.unwrap();
let key_value = &public_key_json["value"][0]["value"][1]["value"];
// Public Key bytes
let hex_key = &key_value[0]["value"].as_str().unwrap();
let public_key = PublicKey::try_from_bytes(&hex::decode(hex_key).unwrap()).unwrap();
// Policy
let policy_hex = &key_value[1]["value"][4]["value"][0]["value"][2]["value"]
.as_str()
.unwrap();
let policy: Policy = serde_json::from_slice(&hex::decode(policy_hex).unwrap()).unwrap();
let policy_attributes =
Attributes::try_from("Department::FIN, Security Level::Top Secret").unwrap();
let meta_data = Metadata {
uid: vec![1, 2, 3, 4, 5, 6, 7, 8, 9],
additional_data: Some(vec![10, 11, 12, 13, 14]),
};
let encrypted_header = encrypt_hybrid_header::<Gpsw<Bls12_381>, Aes256GcmCrypto>(
&policy,
&public_key,
&policy_attributes,
Some(meta_data),
)
.unwrap();
//
// Check webassembly function
let user_decryption_key_json: Value = serde_json::from_str(include_str!(
"../hybrid_crypto/tests/fin_top_secret_user_key.json"
))
.unwrap();
let key_value = &user_decryption_key_json["value"][0]["value"][1]["value"];
let hex_key = &key_value[0]["value"].as_str().unwrap();
let user_decryption_key_bytes = hex::decode(hex_key).unwrap();
// Prepare JS inputs
let user_decryption_key_js = Uint8Array::from(user_decryption_key_bytes.as_slice());
let encrypted_header_js = Uint8Array::from(encrypted_header.encrypted_header_bytes.as_slice());
let cleartext_header_bytes =
webassembly_decrypt_hybrid_header(user_decryption_key_js, encrypted_header_js).unwrap();
let _cleartext_header =
ClearTextHeader::<Aes256GcmCrypto>::try_from_bytes(&cleartext_header_bytes.to_vec()[..])
.unwrap();
}
#[wasm_bindgen_test]
pub fn test_non_reg_decrypt_hybrid_block() {
let symmetric_key_bytes =
hex::decode("802de96f19589fbc0eb2f26705dc1ed261e9c80f2fec301ca7d0ecea3176405b").unwrap();
let uid_bytes =
hex::decode("cd8ca2eeb654b5f39f347f4e3f91b3a15c450c1e52c40716237b4c18510f65b4").unwrap();
let encrypted_bytes = hex::decode("e09ba17fdff90afbb18546211268b8aef6517a73b701283ab334c0720372f565c751a311c1ec09a6bbb070f8a1961ca3f048b280ea36a578a0068edea8408f3cf4ab26f5a71933dffed384ea7d33e42c16fe17a1026937a345386bb980917d6d2175a48b6d69e8322689dde0bf99cee9d2da5bbee1f29b2005725b6969021462e6608284a5135677b03d8fcce03563cc4d8988f455d27b95ef62080f4c2f18e7897636ac69e9d216668765d2025f66c805d549c4ef779c32ac3286bee8d35c1b758b51f1686d2aea996cc1f3bfff2aea7d605cce963e5bc69f77f284a1c05b803df08fcdec6a6d4f0c74ad8f6076d9ca692642dcdff64a34d1fbbb4d57aea776ce8032b03d63c9e376377fb95725b6d3ac6be3a29f47d15eb22b5c81bf6168785844da8d22914076415957d9e253142f14c5c68fbe1108d74832e2347425f89b46321ac0c7b939f793e3c39e5dbb83d9e6be29db4aa3df0e645cc859aac9a0324d546b70856e2ae89c77b87a8e25eac90f9265642bbd8c407f0aa307aef613bd79fa8fd6c959c959007791621e5fe047edfcadae2c195bb681b6621a9583c8d51911e39df50331b495b603fbf826eebeffe26cd2bc0287a280801bc54cfa9fed1279a58843bb8ea1262982753481dc61852cca49279d0de5e287f6a43dca38").unwrap();
let symmetric_key_js = Uint8Array::from(symmetric_key_bytes.as_slice());
let uid_js = Uint8Array::from(uid_bytes.as_slice());
let encrypted_js = Uint8Array::from(encrypted_bytes.as_slice());
webassembly_decrypt_hybrid_block(symmetric_key_js, Some(uid_js), Some(0), encrypted_js)
.unwrap();
}
#[wasm_bindgen_test]
pub fn test_encrypt_hybrid_header() {
let public_key_json: Value = serde_json::from_str(include_str!(
"../hybrid_crypto/tests/public_master_key.json"
))
.unwrap();
let key_value = &public_key_json["value"][0]["value"][1]["value"];
// Public Key bytes
let hex_key = &key_value[0]["value"].as_str().unwrap();
let public_key_bytes = hex::decode(hex_key).unwrap();
// Policy
let policy_hex = &key_value[1]["value"][4]["value"][0]["value"][2]["value"]
.as_str()
.unwrap();
let policy_bytes = hex::decode(policy_hex).unwrap();
// Prepare JS inputs
let policy_js = Uint8Array::from(policy_bytes.as_slice());
let public_key_js = Uint8Array::from(public_key_bytes.as_slice());
let uid_js = js_sys::Uint8Array::new(&JsValue::from_str("12345678"));
let encrypted_header_js = webassembly_encrypt_hybrid_header(
policy_js,
public_key_js,
"Department::FIN, Security Level::Top Secret",
uid_js,
)
.unwrap();
let encrypted_header =
EncryptedHeader::<Aes256GcmCrypto>::try_from_bytes(&encrypted_header_js.to_vec()[..])
.unwrap();
// Decrypt
let user_decryption_key_json: Value = serde_json::from_str(include_str!(
"../hybrid_crypto/tests/fin_top_secret_user_key.json"
))
.unwrap();
let key_value = &user_decryption_key_json["value"][0]["value"][1]["value"];
let hex_key = &key_value[0]["value"].as_str().unwrap();
let user_decryption_key =
UserDecryptionKey::try_from_bytes(&hex::decode(hex_key).unwrap()).unwrap();
decrypt_hybrid_header::<Gpsw<Bls12_381>, Aes256GcmCrypto>(
&user_decryption_key,
&encrypted_header.encrypted_header_bytes,
)
.unwrap();
}
#[wasm_bindgen_test]
pub fn test_encrypt_hybrid_block() {
let symmetric_key_bytes =
hex::decode("802de96f19589fbc0eb2f26705dc1ed261e9c80f2fec301ca7d0ecea3176405b").unwrap();
let uid_bytes =
hex::decode("cd8ca2eeb654b5f39f347f4e3f91b3a15c450c1e52c40716237b4c18510f65b4").unwrap();
let symmetric_key =
<Aes256GcmCrypto as SymmetricCrypto>::Key::try_from_bytes(&symmetric_key_bytes).unwrap();
let symmetric_key_js = Uint8Array::from(symmetric_key_bytes.as_slice());
let uid_js = Uint8Array::from(uid_bytes.as_slice());
let data_js = Uint8Array::from([1, 2, 3, 4, 5, 6, 7, 8].as_slice());
let ciphertext =
webassembly_encrypt_hybrid_block(symmetric_key_js, Some(uid_js), Some(0), data_js).unwrap();
let mut ciphertext_bytes = vec![0_u8; ciphertext.length() as usize];
ciphertext.copy_to(&mut ciphertext_bytes[..]);
let _clear_text =
decrypt_hybrid_block::<Gpsw<Bls12_381>, Aes256GcmCrypto, MAX_CLEAR_TEXT_SIZE>(
&symmetric_key,
&uid_bytes,
0,
&ciphertext_bytes,
)
.unwrap();
}