diff --git a/anoncreds/src/data_types/anoncreds/rev_reg.rs b/anoncreds/src/data_types/anoncreds/rev_reg.rs index dcd8692b..34082589 100644 --- a/anoncreds/src/data_types/anoncreds/rev_reg.rs +++ b/anoncreds/src/data_types/anoncreds/rev_reg.rs @@ -73,6 +73,26 @@ impl RevocationStatusList { self.revocation_list.get(idx).as_deref().copied() } + pub fn revoke(&mut self, idx: usize) -> Option { + match self.revocation_list.get_mut(idx) { + Some(mut i) => { + *i = true; + Some(true) + } + None => None, + } + } + + pub fn unrevoke(&mut self, idx: usize) -> Option { + match self.revocation_list.get_mut(idx) { + Some(mut i) => { + *i = false; + Some(true) + } + None => None, + } + } + pub fn new( rev_reg_def_id: Option<&str>, revocation_list: bitvec::vec::BitVec, diff --git a/anoncreds/src/services/issuer.rs b/anoncreds/src/services/issuer.rs index 396850bd..c0f27513 100644 --- a/anoncreds/src/services/issuer.rs +++ b/anoncreds/src/services/issuer.rs @@ -305,10 +305,6 @@ pub fn create_credential( // When it is set to `false`, or 0, we invert the value. This means that we use // `issuance_by_default`. let issuance_type = !status; - match revocation_config { - Some(revocation) => { - let rev_reg_def = &revocation.reg_def.value; - let mut rev_reg = revocation.registry.value.clone(); let (credential_signature, signature_correctness_proof, delta) = CryptoIssuer::sign_credential_with_revoc( diff --git a/anoncreds/src/services/prover.rs b/anoncreds/src/services/prover.rs index b7033141..0c3a9e38 100644 --- a/anoncreds/src/services/prover.rs +++ b/anoncreds/src/services/prover.rs @@ -265,6 +265,15 @@ pub fn create_or_update_revocation_state( old_rev_status_list, ); + let rev_reg: Option = rev_status_list.into(); + let rev_reg = rev_reg.ok_or(err_msg!( + "revocation registry is required to create or update the revocation state" + ))?; + + let timestamp = rev_status_list.timestamp().ok_or_else(|| { + err_msg!("Timestamp is required to create or update the revocation state") + })?; + let mut issued = HashSet::::new(); let mut revoked = HashSet::::new(); let witness = if let (Some(source_rev_state), Some(source_rev_list)) = @@ -307,10 +316,6 @@ pub fn create_or_update_revocation_state( &mut issued, &mut revoked, ); - let rev_reg: Option = rev_status_list.into(); - let rev_reg = rev_reg.ok_or(err_msg!( - "revocation registry is not inside the revocation status list" - ))?; let rev_reg_delta = RevocationRegistryDelta::from_parts(None, &rev_reg, &issued, &revoked); Witness::new( rev_reg_idx, diff --git a/anoncreds/tests/anoncreds_demos.rs b/anoncreds/tests/anoncreds_demos.rs index 1f1accc9..a5bdef73 100644 --- a/anoncreds/tests/anoncreds_demos.rs +++ b/anoncreds/tests/anoncreds_demos.rs @@ -240,7 +240,7 @@ fn anoncreds_works_for_single_issuer_single_prover() { None, ) .expect("Error verifying presentation"); - assert!(valid); + assert!(valid.0); } #[test] @@ -315,7 +315,7 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { // Prover creates a Credential Request let (cred_request, cred_request_metadata) = prover::create_credential_request( - &prover_wallet.did, + None, &cred_def_pub, &prover_wallet.master_secret, "default", @@ -467,7 +467,7 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { Some(&rev_reg_map), ) .expect("Error verifying presentation"); - assert!(valid); + assert!(valid.0); // Issuer Revoke the holder's credentail let tr = TailsFileReader::new_tails_reader(location.as_str()); @@ -526,7 +526,7 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { Some(&rev_reg_map), ) .expect("Error verifying presentation"); - assert!(!valid); + assert!(!valid.0); } /* diff --git a/anoncreds/tests/utils/anoncreds.rs b/anoncreds/tests/utils/anoncreds.rs index 1ac1d581..99d8432b 100644 --- a/anoncreds/tests/utils/anoncreds.rs +++ b/anoncreds/tests/utils/anoncreds.rs @@ -9,9 +9,8 @@ use anoncreds::data_types::anoncreds::rev_reg_def::{ use anoncreds::data_types::anoncreds::schema::{Schema, SchemaId}; use anoncreds::types::{ CredentialDefinitionPrivate, CredentialKeyCorrectnessProof, CredentialOffer, CredentialRequest, - CredentialRequestMetadata, + CredentialRequestMetadata, RevocationStatusList, }; -use indy_utils::did::DidValue; use std::collections::HashMap; pub static ISSUER_ID: &str = "mock:issuer_id/path&q=bar"; @@ -30,12 +29,14 @@ pub struct StoredRevDef { } #[derive(Debug, Default)] -pub struct Ledger { +pub struct Ledger<'a> { // CredentialDefinition does not impl Clone pub cred_defs: HashMap, pub schemas: HashMap, pub rev_reg_defs: HashMap, pub rev_regs: HashMap>, + // revocation_reg_id: RevocationStatusList + pub revcation_list: HashMap<&'a str, RevocationStatusList>, } // A struct for keeping all issuer-related objects together @@ -43,7 +44,9 @@ pub struct Ledger { pub struct IssuerWallet<'a> { pub id: &'a str, pub cred_defs: HashMap<&'a str, StoredCredDef>, + // revocation_reg_id: StoredRevDef pub rev_defs: HashMap<&'a str, StoredRevDef>, + // (revocation_reg_id, timestamp): RevocationRegistry pub rev_regs: HashMap<(&'a str, u64), RevocationRegistry>, } @@ -59,6 +62,7 @@ impl<'a> Default for IssuerWallet<'a> { } // A struct for keeping all issuer-related objects together +#[derive(Debug)] pub struct ProverWallet<'a> { pub credentials: Vec, pub master_secret: MasterSecret, diff --git a/anoncreds/tests/utils/mock.rs b/anoncreds/tests/utils/mock.rs index 8bd09629..88a89898 100644 --- a/anoncreds/tests/utils/mock.rs +++ b/anoncreds/tests/utils/mock.rs @@ -19,10 +19,11 @@ use anoncreds::{ types::{ CredentialDefinitionConfig, CredentialRequest, CredentialRevocationConfig, CredentialRevocationState, MakeCredentialValues, PresentCredentials, PresentationRequest, - RegistryType, SignatureType, + RegistryType, RevocationStatusList, SignatureType, }, verifier, }; +use bitvec::bitvec; // {cred_def_id: { // schema_id, credential_values, support_revocation, rev_reg_id, rev_idx @@ -38,7 +39,7 @@ pub type ProverValues<'a> = HashMap<&'a str, (Vec<&'a str>, Vec<&'a str>)>; pub struct Mock<'a> { pub issuer_wallets: HashMap<&'a str, IssuerWallet<'a>>, pub prover_wallets: HashMap<&'a str, ProverWallet<'a>>, - pub ledger: Ledger, + pub ledger: Ledger<'a>, pub tails_path: &'a str, pub max_cred_num: u32, } @@ -163,6 +164,20 @@ impl<'a> Mock<'a> { .rev_regs .insert((&rev_reg_id, time_now), rev_reg.clone()); + // TODO create_revocation_registry needs issuance type to update this + let list = bitvec![0; self.max_cred_num as usize ]; + let revocation_list = RevocationStatusList::new( + Some(rev_reg_id), + list, + Some(rev_reg.clone().value), + Some(time_now), + ) + .unwrap(); + + self.ledger + .revcation_list + .insert(rev_reg_id, revocation_list); + self.ledger.rev_reg_defs.insert( RevocationRegistryDefinitionId::new_unchecked(*rev_reg_id), rev_reg_def_pub, @@ -211,14 +226,15 @@ impl<'a> Mock<'a> { issuer_wallet: &IssuerWallet, ledger: &Ledger, cred_request: &CredentialRequest, - cred_offer: &CredentialOffer, + offer: &CredentialOffer, rev_reg_id: &str, cred_def_id: &str, - schema: &Schema, values: &HashMap<&str, &str>, prev_rev_reg_time: u64, rev_idx: u32, ) -> (Credential, Option) { + let schema = self.ledger.schemas.get(&offer.schema_id).unwrap(); + let revocation_list = self.ledger.revcation_list.get(rev_reg_id); let mut cred_values = MakeCredentialValues::default(); let names: Vec = schema.attr_names.clone().0.into_iter().collect(); for (i, v) in names.iter().enumerate() { @@ -262,10 +278,11 @@ impl<'a> Mock<'a> { .get(&CredentialDefinitionId::new_unchecked(cred_def_id)) .unwrap(), &issuer_wallet.cred_defs[cred_def_id].private, - cred_offer, + offer, cred_request, cred_values.into(), rev_id, + revocation_list, rev_config, ) .expect("Error creating credential"); @@ -292,7 +309,7 @@ impl<'a> Mock<'a> { .unwrap(); // Prover creates a Credential Request let cred_req_data = prover::create_credential_request( - &self.prover_wallets[prover_id].did, + Some(prover_id), &cred_def, &self.prover_wallets[prover_id].master_secret, "default", @@ -308,7 +325,6 @@ impl<'a> Mock<'a> { &offer, *rev_reg_id, cred_def_id, - self.ledger.schemas.get(&offer.schema_id).unwrap(), cred_values, time_prev_rev_reg, *rev_idx, @@ -332,6 +348,9 @@ impl<'a> Mock<'a> { pw.cred_reqs.push(cred_req_data); pw.credentials.push(recv_cred); if let Some(rev_reg) = new_rev_reg { + let mut list = self.ledger.revcation_list.get_mut(*rev_reg_id).unwrap(); + list.unrevoke(*rev_idx as usize); + self.issuer_wallets .get_mut(issuer_id) .unwrap()