use std::{
string::String,
ops::Neg
};
use rabe_bn::{Group, Gt, G1, G2, Fr, pairing};
use rand::Rng;
use utils::{
policy::msp::AbePolicy,
tools::*,
secretsharing::*,
aes::*,
hash::sha3_hash
};
use utils::policy::pest::{PolicyLanguage, parse, PolicyType};
use crate::error::RabeError;
#[cfg(feature = "serde")]
use serde::{Serialize, Deserialize};
#[cfg(feature = "borsh")]
use borsh::{BorshSerialize, BorshDeserialize};
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Ac17PublicKey {
pub g: G1,
pub h_a: Vec<G2>,
pub e_gh_ka: Vec<Gt>,
}
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Ac17MasterKey {
pub g: G1,
pub h: G2,
pub g_k: Vec<G1>,
pub a: Vec<Fr>,
pub b: Vec<Fr>,
}
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Ac17Ciphertext {
pub c_0: Vec<G2>,
pub c: Vec<(String, Vec<G1>)>,
pub c_p: Gt,
pub ct: Vec<u8>,
}
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Ac17CpCiphertext {
pub policy: (String, PolicyLanguage),
pub ct: Ac17Ciphertext,
}
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Ac17KpCiphertext {
pub attr: Vec<String>,
pub ct: Ac17Ciphertext,
}
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Ac17SecretKey {
pub k_0: Vec<G2>,
pub k: Vec<(String, Vec<G1>)>,
pub k_p: Vec<G1>,
}
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Ac17KpSecretKey {
pub policy: (String, PolicyLanguage),
pub sk: Ac17SecretKey,
}
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Ac17CpSecretKey {
pub attr: Vec<String>,
pub sk: Ac17SecretKey,
}
const ASSUMPTION_SIZE: usize = 2;
pub fn setup() -> (Ac17PublicKey, Ac17MasterKey) {
let mut rng = rand::thread_rng();
let g:G1 = rng.gen();
let h:G2 = rng.gen();
let e_gh = pairing(g, h);
let mut a: Vec<Fr> = Vec::new();
let mut b: Vec<Fr> = Vec::new();
for _i in 0usize..ASSUMPTION_SIZE {
a.push(rng.gen());
b.push(rng.gen());
}
let mut _k: Vec<Fr> = Vec::new();
for _i in 0usize..(ASSUMPTION_SIZE + 1) {
_k.push(rng.gen());
}
let mut h_a: Vec<G2> = Vec::new();
for _i in 0usize..ASSUMPTION_SIZE {
h_a.push(h * a[_i]);
}
h_a.push(h);
let mut g_k: Vec<G1> = Vec::new();
for _i in 0usize..(ASSUMPTION_SIZE + 1) {
g_k.push(g * _k[_i]);
}
let mut e_gh_ka: Vec<Gt> = Vec::new();
for _i in 0usize..ASSUMPTION_SIZE {
e_gh_ka.push(e_gh.pow(_k[_i.clone()] * a[_i] + _k[ASSUMPTION_SIZE]));
}
return (
Ac17PublicKey { g, h_a, e_gh_ka },
Ac17MasterKey { g, h, g_k, a, b }
)
}
pub fn cp_keygen(
msk: &Ac17MasterKey,
attributes: &[&str]
) -> Result<Ac17CpSecretKey, RabeError> {
if attributes.is_empty() {
return Err(RabeError::new("empty attributes!"));
}
let mut rng = rand::thread_rng();
let mut r: Vec<Fr> = Vec::new();
let mut sum = Fr::zero();
for _i in 0usize..ASSUMPTION_SIZE {
let random:Fr = rng.gen();
r.push(random);
sum = sum + random;
}
let mut br: Vec<Fr> = Vec::new();
for _i in 0usize..ASSUMPTION_SIZE {
br.push(msk.b[_i.clone()] * r[_i])
}
br.push(sum);
let mut k_0: Vec<G2> = Vec::new();
for _i in 0usize..(ASSUMPTION_SIZE + 1) {
k_0.push(msk.h * br[_i])
}
let mut k: Vec<(String, Vec<G1>)> = Vec::new();
let a = msk.a.clone();
for attr in attributes {
let mut key: Vec<G1> = Vec::new();
let sigma_attr:Fr = rng.gen();
for _t in 0usize..ASSUMPTION_SIZE {
let mut prod = G1::zero();
let _a_t = a[_t].inverse().unwrap();
for _l in 0usize..(ASSUMPTION_SIZE + 1) {
let mut _hash = String::new();
_hash.push_str(&attr);
_hash.push_str(&_l.to_string());
_hash.push_str(&_t.to_string());
prod = prod + (sha3_hash(msk.g, &_hash).expect("could not hash _hash") * (br[_l] * _a_t));
}
prod = prod + (msk.g * (sigma_attr * _a_t));
key.push(prod);
}
key.push(msk.g * sigma_attr.neg());
k.push((attr.to_string(), key));
}
let mut _k_p: Vec<G1> = Vec::new();
let _g_k = msk.g_k.clone();
let _sigma:Fr = rng.gen();
for _t in 0usize..ASSUMPTION_SIZE {
let mut _prod = _g_k[_t];
let _a_t = a[_t].inverse().unwrap();
for _l in 0usize..(ASSUMPTION_SIZE + 1) {
let mut _hash = String::new();
_hash.push_str(&String::from("01"));
_hash.push_str(&_l.to_string());
_hash.push_str(&_t.to_string());
_prod = _prod + (sha3_hash(msk.g, &_hash).expect("could not hash _hash") * (br[_l] * _a_t));
}
_prod = _prod + (msk.g * (_sigma * _a_t));
_k_p.push(_prod);
}
_k_p.push(_g_k[ASSUMPTION_SIZE] + (msk.g * _sigma.neg()));
let attr = attributes.iter().map(|a| a.to_string()).collect();
let sk = Ac17SecretKey { k_0, k, k_p: _k_p };
Ok(Ac17CpSecretKey { attr, sk })
}
pub fn cp_encrypt(
pk: &Ac17PublicKey,
policy: &str,
plaintext: &[u8],
language: PolicyLanguage,
) -> Result<Ac17CpCiphertext, RabeError> {
let mut rng = rand::thread_rng();
match parse(policy, language) {
Ok(_policy) => {
let msp: AbePolicy = AbePolicy::from_policy(&_policy).unwrap();
let num_cols = msp.m[0].len();
let num_rows = msp.m.len();
let mut s: Vec<Fr> = Vec::new();
let mut sum = Fr::zero();
for _i in 0usize..ASSUMPTION_SIZE {
let random:Fr = rng.gen();
s.push(random);
sum = sum + random;
}
let mut c_0: Vec<G2> = Vec::new();
let h_a = pk.h_a.clone();
for _i in 0usize..ASSUMPTION_SIZE {
c_0.push(h_a[_i.clone()] * s[_i]);
}
c_0.push(h_a[ASSUMPTION_SIZE] * sum);
let mut _hash_table: Vec<Vec<Vec<G1>>> = Vec::new();
for _j in 0usize..num_cols {
let mut _x: Vec<Vec<G1>> = Vec::new();
let mut _hash1 = String::new();
_hash1.push_str(&String::from("0"));
_hash1.push_str(&(_j + 1).to_string());
for _l in 0usize..(ASSUMPTION_SIZE + 1) {
let mut _y: Vec<G1> = Vec::new();
let mut _hash2 = String::new();
_hash2.push_str(&_hash1);
_hash2.push_str(&_l.to_string());
for _t in 0usize..ASSUMPTION_SIZE {
let mut _hash3 = String::new();
_hash3.push_str(&_hash2);
_hash3.push_str(&_t.to_string());
match sha3_hash(pk.g, &_hash3) {
Ok(hashed) => _y.push(hashed),
Err(e) => return Err(e)
};
}
_x.push(_y)
}
_hash_table.push(_x);
}
let mut c: Vec<(String, Vec<G1>)> = Vec::new();
for _i in 0usize..num_rows {
let mut _ct: Vec<G1> = Vec::new();
for _l in 0usize..(ASSUMPTION_SIZE + 1) {
let mut _prod = G1::zero();
for _t in 0usize..ASSUMPTION_SIZE {
let mut _hash = String::new();
_hash.push_str(&msp.pi[_i]);
_hash.push_str(&_l.to_string());
_hash.push_str(&_t.to_string());
match sha3_hash(pk.g, &_hash) {
Ok(mut hash) => {
for _j in 0usize..num_cols {
if msp.m[_i][_j] == 1 {
hash = hash + _hash_table[_j][_l][_t];
} else if msp.m[_i][_j] == -1 {
hash = hash - _hash_table[_j][_l][_t];
}
}
_prod = _prod + (hash * s[_t]);
},
Err(e) => return Err(e)
}
}
_ct.push(_prod);
}
c.push((msp.pi[_i].to_string(), _ct));
}
let mut c_p = Gt::one();
for _i in 0usize..ASSUMPTION_SIZE {
c_p = c_p * (pk.e_gh_ka[_i].pow(s[_i]));
}
let msg: Gt = rng.gen();
match encrypt_symmetric(msg, &plaintext.to_vec()) {
Ok(ct) => {
Ok(Ac17CpCiphertext {
policy: (policy.to_string(), language),
ct: Ac17Ciphertext { c_0, c, c_p: c_p * msg, ct },
})
},
Err(e) => Err(e)
}
},
Err(e) => Err(e)
}
}
pub fn cp_decrypt(
sk: &Ac17CpSecretKey,
ct: &Ac17CpCiphertext
) -> Result<Vec<u8>, RabeError> {
match parse(ct.policy.0.as_ref(), ct.policy.1) {
Ok(pol) => {
return if traverse_policy(&sk.attr, &pol, PolicyType::Leaf) == false {
Err(RabeError::new("Error in cp_decrypt: attributes in SK do not match policy in CT."))
} else {
match calc_pruned(&sk.attr, &pol, None) {
Err(e) => Err(e),
Ok((_match, _list)) => {
if _match {
let mut _prod1_gt = Gt::one();
let mut _prod2_gt = Gt::one();
for _i in 0usize..(ASSUMPTION_SIZE + 1) {
let mut _prod_h = G1::zero();
let mut _prod_g = G1::zero();
for _current in _list.iter() {
for _attr in ct.ct.c.iter() {
if _attr.0 == _current.0.to_string() {
_prod_g = _prod_g + _attr.1[_i];
}
}
for _attr in sk.sk.k.iter() {
if _attr.0 == _current.0.to_string() {
_prod_h = _prod_h + _attr.1[_i];
}
}
}
_prod1_gt = _prod1_gt * pairing(sk.sk.k_p[_i] + _prod_h, ct.ct.c_0[_i]);
_prod2_gt = _prod2_gt * pairing(_prod_g, sk.sk.k_0[_i]);
}
let _msg = ct.ct.c_p * (_prod2_gt * _prod1_gt.inverse());
decrypt_symmetric(_msg, &ct.ct.ct)
} else {
Err(RabeError::new("Error: attributes in sk do not match policy in ct."))
}
}
}
};
},
Err(e) => Err(e)
}
}
pub fn kp_keygen(
msk: &Ac17MasterKey,
policy: &str,
lang: PolicyLanguage
) -> Result<Ac17KpSecretKey, RabeError> {
let mut _rng = rand::thread_rng();
match parse(policy, lang) {
Ok(pol) => {
let msp: AbePolicy = AbePolicy::from_policy(&pol).unwrap();
let _num_cols = msp.m[0].len();
let _num_rows = msp.m.len();
let mut _r: Vec<Fr> = Vec::new();
let mut _sum = Fr::zero();
for _i in 0usize..ASSUMPTION_SIZE {
let _rand:Fr = _rng.gen();
_r.push(_rand);
_sum = _sum + _rand;
}
let mut _br: Vec<Fr> = Vec::new();
for _i in 0usize..ASSUMPTION_SIZE {
_br.push(msk.b[_i] * _r[_i])
}
_br.push(_sum);
let mut _k_0: Vec<G2> = Vec::new();
for _i in 0usize..(ASSUMPTION_SIZE + 1) {
_k_0.push(msk.h * _br[_i])
}
let mut _sigma_prime: Vec<Fr> = Vec::new();
for _i in 0usize..(_num_cols - 1) {
_sigma_prime.push(_rng.gen())
}
let mut _k: Vec<(String, Vec<G1>)> = Vec::new();
let _a = msk.a.clone();
let _g = msk.g.clone();
for _i in 0usize.._num_rows {
let mut _key: Vec<G1> = Vec::new();
let _sigma_attr:Fr = _rng.gen();
for _t in 0usize..ASSUMPTION_SIZE {
let mut _prod = G1::zero();
let _a_t = _a[_t].inverse().unwrap();
for _l in 0usize..(ASSUMPTION_SIZE + 1) {
let mut _hash = String::new();
_hash.push_str(&msp.pi[_i]);
_hash.push_str(&_l.to_string());
_hash.push_str(&_t.to_string());
_prod = _prod + (sha3_hash(msk.g, &_hash).expect("could not hash _hash") * (_br[_l] * _a_t));
}
_prod = _prod + (msk.g * (_sigma_attr * _a_t));
if msp.m[_i][0] == 1 {
_prod = _prod + (msk.g_k[_t]);
} else if msp.m[_i][0] == -1 {
_prod = _prod - (msk.g_k[_t]);
}
let mut _temp = G1::zero();
for _j in 1usize.._num_cols {
let mut _hash0 = String::new();
_hash0.push_str(&String::from("0"));
_hash0.push_str(&_j.to_string());
for _l in 0usize..(ASSUMPTION_SIZE + 1) {
let mut _hash1 = String::new();
_hash1.push_str(&_hash0);
_hash1.push_str(&_l.to_string());
_hash1.push_str(&_t.to_string());
_temp = _temp + (sha3_hash(msk.g, &_hash1).expect("could not hash _hash") * (_br[_l] * _a_t));
}
_temp = _temp + (msk.g * _sigma_prime[_j - 1].neg());
if msp.m[_i][_j] == 1 {
_prod = _prod + _temp;
} else if msp.m[_i][_j] == -1 {
_prod = _prod - _temp;
}
}
_key.push(_prod);
}
let mut _sk_i3 = msk.g * _sigma_attr.neg();
if msp.m[_i][0] == 1 {
_sk_i3 = _sk_i3 + (msk.g_k[ASSUMPTION_SIZE]);
} else if msp.m[_i][0] == -1 {
_sk_i3 = _sk_i3 - (msk.g_k[ASSUMPTION_SIZE]);
}
for _j in 1usize.._num_cols {
if msp.m[_i][_j] == 1 {
_sk_i3 = _sk_i3 + (msk.g * _sigma_prime[_j - 1].neg());
} else if msp.m[_i][_j] == -1 {
_sk_i3 = _sk_i3 - (msk.g * _sigma_prime[_j - 1].neg());
}
}
_key.push(_sk_i3);
_k.push((msp.pi[_i].to_string(), _key));
}
Ok(Ac17KpSecretKey {
policy: (policy.to_string(), lang),
sk: Ac17SecretKey { k_0: _k_0, k: _k, k_p: Vec::new()},
})
},
Err(e) => Err(e)
}
}
pub fn kp_encrypt(
pk: &Ac17PublicKey,
attributes: &[&str],
data: &[u8],
) -> Result<Ac17KpCiphertext, RabeError> {
let mut rng = rand::thread_rng();
let mut s: Vec<Fr> = Vec::new();
let mut sum = Fr::zero();
for _i in 0usize..ASSUMPTION_SIZE {
let random:Fr = rng.gen();
s.push(random);
sum = sum + random;
}
let mut c_0: Vec<G2> = Vec::new();
let h_a = pk.h_a.clone();
for _i in 0usize..ASSUMPTION_SIZE {
c_0.push(h_a[_i.clone()] * s[_i]);
}
c_0.push(h_a[ASSUMPTION_SIZE] * sum);
let mut c: Vec<(String, Vec<G1>)> = Vec::new();
for _attr in attributes {
let mut _ct: Vec<G1> = Vec::new();
for _l in 0usize..(ASSUMPTION_SIZE + 1) {
let mut _prod = G1::zero();
for _t in 0usize..ASSUMPTION_SIZE {
let mut _hash = String::new();
_hash.push_str(&_attr);
_hash.push_str(&_l.to_string());
_hash.push_str(&_t.to_string());
match sha3_hash(pk.g, &_hash) {
Ok(hash) => {
_prod = _prod + (hash * s[_t])
},
Err(e) => return Err(e)
};
}
_ct.push(_prod);
}
c.push((_attr.to_string(), _ct));
}
let mut c_p = Gt::one();
for _i in 0usize..ASSUMPTION_SIZE {
c_p = c_p * (pk.e_gh_ka[_i].pow(s[_i]));
}
let _msg: Gt = rng.gen();
match encrypt_symmetric(_msg, &data.to_vec()) {
Ok(ct) => {
Ok(Ac17KpCiphertext {
attr: attributes.iter().map(|a| a.to_string()).collect(),
ct: Ac17Ciphertext { c_0, c, c_p: c_p * _msg, ct },
})
},
Err(e) => Err(e)
}
}
pub fn kp_decrypt(
sk: &Ac17KpSecretKey,
ct: &Ac17KpCiphertext
) -> Result<Vec<u8>, RabeError> {
match parse(sk.policy.0.as_ref(), sk.policy.1) {
Ok(pol) => {
return if traverse_policy(&ct.attr, &pol, PolicyType::Leaf) == false {
Err(RabeError::new("Error in kp_decrypt: attributes in ct do not match policy in sk."))
} else {
match calc_pruned(&ct.attr, &pol, None) {
Err(e) => Err(e),
Ok(_p) => {
let (_match, _list) = _p;
if _match {
let mut _prod1_gt = Gt::one();
let mut _prod2_gt = Gt::one();
for _i in 0usize..(ASSUMPTION_SIZE + 1) {
let mut _prod_h = G1::zero();
let mut _prod_g = G1::zero();
for _current in _list.iter() {
for _attr in ct.ct.c.iter() {
if _attr.0 == _current.0.to_string() {
_prod_g = _prod_g + _attr.1[_i];
}
}
for _attr in sk.sk.k.iter() {
if _attr.0 == _current.0.to_string() {
_prod_h = _prod_h + _attr.1[_i];
}
}
}
_prod1_gt = _prod1_gt * pairing(_prod_h, ct.ct.c_0[_i]);
_prod2_gt = _prod2_gt * pairing(_prod_g, sk.sk.k_0[_i]);
}
let _msg = ct.ct.c_p * (_prod2_gt * _prod1_gt.inverse());
decrypt_symmetric(_msg, &ct.ct.ct)
} else {
Err(RabeError::new("Error in kp_decrypt: pruned attributes in sk do not match policy in ct."))
}
}
}
}
},
Err(e) => Err(e)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn kp_and() {
let (pk, msk) = setup();
let plaintext = String::from("dance like no one's watching, encrypt like everyone is!")
.into_bytes();
let policy = String::from(r#"{"name": "and", "children": [{"name": "A"}, {"name": "B"}]}"#);
let ct: Ac17KpCiphertext =
kp_encrypt(&pk, &vec!["A", "B"], &plaintext).unwrap();
let sk: Ac17KpSecretKey = kp_keygen(&msk, &policy, PolicyLanguage::JsonPolicy).unwrap();
assert_eq!(kp_decrypt(&sk, &ct).unwrap(), plaintext);
}
#[test]
fn kp_or_and() {
let (pk, msk) = setup();
let plaintext = String::from("dance like no one's watching, encrypt like everyone is!")
.into_bytes();
let policy = String::from(r#"{"name":"or", "children": [{"name": "and", "children": [{"name": "A"}, {"name": "B"}]}, {"name": "and", "children": [{"name": "C"}, {"name": "D"}]}]}"#);
let ct: Ac17KpCiphertext =
kp_encrypt(&pk, &vec!["A", "B"], &plaintext).unwrap();
let sk: Ac17KpSecretKey = kp_keygen(&msk, &policy, PolicyLanguage::JsonPolicy).unwrap();
assert_eq!(kp_decrypt(&sk, &ct).unwrap(), plaintext);
let ct: Ac17KpCiphertext =
kp_encrypt(&pk, &vec!["C", "D"], &plaintext).unwrap();
let sk: Ac17KpSecretKey = kp_keygen(&msk, &policy, PolicyLanguage::JsonPolicy).unwrap();
assert_eq!(kp_decrypt(&sk, &ct).unwrap(), plaintext);
}
#[test]
fn kp_or() {
let (pk, msk) = setup();
let plaintext = String::from("dance like no one's watching, encrypt like everyone is!")
.into_bytes();
let policy = String::from(r#"{"name": "or", "children": [{"name": "A"}, {"name": "B"}]}"#);
let ct: Ac17KpCiphertext = kp_encrypt(&pk, &vec!["B"], &plaintext).unwrap();
let sk: Ac17KpSecretKey = kp_keygen(&msk, &policy, PolicyLanguage::JsonPolicy).unwrap();
assert_eq!(kp_decrypt(&sk, &ct).unwrap(), plaintext);
}
#[test]
fn kp_not() {
let (pk, msk) = setup();
let plaintext = String::from("dance like no one's watching, encrypt like everyone is!")
.into_bytes();
let policy = String::from(r#"{"name": "or", "children": [{"name": "A"}, {"name": "B"}]}"#);
let ct: Ac17KpCiphertext = kp_encrypt(&pk, &vec!["C"], &plaintext).unwrap();
let sk: Ac17KpSecretKey = kp_keygen(&msk, &policy, PolicyLanguage::JsonPolicy).unwrap();
assert_eq!(kp_decrypt(&sk, &ct).is_ok(), false);
}
#[test]
fn cp_and() {
let (pk, msk) = setup();
let plaintext = String::from("dance like no one's watching, encrypt like everyone is!")
.into_bytes();
let policy = String::from(r#"{"name": "and", "children": [{"name": "A"}, {"name": "B"}]}"#);
let ct: Ac17CpCiphertext = cp_encrypt(&pk, &policy, &plaintext, PolicyLanguage::JsonPolicy).unwrap();
let sk: Ac17CpSecretKey = cp_keygen(&msk, &vec!["A", "B"]).unwrap();
assert_eq!(cp_decrypt(&sk, &ct).unwrap(), plaintext);
}
#[test]
fn cp_or() {
let (pk, msk) = setup();
let plaintext = String::from("dance like no one's watching, encrypt like everyone is!")
.into_bytes();
let policy = String::from(r#"{"name": "or", "children": [{"name": "A"}, {"name": "B"}, {"name": "C"}]}"#);
let ct: Ac17CpCiphertext = cp_encrypt(&pk, &policy, &plaintext, PolicyLanguage::JsonPolicy).unwrap();
let sk_m1: Ac17CpSecretKey = cp_keygen(&msk, &vec!["A"]).unwrap();
let pt = cp_decrypt(&sk_m1, &ct);
assert_eq!(pt.is_ok(), true);
assert_eq!(pt.unwrap(), plaintext);
}
#[test]
fn cp_or_and_and() {
let (pk, msk) = setup();
let plaintext = String::from("dance like no one's watching, encrypt like everyone is!")
.into_bytes();
let policy = String::from(r#"{"name": "or", "children": [{"name": "and", "children": [{"name": "A"}, {"name": "B"}]}, {"name": "and", "children": [{"name": "C"}, {"name": "D"}]}]}"#);
let ct: Ac17CpCiphertext = cp_encrypt(&pk, &policy, &plaintext, PolicyLanguage::JsonPolicy).unwrap();
let sk: Ac17CpSecretKey = cp_keygen(&msk, &vec!["A","B","C","D"], ).unwrap();
assert_eq!(cp_decrypt(&sk, &ct).unwrap(), plaintext);
}
}