Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Signed-off-by: bwty <[email protected]>
  • Loading branch information
whalelephant committed Feb 15, 2023
1 parent 1485675 commit 5bea53c
Show file tree
Hide file tree
Showing 8 changed files with 342 additions and 188 deletions.
22 changes: 11 additions & 11 deletions src/data_types/pres_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub struct PresentationRequestPayload {
pub requested_attributes: HashMap<String, AttributeInfo>,
#[serde(default)]
pub requested_predicates: HashMap<String, PredicateInfo>,
pub non_revoked: Option<NonRevocedInterval>,
pub non_revoked: Option<NonRevokedInterval>,
}

#[derive(Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -123,18 +123,18 @@ impl Serialize for PresentationRequest {
pub type PresentationRequestExtraQuery = HashMap<String, Query>;

#[derive(Clone, Default, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub struct NonRevocedInterval {
pub struct NonRevokedInterval {
pub from: Option<u64>,
pub to: Option<u64>,
}

impl NonRevocedInterval {
impl NonRevokedInterval {
pub fn new(from: Option<u64>, to: Option<u64>) -> Self {
Self { from, to }
}
// Returns the most stringent interval,
// i.e. the latest from and the earliest to
pub fn compare_and_set(&mut self, to_compare: &NonRevocedInterval) {
pub fn compare_and_set(&mut self, to_compare: &NonRevokedInterval) {
// Update if
// - the new `from` value is later, smaller interval
// - the new `from` value is Some if previouly was None
Expand Down Expand Up @@ -185,7 +185,7 @@ pub struct AttributeInfo {
#[serde(skip_serializing_if = "Option::is_none")]
pub names: Option<Vec<String>>,
pub restrictions: Option<Query>,
pub non_revoked: Option<NonRevocedInterval>,
pub non_revoked: Option<NonRevokedInterval>,
}

#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
Expand All @@ -194,7 +194,7 @@ pub struct PredicateInfo {
pub p_type: PredicateTypes,
pub p_value: i32,
pub restrictions: Option<Query>,
pub non_revoked: Option<NonRevocedInterval>,
pub non_revoked: Option<NonRevokedInterval>,
}

#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
Expand Down Expand Up @@ -383,7 +383,7 @@ mod tests {

#[test]
fn override_works() {
let mut interval = NonRevocedInterval::default();
let mut interval = NonRevokedInterval::default();
let override_map = HashMap::from([(10u64, 5u64)]);

interval.from = Some(10);
Expand All @@ -393,10 +393,10 @@ mod tests {

#[test]
fn compare_and_set_works() {
let mut int = NonRevocedInterval::default();
let wide_int = NonRevocedInterval::new(Some(1), Some(100));
let mid_int = NonRevocedInterval::new(Some(5), Some(80));
let narrow_int = NonRevocedInterval::new(Some(10), Some(50));
let mut int = NonRevokedInterval::default();
let wide_int = NonRevokedInterval::new(Some(1), Some(100));
let mid_int = NonRevokedInterval::new(Some(5), Some(80));
let narrow_int = NonRevokedInterval::new(Some(10), Some(50));

assert_eq!(int.from, None);
assert_eq!(int.to, None);
Expand Down
14 changes: 7 additions & 7 deletions src/ffi/presentation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,24 +218,24 @@ pub extern "C" fn anoncreds_create_presentation(
pub struct FfiNonrevokedIntervalOverride<'a> {
rev_reg_def_id: FfiStr<'a>,
/// Timestamp in the `PresentationRequest`
req_timestamp: i64,
requested_from_ts: i64,
/// Timestamp from which verifier accepts,
/// should be less than `req_timestamp`
override_timestamp: i64,
override_rev_status_list_ts: i64,
}

impl<'a> FfiNonrevokedIntervalOverride<'a> {
fn load(&self) -> Result<(RevocationRegistryDefinitionId, u64, u64)> {
let id = RevocationRegistryDefinitionId::new(self.rev_reg_def_id.as_str().to_owned())?;
let req_timestamp = self
.req_timestamp
let requested_from_ts = self
.requested_from_ts
.try_into()
.map_err(|_| err_msg!("Invalid req timestamp "))?;
let override_timestamp = self
.override_timestamp
let override_rev_status_list_ts = self
.override_rev_status_list_ts
.try_into()
.map_err(|_| err_msg!("Invalid override timestamp "))?;
Ok((id, req_timestamp, override_timestamp))
Ok((id, requested_from_ts, override_rev_status_list_ts))
}
}

Expand Down
105 changes: 104 additions & 1 deletion src/services/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use std::collections::{HashMap, HashSet};
use crate::data_types::{
credential::AttributeValues,
nonce::Nonce,
pres_request::{AttributeInfo, PredicateInfo},
pres_request::{AttributeInfo, NonRevokedInterval, PredicateInfo, PresentationRequestPayload},
presentation::RequestedProof,
};
use crate::utils::hash::SHA256;

Expand Down Expand Up @@ -137,3 +138,105 @@ pub fn build_sub_proof_request(
pub fn new_nonce() -> Result<Nonce> {
Nonce::new().map_err(err_map!(Unexpected))
}

pub fn get_revealed_attributes_for_credential(
sub_proof_index: usize,
requested_proof: &RequestedProof,
pres_req: &PresentationRequestPayload,
) -> Result<(Vec<AttributeInfo>, Option<NonRevokedInterval>)> {
trace!("_get_revealed_attributes_for_credential >>> sub_proof_index: {:?}, requested_credentials: {:?}, pres_req: {:?}",
sub_proof_index, requested_proof, pres_req);
let mut nonrevoked_interval: Option<NonRevokedInterval> = None;
let mut revealed_attrs_for_credential = requested_proof
.revealed_attrs
.iter()
.filter(|&(attr_referent, revealed_attr_info)| {
sub_proof_index == revealed_attr_info.sub_proof_index as usize
&& pres_req.requested_attributes.contains_key(attr_referent)
})
.map(|(attr_referent, _)| {
let info = pres_req.requested_attributes[attr_referent].clone();
if let Some(int) = &info.non_revoked {
match nonrevoked_interval.as_mut() {
Some(ni) => {
ni.compare_and_set(int);
}
None => nonrevoked_interval = Some(int.clone()),
}
};

info
})
.collect::<Vec<AttributeInfo>>();

revealed_attrs_for_credential.append(
&mut requested_proof
.revealed_attr_groups
.iter()
.filter(|&(attr_referent, revealed_attr_info)| {
sub_proof_index == revealed_attr_info.sub_proof_index as usize
&& pres_req.requested_attributes.contains_key(attr_referent)
})
.map(|(attr_referent, _)| {
let info = pres_req.requested_attributes[attr_referent].clone();
if let Some(int) = &info.non_revoked {
match nonrevoked_interval.as_mut() {
Some(ni) => {
ni.compare_and_set(int);
}
None => nonrevoked_interval = Some(NonRevokedInterval::default()),
}
};
info
})
.collect::<Vec<AttributeInfo>>(),
);

trace!(
"_get_revealed_attributes_for_credential <<< revealed_attrs_for_credential: {:?}",
revealed_attrs_for_credential
);

Ok((revealed_attrs_for_credential, nonrevoked_interval))
}

pub fn get_predicates_for_credential(
sub_proof_index: usize,
requested_proof: &RequestedProof,
pres_req: &PresentationRequestPayload,
) -> Result<(Vec<PredicateInfo>, Option<NonRevokedInterval>)> {
trace!("_get_predicates_for_credential >>> sub_proof_index: {:?}, requested_credentials: {:?}, pres_req: {:?}",
sub_proof_index, requested_proof, pres_req);

let mut nonrevoked_interval: Option<NonRevokedInterval> = None;
let predicates_for_credential = requested_proof
.predicates
.iter()
.filter(|&(predicate_referent, requested_referent)| {
sub_proof_index == requested_referent.sub_proof_index as usize
&& pres_req
.requested_predicates
.contains_key(predicate_referent)
})
.map(|(predicate_referent, _)| {
let info = pres_req.requested_predicates[predicate_referent].clone();
if let Some(int) = &info.non_revoked {
match nonrevoked_interval.as_mut() {
Some(ni) => {
ni.compare_and_set(int);
}
None => nonrevoked_interval = Some(int.clone()),
}
};

info
})
.collect::<Vec<PredicateInfo>>();

trace!(
"_get_predicates_for_credential <<< predicates_for_credential: {:?}",
predicates_for_credential
);

Ok((predicates_for_credential, nonrevoked_interval))
}
59 changes: 48 additions & 11 deletions src/services/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,15 +203,61 @@ pub fn create_presentation(
)?;
let sub_proof_request = build_sub_proof_request(&req_attrs, &req_predicates)?;

update_requested_proof(
req_attrs,
req_predicates,
pres_req_val,
credential,
sub_proof_index,
&mut requested_proof,
)?;

// Checks conditions to add revocation proof
let (rev_reg, witness) = if pres_req_val.non_revoked.is_some() {
// Global revocation request
(
present.rev_state.as_ref().map(|r_info| &r_info.rev_reg),
present.rev_state.as_ref().map(|r_info| &r_info.witness),
)
} else {
// There exists at least 1 local revocation request
let ((_, nonrevoked_attr), (_, nonrevoked_preds)) = (
get_revealed_attributes_for_credential(
sub_proof_index as usize,
&requested_proof,
pres_req_val,
)?,
get_predicates_for_credential(
sub_proof_index as usize,
&requested_proof,
pres_req_val,
)?,
);
if nonrevoked_attr.is_some() || nonrevoked_preds.is_some() {
(
present.rev_state.as_ref().map(|r_info| &r_info.rev_reg),
present.rev_state.as_ref().map(|r_info| &r_info.witness),
)
} else {
// Neither global nor local is required
(None, None)
}
};

// if `present.rev_state` is available,
// then it will create an init_proof that contains NRP.
//
// Therefore, this will have to be part of the finalised `aggregated_proof`.
// Regardless if nonrevoke_interval is requested by the verifier
proof_builder.add_sub_proof_request(
&sub_proof_request,
&credential_schema,
&non_credential_schema,
&credential.signature,
&credential_values,
&credential_pub_key,
present.rev_state.as_ref().map(|r_info| &r_info.rev_reg),
present.rev_state.as_ref().map(|r_info| &r_info.witness),
rev_reg,
witness,
)?;

let identifier = match pres_req {
Expand All @@ -231,15 +277,6 @@ pub fn create_presentation(

identifiers.push(identifier);

update_requested_proof(
req_attrs,
req_predicates,
pres_req_val,
credential,
sub_proof_index,
&mut requested_proof,
)?;

sub_proof_index += 1;
}

Expand Down
Loading

0 comments on commit 5bea53c

Please sign in to comment.