use rabe_bn::{Group, Fr, G1, G2, Gt, pairing};
use rand::Rng;
use std::string::String;
use utils::{
aes::*,
hash::sha3_hash_fr,
policy::dnf::DnfPolicy,
tools::*
};
use utils::policy::pest::{PolicyLanguage, parse, PolicyType};
use utils::policy::dnf::policy_in_dnf;
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 Mke08PublicKey {
pub g1: G1,
pub g2: G2,
pub p1: G1,
pub p2: G2,
pub e_gg_y1: Gt,
pub e_gg_y2: Gt,
}
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Mke08MasterKey {
pub g1: G1,
pub g2: G2,
}
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Mke08UserKey {
pub sk: Mke08SecretUserKey,
pub pk: Mke08PublicUserKey,
pub sk_a: Vec<Mke08SecretAttributeKey>,
}
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Mke08PublicUserKey {
pub name: String,
pub g1: G1,
pub g2: G2,
}
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Mke08SecretUserKey {
pub g1: G1,
pub g2: G2,
}
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Mke08SecretAuthorityKey {
pub name: String,
pub r: Fr,
}
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Mke08PublicAttributeKey {
pub attr: String,
pub g1: G1,
pub g2: G2,
pub gt1: Gt,
pub gt2: Gt,
}
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Mke08SecretAttributeKey {
pub attr: String,
pub g1: G1,
pub g2: G2,
}
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Mke08Ciphertext {
pub policy: (String, PolicyLanguage),
pub e: Vec<Mke08CTConjunction>,
pub ct: Vec<u8>,
}
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Mke08CTConjunction {
pub str: Vec<String>,
pub j1: Gt,
pub j2: Gt,
pub j3: G1,
pub j4: G2,
pub j5: G1,
pub j6: G2,
}
pub fn setup() -> (Mke08PublicKey, Mke08MasterKey) {
let mut rng = rand::thread_rng();
let g1:G1 = rng.gen();
let g2:G2 = rng.gen();
let p1:G1 = rng.gen();
let p2:G2 = rng.gen();
let y1:Fr = rng.gen();
let y2:Fr = rng.gen();
let e_gg_y1 = pairing(g1, g2).pow(y1);
let e_gg_y2 = pairing(g1, g2).pow(y2);
let msk_g1 = g1 * y1;
let msk_g2 = g2 * y2;
(
Mke08PublicKey { g1, g2, p1, p2, e_gg_y1, e_gg_y2 },
Mke08MasterKey { g1: msk_g1, g2: msk_g2 }
)
}
pub fn keygen(
pk: &Mke08PublicKey,
msk: &Mke08MasterKey,
name: &str
) -> Mke08UserKey {
let mut rng = rand::thread_rng();
let mk_u:Fr = rng.gen();
return Mke08UserKey {
sk: Mke08SecretUserKey {
g1: msk.g1 + (pk.p1 * mk_u),
g2: msk.g2 + (pk.p2 * mk_u),
},
pk: Mke08PublicUserKey {
name: name.to_string(),
g1: pk.g1 * mk_u,
g2: pk.g2 * mk_u,
},
sk_a: Vec::new(),
};
}
pub fn authgen(
name: &str
) -> Mke08SecretAuthorityKey {
return Mke08SecretAuthorityKey {
name: name.to_string(),
r: rand::thread_rng().gen(),
};
}
pub fn request_authority_pk(
pk: &Mke08PublicKey,
attribute: &str,
sk_a: &Mke08SecretAuthorityKey,
) -> Result<Mke08PublicAttributeKey, RabeError> {
return if from_authority(attribute, &sk_a.name) {
match sha3_hash_fr(attribute) {
Ok(hash_1) => {
match sha3_hash_fr(&sk_a.name) {
Ok(hash_2) => {
let exp = hash_1 * hash_2 * sk_a.r;
Ok(Mke08PublicAttributeKey {
attr: attribute.to_string(),
g1: pk.g1 * exp,
g2: pk.g2 * exp,
gt1: pk.e_gg_y1.pow(exp),
gt2: pk.e_gg_y2.pow(exp),
})
},
Err(e) => Err(e)
}
},
Err(e) => Err(e)
}
} else {
Err(RabeError::new(&format!("attribute {} is not from_authority() or !is_eligible()", attribute.to_string())))
}
}
pub fn request_authority_sk(
pk_u: &Mke08PublicUserKey,
attr: &str,
sk_a: &Mke08SecretAuthorityKey,
) -> Result<Mke08SecretAttributeKey, RabeError> {
return if from_authority(attr, &sk_a.name) && is_eligible(attr, &pk_u.name) {
match sha3_hash_fr(attr) {
Ok(hash_1) => {
match sha3_hash_fr(&sk_a.name) {
Ok(hash_2) => {
let exp = hash_1 * hash_2 * sk_a.r;
Ok(Mke08SecretAttributeKey {
attr: attr.to_string(),
g1: pk_u.g1 * exp,
g2: pk_u.g2 * exp,
})
},
Err(e) => Err(e)
}
},
Err(e) => Err(e)
}
} else {
Err(RabeError::new(&format!("attribute {} is not from_authority() or !is_eligible()", attr.to_string())))
}
}
pub fn encrypt(
pk: &Mke08PublicKey,
attr_pks: &[&Mke08PublicAttributeKey],
policy: &str,
language: PolicyLanguage,
plaintext: &[u8],
) -> Result<Mke08Ciphertext, RabeError> {
match parse(policy, language) {
Ok(pol) => {
return if policy_in_dnf(&pol, false, None) {
let mut rng = rand::thread_rng();
let policy_dnf = DnfPolicy::from_string(&policy, attr_pks, language).unwrap();
let msg1 = pairing(rng.gen(), rng.gen());
let msg2 = msg1.pow(rng.gen());
let msg = msg1 * msg2;
let mut e: Vec<Mke08CTConjunction> = Vec::new();
for term in policy_dnf.terms.into_iter() {
let r_j: Fr = rng.gen();
e.push(Mke08CTConjunction {
str: term.0,
j1: term.1.pow(r_j) * msg1,
j2: term.2.pow(r_j) * msg2,
j3: pk.p1 * r_j,
j4: pk.p2 * r_j,
j5: term.3 * r_j,
j6: term.4 * r_j,
});
}
match encrypt_symmetric(msg, &plaintext.to_vec()) {
Ok(ct) => Ok(Mke08Ciphertext { policy: (policy.to_string(), language), e, ct }),
Err(e) => Err(e)
}
} else {
Err(RabeError::new("Error in mke08/encrypt: policy is not in dnf"))
}
},
Err(e) => Err(e)
}
}
pub fn decrypt(
sk: &Mke08UserKey,
ct: &Mke08Ciphertext
) -> Result<Vec<u8>, RabeError> {
let attr_str = sk.sk_a
.iter()
.map(|triple| {
let _a = triple.clone();
_a.attr.to_string()
})
.collect::<Vec<_>>();
match parse(ct.policy.0.as_ref(), ct.policy.1) {
Ok(pol) => {
return if traverse_policy(&attr_str, &pol, PolicyType::Leaf) == false {
Err(RabeError::new("Error in mke08/decrypt: attributes in sk do not match policy in ct."))
} else {
let mut msg = Gt::one();
for (_i, _e_j) in ct.e.iter().enumerate() {
if is_satisfiable(&_e_j.str, &sk.sk_a) {
let _sk_sum = calc_satisfiable(&_e_j.str, &sk.sk_a);
msg = _e_j.j1 * _e_j.j2 * pairing(_e_j.j3, _sk_sum.1) *
pairing(_sk_sum.0, _e_j.j4) *
(pairing(_e_j.j5, sk.sk.g2) * pairing(sk.sk.g1, _e_j.j6))
.inverse();
break;
}
}
decrypt_symmetric(msg, &ct.ct)
}
},
Err(e) => Err(e)
}
}
fn is_satisfiable(
conjunction: &Vec<String>,
sk: &Vec<Mke08SecretAttributeKey>
) -> bool {
let mut ret: bool = true;
for _attr in conjunction {
match sk.into_iter().find(|&x| x.attr == *_attr) {
None => {
ret = false;
break;
}
Some(_attr_sk) => {}
}
}
ret
}
fn calc_satisfiable(
conjunction: &Vec<String>,
sk: &Vec<Mke08SecretAttributeKey>
) -> (G1, G2) {
let mut ret: (G1, G2) = (G1::one(), G2::one());
for _i in 0usize..conjunction.len() {
match sk.into_iter().find(
|&x| x.attr == conjunction[_i].to_string(),
) {
None => {}
Some(found) => {
if _i == 0 {
ret = (found.g1, found.g2);
} else {
ret = (ret.0 + found.g1, ret.1 + found.g2);
}
}
}
}
ret
}
#[allow(dead_code)]
fn from_authority(
attr: &str,
authority: &str
) -> bool {
let v: Vec<_> = attr.match_indices("::").collect();
if v.len() == 1 {
return attr.get(0..v[0].0).unwrap().to_string() == authority.to_string();
}
return false;
}
#[allow(dead_code)]
fn is_eligible(
_attr: &str,
_user: &str
) -> bool {
return true;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn and() {
let (pk, msk) = setup();
let mut sk = keygen(&pk, &msk, "user1");
let auth1 = authgen("auth1");
let auth2 = authgen("auth2");
let _att1_pk = request_authority_pk(&pk, "auth1::A", &auth1).unwrap();
let _att2_pk = request_authority_pk(&pk, "auth2::B", &auth2).unwrap();
sk.sk_a.push(
request_authority_sk(&sk.pk, "auth1::A", &auth1).unwrap(),
);
sk.sk_a.push(
request_authority_sk(&sk.pk, "auth2::B", &auth2).unwrap(),
);
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": "auth1::A"}, {"name": "auth2::B"}]}"#);
let att_pk: Vec<&Mke08PublicAttributeKey> = vec![&_att1_pk, &_att2_pk];
let _ct: Mke08Ciphertext = encrypt(&pk, &att_pk.as_slice(), &policy, PolicyLanguage::JsonPolicy, &plaintext)
.unwrap();
let _match = decrypt(&sk, &_ct);
assert_eq!(_match.is_ok(), true);
assert_eq!(_match.unwrap(), plaintext);
}
#[test]
fn or() {
let (pk, msk) = setup();
let mut sk = keygen(&pk, &msk, "user1");
let auth1 = authgen("auth1");
let auth2 = authgen("auth2");
let _att1_pk = request_authority_pk(&pk, "auth1::C", &auth1).unwrap();
let _att2_pk = request_authority_pk(&pk, "auth2::B", &auth2).unwrap();
sk.sk_a.push(
request_authority_sk(&sk.pk, "auth1::C", &auth1).unwrap(),
);
sk.sk_a.push(
request_authority_sk(&sk.pk, "auth2::B", &auth2).unwrap(),
);
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": "auth1::A"}, {"name": "auth2::B"}]}"#);
let att_pks: Vec<&Mke08PublicAttributeKey> = vec![&_att1_pk, &_att2_pk];
let ct: Mke08Ciphertext = encrypt(&pk, att_pks.as_slice(), &policy, PolicyLanguage::JsonPolicy, &plaintext)
.unwrap();
let ct_decrypted = decrypt(&sk, &ct);
assert_eq!(ct_decrypted.is_ok(), true);
assert_eq!(ct_decrypted.unwrap(), plaintext);
}
#[test]
fn or_and() {
let (pk, msk) = setup();
let mut sk = keygen(&pk, &msk, "user1");
let auth1 = authgen("auth1");
let auth2 = authgen("auth2");
let attr1_pk = request_authority_pk(&pk, "auth1::A", &auth1).unwrap();
let attr2_pk = request_authority_pk(&pk, "auth2::B", &auth2).unwrap();
let attr3_pk = request_authority_pk(&pk, "auth2::X", &auth2).unwrap();
sk.sk_a.push(
request_authority_sk(&sk.pk, "auth1::A", &auth1).unwrap(),
);
sk.sk_a.push(
request_authority_sk(&sk.pk, "auth2::B", &auth2, ).unwrap(),
);
sk.sk_a.push(
request_authority_sk(&sk.pk, "auth2::X", &auth2, ).unwrap(),
);
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": "auth1::A"}, {"name": "auth2::B"}]}, {"name": "auth2::X"}]}"#,
);
let attr_pks: Vec<&Mke08PublicAttributeKey> = vec![&attr1_pk, &attr2_pk, &attr3_pk];
let ct: Mke08Ciphertext = encrypt(
&pk,
&attr_pks.as_slice(),
&policy,
PolicyLanguage::JsonPolicy,
&plaintext,
).unwrap();
let ct_decrypted = decrypt(&sk, &ct);
assert_eq!(ct_decrypted.is_ok(), true);
assert_eq!(ct_decrypted.unwrap(), plaintext);
}
}