From 43e6f46dabcb5487296517b810b7a377aa5e112c Mon Sep 17 00:00:00 2001 From: blu3beri Date: Wed, 11 Jan 2023 10:20:12 +0100 Subject: [PATCH 01/10] removed the revocation registry config type Signed-off-by: blu3beri --- .../src/data_types/anoncreds/rev_reg_def.rs | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/anoncreds/src/data_types/anoncreds/rev_reg_def.rs b/anoncreds/src/data_types/anoncreds/rev_reg_def.rs index cfa19d93..fe75e68d 100644 --- a/anoncreds/src/data_types/anoncreds/rev_reg_def.rs +++ b/anoncreds/src/data_types/anoncreds/rev_reg_def.rs @@ -1,7 +1,7 @@ use std::str::FromStr; use crate::{ - data_types::{invalid, ConversionError, Validatable, ValidationError}, + data_types::{ConversionError, Validatable, ValidationError}, impl_anoncreds_object_identifier, }; @@ -109,20 +109,3 @@ impl Validatable for RevocationRegistryDefinitionV1 { pub struct RevocationRegistryDefinitionPrivate { pub value: ursa::cl::RevocationKeyPrivate, } - -#[derive(Deserialize, Debug, Serialize)] -pub struct RevocationRegistryConfig { - pub issuance_type: Option, - pub max_cred_num: Option, -} - -impl Validatable for RevocationRegistryConfig { - fn validate(&self) -> Result<(), ValidationError> { - if let Some(num_) = self.max_cred_num { - if num_ == 0 { - return Err(invalid!("RevocationRegistryConfig validation failed: `max_cred_num` must be greater than 0")); - } - } - Ok(()) - } -} From cb206ab10cda229d861c6586c286c7d43d9a0307 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Wed, 11 Jan 2023 11:05:15 +0100 Subject: [PATCH 02/10] removed V1 wrapper around revocation objects Signed-off-by: blu3beri --- anoncreds/src/data_types/anoncreds/rev_reg.rs | 40 ++------ .../src/data_types/anoncreds/rev_reg_def.rs | 11 +-- anoncreds/src/ffi/revocation.rs | 18 +--- anoncreds/src/services/issuer.rs | 98 ++++++------------- anoncreds/src/services/prover.rs | 8 +- anoncreds/src/services/verifier.rs | 10 +- anoncreds/tests/anoncreds_demos.rs | 18 ++-- 7 files changed, 56 insertions(+), 147 deletions(-) diff --git a/anoncreds/src/data_types/anoncreds/rev_reg.rs b/anoncreds/src/data_types/anoncreds/rev_reg.rs index c4f20fa0..ce16944f 100644 --- a/anoncreds/src/data_types/anoncreds/rev_reg.rs +++ b/anoncreds/src/data_types/anoncreds/rev_reg.rs @@ -10,49 +10,29 @@ use crate::{data_types::Validatable, error, impl_anoncreds_object_identifier}; impl_anoncreds_object_identifier!(RevocationRegistryId); #[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(tag = "ver")] -pub enum RevocationRegistry { - #[serde(rename = "1.0")] - RevocationRegistryV1(RevocationRegistryV1), +pub struct RevocationRegistry { + pub value: ursa::cl::RevocationRegistry, } impl RevocationRegistry { pub fn initial_delta(&self) -> RevocationRegistryDelta { - match self { - Self::RevocationRegistryV1(v1) => { - RevocationRegistryDelta::RevocationRegistryDeltaV1(RevocationRegistryDeltaV1 { - value: { - let empty = HashSet::new(); - ursa::cl::RevocationRegistryDelta::from_parts( - None, &v1.value, &empty, &empty, - ) - }, - }) - } + RevocationRegistryDelta { + value: { + let empty = HashSet::new(); + ursa::cl::RevocationRegistryDelta::from_parts(None, &self.value, &empty, &empty) + }, } } } -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct RevocationRegistryV1 { - pub value: ursa::cl::RevocationRegistry, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(tag = "ver")] -pub enum RevocationRegistryDelta { - #[serde(rename = "1.0")] - RevocationRegistryDeltaV1(RevocationRegistryDeltaV1), -} - -impl Validatable for RevocationRegistryDelta {} - #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct RevocationRegistryDeltaV1 { +pub struct RevocationRegistryDelta { pub value: ursa::cl::RevocationRegistryDelta, } +impl Validatable for RevocationRegistryDelta {} + #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct RevocationStatusList { diff --git a/anoncreds/src/data_types/anoncreds/rev_reg_def.rs b/anoncreds/src/data_types/anoncreds/rev_reg_def.rs index fe75e68d..4d7a364f 100644 --- a/anoncreds/src/data_types/anoncreds/rev_reg_def.rs +++ b/anoncreds/src/data_types/anoncreds/rev_reg_def.rs @@ -83,23 +83,16 @@ pub struct RevocationRegistryDefinitionValuePublicKeys { pub accum_key: ursa::cl::RevocationKeyPublic, } -#[derive(Clone, Debug, Deserialize, Serialize)] -#[serde(tag = "ver")] -pub enum RevocationRegistryDefinition { - #[serde(rename = "1.0")] - RevocationRegistryDefinitionV1(RevocationRegistryDefinitionV1), -} - #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] -pub struct RevocationRegistryDefinitionV1 { +pub struct RevocationRegistryDefinition { pub revoc_def_type: RegistryType, pub tag: String, pub cred_def_id: CredentialDefinitionId, pub value: RevocationRegistryDefinitionValue, } -impl Validatable for RevocationRegistryDefinitionV1 { +impl Validatable for RevocationRegistryDefinition { fn validate(&self) -> Result<(), ValidationError> { self.cred_def_id.validate() } diff --git a/anoncreds/src/ffi/revocation.rs b/anoncreds/src/ffi/revocation.rs index 9b908d26..32664eed 100644 --- a/anoncreds/src/ffi/revocation.rs +++ b/anoncreds/src/ffi/revocation.rs @@ -180,21 +180,9 @@ pub extern "C" fn anoncreds_revocation_registry_definition_get_attribute( let reg_def = handle.load()?; let reg_def = reg_def.cast_ref::()?; let val = match name.as_opt_str().unwrap_or_default() { - "max_cred_num" => match reg_def { - RevocationRegistryDefinition::RevocationRegistryDefinitionV1(r) => { - r.value.max_cred_num.to_string() - } - }, - "tails_hash" => match reg_def { - RevocationRegistryDefinition::RevocationRegistryDefinitionV1(r) => { - r.value.tails_hash.to_string() - } - }, - "tails_location" => match reg_def { - RevocationRegistryDefinition::RevocationRegistryDefinitionV1(r) => { - r.value.tails_location.to_string() - } - }, + "max_cred_num" => reg_def.value.max_cred_num.to_string(), + "tails_hash" => reg_def.value.tails_hash.to_string(), + "tails_location" => reg_def.value.tails_location.to_string(), s => return Err(err_msg!("Unsupported attribute: {}", s)), }; unsafe { *result_p = rust_string_to_c(val) }; diff --git a/anoncreds/src/services/issuer.rs b/anoncreds/src/services/issuer.rs index 88568dc3..f4a38884 100644 --- a/anoncreds/src/services/issuer.rs +++ b/anoncreds/src/services/issuer.rs @@ -13,11 +13,8 @@ use crate::data_types::anoncreds::schema::SchemaId; use crate::data_types::anoncreds::{ cred_def::{CredentialDefinition, CredentialDefinitionData}, nonce::Nonce, - rev_reg::{RevocationRegistryDeltaV1, RevocationRegistryV1}, - rev_reg_def::{ - RevocationRegistryDefinitionV1, RevocationRegistryDefinitionValue, - RevocationRegistryDefinitionValuePublicKeys, - }, + rev_reg::RevocationRegistryDelta, + rev_reg_def::{RevocationRegistryDefinitionValue, RevocationRegistryDefinitionValuePublicKeys}, schema::Schema, }; use crate::error::Result; @@ -164,18 +161,16 @@ where tails_hash, }; - let revoc_reg_def = RevocationRegistryDefinition::RevocationRegistryDefinitionV1( - RevocationRegistryDefinitionV1 { - revoc_def_type: rev_reg_type, - tag: tag.to_string(), - cred_def_id, - value: revoc_reg_def_value, - }, - ); + let revoc_reg_def = RevocationRegistryDefinition { + revoc_def_type: rev_reg_type, + tag: tag.to_string(), + cred_def_id, + value: revoc_reg_def_value, + }; - let revoc_reg = RevocationRegistry::RevocationRegistryV1(RevocationRegistryV1 { + let revoc_reg = RevocationRegistry { value: revoc_registry, - }); + }; // now update registry to reflect issuance-by-default let (revoc_reg, revoc_init_delta) = if issuance_type == IssuanceType::ISSUANCE_BY_DEFAULT { @@ -214,10 +209,8 @@ pub fn update_revocation_registry( revoked: BTreeSet, tails_reader: &TailsReader, ) -> Result<(RevocationRegistry, RevocationRegistryDelta)> { - let RevocationRegistryDefinition::RevocationRegistryDefinitionV1(rev_reg_def) = rev_reg_def; - let mut rev_reg = match rev_reg { - RevocationRegistry::RevocationRegistryV1(v1) => v1.value.clone(), - }; + let mut rev_reg = rev_reg.value.clone(); + let max_cred_num = rev_reg_def.value.max_cred_num; let delta = CryptoIssuer::update_revocation_registry( &mut rev_reg, @@ -227,10 +220,8 @@ pub fn update_revocation_registry( tails_reader, )?; Ok(( - RevocationRegistry::RevocationRegistryV1(RevocationRegistryV1 { value: rev_reg }), - RevocationRegistryDelta::RevocationRegistryDeltaV1(RevocationRegistryDeltaV1 { - value: delta, - }), + RevocationRegistry { value: rev_reg }, + RevocationRegistryDelta { value: delta }, )) } @@ -290,12 +281,8 @@ pub fn create_credential( let (credential_signature, signature_correctness_proof, rev_reg, rev_reg_delta, witness) = match revocation_config { Some(revocation) => { - let rev_reg_def = match revocation.reg_def { - RevocationRegistryDefinition::RevocationRegistryDefinitionV1(v1) => &v1.value, - }; - let mut rev_reg = match revocation.registry { - RevocationRegistry::RevocationRegistryV1(v1) => v1.value.clone(), - }; + 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( @@ -370,13 +357,8 @@ pub fn create_credential( witness, }; - let rev_reg = rev_reg - .map(|reg| RevocationRegistry::RevocationRegistryV1(RevocationRegistryV1 { value: reg })); - let rev_reg_delta = rev_reg_delta.map(|delta| { - RevocationRegistryDelta::RevocationRegistryDeltaV1(RevocationRegistryDeltaV1 { - value: delta, - }) - }); + let rev_reg = rev_reg.map(|reg| RevocationRegistry { value: reg }); + let rev_reg_delta = rev_reg_delta.map(|delta| RevocationRegistryDelta { value: delta }); trace!( "create_credential <<< credential {:?}, rev_reg_delta {:?}", @@ -400,20 +382,15 @@ pub fn revoke_credential( secret!(&cred_rev_idx) ); - let max_cred_num = match rev_reg_def { - RevocationRegistryDefinition::RevocationRegistryDefinitionV1(v1) => v1.value.max_cred_num, - }; - let mut rev_reg = match rev_reg { - RevocationRegistry::RevocationRegistryV1(v1) => v1.value.clone(), - }; + let max_cred_num = rev_reg_def.value.max_cred_num; + let mut rev_reg = rev_reg.value.clone(); let rev_reg_delta = CryptoIssuer::revoke_credential(&mut rev_reg, max_cred_num, cred_rev_idx, tails_reader)?; - let new_rev_reg = - RevocationRegistry::RevocationRegistryV1(RevocationRegistryV1 { value: rev_reg }); - let delta = RevocationRegistryDelta::RevocationRegistryDeltaV1(RevocationRegistryDeltaV1 { + let new_rev_reg = RevocationRegistry { value: rev_reg }; + let delta = RevocationRegistryDelta { value: rev_reg_delta, - }); + }; trace!("revoke <<< rev_reg_delta {:?}", delta); Ok((new_rev_reg, delta)) @@ -433,20 +410,16 @@ pub fn recover_credential( secret!(&cred_rev_idx) ); - let max_cred_num = match rev_reg_def { - RevocationRegistryDefinition::RevocationRegistryDefinitionV1(v1) => v1.value.max_cred_num, - }; - let mut rev_reg = match rev_reg { - RevocationRegistry::RevocationRegistryV1(v1) => v1.value.clone(), - }; + let max_cred_num = rev_reg_def.value.max_cred_num; + let mut rev_reg = rev_reg.value.clone(); + let rev_reg_delta = CryptoIssuer::recovery_credential(&mut rev_reg, max_cred_num, cred_rev_idx, tails_reader)?; - let new_rev_reg = - RevocationRegistry::RevocationRegistryV1(RevocationRegistryV1 { value: rev_reg }); - let delta = RevocationRegistryDelta::RevocationRegistryDeltaV1(RevocationRegistryDeltaV1 { + let new_rev_reg = RevocationRegistry { value: rev_reg }; + let delta = RevocationRegistryDelta { value: rev_reg_delta, - }); + }; trace!("recover <<< rev_reg_delta {:?}", delta); Ok((new_rev_reg, delta)) @@ -456,16 +429,9 @@ pub fn merge_revocation_registry_deltas( rev_reg_delta: &RevocationRegistryDelta, other_delta: &RevocationRegistryDelta, ) -> Result { - match (rev_reg_delta, other_delta) { - ( - RevocationRegistryDelta::RevocationRegistryDeltaV1(v1), - RevocationRegistryDelta::RevocationRegistryDeltaV1(other), - ) => { - let mut result = v1.clone(); - result.value.merge(&other.value)?; - Ok(RevocationRegistryDelta::RevocationRegistryDeltaV1(result)) - } - } + let mut result = rev_reg_delta.clone(); + result.value.merge(&other_delta.value)?; + Ok(result) } #[cfg(test)] diff --git a/anoncreds/src/services/prover.rs b/anoncreds/src/services/prover.rs index c70dba78..bc503d25 100644 --- a/anoncreds/src/services/prover.rs +++ b/anoncreds/src/services/prover.rs @@ -104,12 +104,7 @@ pub fn process_credential( )?; let credential_values = build_credential_values(&credential.values.0, Some(&master_secret.value))?; - let rev_pub_key = match rev_reg_def { - Some(RevocationRegistryDefinition::RevocationRegistryDefinitionV1(def)) => { - Some(&def.value.public_keys.accum_key) - } - _ => None, - }; + let rev_pub_key = rev_reg_def.map(|d| &d.value.public_keys.accum_key); CryptoProver::process_credential_signature( &mut credential.signature, @@ -270,7 +265,6 @@ pub fn create_or_update_revocation_state( old_rev_reg_list, ); - let RevocationRegistryDefinition::RevocationRegistryDefinitionV1(revoc_reg_def) = revoc_reg_def; let mut issued = HashSet::::new(); let mut revoked = HashSet::::new(); let witness = diff --git a/anoncreds/src/services/verifier.rs b/anoncreds/src/services/verifier.rs index ec973c44..bf85b598 100644 --- a/anoncreds/src/services/verifier.rs +++ b/anoncreds/src/services/verifier.rs @@ -173,14 +173,8 @@ pub fn verify_presentation( cred_def.value.revocation.as_ref(), )?; - let rev_key_pub = rev_reg_def.as_ref().map(|r_reg_def| match r_reg_def { - RevocationRegistryDefinition::RevocationRegistryDefinitionV1(reg_def) => { - ®_def.value.public_keys.accum_key - } - }); - let rev_reg = rev_reg.as_ref().map(|r_reg| match r_reg { - RevocationRegistry::RevocationRegistryV1(reg_def) => ®_def.value, - }); + let rev_key_pub = rev_reg_def.map(|d| &d.value.public_keys.accum_key); + let rev_reg = rev_reg.map(|r| &r.value); proof_verifier.add_sub_proof_request( &sub_pres_request, diff --git a/anoncreds/tests/anoncreds_demos.rs b/anoncreds/tests/anoncreds_demos.rs index 8af3aae8..2ef8088f 100644 --- a/anoncreds/tests/anoncreds_demos.rs +++ b/anoncreds/tests/anoncreds_demos.rs @@ -16,7 +16,7 @@ use anoncreds::{ types::{ CredentialDefinitionConfig, CredentialRevocationConfig, CredentialRevocationState, IssuanceType, MakeCredentialValues, PresentCredentials, PresentationRequest, RegistryType, - RevocationRegistry, RevocationRegistryDefinition, RevocationStatusList, SignatureType, + RevocationStatusList, SignatureType, }, verifier, }; @@ -339,11 +339,8 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { let rev_reg_id = RevocationRegistryId::new_unchecked(REV_REG_ID); // Get the location of the tails_file so it can be read - let location = match rev_reg_def_pub.clone() { - RevocationRegistryDefinition::RevocationRegistryDefinitionV1(value) => { - value.value.tails_location - } - }; + let location = rev_reg_def_pub.clone().value.tails_location; + let tr = TailsFileReader::new_tails_reader(location.as_str()); // The Prover's index in the revocation list is REV_IDX @@ -414,9 +411,8 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { // Prover: here we deliberately do not put in the same timestamp as the global non_revoked time interval, // this shows that it is not used let prover_timestamp = 1234u64; - let rev_reg = match cred_rev_reg.clone() { - RevocationRegistry::RevocationRegistryV1(r) => r.value, - }; + let rev_reg = cred_rev_reg.value.clone(); + let rev_state = CredentialRevocationState { timestamp: prover_timestamp, rev_reg: rev_reg.clone(), @@ -477,9 +473,7 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { // revoked_bit is not a reference so can drop drop(revoked_bit); - let ursa_rev_reg = match revoked_rev_reg.clone() { - RevocationRegistry::RevocationRegistryV1(v) => v.value, - }; + let ursa_rev_reg = revoked_rev_reg.value.clone(); let revocation_list = RevocationStatusList::new(REV_REG_ID, list, ursa_rev_reg, prover_timestamp).unwrap(); From 8b380474840347beca120a408583eda682220f5b Mon Sep 17 00:00:00 2001 From: blu3beri Date: Wed, 11 Jan 2023 11:12:44 +0100 Subject: [PATCH 03/10] removed issuance by default reference Signed-off-by: blu3beri --- .../src/data_types/anoncreds/rev_reg_def.rs | 40 ------------------- anoncreds/src/ffi/revocation.rs | 11 +---- anoncreds/src/services/issuer.rs | 23 +++-------- anoncreds/src/services/prover.rs | 6 ++- anoncreds/src/services/types.rs | 3 +- anoncreds/tests/anoncreds_demos.rs | 3 +- 6 files changed, 14 insertions(+), 72 deletions(-) diff --git a/anoncreds/src/data_types/anoncreds/rev_reg_def.rs b/anoncreds/src/data_types/anoncreds/rev_reg_def.rs index 4d7a364f..26c1016e 100644 --- a/anoncreds/src/data_types/anoncreds/rev_reg_def.rs +++ b/anoncreds/src/data_types/anoncreds/rev_reg_def.rs @@ -9,47 +9,8 @@ use super::cred_def::CredentialDefinitionId; pub const CL_ACCUM: &str = "CL_ACCUM"; -pub const ISSUANCE_BY_DEFAULT: &str = "ISSUANCE_BY_DEFAULT"; -pub const ISSUANCE_ON_DEMAND: &str = "ISSUANCE_ON_DEMAND"; - impl_anoncreds_object_identifier!(RevocationRegistryDefinitionId); -#[allow(non_camel_case_types)] -#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)] -pub enum IssuanceType { - #[default] - ISSUANCE_BY_DEFAULT, - ISSUANCE_ON_DEMAND, -} - -impl FromStr for IssuanceType { - type Err = ConversionError; - - fn from_str(s: &str) -> Result { - match s { - ISSUANCE_BY_DEFAULT => Ok(Self::ISSUANCE_BY_DEFAULT), - ISSUANCE_ON_DEMAND => Ok(Self::ISSUANCE_ON_DEMAND), - _ => Err(ConversionError::from_msg("Invalid issuance type")), - } - } -} - -impl From for usize { - fn from(value: IssuanceType) -> usize { - match value { - // Credentials are by default revoked - IssuanceType::ISSUANCE_ON_DEMAND => 1, - // Credentials are by default not revoked - IssuanceType::ISSUANCE_BY_DEFAULT => 0, - } - } -} - -impl IssuanceType { - pub fn to_bool(&self) -> bool { - *self == IssuanceType::ISSUANCE_BY_DEFAULT - } -} #[allow(non_camel_case_types)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub enum RegistryType { @@ -70,7 +31,6 @@ impl FromStr for RegistryType { #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct RevocationRegistryDefinitionValue { - pub issuance_type: IssuanceType, pub max_cred_num: u32, pub public_keys: RevocationRegistryDefinitionValuePublicKeys, pub tails_hash: String, diff --git a/anoncreds/src/ffi/revocation.rs b/anoncreds/src/ffi/revocation.rs index 32664eed..a748570d 100644 --- a/anoncreds/src/ffi/revocation.rs +++ b/anoncreds/src/ffi/revocation.rs @@ -16,9 +16,8 @@ use crate::services::{ prover::create_or_update_revocation_state, tails::{TailsFileReader, TailsFileWriter}, types::{ - CredentialRevocationState, IssuanceType, RegistryType, RevocationRegistry, - RevocationRegistryDefinition, RevocationRegistryDefinitionPrivate, RevocationRegistryDelta, - RevocationStatusList, + CredentialRevocationState, RegistryType, RevocationRegistry, RevocationRegistryDefinition, + RevocationRegistryDefinitionPrivate, RevocationRegistryDelta, RevocationStatusList, }, }; @@ -28,7 +27,6 @@ pub extern "C" fn anoncreds_create_revocation_registry( cred_def_id: FfiStr, tag: FfiStr, rev_reg_type: FfiStr, - issuance_type: FfiStr, max_cred_num: i64, tails_dir_path: FfiStr, reg_def_p: *mut ObjectHandle, @@ -51,17 +49,12 @@ pub extern "C" fn anoncreds_create_revocation_registry( .ok_or_else(|| err_msg!("Missing registry type"))?; RegistryType::from_str(rtype).map_err(err_map!(Input))? }; - let issuance_type = match issuance_type.as_opt_str() { - Some(s) => IssuanceType::from_str(s).map_err(err_map!(Input))?, - None => IssuanceType::default(), - }; let mut tails_writer = TailsFileWriter::new(tails_dir_path.into_opt_string()); let (reg_def, reg_def_private, reg_entry, reg_init_delta) = create_revocation_registry( cred_def.load()?.cast_ref()?, cred_def_id, tag, rev_reg_type, - issuance_type, max_cred_num .try_into() .map_err(|_| err_msg!("Invalid maximum credential count"))?, diff --git a/anoncreds/src/services/issuer.rs b/anoncreds/src/services/issuer.rs index f4a38884..d8d90703 100644 --- a/anoncreds/src/services/issuer.rs +++ b/anoncreds/src/services/issuer.rs @@ -121,7 +121,6 @@ pub fn create_revocation_registry( cred_def_id: impl TryInto, tag: &str, rev_reg_type: RegistryType, - issuance_type: IssuanceType, max_cred_num: u32, tails_writer: &mut TW, ) -> Result<( @@ -133,8 +132,8 @@ pub fn create_revocation_registry( where TW: TailsWriter, { - trace!("create_revocation_registry >>> cred_def: {:?}, tag: {:?}, max_cred_num: {:?}, rev_reg_type: {:?}, issuance_type: {:?}", - cred_def, tag, max_cred_num, rev_reg_type, issuance_type); + trace!("create_revocation_registry >>> cred_def: {:?}, tag: {:?}, max_cred_num: {:?}, rev_reg_type: {:?}", + cred_def, tag, max_cred_num, rev_reg_type); let cred_def_id = cred_def_id.try_into()?; let credential_pub_key = cred_def.get_public_key().map_err(err_map!( @@ -155,7 +154,6 @@ where let revoc_reg_def_value = RevocationRegistryDefinitionValue { max_cred_num, - issuance_type, public_keys: rev_keys_pub, tails_location: tails_location.clone(), tails_hash, @@ -173,7 +171,7 @@ where }; // now update registry to reflect issuance-by-default - let (revoc_reg, revoc_init_delta) = if issuance_type == IssuanceType::ISSUANCE_BY_DEFAULT { + let (revoc_reg, revoc_init_delta) = { let tails_reader = TailsFileReader::new_tails_reader(&tails_location); let issued = BTreeSet::from_iter(1..=max_cred_num); update_revocation_registry( @@ -183,9 +181,6 @@ where BTreeSet::new(), &tails_reader, )? - } else { - let delta = revoc_reg.initial_delta(); - (revoc_reg, delta) }; let revoc_def_priv = RevocationRegistryDefinitionPrivate { @@ -296,7 +291,8 @@ pub fn create_credential( &cred_def_private.value, revocation.registry_idx, rev_reg_def.max_cred_num, - rev_reg_def.issuance_type.to_bool(), + // issuance by default + true, &mut rev_reg, &revocation.reg_def_private.value, &revocation.tails_reader, @@ -304,14 +300,7 @@ pub fn create_credential( let witness = { let empty = HashSet::new(); - let (by_default, issued, revoked) = match rev_reg_def.issuance_type { - IssuanceType::ISSUANCE_ON_DEMAND => { - (false, revocation.registry_used, &empty) - } - IssuanceType::ISSUANCE_BY_DEFAULT => { - (true, &empty, revocation.registry_used) - } - }; + let (by_default, issued, revoked) = (true, &empty, revocation.registry_used); let rev_reg_delta = CryptoRevocationRegistryDelta::from_parts(None, &rev_reg, issued, revoked); diff --git a/anoncreds/src/services/prover.rs b/anoncreds/src/services/prover.rs index bc503d25..39da297d 100644 --- a/anoncreds/src/services/prover.rs +++ b/anoncreds/src/services/prover.rs @@ -293,7 +293,8 @@ pub fn create_or_update_revocation_state( } else { let list_size = usize::try_from(revoc_reg_def.value.max_cred_num) .map_err(|e| Error::from_msg(crate::ErrorKind::InvalidState, e.to_string()))?; - let bit: usize = revoc_reg_def.value.issuance_type.into(); + // Issuance by default + let bit: usize = 0; let list = bitvec![bit; list_size]; _create_index_deltas( rev_reg_list.state_owned().bitxor(list), @@ -306,7 +307,8 @@ pub fn create_or_update_revocation_state( Witness::new( rev_reg_idx, revoc_reg_def.value.max_cred_num, - revoc_reg_def.value.issuance_type.to_bool(), + // issuance by default + true, &rev_reg_delta, &tails_reader, )? diff --git a/anoncreds/src/services/types.rs b/anoncreds/src/services/types.rs index f792f258..27d89146 100644 --- a/anoncreds/src/services/types.rs +++ b/anoncreds/src/services/types.rs @@ -11,8 +11,7 @@ pub use crate::data_types::anoncreds::{ presentation::Presentation, rev_reg::{RevocationRegistry, RevocationRegistryDelta, RevocationStatusList}, rev_reg_def::{ - IssuanceType, RegistryType, RevocationRegistryDefinition, - RevocationRegistryDefinitionPrivate, + RegistryType, RevocationRegistryDefinition, RevocationRegistryDefinitionPrivate, }, schema::AttributeNames, }; diff --git a/anoncreds/tests/anoncreds_demos.rs b/anoncreds/tests/anoncreds_demos.rs index 2ef8088f..1966e773 100644 --- a/anoncreds/tests/anoncreds_demos.rs +++ b/anoncreds/tests/anoncreds_demos.rs @@ -15,7 +15,7 @@ use anoncreds::{ tails::{TailsFileReader, TailsFileWriter}, types::{ CredentialDefinitionConfig, CredentialRevocationConfig, CredentialRevocationState, - IssuanceType, MakeCredentialValues, PresentCredentials, PresentationRequest, RegistryType, + MakeCredentialValues, PresentCredentials, PresentationRequest, RegistryType, RevocationStatusList, SignatureType, }, verifier, @@ -286,7 +286,6 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { CRED_DEF_ID, "some_tag", RegistryType::CL_ACCUM, - IssuanceType::ISSUANCE_BY_DEFAULT, MAX_CRED_NUM, &mut tf, ) From b32a7f4b6d347f4cb09e6fe5bfc33289246b21b9 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Wed, 11 Jan 2023 13:49:08 +0100 Subject: [PATCH 04/10] added issuer_id Signed-off-by: blu3beri --- anoncreds/src/data_types/anoncreds/rev_reg_def.rs | 3 ++- anoncreds/src/ffi/revocation.rs | 5 +++++ anoncreds/src/services/issuer.rs | 3 +++ anoncreds/tests/anoncreds_demos.rs | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/anoncreds/src/data_types/anoncreds/rev_reg_def.rs b/anoncreds/src/data_types/anoncreds/rev_reg_def.rs index 26c1016e..e0d84479 100644 --- a/anoncreds/src/data_types/anoncreds/rev_reg_def.rs +++ b/anoncreds/src/data_types/anoncreds/rev_reg_def.rs @@ -5,7 +5,7 @@ use crate::{ impl_anoncreds_object_identifier, }; -use super::cred_def::CredentialDefinitionId; +use super::{cred_def::CredentialDefinitionId, issuer_id::IssuerId}; pub const CL_ACCUM: &str = "CL_ACCUM"; @@ -46,6 +46,7 @@ pub struct RevocationRegistryDefinitionValuePublicKeys { #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct RevocationRegistryDefinition { + pub issuer_id: IssuerId, pub revoc_def_type: RegistryType, pub tag: String, pub cred_def_id: CredentialDefinitionId, diff --git a/anoncreds/src/ffi/revocation.rs b/anoncreds/src/ffi/revocation.rs index a748570d..b5ec5aa8 100644 --- a/anoncreds/src/ffi/revocation.rs +++ b/anoncreds/src/ffi/revocation.rs @@ -25,6 +25,7 @@ use crate::services::{ pub extern "C" fn anoncreds_create_revocation_registry( cred_def: ObjectHandle, cred_def_id: FfiStr, + issuer_id: FfiStr, tag: FfiStr, rev_reg_type: FfiStr, max_cred_num: i64, @@ -43,6 +44,9 @@ pub extern "C" fn anoncreds_create_revocation_registry( let cred_def_id = cred_def_id .as_opt_str() .ok_or_else(|| err_msg!("Missing cred def id"))?; + let issuer_id = issuer_id + .as_opt_str() + .ok_or_else(|| err_msg!("Missing issuer id"))?; let rev_reg_type = { let rtype = rev_reg_type .as_opt_str() @@ -53,6 +57,7 @@ pub extern "C" fn anoncreds_create_revocation_registry( let (reg_def, reg_def_private, reg_entry, reg_init_delta) = create_revocation_registry( cred_def.load()?.cast_ref()?, cred_def_id, + issuer_id, tag, rev_reg_type, max_cred_num diff --git a/anoncreds/src/services/issuer.rs b/anoncreds/src/services/issuer.rs index d8d90703..d9d3cd3a 100644 --- a/anoncreds/src/services/issuer.rs +++ b/anoncreds/src/services/issuer.rs @@ -119,6 +119,7 @@ where pub fn create_revocation_registry( cred_def: &CredentialDefinition, cred_def_id: impl TryInto, + issuer_id: impl TryInto, tag: &str, rev_reg_type: RegistryType, max_cred_num: u32, @@ -135,6 +136,7 @@ where trace!("create_revocation_registry >>> cred_def: {:?}, tag: {:?}, max_cred_num: {:?}, rev_reg_type: {:?}", cred_def, tag, max_cred_num, rev_reg_type); let cred_def_id = cred_def_id.try_into()?; + let issuer_id = issuer_id.try_into()?; let credential_pub_key = cred_def.get_public_key().map_err(err_map!( Unexpected, @@ -161,6 +163,7 @@ where let revoc_reg_def = RevocationRegistryDefinition { revoc_def_type: rev_reg_type, + issuer_id, tag: tag.to_string(), cred_def_id, value: revoc_reg_def_value, diff --git a/anoncreds/tests/anoncreds_demos.rs b/anoncreds/tests/anoncreds_demos.rs index 1966e773..5aa1f245 100644 --- a/anoncreds/tests/anoncreds_demos.rs +++ b/anoncreds/tests/anoncreds_demos.rs @@ -284,6 +284,7 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { let (rev_reg_def_pub, rev_reg_def_priv, rev_reg, _) = issuer::create_revocation_registry( &cred_def_pub, CRED_DEF_ID, + ISSUER_ID, "some_tag", RegistryType::CL_ACCUM, MAX_CRED_NUM, From ffb81fc3fef4026e1829be0747ead35115fe0093 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Thu, 12 Jan 2023 10:18:05 +0100 Subject: [PATCH 05/10] Added revocation status list to create_credential function Signed-off-by: blu3beri --- anoncreds/src/data_types/anoncreds/rev_reg.rs | 4 ++ anoncreds/src/ffi/credential.rs | 3 ++ anoncreds/src/services/issuer.rs | 44 +++++++++++++------ anoncreds/tests/anoncreds_demos.rs | 1 + 4 files changed, 39 insertions(+), 13 deletions(-) diff --git a/anoncreds/src/data_types/anoncreds/rev_reg.rs b/anoncreds/src/data_types/anoncreds/rev_reg.rs index ce16944f..61e232a2 100644 --- a/anoncreds/src/data_types/anoncreds/rev_reg.rs +++ b/anoncreds/src/data_types/anoncreds/rev_reg.rs @@ -63,6 +63,10 @@ impl RevocationStatusList { self.revocation_list.clone() } + pub(crate) fn get(&self, idx: usize) -> Option { + self.revocation_list.get(idx).as_deref().copied() + } + pub fn new( rev_reg_id: &str, revocation_list: bitvec::vec::BitVec, diff --git a/anoncreds/src/ffi/credential.rs b/anoncreds/src/ffi/credential.rs index 3fd17675..6b251711 100644 --- a/anoncreds/src/ffi/credential.rs +++ b/anoncreds/src/ffi/credential.rs @@ -60,6 +60,7 @@ pub extern "C" fn anoncreds_create_credential( attr_raw_values: FfiStrList, attr_enc_values: FfiStrList, rev_reg_id: FfiStr, + rev_reg_list: ObjectHandle, revocation: *const FfiCredRevInfo, cred_p: *mut ObjectHandle, rev_reg_p: *mut ObjectHandle, @@ -135,6 +136,7 @@ pub extern "C" fn anoncreds_create_credential( } else { None }; + let (cred, rev_reg, rev_delta) = create_credential( cred_def.load()?.cast_ref()?, cred_def_private.load()?.cast_ref()?, @@ -142,6 +144,7 @@ pub extern "C" fn anoncreds_create_credential( cred_request.load()?.cast_ref()?, cred_values.into(), rev_reg_id, + rev_reg_list.load()?.cast_ref().ok(), revocation_config .as_ref() .map(RevocationConfig::as_ref_config) diff --git a/anoncreds/src/services/issuer.rs b/anoncreds/src/services/issuer.rs index d9d3cd3a..590e404d 100644 --- a/anoncreds/src/services/issuer.rs +++ b/anoncreds/src/services/issuer.rs @@ -256,6 +256,7 @@ pub fn create_credential( cred_request: &CredentialRequest, cred_values: CredentialValues, rev_reg_id: Option, + rev_status_list: Option<&RevocationStatusList>, revocation_config: Option, ) -> Result<( Credential, @@ -277,10 +278,28 @@ pub fn create_credential( let prover_did = cred_request.prover_did.as_ref().unwrap_or(&rand_str); let (credential_signature, signature_correctness_proof, rev_reg, rev_reg_delta, witness) = - match revocation_config { - Some(revocation) => { - let rev_reg_def = &revocation.reg_def.value; - let mut rev_reg = revocation.registry.value.clone(); + match (revocation_config, rev_status_list ) { + (Some(revocation_config), Some(rev_status_list)) => { + let rev_reg_def = &revocation_config.reg_def.value; + let mut rev_reg = revocation_config.registry.value.clone(); + + let status = rev_status_list.get(revocation_config.registry_idx as usize).ok_or_else(|| + err_msg!("Revocation status list does not have the index {}", revocation_config.registry_idx) + )?; + + // This will be a temporary solution for the `issuance_on_demand` vs + // `issuance_by_default` state. Right now, we pass in the revcation status list and + // we check in this list whether the provided idx (revocation_config.registry_idx) + // is inside the revocation status list. If it is not in there we hit an edge case, + // which should not be possible within the happy flow. + // + // If the index is inside the revocation status list we check whether it is set to + // `true` or `false` within the bitvec. + // When it is set to `true`, or 1, we invert the value. This means that we use + // `issuance_on_demand`. + // When it is set to `false`, or 0, we invert the value. This means that we use + // `issuance_by_default`. + let issuance_type = !status; let (credential_signature, signature_correctness_proof, delta) = CryptoIssuer::sign_credential_with_revoc( @@ -292,27 +311,26 @@ pub fn create_credential( &credential_values, &cred_public_key, &cred_def_private.value, - revocation.registry_idx, + revocation_config.registry_idx, rev_reg_def.max_cred_num, - // issuance by default - true, + issuance_type, &mut rev_reg, - &revocation.reg_def_private.value, - &revocation.tails_reader, + &revocation_config.reg_def_private.value, + &revocation_config.tails_reader, )?; let witness = { let empty = HashSet::new(); - let (by_default, issued, revoked) = (true, &empty, revocation.registry_used); + let (by_default, issued, revoked) = (true, &empty, revocation_config.registry_used); let rev_reg_delta = CryptoRevocationRegistryDelta::from_parts(None, &rev_reg, issued, revoked); Witness::new( - revocation.registry_idx, + revocation_config.registry_idx, rev_reg_def.max_cred_num, by_default, &rev_reg_delta, - &revocation.tails_reader, + &revocation_config.tails_reader, )? }; ( @@ -323,7 +341,7 @@ pub fn create_credential( Some(witness), ) } - None => { + _ => { let (signature, correctness_proof) = CryptoIssuer::sign_credential( prover_did, &cred_request.blinded_ms, diff --git a/anoncreds/tests/anoncreds_demos.rs b/anoncreds/tests/anoncreds_demos.rs index 5aa1f245..8490b201 100644 --- a/anoncreds/tests/anoncreds_demos.rs +++ b/anoncreds/tests/anoncreds_demos.rs @@ -111,6 +111,7 @@ fn anoncreds_works_for_single_issuer_single_prover() { cred_values.into(), None, None, + None, ) .expect("Error creating credential"); From c25245b5b5482b1771b584a001e397db1c99ca9c Mon Sep 17 00:00:00 2001 From: blu3beri Date: Thu, 12 Jan 2023 14:00:28 +0100 Subject: [PATCH 06/10] updated rev_reg_id to rev_reg_def_id Signed-off-by: blu3beri --- anoncreds/src/data_types/anoncreds/rev_reg.rs | 12 +- anoncreds/src/ffi/credential.rs | 4 +- anoncreds/src/ffi/revocation.rs | 10 +- anoncreds/src/services/issuer.rs | 18 ++- anoncreds/src/services/prover.rs | 107 +++++++++--------- anoncreds/tests/anoncreds_demos.rs | 13 ++- 6 files changed, 89 insertions(+), 75 deletions(-) diff --git a/anoncreds/src/data_types/anoncreds/rev_reg.rs b/anoncreds/src/data_types/anoncreds/rev_reg.rs index 61e232a2..918f662f 100644 --- a/anoncreds/src/data_types/anoncreds/rev_reg.rs +++ b/anoncreds/src/data_types/anoncreds/rev_reg.rs @@ -36,7 +36,7 @@ impl Validatable for RevocationRegistryDelta {} #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct RevocationStatusList { - rev_reg_id: RevocationRegistryId, + rev_reg_def_id: RevocationRegistryId, #[serde(with = "serde_revocation_list")] revocation_list: bitvec::vec::BitVec, #[serde(flatten)] @@ -45,8 +45,8 @@ pub struct RevocationStatusList { } impl From<&RevocationStatusList> for ursa::cl::RevocationRegistry { - fn from(rev_reg_list: &RevocationStatusList) -> ursa::cl::RevocationRegistry { - rev_reg_list.registry.clone() + fn from(rev_status_list: &RevocationStatusList) -> ursa::cl::RevocationRegistry { + rev_status_list.registry.clone() } } @@ -68,13 +68,13 @@ impl RevocationStatusList { } pub fn new( - rev_reg_id: &str, + rev_reg_def_id: &str, revocation_list: bitvec::vec::BitVec, registry: ursa::cl::RevocationRegistry, timestamp: u64, ) -> Result { Ok(RevocationStatusList { - rev_reg_id: RevocationRegistryId::new(rev_reg_id)?, + rev_reg_def_id: RevocationRegistryId::new(rev_reg_def_id)?, revocation_list, registry, timestamp, @@ -141,7 +141,7 @@ mod tests { const REVOCATION_LIST: &str = r#" { - "revRegId": "reg", + "revRegDefId": "reg", "revocationList": [1, 1, 1, 1], "accum": "1 1379509F4D411630D308A5ABB4F422FCE6737B330B1C5FD286AA5C26F2061E60 1 235535CC45D4816C7686C5A402A230B35A62DDE82B4A652E384FD31912C4E4BB 1 0C94B61595FCAEFC892BB98A27D524C97ED0B7ED1CC49AD6F178A59D4199C9A4 1 172482285606DEE8500FC8A13E6A35EC071F8B84F0EB4CD3DD091C0B4CD30E5E 2 095E45DDF417D05FB10933FFC63D474548B7FFFF7888802F07FFFFFF7D07A8A8 1 0000000000000000000000000000000000000000000000000000000000000000", "timestamp": 1234 diff --git a/anoncreds/src/ffi/credential.rs b/anoncreds/src/ffi/credential.rs index 6b251711..757e06ca 100644 --- a/anoncreds/src/ffi/credential.rs +++ b/anoncreds/src/ffi/credential.rs @@ -60,7 +60,7 @@ pub extern "C" fn anoncreds_create_credential( attr_raw_values: FfiStrList, attr_enc_values: FfiStrList, rev_reg_id: FfiStr, - rev_reg_list: ObjectHandle, + rev_status_list: ObjectHandle, revocation: *const FfiCredRevInfo, cred_p: *mut ObjectHandle, rev_reg_p: *mut ObjectHandle, @@ -144,7 +144,7 @@ pub extern "C" fn anoncreds_create_credential( cred_request.load()?.cast_ref()?, cred_values.into(), rev_reg_id, - rev_reg_list.load()?.cast_ref().ok(), + rev_status_list.load()?.cast_ref().ok(), revocation_config .as_ref() .map(RevocationConfig::as_ref_config) diff --git a/anoncreds/src/ffi/revocation.rs b/anoncreds/src/ffi/revocation.rs index b5ec5aa8..266cee1c 100644 --- a/anoncreds/src/ffi/revocation.rs +++ b/anoncreds/src/ffi/revocation.rs @@ -232,17 +232,17 @@ impl_anoncreds_object_from_json!(RevocationStatusList, anoncreds_revocation_list #[no_mangle] pub extern "C" fn anoncreds_create_or_update_revocation_state( rev_reg_def: ObjectHandle, - rev_reg_list: ObjectHandle, + rev_status_list: ObjectHandle, rev_reg_index: i64, tails_path: FfiStr, rev_state: ObjectHandle, - old_rev_reg_list: ObjectHandle, + old_rev_status_list: ObjectHandle, rev_state_p: *mut ObjectHandle, ) -> ErrorCode { catch_error(|| { check_useful_c_ptr!(rev_state_p); let prev_rev_state = rev_state.opt_load()?; - let prev_rev_reg_list = old_rev_reg_list.opt_load()?; + let prev_rev_status_list = old_rev_status_list.opt_load()?; let tails_reader = TailsFileReader::new_tails_reader( tails_path .as_opt_str() @@ -251,7 +251,7 @@ pub extern "C" fn anoncreds_create_or_update_revocation_state( let rev_state = create_or_update_revocation_state( tails_reader, rev_reg_def.load()?.cast_ref()?, - rev_reg_list.load()?.cast_ref()?, + rev_status_list.load()?.cast_ref()?, rev_reg_index .try_into() .map_err(|_| err_msg!("Invalid credential revocation index"))?, @@ -259,7 +259,7 @@ pub extern "C" fn anoncreds_create_or_update_revocation_state( .as_ref() .map(AnonCredsObject::cast_ref) .transpose()?, - prev_rev_reg_list + prev_rev_status_list .as_ref() .map(AnonCredsObject::cast_ref) .transpose()?, diff --git a/anoncreds/src/services/issuer.rs b/anoncreds/src/services/issuer.rs index 590e404d..c0f27513 100644 --- a/anoncreds/src/services/issuer.rs +++ b/anoncreds/src/services/issuer.rs @@ -278,14 +278,19 @@ pub fn create_credential( let prover_did = cred_request.prover_did.as_ref().unwrap_or(&rand_str); let (credential_signature, signature_correctness_proof, rev_reg, rev_reg_delta, witness) = - match (revocation_config, rev_status_list ) { + match (revocation_config, rev_status_list) { (Some(revocation_config), Some(rev_status_list)) => { let rev_reg_def = &revocation_config.reg_def.value; let mut rev_reg = revocation_config.registry.value.clone(); - let status = rev_status_list.get(revocation_config.registry_idx as usize).ok_or_else(|| - err_msg!("Revocation status list does not have the index {}", revocation_config.registry_idx) - )?; + let status = rev_status_list + .get(revocation_config.registry_idx as usize) + .ok_or_else(|| { + err_msg!( + "Revocation status list does not have the index {}", + revocation_config.registry_idx + ) + })?; // This will be a temporary solution for the `issuance_on_demand` vs // `issuance_by_default` state. Right now, we pass in the revcation status list and @@ -295,7 +300,7 @@ pub fn create_credential( // // If the index is inside the revocation status list we check whether it is set to // `true` or `false` within the bitvec. - // When it is set to `true`, or 1, we invert the value. This means that we use + // When it is set to `true`, or 1, we invert the value. This means that we use // `issuance_on_demand`. // When it is set to `false`, or 0, we invert the value. This means that we use // `issuance_by_default`. @@ -321,7 +326,8 @@ pub fn create_credential( let witness = { let empty = HashSet::new(); - let (by_default, issued, revoked) = (true, &empty, revocation_config.registry_used); + let (by_default, issued, revoked) = + (true, &empty, revocation_config.registry_used); let rev_reg_delta = CryptoRevocationRegistryDelta::from_parts(None, &rev_reg, issued, revoked); diff --git a/anoncreds/src/services/prover.rs b/anoncreds/src/services/prover.rs index 39da297d..bf5131ee 100644 --- a/anoncreds/src/services/prover.rs +++ b/anoncreds/src/services/prover.rs @@ -249,75 +249,78 @@ pub fn create_presentation( pub fn create_or_update_revocation_state( tails_reader: TailsReader, revoc_reg_def: &RevocationRegistryDefinition, - rev_reg_list: &RevocationStatusList, + rev_status_list: &RevocationStatusList, rev_reg_idx: u32, rev_state: Option<&CredentialRevocationState>, // for witness update - old_rev_reg_list: Option<&RevocationStatusList>, // for witness update + old_rev_status_list: Option<&RevocationStatusList>, // for witness update ) -> Result { trace!( "create_or_update_revocation_state >>> , tails_reader: {:?}, revoc_reg_def: {:?}, \ - rev_reg_list: {:?}, rev_reg_idx: {}, rev_state: {:?}, old_rev_reg_list {:?}", + rev_status_list: {:?}, rev_reg_idx: {}, rev_state: {:?}, old_rev_status_list {:?}", tails_reader, revoc_reg_def, - rev_reg_list, + rev_status_list, rev_reg_idx, rev_state, - old_rev_reg_list, + old_rev_status_list, ); let mut issued = HashSet::::new(); let mut revoked = HashSet::::new(); - let witness = - if let (Some(source_rev_state), Some(source_rev_list)) = (rev_state, old_rev_reg_list) { - _create_index_deltas( - rev_reg_list.state_owned().bitxor(source_rev_list.state()), - rev_reg_list.state(), - &mut issued, - &mut revoked, - ); + let witness = if let (Some(source_rev_state), Some(source_rev_list)) = + (rev_state, old_rev_status_list) + { + _create_index_deltas( + rev_status_list + .state_owned() + .bitxor(source_rev_list.state()), + rev_status_list.state(), + &mut issued, + &mut revoked, + ); - let rev_reg_delta = RevocationRegistryDelta::from_parts( - Some(&source_rev_list.into()), - &rev_reg_list.into(), - &issued, - &revoked, - ); - let mut witness = source_rev_state.witness.clone(); - witness.update( - rev_reg_idx, - revoc_reg_def.value.max_cred_num, - &rev_reg_delta, - &tails_reader, - )?; - witness - } else { - let list_size = usize::try_from(revoc_reg_def.value.max_cred_num) - .map_err(|e| Error::from_msg(crate::ErrorKind::InvalidState, e.to_string()))?; - // Issuance by default - let bit: usize = 0; - let list = bitvec![bit; list_size]; - _create_index_deltas( - rev_reg_list.state_owned().bitxor(list), - rev_reg_list.state(), - &mut issued, - &mut revoked, - ); - let rev_reg_delta = - RevocationRegistryDelta::from_parts(None, &rev_reg_list.into(), &issued, &revoked); - Witness::new( - rev_reg_idx, - revoc_reg_def.value.max_cred_num, - // issuance by default - true, - &rev_reg_delta, - &tails_reader, - )? - }; + let rev_reg_delta = RevocationRegistryDelta::from_parts( + Some(&source_rev_list.into()), + &rev_status_list.into(), + &issued, + &revoked, + ); + let mut witness = source_rev_state.witness.clone(); + witness.update( + rev_reg_idx, + revoc_reg_def.value.max_cred_num, + &rev_reg_delta, + &tails_reader, + )?; + witness + } else { + let list_size = usize::try_from(revoc_reg_def.value.max_cred_num) + .map_err(|e| Error::from_msg(crate::ErrorKind::InvalidState, e.to_string()))?; + // Issuance by default + let bit: usize = 0; + let list = bitvec![bit; list_size]; + _create_index_deltas( + rev_status_list.state_owned().bitxor(list), + rev_status_list.state(), + &mut issued, + &mut revoked, + ); + let rev_reg_delta = + RevocationRegistryDelta::from_parts(None, &rev_status_list.into(), &issued, &revoked); + Witness::new( + rev_reg_idx, + revoc_reg_def.value.max_cred_num, + // issuance by default + true, + &rev_reg_delta, + &tails_reader, + )? + }; Ok(CredentialRevocationState { witness, - rev_reg: rev_reg_list.into(), - timestamp: rev_reg_list.timestamp(), + rev_reg: rev_status_list.into(), + timestamp: rev_status_list.timestamp(), }) } diff --git a/anoncreds/tests/anoncreds_demos.rs b/anoncreds/tests/anoncreds_demos.rs index 8490b201..f07af0c0 100644 --- a/anoncreds/tests/anoncreds_demos.rs +++ b/anoncreds/tests/anoncreds_demos.rs @@ -33,6 +33,7 @@ pub static CRED_DEF_ID: &str = "mock:uri"; pub static ISSUER_ID: &str = "mock:issuer_id/path&q=bar"; pub const GVT_SCHEMA_NAME: &str = "gvt"; pub const GVT_SCHEMA_ATTRIBUTES: &[&str; 4] = &["name", "age", "sex", "height"]; +pub static REV_REG_DEF_ID: &str = "mock:uri:revregdefid"; pub static REV_REG_ID: &str = "mock:uri:revregid"; pub static REV_IDX: u32 = 89; pub static MAX_CRED_NUM: u32 = 150; @@ -337,7 +338,7 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { .add_raw("age", "28") .expect("Error encoding attribute"); - let rev_reg_id = RevocationRegistryId::new_unchecked(REV_REG_ID); + let rev_reg_def_id = RevocationRegistryId::new_unchecked(REV_REG_DEF_ID); // Get the location of the tails_file so it can be read let location = rev_reg_def_pub.clone().value.tails_location; @@ -354,7 +355,9 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { &cred_offer, &cred_request, cred_values.into(), - Some(rev_reg_id.clone()), + Some(rev_reg_def_id.clone()), + // TODO: this should be a rev_status_list + None, Some(CredentialRevocationConfig { reg_def: &rev_reg_def_pub, reg_def_private: &rev_reg_def_priv, @@ -444,11 +447,13 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { // Verifier verifies presentation of not Revoked rev_state // TODO: rev reg def id is the same as the rev reg id? - let rev_reg_def_id = RevocationRegistryDefinitionId::new_unchecked(REV_REG_ID); + let rev_reg_def_id = RevocationRegistryDefinitionId::new_unchecked(REV_REG_DEF_ID); let rev_reg_def_map = HashMap::from([(&rev_reg_def_id, &rev_reg_def_pub)]); // Create the map that contines the registries let rev_timestamp_map = HashMap::from([(prover_timestamp, &cred_rev_reg)]); + + let rev_reg_id = RevocationRegistryId::new_unchecked(REV_REG_ID); let mut rev_reg_map = HashMap::from([(rev_reg_id.clone(), rev_timestamp_map.clone())]); let valid = verifier::verify_presentation( @@ -477,7 +482,7 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { let ursa_rev_reg = revoked_rev_reg.value.clone(); let revocation_list = - RevocationStatusList::new(REV_REG_ID, list, ursa_rev_reg, prover_timestamp).unwrap(); + RevocationStatusList::new(REV_REG_DEF_ID, list, ursa_rev_reg, prover_timestamp).unwrap(); let new_rev_state = prover::create_or_update_revocation_state( tr, &rev_reg_def_pub, From 66560a3588cb99ec477273dd5ccf23065c95d402 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Thu, 12 Jan 2023 15:42:18 +0100 Subject: [PATCH 07/10] made id, timestamp and rev reg inside the rev status list optional Signed-off-by: blu3beri --- anoncreds/src/data_types/anoncreds/rev_reg.rs | 28 +++++++++++-------- anoncreds/src/services/prover.rs | 26 +++++++++++++---- anoncreds/tests/anoncreds_demos.rs | 18 +++++++++--- 3 files changed, 51 insertions(+), 21 deletions(-) diff --git a/anoncreds/src/data_types/anoncreds/rev_reg.rs b/anoncreds/src/data_types/anoncreds/rev_reg.rs index 918f662f..ca84201b 100644 --- a/anoncreds/src/data_types/anoncreds/rev_reg.rs +++ b/anoncreds/src/data_types/anoncreds/rev_reg.rs @@ -36,22 +36,24 @@ impl Validatable for RevocationRegistryDelta {} #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct RevocationStatusList { - rev_reg_def_id: RevocationRegistryId, + #[serde(skip_serializing_if = "Option::is_none")] + rev_reg_def_id: Option, #[serde(with = "serde_revocation_list")] revocation_list: bitvec::vec::BitVec, - #[serde(flatten)] - registry: ursa::cl::RevocationRegistry, - timestamp: u64, + #[serde(flatten, skip_serializing_if = "Option::is_none")] + registry: Option, + #[serde(skip_serializing_if = "Option::is_none")] + timestamp: Option, } -impl From<&RevocationStatusList> for ursa::cl::RevocationRegistry { - fn from(rev_status_list: &RevocationStatusList) -> ursa::cl::RevocationRegistry { +impl From<&RevocationStatusList> for Option { + fn from(rev_status_list: &RevocationStatusList) -> Option { rev_status_list.registry.clone() } } impl RevocationStatusList { - pub(crate) fn timestamp(&self) -> u64 { + pub(crate) fn timestamp(&self) -> Option { self.timestamp } @@ -59,6 +61,10 @@ impl RevocationStatusList { &self.revocation_list } + pub fn set_registry(&mut self, registry: ursa::cl::RevocationRegistry) { + self.registry = Some(registry) + } + pub(crate) fn state_owned(&self) -> bitvec::vec::BitVec { self.revocation_list.clone() } @@ -68,13 +74,13 @@ impl RevocationStatusList { } pub fn new( - rev_reg_def_id: &str, + rev_reg_def_id: Option<&str>, revocation_list: bitvec::vec::BitVec, - registry: ursa::cl::RevocationRegistry, - timestamp: u64, + registry: Option, + timestamp: Option, ) -> Result { Ok(RevocationStatusList { - rev_reg_def_id: RevocationRegistryId::new(rev_reg_def_id)?, + rev_reg_def_id: rev_reg_def_id.map(RevocationRegistryId::new).transpose()?, revocation_list, registry, timestamp, diff --git a/anoncreds/src/services/prover.rs b/anoncreds/src/services/prover.rs index bf5131ee..9f087992 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)) = @@ -279,9 +288,11 @@ pub fn create_or_update_revocation_state( &mut revoked, ); + let source_rev_reg: Option = source_rev_list.into(); + let rev_reg_delta = RevocationRegistryDelta::from_parts( - Some(&source_rev_list.into()), - &rev_status_list.into(), + source_rev_reg.as_ref(), + &rev_reg, &issued, &revoked, ); @@ -305,8 +316,11 @@ pub fn create_or_update_revocation_state( &mut issued, &mut revoked, ); - let rev_reg_delta = - RevocationRegistryDelta::from_parts(None, &rev_status_list.into(), &issued, &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, revoc_reg_def.value.max_cred_num, @@ -319,8 +333,8 @@ pub fn create_or_update_revocation_state( Ok(CredentialRevocationState { witness, - rev_reg: rev_status_list.into(), - timestamp: rev_status_list.timestamp(), + rev_reg, + timestamp, }) } diff --git a/anoncreds/tests/anoncreds_demos.rs b/anoncreds/tests/anoncreds_demos.rs index f07af0c0..1e2d9a1c 100644 --- a/anoncreds/tests/anoncreds_demos.rs +++ b/anoncreds/tests/anoncreds_demos.rs @@ -348,6 +348,10 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { // The Prover's index in the revocation list is REV_IDX let registry_used = HashSet::from([REV_IDX]); + let list = bitvec![0; MAX_CRED_NUM as usize ]; + let mut revocation_status_list = + RevocationStatusList::new(None, list, None, None).expect("Error creating status list"); + // TODO: Here Delta is not needed but is it used elsewhere? let (issue_cred, cred_rev_reg, _) = issuer::create_credential( &*gvt_cred_def, @@ -356,8 +360,7 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { &cred_request, cred_values.into(), Some(rev_reg_def_id.clone()), - // TODO: this should be a rev_status_list - None, + Some(&revocation_status_list), Some(CredentialRevocationConfig { reg_def: &rev_reg_def_pub, reg_def_private: &rev_reg_def_priv, @@ -370,6 +373,8 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { .expect("Error creating credential"); let cred_rev_reg = cred_rev_reg.unwrap(); + revocation_status_list.set_registry(cred_rev_reg.value.clone()); + // Prover receives the credential and processes it let mut recv_cred = issue_cred; prover::process_credential( @@ -481,8 +486,13 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { let ursa_rev_reg = revoked_rev_reg.value.clone(); - let revocation_list = - RevocationStatusList::new(REV_REG_DEF_ID, list, ursa_rev_reg, prover_timestamp).unwrap(); + let revocation_list = RevocationStatusList::new( + Some(REV_REG_DEF_ID), + list, + Some(ursa_rev_reg), + Some(prover_timestamp), + ) + .unwrap(); let new_rev_state = prover::create_or_update_revocation_state( tr, &rev_reg_def_pub, From 29d0648d36e70bc0fc5b6ed98a9a744afe030b32 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Fri, 13 Jan 2023 12:49:04 +0100 Subject: [PATCH 08/10] tests working Signed-off-by: blu3beri --- anoncreds/tests/anoncreds_demos.rs | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/anoncreds/tests/anoncreds_demos.rs b/anoncreds/tests/anoncreds_demos.rs index 1e2d9a1c..2a8fc9d8 100644 --- a/anoncreds/tests/anoncreds_demos.rs +++ b/anoncreds/tests/anoncreds_demos.rs @@ -4,7 +4,7 @@ use std::{ }; use anoncreds::{ - data_types::anoncreds::{ + data_types::anoncreds::{ cred_def::{CredentialDefinition, CredentialDefinitionId}, presentation::Presentation, rev_reg::RevocationRegistryId, @@ -33,7 +33,6 @@ pub static CRED_DEF_ID: &str = "mock:uri"; pub static ISSUER_ID: &str = "mock:issuer_id/path&q=bar"; pub const GVT_SCHEMA_NAME: &str = "gvt"; pub const GVT_SCHEMA_ATTRIBUTES: &[&str; 4] = &["name", "age", "sex", "height"]; -pub static REV_REG_DEF_ID: &str = "mock:uri:revregdefid"; pub static REV_REG_ID: &str = "mock:uri:revregid"; pub static REV_IDX: u32 = 89; pub static MAX_CRED_NUM: u32 = 150; @@ -338,7 +337,7 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { .add_raw("age", "28") .expect("Error encoding attribute"); - let rev_reg_def_id = RevocationRegistryId::new_unchecked(REV_REG_DEF_ID); + let rev_reg_def_id = RevocationRegistryId::new_unchecked(REV_REG_ID); // Get the location of the tails_file so it can be read let location = rev_reg_def_pub.clone().value.tails_location; @@ -349,7 +348,7 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { let registry_used = HashSet::from([REV_IDX]); let list = bitvec![0; MAX_CRED_NUM as usize ]; - let mut revocation_status_list = + let revocation_status_list = RevocationStatusList::new(None, list, None, None).expect("Error creating status list"); // TODO: Here Delta is not needed but is it used elsewhere? @@ -373,8 +372,6 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { .expect("Error creating credential"); let cred_rev_reg = cred_rev_reg.unwrap(); - revocation_status_list.set_registry(cred_rev_reg.value.clone()); - // Prover receives the credential and processes it let mut recv_cred = issue_cred; prover::process_credential( @@ -420,7 +417,7 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { // Prover: here we deliberately do not put in the same timestamp as the global non_revoked time interval, // this shows that it is not used let prover_timestamp = 1234u64; - let rev_reg = cred_rev_reg.value.clone(); + let rev_reg = cred_rev_reg.clone().value; let rev_state = CredentialRevocationState { timestamp: prover_timestamp, @@ -452,7 +449,7 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { // Verifier verifies presentation of not Revoked rev_state // TODO: rev reg def id is the same as the rev reg id? - let rev_reg_def_id = RevocationRegistryDefinitionId::new_unchecked(REV_REG_DEF_ID); + let rev_reg_def_id = RevocationRegistryDefinitionId::new_unchecked(REV_REG_ID); let rev_reg_def_map = HashMap::from([(&rev_reg_def_id, &rev_reg_def_pub)]); // Create the map that contines the registries @@ -484,15 +481,10 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { // revoked_bit is not a reference so can drop drop(revoked_bit); - let ursa_rev_reg = revoked_rev_reg.value.clone(); + let ursa_rev_reg = revoked_rev_reg.clone().value; - let revocation_list = RevocationStatusList::new( - Some(REV_REG_DEF_ID), - list, - Some(ursa_rev_reg), - Some(prover_timestamp), - ) - .unwrap(); + let revocation_list = + RevocationStatusList::new(Some(REV_REG_ID), list, Some(ursa_rev_reg), Some(prover_timestamp)).unwrap(); let new_rev_state = prover::create_or_update_revocation_state( tr, &rev_reg_def_pub, From 10747ac6d71676a815dff82625a23502d18266bf Mon Sep 17 00:00:00 2001 From: blu3beri Date: Fri, 13 Jan 2023 12:50:45 +0100 Subject: [PATCH 09/10] rename rev_reg_def_id variable to rev_reg_id Signed-off-by: blu3beri --- anoncreds/tests/anoncreds_demos.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/anoncreds/tests/anoncreds_demos.rs b/anoncreds/tests/anoncreds_demos.rs index 2a8fc9d8..e1fe72ff 100644 --- a/anoncreds/tests/anoncreds_demos.rs +++ b/anoncreds/tests/anoncreds_demos.rs @@ -337,7 +337,7 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { .add_raw("age", "28") .expect("Error encoding attribute"); - let rev_reg_def_id = RevocationRegistryId::new_unchecked(REV_REG_ID); + let rev_reg_id = RevocationRegistryId::new_unchecked(REV_REG_ID); // Get the location of the tails_file so it can be read let location = rev_reg_def_pub.clone().value.tails_location; @@ -358,7 +358,7 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { &cred_offer, &cred_request, cred_values.into(), - Some(rev_reg_def_id.clone()), + Some(rev_reg_id.clone()), Some(&revocation_status_list), Some(CredentialRevocationConfig { reg_def: &rev_reg_def_pub, From d89a48c4fdb96bb2e5aba87fd55273a286287c47 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Fri, 13 Jan 2023 13:01:13 +0100 Subject: [PATCH 10/10] ran formatter Signed-off-by: blu3beri --- anoncreds/tests/anoncreds_demos.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/anoncreds/tests/anoncreds_demos.rs b/anoncreds/tests/anoncreds_demos.rs index e1fe72ff..0e65d30c 100644 --- a/anoncreds/tests/anoncreds_demos.rs +++ b/anoncreds/tests/anoncreds_demos.rs @@ -4,7 +4,7 @@ use std::{ }; use anoncreds::{ - data_types::anoncreds::{ + data_types::anoncreds::{ cred_def::{CredentialDefinition, CredentialDefinitionId}, presentation::Presentation, rev_reg::RevocationRegistryId, @@ -483,8 +483,13 @@ fn anoncreds_with_revocation_works_for_single_issuer_single_prover() { let ursa_rev_reg = revoked_rev_reg.clone().value; - let revocation_list = - RevocationStatusList::new(Some(REV_REG_ID), list, Some(ursa_rev_reg), Some(prover_timestamp)).unwrap(); + let revocation_list = RevocationStatusList::new( + Some(REV_REG_ID), + list, + Some(ursa_rev_reg), + Some(prover_timestamp), + ) + .unwrap(); let new_rev_state = prover::create_or_update_revocation_state( tr, &rev_reg_def_pub,