Skip to content

Commit

Permalink
Merge pull request #56 from blu3beri/update-revocation-registry-defin…
Browse files Browse the repository at this point in the history
…ition

update revocation registry definition
  • Loading branch information
berendsliedrecht authored Jan 16, 2023
2 parents b39b40d + d89a48c commit 293f1ef
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 314 deletions.
76 changes: 33 additions & 43 deletions anoncreds/src/data_types/anoncreds/rev_reg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,87 +10,77 @@ 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 {
rev_reg_id: RevocationRegistryId,
#[serde(skip_serializing_if = "Option::is_none")]
rev_reg_def_id: Option<RevocationRegistryId>,
#[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<ursa::cl::RevocationRegistry>,
#[serde(skip_serializing_if = "Option::is_none")]
timestamp: Option<u64>,
}

impl From<&RevocationStatusList> for ursa::cl::RevocationRegistry {
fn from(rev_reg_list: &RevocationStatusList) -> ursa::cl::RevocationRegistry {
rev_reg_list.registry.clone()
impl From<&RevocationStatusList> for Option<ursa::cl::RevocationRegistry> {
fn from(rev_status_list: &RevocationStatusList) -> Option<ursa::cl::RevocationRegistry> {
rev_status_list.registry.clone()
}
}

impl RevocationStatusList {
pub(crate) fn timestamp(&self) -> u64 {
pub(crate) fn timestamp(&self) -> Option<u64> {
self.timestamp
}

pub(crate) fn state(&self) -> &bitvec::vec::BitVec {
&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()
}

pub(crate) fn get(&self, idx: usize) -> Option<bool> {
self.revocation_list.get(idx).as_deref().copied()
}

pub fn new(
rev_reg_id: &str,
rev_reg_def_id: Option<&str>,
revocation_list: bitvec::vec::BitVec,
registry: ursa::cl::RevocationRegistry,
timestamp: u64,
registry: Option<ursa::cl::RevocationRegistry>,
timestamp: Option<u64>,
) -> Result<Self, error::Error> {
Ok(RevocationStatusList {
rev_reg_id: RevocationRegistryId::new(rev_reg_id)?,
rev_reg_def_id: rev_reg_def_id.map(RevocationRegistryId::new).transpose()?,
revocation_list,
registry,
timestamp,
Expand Down Expand Up @@ -157,7 +147,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
Expand Down
73 changes: 5 additions & 68 deletions anoncreds/src/data_types/anoncreds/rev_reg_def.rs
Original file line number Diff line number Diff line change
@@ -1,55 +1,16 @@
use std::str::FromStr;

use crate::{
data_types::{invalid, ConversionError, Validatable, ValidationError},
data_types::{ConversionError, Validatable, ValidationError},
impl_anoncreds_object_identifier,
};

use super::cred_def::CredentialDefinitionId;
use super::{cred_def::CredentialDefinitionId, issuer_id::IssuerId};

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<Self, Self::Err> {
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<IssuanceType> 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 {
Expand All @@ -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,
Expand All @@ -83,23 +43,17 @@ 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 issuer_id: IssuerId,
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()
}
Expand All @@ -109,20 +63,3 @@ impl Validatable for RevocationRegistryDefinitionV1 {
pub struct RevocationRegistryDefinitionPrivate {
pub value: ursa::cl::RevocationKeyPrivate,
}

#[derive(Deserialize, Debug, Serialize)]
pub struct RevocationRegistryConfig {
pub issuance_type: Option<IssuanceType>,
pub max_cred_num: Option<u32>,
}

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(())
}
}
3 changes: 3 additions & 0 deletions anoncreds/src/ffi/credential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ pub extern "C" fn anoncreds_create_credential(
attr_raw_values: FfiStrList,
attr_enc_values: FfiStrList,
rev_reg_id: FfiStr,
rev_status_list: ObjectHandle,
revocation: *const FfiCredRevInfo,
cred_p: *mut ObjectHandle,
rev_reg_p: *mut ObjectHandle,
Expand Down Expand Up @@ -135,13 +136,15 @@ 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()?,
cred_offer.load()?.cast_ref()?,
cred_request.load()?.cast_ref()?,
cred_values.into(),
rev_reg_id,
rev_status_list.load()?.cast_ref().ok(),
revocation_config
.as_ref()
.map(RevocationConfig::as_ref_config)
Expand Down
44 changes: 15 additions & 29 deletions anoncreds/src/ffi/revocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,18 @@ 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,
},
};

#[no_mangle]
pub extern "C" fn anoncreds_create_revocation_registry(
cred_def: ObjectHandle,
cred_def_id: FfiStr,
issuer_id: FfiStr,
tag: FfiStr,
rev_reg_type: FfiStr,
issuance_type: FfiStr,
max_cred_num: i64,
tails_dir_path: FfiStr,
reg_def_p: *mut ObjectHandle,
Expand All @@ -45,23 +44,22 @@ 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()
.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,
issuer_id,
tag,
rev_reg_type,
issuance_type,
max_cred_num
.try_into()
.map_err(|_| err_msg!("Invalid maximum credential count"))?,
Expand Down Expand Up @@ -180,21 +178,9 @@ pub extern "C" fn anoncreds_revocation_registry_definition_get_attribute(
let reg_def = handle.load()?;
let reg_def = reg_def.cast_ref::<RevocationRegistryDefinition>()?;
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) };
Expand Down Expand Up @@ -246,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()
Expand All @@ -265,15 +251,15 @@ 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"))?,
prev_rev_state
.as_ref()
.map(AnonCredsObject::cast_ref)
.transpose()?,
prev_rev_reg_list
prev_rev_status_list
.as_ref()
.map(AnonCredsObject::cast_ref)
.transpose()?,
Expand Down
Loading

0 comments on commit 293f1ef

Please sign in to comment.