diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dcf8622..9b3c773 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -91,9 +91,6 @@ jobs: - name: Debug build run: cargo build --all-targets --features vendored - - name: Test indy-utils - run: cargo test --manifest-path indy-utils/Cargo.toml - # - name: Test indy-data-types (CL) # run: cargo test --manifest-path indy-data-types/Cargo.toml --features cl diff --git a/Cargo.toml b/Cargo.toml index 89e9422..220cac6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,7 @@ [workspace] +resolver = "2" -members = [ - "indy-credx", - "indy-data-types", - "indy-test-utils", - "indy-utils" -] +members = ["indy-credx", "indy-data-types"] [profile.release] panic = "abort" diff --git a/README.md b/README.md index ea5f3ab..f6209e3 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,6 @@ Shared Rust libraries for Hyperledger Indy. - `indy-data-types`: Data type definitions for Schemas, Credential Definitions and other types related to credential issuance and processing. -- `indy-test-utils`: Utilities for use in integration tests. - -- `indy-utils`: Standard wrappers around binary data encodings. Includes support for normalizing transactions for signing, deriving DIDs and verification keys. - ## Credit The initial implementation of `indy-shared-rs` was developed by the Verifiable Organizations Network (VON) team based at the Province of British Columbia, and derives largely from the implementations within [Hyperledger Indy-SDK](https://github.com/hyperledger/indy-sdk). To learn more about VON and what's happening with decentralized identity in British Columbia, please go to [https://vonx.io](https://vonx.io). diff --git a/indy-credx/Cargo.toml b/indy-credx/Cargo.toml index 50692e8..8bc9d94 100644 --- a/indy-credx/Cargo.toml +++ b/indy-credx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "indy-credx" -version = "1.0.3" +version = "1.1.0" authors = ["Hyperledger Indy Contributors "] description = "Verifiable credential issuance and presentation for Hyperledger Indy (https://www.hyperledger.org/projects), which provides a distributed-ledger-based foundation for self-sovereign identity (https://sovrin.org)." edition = "2021" @@ -25,10 +25,9 @@ vendored = ["indy-data-types/vendored"] [dependencies] env_logger = { version = "0.10", optional = true } ffi-support = { version = "0.4.0", optional = true } -indy-data-types = { version = "0.6.1", features = [ +indy-data-types = { version = "0.7", features = [ "cl_native", ], path = "../indy-data-types" } -indy-utils = { version = "0.6.0", default-features = false, path = "../indy-utils" } log = "0.4" once_cell = "1" rand = "0.8" @@ -36,5 +35,4 @@ regex = "1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" sha2 = "0.10" -thiserror = "1.0" zeroize = { version = "1", optional = true } diff --git a/indy-credx/src/error.rs b/indy-credx/src/error.rs index 059e2c9..ecf76ed 100644 --- a/indy-credx/src/error.rs +++ b/indy-credx/src/error.rs @@ -116,8 +116,8 @@ impl From for Error { } } -impl From for Error { - fn from(err: indy_utils::ValidationError) -> Self { +impl From for Error { + fn from(err: indy_data_types::ValidationError) -> Self { Error::from_opt_msg(ErrorKind::Input, err.context) } } diff --git a/indy-credx/src/ffi/cred_def.rs b/indy-credx/src/ffi/cred_def.rs index bd99f82..021c62e 100644 --- a/indy-credx/src/ffi/cred_def.rs +++ b/indy-credx/src/ffi/cred_def.rs @@ -1,7 +1,8 @@ use std::os::raw::c_char; +use std::str::FromStr; use ffi_support::{rust_string_to_c, FfiStr}; -use indy_utils::Qualifiable; +use indy_data_types::Qualifiable; use super::error::{catch_error, ErrorCode}; use super::object::{IndyObjectId, ObjectHandle}; diff --git a/indy-credx/src/ffi/cred_offer.rs b/indy-credx/src/ffi/cred_offer.rs index 295ff1d..f648470 100644 --- a/indy-credx/src/ffi/cred_offer.rs +++ b/indy-credx/src/ffi/cred_offer.rs @@ -1,5 +1,5 @@ use ffi_support::FfiStr; -use indy_utils::Qualifiable; +use indy_data_types::Qualifiable; use super::error::{catch_error, ErrorCode}; use super::object::ObjectHandle; diff --git a/indy-credx/src/ffi/cred_req.rs b/indy-credx/src/ffi/cred_req.rs index f442628..0f35873 100644 --- a/indy-credx/src/ffi/cred_req.rs +++ b/indy-credx/src/ffi/cred_req.rs @@ -1,5 +1,5 @@ use ffi_support::FfiStr; -use indy_utils::Qualifiable; +use indy_data_types::Qualifiable; use super::error::{catch_error, ErrorCode}; use super::object::ObjectHandle; diff --git a/indy-credx/src/ffi/object.rs b/indy-credx/src/ffi/object.rs index 436c064..ab7d570 100644 --- a/indy-credx/src/ffi/object.rs +++ b/indy-credx/src/ffi/object.rs @@ -4,9 +4,10 @@ use std::fmt::Debug; use std::hash::{Hash, Hasher}; use std::ops::{Deref, DerefMut}; use std::os::raw::c_char; -use std::sync::{Arc, Mutex}; +use std::sync::{atomic::AtomicUsize, Arc, Mutex}; use ffi_support::{rust_string_to_c, ByteBuffer}; +use indy_data_types::{Validatable, ValidationError}; use once_cell::sync::Lazy; use serde::Serialize; @@ -16,9 +17,17 @@ use crate::error::Result; pub(crate) static FFI_OBJECTS: Lazy>> = Lazy::new(|| Mutex::new(BTreeMap::new())); -indy_utils::new_handle_type!(ObjectHandle, FFI_OBJECT_COUNTER); +static FFI_OBJECT_COUNTER: AtomicUsize = AtomicUsize::new(0); + +#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(transparent)] +pub struct ObjectHandle(pub usize); impl ObjectHandle { + pub fn next() -> Self { + Self(FFI_OBJECT_COUNTER.fetch_add(1, std::sync::atomic::Ordering::SeqCst) + 1) + } + pub(crate) fn create(value: O) -> Result { let handle = Self::next(); FFI_OBJECTS @@ -62,9 +71,32 @@ impl ObjectHandle { } } -impl Default for ObjectHandle { - fn default() -> Self { - Self(0) +impl std::fmt::Display for ObjectHandle { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}({})", stringify!($newtype), self.0) + } +} + +impl std::ops::Deref for ObjectHandle { + type Target = usize; + fn deref(&self) -> &usize { + &self.0 + } +} + +impl PartialEq for ObjectHandle { + fn eq(&self, other: &usize) -> bool { + self.0 == *other + } +} + +impl Validatable for ObjectHandle { + fn validate(&self) -> std::result::Result<(), ValidationError> { + if **self == 0 { + Err("Invalid handle: zero".into()) + } else { + Ok(()) + } } } @@ -74,6 +106,7 @@ pub(crate) struct IndyObject(Arc); impl IndyObject { pub fn new(value: O) -> Self { + assert!(std::mem::size_of::() != 0); Self(Arc::new(value)) } @@ -97,6 +130,10 @@ impl IndyObject { impl PartialEq for IndyObject { fn eq(&self, other: &IndyObject) -> bool { + #[allow(clippy::vtable_address_comparisons)] + // this is allowed only because we create all such objects + // in one place (the `new` method) and ensure they are not + // zero-sized. Arc::ptr_eq(&self.0, &other.0) } } @@ -214,7 +251,7 @@ pub(crate) struct IndyObjectList(Vec); impl IndyObjectList { pub fn load(handles: &[ObjectHandle]) -> Result { let loaded = handles - .into_iter() + .iter() .map(ObjectHandle::load) .collect::>()?; Ok(Self(loaded)) diff --git a/indy-credx/src/ffi/presentation.rs b/indy-credx/src/ffi/presentation.rs index a2e5c5f..9763f9d 100644 --- a/indy-credx/src/ffi/presentation.rs +++ b/indy-credx/src/ffi/presentation.rs @@ -218,6 +218,7 @@ pub extern "C" fn credx_verify_presentation_legacy( ) } +#[allow(clippy::too_many_arguments)] fn _credx_verify_presentation( presentation: ObjectHandle, pres_req: ObjectHandle, diff --git a/indy-credx/src/ffi/revocation.rs b/indy-credx/src/ffi/revocation.rs index 65305be..e17daf3 100644 --- a/indy-credx/src/ffi/revocation.rs +++ b/indy-credx/src/ffi/revocation.rs @@ -1,9 +1,10 @@ use std::collections::BTreeSet; use std::convert::TryInto; use std::os::raw::c_char; +use std::str::FromStr; use ffi_support::{rust_string_to_c, FfiStr}; -use indy_utils::Qualifiable; +use indy_data_types::Qualifiable; use super::error::{catch_error, ErrorCode}; use super::object::{IndyObject, IndyObjectId, ObjectHandle}; diff --git a/indy-credx/src/ffi/schema.rs b/indy-credx/src/ffi/schema.rs index 845f6a7..d95e35b 100644 --- a/indy-credx/src/ffi/schema.rs +++ b/indy-credx/src/ffi/schema.rs @@ -1,7 +1,7 @@ use std::os::raw::c_char; use ffi_support::{rust_string_to_c, FfiStr}; -use indy_utils::Qualifiable; +use indy_data_types::Qualifiable; use super::error::{catch_error, ErrorCode}; use super::object::{IndyObjectId, ObjectHandle}; diff --git a/indy-credx/src/services/helpers.rs b/indy-credx/src/services/helpers.rs index 8d28c25..c808d10 100644 --- a/indy-credx/src/services/helpers.rs +++ b/indy-credx/src/services/helpers.rs @@ -14,7 +14,7 @@ use crate::anoncreds_clsignatures::{ use crate::error::Result; pub fn attr_common_view(attr: &str) -> String { - attr.replace(" ", "").to_lowercase() + attr.replace(' ', "").to_lowercase() } pub fn build_credential_schema(attrs: &HashSet) -> Result { diff --git a/indy-credx/src/services/issuer.rs b/indy-credx/src/services/issuer.rs index f9bc9b4..5c65d16 100644 --- a/indy-credx/src/services/issuer.rs +++ b/indy-credx/src/services/issuer.rs @@ -14,7 +14,7 @@ use indy_data_types::anoncreds::{ }, schema::SchemaV1, }; -use indy_utils::{Qualifiable, Validatable}; +use indy_data_types::{Qualifiable, Validatable}; use super::tails::TailsWriter; @@ -29,7 +29,7 @@ pub fn create_schema( origin_did, schema_name, schema_version, attr_names); origin_did.validate()?; - let schema_id = SchemaId::new(&origin_did, schema_name, schema_version); + let schema_id = SchemaId::new(origin_did, schema_name, schema_version); let schema = SchemaV1 { id: schema_id, name: schema_name.to_string(), @@ -57,12 +57,12 @@ pub fn make_credential_definition_id( }; let schema_infix_id = schema_seq_no .map(|n| SchemaId(n.to_string())) - .unwrap_or(schema_id.clone()); + .unwrap_or(schema_id); Ok(CredentialDefinitionId::new( origin_did, &schema_infix_id, - &signature_type.to_str(), + signature_type.to_str(), tag, )) } @@ -84,9 +84,7 @@ pub fn create_credential_definition( config ); - let schema = match schema { - Schema::SchemaV1(s) => s, - }; + let Schema::SchemaV1(schema) = schema; let cred_def_id = make_credential_definition_id(origin_did, &schema.id, schema.seq_no, tag, signature_type)?; @@ -142,9 +140,7 @@ pub fn make_revocation_registry_id( tag: &str, rev_reg_type: RegistryType, ) -> Result { - let cred_def = match cred_def { - CredentialDefinition::CredentialDefinitionV1(c) => c, - }; + let CredentialDefinition::CredentialDefinitionV1(cred_def) = cred_def; let origin_did = match (origin_did.get_method(), cred_def.id.get_method()) { (None, Some(_)) => { @@ -157,9 +153,9 @@ pub fn make_revocation_registry_id( }; Ok(RevocationRegistryId::new( - &origin_did, + origin_did, &cred_def.id, - &rev_reg_type.to_str(), + rev_reg_type.to_str(), tag, )) } @@ -186,9 +182,7 @@ where let rev_reg_id = make_revocation_registry_id(origin_did, cred_def, tag, rev_reg_type)?; - let cred_def = match cred_def { - CredentialDefinition::CredentialDefinitionV1(c) => c, - }; + let CredentialDefinition::CredentialDefinitionV1(cred_def) = cred_def; let credential_pub_key = cred_def.get_public_key().map_err(err_map!( Unexpected, "Error fetching public key from credential definition" @@ -211,13 +205,13 @@ where max_cred_num, issuance_type, public_keys: rev_keys_pub, - tails_location: tails_location.clone(), + tails_location, tails_hash, }; let revoc_reg_def = RevocationRegistryDefinition::RevocationRegistryDefinitionV1( RevocationRegistryDefinitionV1 { - id: rev_reg_id.clone(), + id: rev_reg_id, revoc_def_type: rev_reg_type, tag: tag.to_string(), cred_def_id: cred_def.id.clone(), @@ -260,9 +254,7 @@ pub fn update_revocation_registry( ))? } }; - let rev_reg_def = match rev_reg_def { - RevocationRegistryDefinition::RevocationRegistryDefinitionV1(v1) => v1, - }; + let RevocationRegistryDefinition::RevocationRegistryDefinitionV1(rev_reg_def) = rev_reg_def; let mut rev_reg = match rev_reg { RevocationRegistry::RevocationRegistryV1(v1) => v1.value.clone(), }; @@ -292,9 +284,7 @@ pub fn create_credential_offer( let nonce = Nonce::new().map_err(err_map!(Unexpected, "Error creating nonce"))?; - let cred_def = match cred_def { - CredentialDefinition::CredentialDefinitionV1(c) => c, - }; + let CredentialDefinition::CredentialDefinitionV1(cred_def) = cred_def; let key_correctness_proof = correctness_proof .try_clone() @@ -370,8 +360,8 @@ pub fn create_credential( )?; let cred_rev_reg_id = match cred_offer.method_name.as_ref() { - Some(ref _method_name) => Some(reg_reg_id.to_unqualified()), - _ => Some(reg_reg_id.clone()), + Some(_method_name) => Some(reg_reg_id.to_unqualified()), + _ => Some(reg_reg_id), }; ( credential_signature, diff --git a/indy-credx/src/services/prover.rs b/indy-credx/src/services/prover.rs index ab72f33..c3e6c05 100644 --- a/indy-credx/src/services/prover.rs +++ b/indy-credx/src/services/prover.rs @@ -16,7 +16,7 @@ use indy_data_types::anoncreds::{ RevealedAttributeInfo, SubProofReferent, }, }; -use indy_utils::{Qualifiable, Validatable}; +use indy_data_types::{Qualifiable, Validatable}; use super::tails::TailsFileReader; @@ -38,9 +38,7 @@ pub fn create_credential_request( credential_offer ); - let cred_def = match cred_def { - CredentialDefinition::CredentialDefinitionV1(cd) => cd, - }; + let CredentialDefinition::CredentialDefinitionV1(cred_def) = cred_def; let credential_pub_key = CredentialPublicKey::build_from_parts( &cred_def.value.primary, cred_def.value.revocation.as_ref(), @@ -93,9 +91,7 @@ pub fn process_credential( trace!("process_credential >>> credential: {:?}, cred_request_metadata: {:?}, link_secret: {:?}, cred_def: {:?}, rev_reg_def: {:?}", credential, cred_request_metadata, secret!(&link_secret), cred_def, rev_reg_def); - let cred_def = match cred_def { - CredentialDefinition::CredentialDefinitionV1(cd) => cd, - }; + let CredentialDefinition::CredentialDefinitionV1(cred_def) = cred_def; let credential_pub_key = CredentialPublicKey::build_from_parts( &cred_def.value.primary, cred_def.value.revocation.as_ref(), @@ -154,9 +150,10 @@ pub fn create_presentation( let mut proof_builder = ClProver::new_proof_builder()?; proof_builder.add_common_attribute("master_secret")?; - let mut requested_proof = RequestedProof::default(); - - requested_proof.self_attested_attrs = self_attested.unwrap_or_default(); + let mut requested_proof = RequestedProof { + self_attested_attrs: self_attested.unwrap_or_default(), + ..Default::default() + }; let mut sub_proof_index = 0; let non_credential_schema = build_non_credential_schema()?; @@ -168,12 +165,9 @@ pub fn create_presentation( } let credential = present.cred; - let schema = *schemas + let Schema::SchemaV1(schema) = *schemas .get(&credential.schema_id) .ok_or_else(|| err_msg!("Schema not provided for ID: {}", credential.schema_id))?; - let schema = match schema { - Schema::SchemaV1(schema) => schema, - }; let cred_def = *cred_defs.get(&credential.cred_def_id).ok_or_else(|| { err_msg!( @@ -181,9 +175,7 @@ pub fn create_presentation( credential.cred_def_id ) })?; - let cred_def = match cred_def { - CredentialDefinition::CredentialDefinitionV1(cd) => cd, - }; + let CredentialDefinition::CredentialDefinitionV1(cred_def) = cred_def; let credential_pub_key = CredentialPublicKey::build_from_parts( &cred_def.value.primary, @@ -272,12 +264,8 @@ rev_reg_delta: {:?}, rev_reg_idx: {}, timestamp: {:?}, rev_state: {:?}", rev_state ); - let revoc_reg_def = match revoc_reg_def { - RevocationRegistryDefinition::RevocationRegistryDefinitionV1(v1) => v1, - }; - let rev_reg_delta = match rev_reg_delta { - RevocationRegistryDelta::RevocationRegistryDeltaV1(v1) => v1, - }; + let RevocationRegistryDefinition::RevocationRegistryDefinitionV1(revoc_reg_def) = revoc_reg_def; + let RevocationRegistryDelta::RevocationRegistryDeltaV1(rev_reg_delta) = rev_reg_delta; let witness = match rev_state { None => Witness::new( @@ -377,7 +365,7 @@ fn get_credential_values_for_attribute( let res = credential_attrs .iter() - .find(|&(ref key, _)| attr_common_view(key) == attr_common_view(&requested_attr)) + .find(|(key, _)| attr_common_view(key) == attr_common_view(requested_attr)) .map(|(_, values)| values.clone()); trace!( @@ -406,7 +394,7 @@ fn update_requested_proof( if let Some(name) = &attribute.name { let attribute_values = - get_credential_values_for_attribute(&credential.values.0, &name).ok_or_else( + get_credential_values_for_attribute(&credential.values.0, name).ok_or_else( || err_msg!("Credential value not found for attribute {:?}", name), )?; @@ -422,7 +410,7 @@ fn update_requested_proof( let mut value_map: HashMap = HashMap::new(); for name in names { let attr_value = - get_credential_values_for_attribute(&credential.values.0, &name) + get_credential_values_for_attribute(&credential.values.0, name) .ok_or_else(|| { err_msg!("Credential value not found for attribute {:?}", name) })?; diff --git a/indy-credx/src/services/tails.rs b/indy-credx/src/services/tails.rs index 4594efa..0fecd74 100644 --- a/indy-credx/src/services/tails.rs +++ b/indy-credx/src/services/tails.rs @@ -4,7 +4,7 @@ use std::fs::File; use std::io::{self, BufReader, BufWriter, Read, Seek, Write}; use std::path::{Path, PathBuf}; -use indy_utils::base58; +use indy_data_types::utils::base58; use rand::random; use sha2::{Digest, Sha256}; diff --git a/indy-credx/src/services/types.rs b/indy-credx/src/services/types.rs index 2f476f9..be5d2eb 100644 --- a/indy-credx/src/services/types.rs +++ b/indy-credx/src/services/types.rs @@ -19,16 +19,15 @@ pub use indy_data_types::{ }, schema::{AttributeNames, Schema}, }, - CredentialDefinitionId, RevocationRegistryId, SchemaId, + did::DidValue, + invalid, CredentialDefinitionId, RevocationRegistryId, SchemaId, Validatable, ValidationError, }; -pub use indy_utils::did::DidValue; -use indy_utils::{invalid, Validatable, ValidationError}; use crate::anoncreds_clsignatures::{RevocationRegistry as CryptoRevocationRegistry, Witness}; use crate::error::Error; use crate::services::helpers::encode_credential_attribute; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Default, Clone, Serialize, Deserialize)] pub struct CredentialDefinitionConfig { pub support_revocation: bool, } @@ -39,14 +38,6 @@ impl CredentialDefinitionConfig { } } -impl Default for CredentialDefinitionConfig { - fn default() -> Self { - Self { - support_revocation: false, - } - } -} - impl Validatable for CredentialDefinitionConfig {} #[derive(Debug, Default)] @@ -82,9 +73,9 @@ impl MakeCredentialValues { } } -impl Into for MakeCredentialValues { - fn into(self) -> CredentialValues { - self.0 +impl From for CredentialValues { + fn from(val: MakeCredentialValues) -> CredentialValues { + val.0 } } diff --git a/indy-credx/src/services/verifier.rs b/indy-credx/src/services/verifier.rs index 12b8526..17bc76f 100644 --- a/indy-credx/src/services/verifier.rs +++ b/indy-credx/src/services/verifier.rs @@ -80,11 +80,11 @@ pub(crate) fn _verify_presentation( let pres_req = pres_req.value(); let received_revealed_attrs: HashMap = - received_revealed_attrs(&presentation)?; + received_revealed_attrs(presentation)?; let received_unrevealed_attrs: HashMap = - received_unrevealed_attrs(&presentation)?; - let received_predicates: HashMap = received_predicates(&presentation)?; - let received_self_attested_attrs: HashSet = received_self_attested_attrs(&presentation); + received_unrevealed_attrs(presentation)?; + let received_predicates: HashMap = received_predicates(presentation)?; + let received_self_attested_attrs: HashSet = received_self_attested_attrs(presentation); compare_attr_from_proof_and_request( pres_req, @@ -94,10 +94,10 @@ pub(crate) fn _verify_presentation( &received_predicates, )?; - verify_revealed_attribute_values(&pres_req, &presentation)?; + verify_revealed_attribute_values(pres_req, presentation)?; verify_requested_restrictions( - &pres_req, + pres_req, &presentation.requested_proof, &received_revealed_attrs, &received_unrevealed_attrs, @@ -120,21 +120,17 @@ pub(crate) fn _verify_presentation( for sub_proof_index in 0..presentation.identifiers.len() { let identifier = presentation.identifiers[sub_proof_index].clone(); - let schema = match schemas + let Schema::SchemaV1(schema) = schemas .get(&identifier.schema_id) - .ok_or_else(|| err_msg!("Schema not provided for ID: {:?}", identifier.schema_id))? - { - Schema::SchemaV1(schema) => schema, - }; + .ok_or_else(|| err_msg!("Schema not provided for ID: {:?}", identifier.schema_id))?; - let cred_def = match cred_defs.get(&identifier.cred_def_id).ok_or_else(|| { - err_msg!( - "Credential Definition not provided for ID: {:?}", - identifier.cred_def_id - ) - })? { - CredentialDefinition::CredentialDefinitionV1(cred_def) => cred_def, - }; + let CredentialDefinition::CredentialDefinitionV1(cred_def) = + cred_defs.get(&identifier.cred_def_id).ok_or_else(|| { + err_msg!( + "Credential Definition not provided for ID: {:?}", + identifier.cred_def_id + ) + })?; let (rev_reg_def, rev_reg) = if let Some(timestamp) = identifier.timestamp { let rev_reg_id = identifier.rev_reg_id.clone().ok_or_else(|| { @@ -241,7 +237,7 @@ fn get_revealed_attributes_for_credential( let mut revealed_attrs_for_credential = requested_proof .revealed_attrs .iter() - .filter(|&(attr_referent, ref revealed_attr_info)| { + .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) }) @@ -252,7 +248,7 @@ fn get_revealed_attributes_for_credential( &mut requested_proof .revealed_attr_groups .iter() - .filter(|&(attr_referent, ref revealed_attr_info)| { + .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) }) @@ -310,7 +306,7 @@ fn compare_attr_from_proof_and_request( .chain(received_unrevealed_attrs) .map(|(r, _)| r.to_string()) .collect::>() - .union(&received_self_attested_attrs) + .union(received_self_attested_attrs) .cloned() .collect(); @@ -349,14 +345,14 @@ fn compare_timestamps_from_proof_and_request( .iter() .map(|(referent, info)| { validate_timestamp( - &received_revealed_attrs, + received_revealed_attrs, referent, &pres_req.non_revoked, &info.non_revoked, ) .or_else(|_| { validate_timestamp( - &received_unrevealed_attrs, + received_unrevealed_attrs, referent, &pres_req.non_revoked, &info.non_revoked, @@ -489,7 +485,7 @@ fn verify_revealed_attribute_values( attr_referent, ) })?; - verify_revealed_attribute_value(attr_name.as_str(), proof, &attr_info)?; + verify_revealed_attribute_value(attr_name.as_str(), proof, attr_info)?; } for (attr_referent, attr_infos) in proof.requested_proof.revealed_attr_groups.iter() { @@ -542,11 +538,7 @@ fn verify_revealed_attribute_value( proof: &Presentation, attr_info: &RevealedAttributeInfo, ) -> Result<()> { - let reveal_attr_encoded = attr_info.encoded.to_string(); - let reveal_attr_encoded = Regex::new("^0*") - .unwrap() - .replace_all(&reveal_attr_encoded, "") - .to_owned(); + let reveal_attr_encoded = attr_info.encoded.trim_start_matches('0'); let sub_proof_index = attr_info.sub_proof_index as usize; let crypto_proof_encoded = proof @@ -562,7 +554,7 @@ fn verify_revealed_attribute_value( })? .revealed_attrs()? .iter() - .find(|(key, _)| attr_common_view(attr_name) == attr_common_view(&key)) + .find(|(key, _)| attr_common_view(attr_name) == attr_common_view(key)) .map(|(_, val)| val.to_string()) .ok_or_else(|| { err_msg!( @@ -597,13 +589,13 @@ fn verify_requested_restrictions( let requested_attrs: HashMap = pres_req .requested_attributes .iter() - .filter(|&(referent, info)| !is_self_attested(&referent, &info, self_attested_attrs)) + .filter(|&(referent, info)| !is_self_attested(referent, info, self_attested_attrs)) .map(|(referent, info)| (referent.to_string(), info.clone())) .collect(); for (referent, info) in requested_attrs.iter() { if let Some(ref query) = info.restrictions { - let filter = gather_filter_info(&referent, &proof_attr_identifiers)?; + let filter = gather_filter_info(referent, &proof_attr_identifiers)?; let attr_value_map: HashMap> = if let Some(name) = info.name.as_ref() @@ -638,7 +630,7 @@ fn verify_requested_restrictions( )); }; - process_operator(&attr_value_map, &query, &filter).map_err(err_map!( + process_operator(&attr_value_map, query, &filter).map_err(err_map!( "Requested restriction validation failed for \"{:?}\" attributes", &attr_value_map ))?; @@ -647,7 +639,7 @@ fn verify_requested_restrictions( for (referent, info) in pres_req.requested_predicates.iter() { if let Some(ref query) = info.restrictions { - let filter = gather_filter_info(&referent, received_predicates)?; + let filter = gather_filter_info(referent, received_predicates)?; // start with the predicate requested attribute, which is un-revealed let mut attr_value_map = HashMap::new(); @@ -683,7 +675,7 @@ fn verify_requested_restrictions( } } - process_operator(&attr_value_map, &query, &filter).map_err(err_map!( + process_operator(&attr_value_map, query, &filter).map_err(err_map!( "Requested restriction validation failed for \"{}\" predicate", &info.name ))?; @@ -748,14 +740,14 @@ fn process_operator( ) -> Result<()> { match restriction_op { Query::Eq(ref tag_name, ref tag_value) => { - process_filter(attr_value_map, &tag_name, &tag_value, filter).map_err(err_map!( + process_filter(attr_value_map, tag_name, tag_value, filter).map_err(err_map!( "$eq operator validation failed for tag: \"{}\", value: \"{}\"", tag_name, tag_value )) } Query::Neq(ref tag_name, ref tag_value) => { - if process_filter(attr_value_map, &tag_name, &tag_value, filter).is_err() { + if process_filter(attr_value_map, tag_name, tag_value, filter).is_err() { Ok(()) } else { Err(err_msg!(ProofRejected, @@ -765,7 +757,7 @@ fn process_operator( Query::In(ref tag_name, ref tag_values) => { let res = tag_values .iter() - .any(|val| process_filter(attr_value_map, &tag_name, &val, filter).is_ok()); + .any(|val| process_filter(attr_value_map, tag_name, val, filter).is_ok()); if res { Ok(()) } else { @@ -797,7 +789,7 @@ fn process_operator( } } Query::Not(ref operator) => { - if process_operator(attr_value_map, &*operator, filter).is_err() { + if process_operator(attr_value_map, operator, filter).is_err() { Ok(()) } else { Err(err_msg!( diff --git a/indy-credx/tests/anoncreds_demos.rs b/indy-credx/tests/anoncreds_demos.rs index e41f395..a539731 100644 --- a/indy-credx/tests/anoncreds_demos.rs +++ b/indy-credx/tests/anoncreds_demos.rs @@ -16,8 +16,8 @@ use self::utils::anoncreds::{IssuerWallet, ProverWallet}; mod utils; -pub static GVT_SCHEMA_NAME: &'static str = "gvt"; -pub static GVT_SCHEMA_ATTRIBUTES: &[&'static str; 4] = &["name", "age", "sex", "height"]; +pub static GVT_SCHEMA_NAME: &str = "gvt"; +pub static GVT_SCHEMA_ATTRIBUTES: &[&str; 4] = &["name", "age", "sex", "height"]; #[test] fn anoncreds_works_for_single_issuer_single_prover() { @@ -56,7 +56,7 @@ fn anoncreds_works_for_single_issuer_single_prover() { // Issuer creates a Credential Offer let cred_offer = issuer::create_credential_offer( gvt_schema.id(), - &gvt_cred_def, + gvt_cred_def, &issuer_wallet.cred_defs[0].key_proof, ) .expect("Error creating credential offer"); @@ -64,7 +64,7 @@ fn anoncreds_works_for_single_issuer_single_prover() { // Prover creates a Credential Request let (cred_request, cred_request_metadata) = prover::create_credential_request( &prover_wallet.did, - &*gvt_cred_def, + gvt_cred_def, &prover_wallet.link_secret, "default", &cred_offer, @@ -86,7 +86,7 @@ fn anoncreds_works_for_single_issuer_single_prover() { .add_raw("age", "28") .expect("Error encoding attribute"); let (issue_cred, _, _) = issuer::create_credential( - &*gvt_cred_def, + gvt_cred_def, &issuer_wallet.cred_defs[0].private, &cred_offer, &cred_request, @@ -101,7 +101,7 @@ fn anoncreds_works_for_single_issuer_single_prover() { &mut recv_cred, &cred_request_metadata, &prover_wallet.link_secret, - &*gvt_cred_def, + gvt_cred_def, None, ) .expect("Error processing credential"); @@ -154,7 +154,7 @@ fn anoncreds_works_for_single_issuer_single_prover() { schemas.insert(gvt_schema.id().clone(), &gvt_schema); let mut cred_defs = HashMap::new(); - cred_defs.insert(gvt_cred_def.id().clone(), &*gvt_cred_def); + cred_defs.insert(gvt_cred_def.id().clone(), gvt_cred_def); let presentation = prover::create_presentation( &pres_request, @@ -254,7 +254,7 @@ fn anoncreds_works_for_single_issuer_single_prover_unrevoked() { let (rev_reg_def, rev_reg_def_private, rev_reg, rev_reg_delta) = issuer::create_revocation_registry( &issuer_wallet.did, - &gvt_cred_def, + gvt_cred_def, "tag", RegistryType::CL_ACCUM, IssuanceType::ISSUANCE_BY_DEFAULT, @@ -271,7 +271,7 @@ fn anoncreds_works_for_single_issuer_single_prover_unrevoked() { // Issuer creates a Credential Offer let cred_offer = issuer::create_credential_offer( gvt_schema.id(), - &gvt_cred_def, + gvt_cred_def, &issuer_wallet.cred_defs[0].key_proof, ) .expect("Error creating credential offer"); @@ -279,7 +279,7 @@ fn anoncreds_works_for_single_issuer_single_prover_unrevoked() { // Prover creates a Credential Request let (cred_request, cred_request_metadata) = prover::create_credential_request( &prover_wallet.did, - &gvt_cred_def, + gvt_cred_def, &prover_wallet.link_secret, "default", &cred_offer, @@ -301,7 +301,7 @@ fn anoncreds_works_for_single_issuer_single_prover_unrevoked() { .add_raw("age", "28") .expect("Error encoding attribute"); let (issue_cred, _rev_reg, _delta) = issuer::create_credential( - &*gvt_cred_def, + gvt_cred_def, &issuer_wallet.cred_defs[0].private, &cred_offer, &cred_request, @@ -322,7 +322,7 @@ fn anoncreds_works_for_single_issuer_single_prover_unrevoked() { &mut recv_cred, &cred_request_metadata, &prover_wallet.link_secret, - &*gvt_cred_def, + gvt_cred_def, Some(&rev_reg_def), ) .expect("Error processing credential"); @@ -354,7 +354,7 @@ fn anoncreds_works_for_single_issuer_single_prover_unrevoked() { .expect("Error creating proof request"); // Prover creates revocation state - let tails_reader = TailsFileReader::new(&tails_path); + let tails_reader = TailsFileReader::new(tails_path); let rev_state = prover::create_or_update_revocation_state( tails_reader, &rev_reg_def, @@ -387,7 +387,7 @@ fn anoncreds_works_for_single_issuer_single_prover_unrevoked() { schemas.insert(gvt_schema.id().clone(), &gvt_schema); let mut cred_defs = HashMap::new(); - cred_defs.insert(gvt_cred_def.id().clone(), &*gvt_cred_def); + cred_defs.insert(gvt_cred_def.id().clone(), gvt_cred_def); let presentation = prover::create_presentation( &pres_request, diff --git a/indy-credx/tests/utils/anoncreds.rs b/indy-credx/tests/utils/anoncreds.rs index 4cbf60e..de702aa 100644 --- a/indy-credx/tests/utils/anoncreds.rs +++ b/indy-credx/tests/utils/anoncreds.rs @@ -3,10 +3,10 @@ use indy_credx::types::{CredentialDefinitionPrivate, CredentialKeyCorrectnessPro use indy_data_types::anoncreds::cred_def::CredentialDefinition; use indy_data_types::anoncreds::credential::Credential; use indy_data_types::anoncreds::link_secret::LinkSecret; -use indy_utils::did::DidValue; +use indy_data_types::did::DidValue; -pub const ISSUER_DID: &'static str = "NcYxiDXkpYi6ov5FcYDi1e"; -pub const PROVER_DID: &'static str = "VsKV7grR1BUE29mG2Fm2kX"; +pub const ISSUER_DID: &str = "NcYxiDXkpYi6ov5FcYDi1e"; +pub const PROVER_DID: &str = "VsKV7grR1BUE29mG2Fm2kX"; pub struct StoredCredDef { pub public: CredentialDefinition, diff --git a/indy-data-types/Cargo.toml b/indy-data-types/Cargo.toml index d4bfa4a..2d680e5 100644 --- a/indy-data-types/Cargo.toml +++ b/indy-data-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "indy-data-types" -version = "0.6.1" +version = "0.7.0" authors = ["Hyperledger Indy Contributors "] description = "Common data types for Hyperledger Indy (https://www.hyperledger.org/projects), which provides a distributed-ledger-based foundation for self-sovereign identity (https://sovrin.org)." edition = "2021" @@ -16,29 +16,35 @@ path = "src/lib.rs" crate-type = ["rlib"] [features] -default = ["anoncreds", "merkle_tree"] +default = ["anoncreds", "ed25519", "merkle_tree"] anoncreds = ["serde_support"] cl = ["anoncreds", "anoncreds-clsignatures", "serde_support"] cl_native = ["anoncreds", "anoncreds-clsignatures/openssl_bn", "serde_support"] +ed25519 = ["curve25519-dalek", "ed25519-dalek", "rand", "sha2", "x25519-dalek"] merkle_tree = ["hex", "sha2"] rich_schema = [] -serde_support = [ - "serde", - "serde_json", - "anoncreds-clsignatures?/serde", - "indy-utils/serde", -] +serde_support = ["serde", "serde_json", "anoncreds-clsignatures?/serde"] vendored = ["anoncreds-clsignatures?/openssl_vendored"] [dependencies] anoncreds-clsignatures = { version = "0.2", optional = true } -indy-utils = { version = "0.6.0", default-features = false, path = "../indy-utils" } +bs58 = "0.5" +curve25519-dalek = { version = "4.1", default-features = false, optional = true } +ed25519-dalek = { version = "2.0", default-features = false, features = [ + "zeroize", +], optional = true } hex = { version = "0.4", optional = true } once_cell = "1" +rand = { version = "0.8", optional = true } regex = "1" serde = { version = "1.0", optional = true, features = ["derive"] } serde_json = { version = "1.0", optional = true, features = ["raw_value"] } sha2 = { version = "0.10", optional = true } +thiserror = "1" +x25519-dalek = { version = "2.0", default-features = false, optional = true, features = [ + "static_secrets", + "zeroize", +] } zeroize = { version = "1", features = ["zeroize_derive"] } [dev-dependencies] diff --git a/indy-data-types/src/anoncreds/cred_def.rs b/indy-data-types/src/anoncreds/cred_def.rs index 17a6ba0..3d06eb9 100644 --- a/indy-data-types/src/anoncreds/cred_def.rs +++ b/indy-data-types/src/anoncreds/cred_def.rs @@ -1,9 +1,10 @@ +use std::str::FromStr; + #[cfg(any(feature = "cl", feature = "cl_native"))] use crate::anoncreds_clsignatures::CredentialPublicKey; use crate::identifiers::cred_def::CredentialDefinitionId; use crate::identifiers::schema::SchemaId; -use crate::utils::Qualifiable; -use crate::{ConversionError, Validatable, ValidationError}; +use crate::{ConversionError, Qualifiable, Validatable, ValidationError}; pub const CL_SIGNATURE_TYPE: &str = "CL"; @@ -14,13 +15,6 @@ pub enum SignatureType { } impl SignatureType { - pub fn from_str(value: &str) -> Result { - match value { - CL_SIGNATURE_TYPE => Ok(Self::CL), - _ => Err(ConversionError::from_msg("Invalid signature type")), - } - } - pub fn to_str(&self) -> &'static str { match *self { SignatureType::CL => CL_SIGNATURE_TYPE, @@ -28,6 +22,17 @@ impl SignatureType { } } +impl FromStr for SignatureType { + type Err = ConversionError; + + fn from_str(value: &str) -> Result { + match value { + CL_SIGNATURE_TYPE => Ok(Self::CL), + _ => Err(ConversionError::from_msg("Invalid signature type")), + } + } +} + #[derive(Debug)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct CredentialDefinitionData { diff --git a/indy-data-types/src/anoncreds/cred_offer.rs b/indy-data-types/src/anoncreds/cred_offer.rs index c37400b..5a2abcf 100644 --- a/indy-data-types/src/anoncreds/cred_offer.rs +++ b/indy-data-types/src/anoncreds/cred_offer.rs @@ -1,8 +1,7 @@ use super::nonce::Nonce; use crate::identifiers::cred_def::CredentialDefinitionId; use crate::identifiers::schema::SchemaId; -use crate::utils::Qualifiable; -use crate::{Validatable, ValidationError}; +use crate::{Qualifiable, Validatable, ValidationError}; #[derive(Debug)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] diff --git a/indy-data-types/src/anoncreds/cred_request.rs b/indy-data-types/src/anoncreds/cred_request.rs index e99e1b5..385b030 100644 --- a/indy-data-types/src/anoncreds/cred_request.rs +++ b/indy-data-types/src/anoncreds/cred_request.rs @@ -1,8 +1,7 @@ use super::nonce::Nonce; +use crate::did::DidValue; use crate::identifiers::cred_def::CredentialDefinitionId; -use crate::utils::Qualifiable; -use crate::{Validatable, ValidationError}; -use indy_utils::did::DidValue; +use crate::{Qualifiable, Validatable, ValidationError}; #[derive(Debug)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] diff --git a/indy-data-types/src/anoncreds/nonce.rs b/indy-data-types/src/anoncreds/nonce.rs index fc3d3d1..123feaa 100644 --- a/indy-data-types/src/anoncreds/nonce.rs +++ b/indy-data-types/src/anoncreds/nonce.rs @@ -49,7 +49,7 @@ impl Nonce { return Err("Invalid bignum: empty value".into()); } for c in strval.chars() { - if c < '0' || c > '9' { + if !c.is_ascii_digit() { return Err("Invalid bignum value".into()); } } @@ -176,28 +176,28 @@ impl<'a> Deserialize<'a> for Nonce { where E: serde::de::Error, { - Ok(Nonce::try_from(value).map_err(E::custom)?) + Nonce::try_from(value).map_err(E::custom) } fn visit_u64(self, value: u64) -> Result where E: serde::de::Error, { - Ok(Nonce::try_from(value).map_err(E::custom)?) + Nonce::try_from(value).map_err(E::custom) } fn visit_u128(self, value: u128) -> Result where E: serde::de::Error, { - Ok(Nonce::try_from(value).map_err(E::custom)?) + Nonce::try_from(value).map_err(E::custom) } fn visit_str(self, value: &str) -> Result where E: serde::de::Error, { - Ok(Nonce::from_dec(value).map_err(E::custom)?) + Nonce::from_dec(value).map_err(E::custom) } } diff --git a/indy-data-types/src/anoncreds/pres_request.rs b/indy-data-types/src/anoncreds/pres_request.rs index 951d512..c1adc66 100644 --- a/indy-data-types/src/anoncreds/pres_request.rs +++ b/indy-data-types/src/anoncreds/pres_request.rs @@ -13,9 +13,8 @@ use crate::did::DidValue; use crate::identifiers::cred_def::CredentialDefinitionId; use crate::identifiers::rev_reg::RevocationRegistryId; use crate::identifiers::schema::SchemaId; -use crate::invalid; -use crate::utils::{qualifiable, Qualifiable}; -use crate::{Validatable, ValidationError}; +use crate::qualifiable::{self, Qualifiable}; +use crate::{invalid, Validatable, ValidationError}; #[derive(Debug, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] @@ -43,7 +42,7 @@ pub enum PresentationRequestVersion { } impl PresentationRequest { - pub fn value<'a>(&'a self) -> &'a PresentationRequestPayload { + pub fn value(&self) -> &PresentationRequestPayload { match self { PresentationRequest::PresentationRequestV1(req) => req, PresentationRequest::PresentationRequestV2(req) => req, @@ -228,7 +227,7 @@ impl Validatable for PresentationRequest { } if let Some(ref restrictions) = requested_attribute.restrictions { - _process_operator(&restrictions, &version)?; + _process_operator(restrictions, &version)?; } } @@ -240,7 +239,7 @@ impl Validatable for PresentationRequest { )); } if let Some(ref restrictions) = requested_predicate.restrictions { - _process_operator(&restrictions, &version)?; + _process_operator(restrictions, &version)?; } } @@ -256,13 +255,13 @@ impl PresentationRequest { requested_attribute.restrictions = requested_attribute .restrictions .as_mut() - .map(|ref mut restrictions| _convert_query_to_unqualified(&restrictions)); + .map(|ref mut restrictions| _convert_query_to_unqualified(restrictions)); } for (_, requested_predicate) in request.requested_predicates.iter_mut() { requested_predicate.restrictions = requested_predicate .restrictions .as_mut() - .map(|ref mut restrictions| _convert_query_to_unqualified(&restrictions)); + .map(|ref mut restrictions| _convert_query_to_unqualified(restrictions)); } }; @@ -299,13 +298,13 @@ fn _convert_query_to_unqualified(query: &Query) -> Query { Query::And(ref queries) => Query::And( queries .iter() - .map(|query| _convert_query_to_unqualified(query)) + .map(_convert_query_to_unqualified) .collect::>(), ), Query::Or(ref queries) => Query::Or( queries .iter() - .map(|query| _convert_query_to_unqualified(query)) + .map(_convert_query_to_unqualified) .collect::>(), ), Query::Not(ref query) => _convert_query_to_unqualified(query), diff --git a/indy-data-types/src/anoncreds/presentation.rs b/indy-data-types/src/anoncreds/presentation.rs index 064cb1f..4a64a76 100644 --- a/indy-data-types/src/anoncreds/presentation.rs +++ b/indy-data-types/src/anoncreds/presentation.rs @@ -13,7 +13,7 @@ pub struct Presentation { pub identifiers: Vec, } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] pub struct RequestedProof { pub revealed_attrs: HashMap, @@ -28,18 +28,6 @@ pub struct RequestedProof { pub predicates: HashMap, } -impl Default for RequestedProof { - fn default() -> Self { - RequestedProof { - revealed_attrs: HashMap::new(), - revealed_attr_groups: HashMap::new(), - self_attested_attrs: HashMap::new(), - unrevealed_attrs: HashMap::new(), - predicates: HashMap::new(), - } - } -} - #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] pub struct SubProofReferent { diff --git a/indy-data-types/src/anoncreds/rev_reg_def.rs b/indy-data-types/src/anoncreds/rev_reg_def.rs index 98cc04c..b41b975 100644 --- a/indy-data-types/src/anoncreds/rev_reg_def.rs +++ b/indy-data-types/src/anoncreds/rev_reg_def.rs @@ -1,7 +1,8 @@ +use std::str::FromStr; + use crate::identifiers::cred_def::CredentialDefinitionId; use crate::identifiers::rev_reg::RevocationRegistryId; -use crate::utils::Qualifiable; -use crate::{invalid, ConversionError, Validatable, ValidationError}; +use crate::{invalid, ConversionError, Qualifiable, Validatable, ValidationError}; pub const CL_ACCUM: &str = "CL_ACCUM"; @@ -9,24 +10,17 @@ pub const ISSUANCE_BY_DEFAULT: &str = "ISSUANCE_BY_DEFAULT"; pub const ISSUANCE_ON_DEMAND: &str = "ISSUANCE_ON_DEMAND"; #[allow(non_camel_case_types)] -#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] pub enum IssuanceType { + #[default] ISSUANCE_BY_DEFAULT, ISSUANCE_ON_DEMAND, } impl IssuanceType { - pub fn from_str(value: &str) -> Result { - match value { - ISSUANCE_BY_DEFAULT => Ok(Self::ISSUANCE_BY_DEFAULT), - ISSUANCE_ON_DEMAND => Ok(Self::ISSUANCE_ON_DEMAND), - _ => Err(ConversionError::from_msg("Invalid issuance type")), - } - } - pub fn to_bool(&self) -> bool { - self.clone() == IssuanceType::ISSUANCE_BY_DEFAULT + matches!(self, IssuanceType::ISSUANCE_BY_DEFAULT) } pub fn to_str(&self) -> &'static str { @@ -37,27 +31,27 @@ impl IssuanceType { } } -impl Default for IssuanceType { - fn default() -> Self { - Self::ISSUANCE_BY_DEFAULT +impl FromStr for IssuanceType { + type Err = ConversionError; + + fn from_str(value: &str) -> Result { + match value { + ISSUANCE_BY_DEFAULT => Ok(Self::ISSUANCE_BY_DEFAULT), + ISSUANCE_ON_DEMAND => Ok(Self::ISSUANCE_ON_DEMAND), + _ => Err(ConversionError::from_msg("Invalid issuance type")), + } } } #[allow(non_camel_case_types)] -#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] pub enum RegistryType { + #[default] CL_ACCUM, } impl RegistryType { - pub fn from_str(value: &str) -> Result { - match value { - CL_ACCUM => Ok(Self::CL_ACCUM), - _ => Err(ConversionError::from_msg("Invalid registry type")), - } - } - pub fn to_str(&self) -> &'static str { match *self { Self::CL_ACCUM => CL_ACCUM, @@ -65,6 +59,17 @@ impl RegistryType { } } +impl FromStr for RegistryType { + type Err = ConversionError; + + fn from_str(value: &str) -> Result { + match value { + CL_ACCUM => Ok(Self::CL_ACCUM), + _ => Err(ConversionError::from_msg("Invalid registry type")), + } + } +} + #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] diff --git a/indy-data-types/src/anoncreds/rich_schema.rs b/indy-data-types/src/anoncreds/rich_schema.rs index fa268f8..88abc57 100644 --- a/indy-data-types/src/anoncreds/rich_schema.rs +++ b/indy-data-types/src/anoncreds/rich_schema.rs @@ -20,7 +20,7 @@ pub struct RSContent(pub String); impl Validatable for RSContent { fn validate(&self) -> Result<(), ValidationError> { // ToDo: Add JSON-LD validation if needed - return Ok(()); + Ok(()) } } @@ -59,7 +59,7 @@ impl Validatable for RichSchema { let _rs_type: RSType = serde_json::from_value(serde_json::value::Value::String(self.rs_type.clone())) .map_err(|_err| _err.to_string())?; - return self.id.validate(); + self.id.validate() } } diff --git a/indy-data-types/src/anoncreds/schema.rs b/indy-data-types/src/anoncreds/schema.rs index 308412a..6a4c817 100644 --- a/indy-data-types/src/anoncreds/schema.rs +++ b/indy-data-types/src/anoncreds/schema.rs @@ -1,6 +1,5 @@ use crate::identifiers::schema::SchemaId; -use crate::utils::Qualifiable; -use crate::{Validatable, ValidationError}; +use crate::{Qualifiable, Validatable, ValidationError}; use std::collections::HashSet; use std::iter::FromIterator; @@ -55,7 +54,7 @@ pub struct SchemaV1 { pub seq_no: Option, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct AttributeNames(pub HashSet); @@ -87,9 +86,9 @@ impl From> for AttributeNames { } } -impl Into> for AttributeNames { - fn into(self) -> HashSet { - self.0 +impl From for HashSet { + fn from(val: AttributeNames) -> HashSet { + val.0 } } diff --git a/indy-data-types/src/anoncreds/wql.rs b/indy-data-types/src/anoncreds/wql.rs index f49e37a..20a10a2 100644 --- a/indy-data-types/src/anoncreds/wql.rs +++ b/indy-data-types/src/anoncreds/wql.rs @@ -198,9 +198,7 @@ mod serde_support { let v = JsonValue::deserialize(deserializer)?; match v { - JsonValue::Object(map) => { - parse_query(map).map_err(|err| de::Error::missing_field(err)) - } + JsonValue::Object(map) => parse_query(map).map_err(de::Error::missing_field), JsonValue::Array(array) => { // cast old restrictions format to wql let mut res: Vec = Vec::new(); @@ -210,7 +208,7 @@ mod serde_support { .ok_or_else(|| de::Error::custom("Restriction is invalid"))? .clone() .into_iter() - .filter(|&(_, ref v)| !v.is_null()) + .filter(|(_, v)| !v.is_null()) .collect(); if !sub_query.is_empty() { @@ -221,7 +219,7 @@ mod serde_support { let mut map = serde_json::Map::new(); map.insert("$or".to_string(), JsonValue::Array(res)); - parse_query(map).map_err(|err| de::Error::custom(err)) + parse_query(map).map_err(de::Error::custom) } _ => Err(de::Error::missing_field( "Restriction must be either object or array", @@ -341,7 +339,7 @@ mod serde_support { (_, JsonValue::Object(map)) => { if map.len() == 1 { let (operator_name, value) = map.into_iter().next().unwrap(); - parse_single_operator(operator_name, key, value).map(|operator| Some(operator)) + parse_single_operator(operator_name, key, value).map(Some) } else { Err("value must be JSON object of length 1") } @@ -2852,9 +2850,9 @@ mod tests { #[test] fn test_old_format_empty() { - let json = format!(r#"[]"#); + let json = r#"[]"#; - let query: Query = ::serde_json::from_str(&json).unwrap(); + let query: Query = ::serde_json::from_str(json).unwrap(); let expected = Query::And(vec![]); @@ -2868,8 +2866,8 @@ mod tests { let value1 = _random_string(10); let json = json!(vec![ - json ! ({name1.clone(): value1.clone()}), - json!({ name2.clone(): ::serde_json::Value::Null }) + json!({ name1.clone(): value1 }), + json!({ name2: ::serde_json::Value::Null }) ]) .to_string(); @@ -2893,7 +2891,7 @@ mod tests { fn test_optimise_or() { let json = r#"[]"#; - let query: Query = ::serde_json::from_str(&json).unwrap(); + let query: Query = ::serde_json::from_str(json).unwrap(); assert_eq!(query.optimise(), None); } diff --git a/indy-utils/src/did.rs b/indy-data-types/src/did.rs similarity index 94% rename from indy-utils/src/did.rs rename to indy-data-types/src/did.rs index 059d45b..31139e2 100644 --- a/indy-utils/src/did.rs +++ b/indy-data-types/src/did.rs @@ -4,10 +4,11 @@ use regex::Regex; #[cfg(feature = "ed25519")] use sha2::{Digest, Sha256}; -use crate::base58; #[cfg(feature = "ed25519")] use crate::keys::{KeyType, PrivateKey, VerKey}; -use crate::{Qualifiable, Validatable, ValidationError}; +use crate::qualifiable::{qualifiable_type, Qualifiable}; +use crate::utils::base58; +use crate::{Validatable, ValidationError}; /// The default identifier DID used when submitting ledger read requests pub static DEFAULT_LIBINDY_DID: Lazy = @@ -32,7 +33,7 @@ pub fn generate_did( Some(1) | None => Ok(base58::encode(&pk.as_ref()[..16])), Some(2) => { let mut hasher = Sha256::new(); - Digest::update(&mut hasher, &pk.as_ref()); + Digest::update(&mut hasher, pk.as_ref()); let hash = hasher.finalize(); Ok(base58::encode(&hash[..16])) } @@ -79,7 +80,7 @@ impl DidValue { pub fn is_abbreviatable(&self) -> bool { match self.get_method() { - Some(ref method) if method.starts_with("sov") => true, + Some(method) if method.starts_with("sov") => true, Some(_) => false, None => true, } @@ -124,7 +125,7 @@ impl std::ops::Deref for ShortDidValue { impl ShortDidValue { /// Convert a short DID value to a qualified DID pub fn qualify(&self, method: Option) -> DidValue { - DidValue::combine(method.as_ref().map(String::as_str), &self) + DidValue::combine(method.as_deref(), self) } } diff --git a/indy-utils/src/error.rs b/indy-data-types/src/error.rs similarity index 96% rename from indy-utils/src/error.rs rename to indy-data-types/src/error.rs index 898f8d1..5e2a01d 100644 --- a/indy-utils/src/error.rs +++ b/indy-data-types/src/error.rs @@ -13,10 +13,12 @@ macro_rules! define_error { } impl $name { + #[allow(unused)] pub fn from_msg>(msg: T) -> Self { Self::from(msg.into()) } + #[allow(unused)] pub fn from_err(err: E) -> Self where E: StdError + Send + Sync + 'static, @@ -76,9 +78,9 @@ macro_rules! define_error { } } - impl Into for $name { - fn into(self) -> String { - self.to_string() + impl From<$name> for String { + fn from(val: $name) -> String { + val.to_string() } } diff --git a/indy-data-types/src/identifiers/cred_def.rs b/indy-data-types/src/identifiers/cred_def.rs index e8266f4..78928b1 100644 --- a/indy-data-types/src/identifiers/cred_def.rs +++ b/indy-data-types/src/identifiers/cred_def.rs @@ -1,8 +1,7 @@ use super::schema::SchemaId; -use crate::utils::{qualifiable, Qualifiable}; +use crate::did::DidValue; +use crate::qualifiable::{self, qualifiable_type, Qualifiable}; use crate::{Validatable, ValidationError}; -use indy_utils::did::DidValue; -use indy_utils::qualifiable_type; use super::DELIMITER; @@ -19,7 +18,7 @@ impl CredentialDefinitionId { tag: &str, ) -> CredentialDefinitionId { let tag = if tag.is_empty() { - format!("") + String::new() } else { format!("{}{}", DELIMITER, tag) }; diff --git a/indy-data-types/src/identifiers/mod.rs b/indy-data-types/src/identifiers/mod.rs index e6a7467..2a5fc0c 100644 --- a/indy-data-types/src/identifiers/mod.rs +++ b/indy-data-types/src/identifiers/mod.rs @@ -10,4 +10,4 @@ pub mod schema; pub mod rich_schema; /// The standard delimiter used in identifier strings -pub const DELIMITER: &'static str = ":"; +pub const DELIMITER: &str = ":"; diff --git a/indy-data-types/src/identifiers/rev_reg.rs b/indy-data-types/src/identifiers/rev_reg.rs index 77fa442..93c6b96 100644 --- a/indy-data-types/src/identifiers/rev_reg.rs +++ b/indy-data-types/src/identifiers/rev_reg.rs @@ -4,10 +4,9 @@ use regex::Regex; use super::cred_def::CredentialDefinitionId; use super::DELIMITER; -use crate::utils::{qualifiable, Qualifiable}; +use crate::did::DidValue; +use crate::qualifiable::{self, qualifiable_type, Qualifiable}; use crate::{Validatable, ValidationError}; -use indy_utils::did::DidValue; -use indy_utils::qualifiable_type; static QUALIFIED_REV_REG_ID: Lazy = Lazy::new(|| { Regex::new("(^revreg:(?P[a-z0-9]+):)?(?P.+):4:(?P.+):(?P.+):(?P.+)$").unwrap() @@ -45,15 +44,14 @@ impl RevocationRegistryId { } pub fn parts(&self) -> Option<(DidValue, CredentialDefinitionId, String, String)> { - match QUALIFIED_REV_REG_ID.captures(&self.0) { - Some(caps) => Some(( + QUALIFIED_REV_REG_ID.captures(&self.0).map(|caps| { + ( DidValue(caps["did"].to_string()), CredentialDefinitionId(caps["cred_def_id"].to_string()), caps["rev_reg_type"].to_string(), caps["tag"].to_string(), - )), - None => None, - } + ) + }) } } diff --git a/indy-data-types/src/identifiers/rich_schema.rs b/indy-data-types/src/identifiers/rich_schema.rs index 42fbc45..3e11012 100644 --- a/indy-data-types/src/identifiers/rich_schema.rs +++ b/indy-data-types/src/identifiers/rich_schema.rs @@ -1,6 +1,5 @@ -use crate::utils::Qualifiable; +use crate::qualifiable::{qualifiable_type, Qualifiable}; use crate::{Validatable, ValidationError}; -use indy_utils::qualifiable_type; qualifiable_type!(RichSchemaId, "A rich schema identifier"); @@ -8,14 +7,14 @@ impl RichSchemaId { pub const PREFIX: &'static str = "rich_schema"; pub fn new(did_string: String) -> RichSchemaId { // ToDo: add RichSchema specific id forming if needed - return RichSchemaId(did_string); + RichSchemaId(did_string) } } impl Validatable for RichSchemaId { fn validate(&self) -> Result<(), ValidationError> { // ToDO: add RichSchema ID specific validation - return Ok(()); + Ok(()) } } @@ -39,7 +38,7 @@ mod tests { #[test] fn _validate_qualified_rs_id() { - assert_eq!(_rs_id_qualified().validate().unwrap(), ()) + _rs_id_qualified().validate().unwrap(); } // #[test] diff --git a/indy-data-types/src/identifiers/schema.rs b/indy-data-types/src/identifiers/schema.rs index b4938e4..50b070d 100644 --- a/indy-data-types/src/identifiers/schema.rs +++ b/indy-data-types/src/identifiers/schema.rs @@ -1,7 +1,6 @@ -use crate::utils::{qualifiable, Qualifiable}; -use crate::{Validatable, ValidationError}; -use indy_utils::did::DidValue; -use indy_utils::qualifiable_type; +use crate::did::DidValue; +use crate::qualifiable::{self, qualifiable_type}; +use crate::{Qualifiable, Validatable, ValidationError}; use super::DELIMITER; diff --git a/indy-utils/src/keys/mod.rs b/indy-data-types/src/keys/mod.rs similarity index 87% rename from indy-utils/src/keys/mod.rs rename to indy-data-types/src/keys/mod.rs index 511ddae..22867e3 100644 --- a/indy-utils/src/keys/mod.rs +++ b/indy-data-types/src/keys/mod.rs @@ -1,20 +1,19 @@ #[cfg(feature = "ed25519")] -use curve25519_dalek::edwards::CompressedEdwardsY; +use std::convert::TryFrom; +use std::str::FromStr; + #[cfg(feature = "ed25519")] -use ed25519_dalek::{ExpandedSecretKey, PublicKey, SecretKey, Signature}; +use curve25519_dalek::{edwards::CompressedEdwardsY, scalar::clamp_integer}; +#[cfg(feature = "ed25519")] +use ed25519_dalek::{Signature, Signer, SigningKey, VerifyingKey}; #[cfg(feature = "ed25519")] use rand::{thread_rng, RngCore}; #[cfg(feature = "ed25519")] use sha2::digest::Digest; - -#[cfg(feature = "ed25519")] -use std::convert::TryFrom; - use zeroize::Zeroize; -use super::base58; -use super::error::ConversionError; -use super::{Validatable, ValidationError}; +use crate::utils::base58; +use crate::{ConversionError, Validatable, ValidationError}; mod types; pub use types::{KeyEncoding, KeyType}; @@ -27,14 +26,14 @@ pub fn build_full_verkey(dest: &str, key: &str) -> Result, + pub key: Box<[u8]>, pub alg: KeyType, } impl PrivateKey { pub fn new>(key: K, alg: Option) -> Self { Self { - key: key.as_ref().to_vec(), + key: key.as_ref().into(), alg: alg.unwrap_or_default(), } } @@ -54,12 +53,11 @@ impl PrivateKey { #[cfg(feature = "ed25519")] pub fn from_seed(seed: &[u8]) -> Result { - let sk = SecretKey::from_bytes(seed) - .map_err(|err| format!("Error creating signing key: {}", err))?; - let mut esk = [0u8; 64]; - esk[..32].copy_from_slice(sk.as_bytes()); - esk[32..].copy_from_slice(PublicKey::from(&sk).as_bytes()); - Ok(Self::new(esk, Some(KeyType::ED25519))) + let sk = SigningKey::from_bytes( + seed.try_into() + .map_err(|_| "Invalid length for secret key")?, + ); + Ok(Self::new(sk.to_keypair_bytes(), Some(KeyType::ED25519))) } pub fn public_key(&self) -> Result { @@ -70,7 +68,7 @@ impl PrivateKey { } pub fn key_bytes(&self) -> Vec { - self.key.clone() + Vec::from(self.key.as_ref()) } #[cfg(feature = "ed25519")] @@ -79,9 +77,9 @@ impl PrivateKey { KeyType::ED25519 => { let mut hash = sha2::Sha512::digest(&self.key[..32]); let x_sk = - x25519_dalek::StaticSecret::from(<[u8; 32]>::try_from(&hash[..32]).unwrap()); + x25519_dalek::StaticSecret::from(clamp_integer(hash[..32].try_into().unwrap())); hash.zeroize(); - Ok(Self::new(&x_sk.to_bytes(), Some(KeyType::X25519))) + Ok(Self::new(x_sk.to_bytes(), Some(KeyType::X25519))) } _ => Err("Unsupported key format for key exchange".into()), } @@ -91,9 +89,8 @@ impl PrivateKey { pub fn sign>(&self, message: M) -> Result, ConversionError> { match self.alg { KeyType::ED25519 => { - let esk = ExpandedSecretKey::from(&SecretKey::from_bytes(&self.key[..32]).unwrap()); - let pk = PublicKey::from_bytes(&self.key[32..]).unwrap(); - let sig = esk.sign(message.as_ref(), &pk); + let esk = SigningKey::from_keypair_bytes((&*self.key).try_into().unwrap()).unwrap(); + let sig = esk.sign(message.as_ref()); Ok(sig.to_bytes().into()) } _ => Err("Unsupported key format for signing".into()), @@ -137,7 +134,7 @@ impl Validatable for PrivateKey { /// A raw verkey used in verifying signatures #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct VerKey { - pub key: Vec, + pub key: Box<[u8]>, pub alg: KeyType, } @@ -145,7 +142,7 @@ impl VerKey { pub fn new>(key: K, alg: Option) -> Self { let alg = alg.unwrap_or_default(); Self { - key: key.as_ref().to_vec(), + key: key.as_ref().into(), alg, } } @@ -169,17 +166,17 @@ impl VerKey { } pub fn key_bytes(&self) -> Vec { - self.key.clone() + Vec::from(self.key.as_ref()) } #[cfg(feature = "ed25519")] pub fn key_exchange(&self) -> Result { match self.alg { KeyType::ED25519 => { - let vky = CompressedEdwardsY::from_slice(&self.key[..]); + let vky = CompressedEdwardsY::from_slice(&self.key).unwrap(); if let Some(x_vk) = vky.decompress() { Ok(Self::new( - x_vk.to_montgomery().as_bytes().to_vec(), + x_vk.to_montgomery().as_bytes(), Some(KeyType::X25519), )) } else { @@ -198,7 +195,7 @@ impl VerKey { ) -> Result { match self.alg { KeyType::ED25519 => { - let vk = PublicKey::from_bytes(&self.key[..]).unwrap(); + let vk = VerifyingKey::try_from(&*self.key).unwrap(); if let Ok(sig) = Signature::try_from(signature.as_ref()) { Ok(vk.verify_strict(message.as_ref(), &sig).is_ok()) } else { @@ -273,8 +270,8 @@ impl EncodedVerKey { } pub fn from_did_and_verkey(did: &str, key: &str) -> Result { - if key.chars().next() == Some('~') { - let mut vk_bytes = base58::decode(&key[1..])?; + if let Some(key) = key.strip_prefix('~') { + let mut vk_bytes = base58::decode(key)?; if vk_bytes.len() != 16 { return Err("Expected 16-byte abbreviated verkey".into()); } @@ -284,7 +281,7 @@ impl EncodedVerKey { } did_bytes.append(&mut vk_bytes); Ok(Self::new( - &base58::encode(did_bytes), + base58::encode(did_bytes), Some(KeyType::ED25519), Some(KeyEncoding::BASE58), )) @@ -327,10 +324,6 @@ impl EncodedVerKey { Self::from_str_qualified(key, None, None, None) } - pub fn from_str(key: &str) -> Result { - Self::from_str_qualified(key, None, None, None) - } - pub fn from_str_qualified( key: &str, dest: Option<&str>, @@ -348,13 +341,12 @@ impl EncodedVerKey { (key, alg) }; - if key.starts_with('~') { - let dest = - unwrap_opt_or_return!(dest, Err("Destination required for short verkey".into())); + if let Some(key) = key.strip_prefix('~') { + let dest = dest.ok_or("Destination required for short verkey")?; let mut result = base58::decode(dest)?; - let mut end = base58::decode(&key[1..])?; + let mut end = base58::decode(key)?; result.append(&mut end); - Ok(Self::new(&base58::encode(result), alg, enc)) + Ok(Self::new(base58::encode(result), alg, enc)) } else { Ok(Self::new(key, alg, enc)) } @@ -426,6 +418,14 @@ impl std::fmt::Display for EncodedVerKey { } } +impl FromStr for EncodedVerKey { + type Err = ConversionError; + + fn from_str(key: &str) -> Result { + Self::from_str_qualified(key, None, None, None) + } +} + impl Validatable for EncodedVerKey { fn validate(&self) -> Result<(), ValidationError> { let verkey = self.decode()?; @@ -509,7 +509,7 @@ mod tests { const SEED: &[u8; 32] = b"aaaabbbbccccddddeeeeffffgggghhhh"; let sk = PrivateKey::from_seed(&SEED[..]).unwrap(); assert_eq!( - &sk.as_ref()[..], + sk.as_ref(), &[ 97, 97, 97, 97, 98, 98, 98, 98, 99, 99, 99, 99, 100, 100, 100, 100, 101, 101, 101, 101, 102, 102, 102, 102, 103, 103, 103, 103, 104, 104, 104, 104, 113, 22, 13, 44, @@ -519,7 +519,7 @@ mod tests { ); let xk = sk.key_exchange().unwrap(); assert_eq!( - &xk.as_ref(), + xk.as_ref(), &[ 208, 235, 232, 147, 241, 214, 250, 182, 45, 157, 20, 202, 31, 184, 226, 115, 149, 82, 210, 89, 50, 100, 22, 67, 21, 8, 124, 198, 100, 252, 237, 107 @@ -532,11 +532,11 @@ mod tests { fn sign_and_verify() { let message = b"hello there"; let sk = PrivateKey::generate(None).unwrap(); - let sig = sk.sign(&message).unwrap(); + let sig = sk.sign(message).unwrap(); let vk = sk.public_key().unwrap(); - assert!(vk.verify_signature(&message, &sig).unwrap()); - assert!(vk.verify_signature(&message, &[]).is_err()); - assert!(!vk.verify_signature(&"goodbye", &sig).unwrap()); + assert!(vk.verify_signature(message, &sig).unwrap()); + assert!(vk.verify_signature(message, b"").is_err()); + assert!(!vk.verify_signature("goodbye", &sig).unwrap()); } #[cfg(feature = "ed25519")] @@ -548,8 +548,8 @@ mod tests { vk.validate().unwrap(); let sk = PrivateKey::new(b"bad key", Some(KeyType::ED25519)); - assert_eq!(sk.validate().is_ok(), false); + assert!(sk.validate().is_err()); let vk = VerKey::new(b"bad key", Some(KeyType::ED25519)); - assert_eq!(vk.validate().is_ok(), false); + assert!(vk.validate().is_err()); } } diff --git a/indy-utils/src/keys/types.rs b/indy-data-types/src/keys/types.rs similarity index 53% rename from indy-utils/src/keys/types.rs rename to indy-data-types/src/keys/types.rs index 2bd0dd2..0551fda 100644 --- a/indy-utils/src/keys/types.rs +++ b/indy-data-types/src/keys/types.rs @@ -1,30 +1,26 @@ -pub const KEY_ENC_BASE58: &'static str = "base58"; +use std::fmt::{self, Display, Formatter}; +use std::ops::Deref; +use std::str::FromStr; -pub const KEY_TYPE_ED25519: &'static str = "ed25519"; -pub const KEY_TYPE_X25519: &'static str = "x25519"; +use crate::ConversionError; + +pub const KEY_ENC_BASE58: &str = "base58"; + +pub const KEY_TYPE_ED25519: &str = "ed25519"; +pub const KEY_TYPE_X25519: &str = "x25519"; /// Enum of known and unknown key types -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum KeyType { + #[default] ED25519, X25519, Other(String), } impl KeyType { - pub fn from_str(keytype: &str) -> KeyType { - match keytype.to_ascii_lowercase().as_str() { - KEY_TYPE_ED25519 => KeyType::ED25519, - KEY_TYPE_X25519 => KeyType::X25519, - _ => KeyType::Other(keytype.to_owned()), - } - } - pub fn is_known(&self) -> bool { - match self { - Self::Other(_) => false, - _ => true, - } + !matches!(self, Self::Other(_)) } pub fn as_str(&self) -> &str { @@ -36,15 +32,21 @@ impl KeyType { } } -impl std::string::ToString for KeyType { - fn to_string(&self) -> String { - self.as_str().to_owned() +impl FromStr for KeyType { + type Err = ConversionError; + + fn from_str(keytype: &str) -> Result { + Ok(match keytype.to_ascii_lowercase().as_str() { + KEY_TYPE_ED25519 => KeyType::ED25519, + KEY_TYPE_X25519 => KeyType::X25519, + _ => KeyType::Other(keytype.to_owned()), + }) } } -impl Default for KeyType { - fn default() -> Self { - KeyType::ED25519 +impl Display for KeyType { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str(self.as_str()) } } @@ -57,31 +59,25 @@ impl std::ops::Deref for KeyType { impl From<&str> for KeyType { fn from(value: &str) -> Self { - Self::from_str(value) + Self::from_str(value).unwrap() } } impl From for KeyType { fn from(value: String) -> Self { - Self::from_str(&value) + Self::from_str(&value).unwrap() } } /// Enum of known and unknown key encodings -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum KeyEncoding { + #[default] BASE58, Other(String), } impl KeyEncoding { - pub fn from_str(keyenc: &str) -> KeyEncoding { - match keyenc.to_ascii_lowercase().as_str() { - KEY_ENC_BASE58 => KeyEncoding::BASE58, - _ => KeyEncoding::Other(keyenc.to_owned()), - } - } - pub fn as_str(&self) -> &str { match self { Self::BASE58 => KEY_ENC_BASE58, @@ -90,19 +86,24 @@ impl KeyEncoding { } } -impl std::string::ToString for KeyEncoding { - fn to_string(&self) -> String { - self.as_str().to_owned() +impl FromStr for KeyEncoding { + type Err = ConversionError; + + fn from_str(keyenc: &str) -> Result { + Ok(match keyenc.to_ascii_lowercase().as_str() { + KEY_ENC_BASE58 => KeyEncoding::BASE58, + _ => KeyEncoding::Other(keyenc.to_owned()), + }) } } -impl Default for KeyEncoding { - fn default() -> Self { - KeyEncoding::BASE58 +impl Display for KeyEncoding { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str(self.as_str()) } } -impl std::ops::Deref for KeyEncoding { +impl Deref for KeyEncoding { type Target = str; fn deref(&self) -> &str { self.as_str() @@ -111,12 +112,12 @@ impl std::ops::Deref for KeyEncoding { impl From<&str> for KeyEncoding { fn from(value: &str) -> Self { - Self::from_str(value) + Self::from_str(value).unwrap() } } impl From for KeyEncoding { fn from(value: String) -> Self { - Self::from_str(&value) + Self::from_str(&value).unwrap() } } diff --git a/indy-data-types/src/lib.rs b/indy-data-types/src/lib.rs index e69b922..077b9a5 100644 --- a/indy-data-types/src/lib.rs +++ b/indy-data-types/src/lib.rs @@ -6,17 +6,21 @@ extern crate serde; #[macro_use] extern crate serde_json; -#[macro_use] -mod macros; - -mod utils { - pub use indy_utils::base58; - pub use indy_utils::{qualifiable, Qualifiable}; -} +mod error; -pub use indy_utils::did; -pub use indy_utils::keys; -pub use indy_utils::{invalid, ConversionError, Validatable, ValidationError}; +#[macro_use] +mod validation; + +pub mod did; +pub mod keys; +pub mod qualifiable; +pub mod utils; + +pub use self::{ + error::{ConversionError, ValidationError}, + qualifiable::Qualifiable, + validation::Validatable, +}; #[cfg(any(feature = "cl", feature = "cl_native"))] pub use anoncreds_clsignatures; diff --git a/indy-data-types/src/macros.rs b/indy-data-types/src/macros.rs deleted file mode 100644 index 0759b37..0000000 --- a/indy-data-types/src/macros.rs +++ /dev/null @@ -1,9 +0,0 @@ -#[cfg(feature = "merkle_tree")] -macro_rules! unwrap_opt_or_return { - ($opt:expr, $err:expr) => { - match $opt { - Some(val) => val, - None => return $err, - } - }; -} diff --git a/indy-data-types/src/merkle_tree/hash.rs b/indy-data-types/src/merkle_tree/hash.rs index 3e18e8c..75816c4 100644 --- a/indy-data-types/src/merkle_tree/hash.rs +++ b/indy-data-types/src/merkle_tree/hash.rs @@ -49,7 +49,7 @@ impl TreeHash for H { T: Hashable, { let mut ctx = Self::new(); - ctx.update(&[0x00]); + ctx.update([0x00]); leaf.update_context(&mut ctx)?; Ok(ctx.finalize().to_vec()) } @@ -59,7 +59,7 @@ impl TreeHash for H { T: Hashable, { let mut ctx = Self::new(); - ctx.update(&[0x01]); + ctx.update([0x01]); left.update_context(&mut ctx)?; right.update_context(&mut ctx)?; Ok(ctx.finalize().to_vec()) @@ -95,7 +95,8 @@ pub trait Hashable { impl> Hashable for T { fn update_context(&self, context: &mut D) -> Result<(), ValidationError> { - Ok(context.update(self.as_ref())) + context.update(self.as_ref()); + Ok(()) } } diff --git a/indy-data-types/src/merkle_tree/mod.rs b/indy-data-types/src/merkle_tree/mod.rs index b2669a1..2a5138b 100644 --- a/indy-data-types/src/merkle_tree/mod.rs +++ b/indy-data-types/src/merkle_tree/mod.rs @@ -10,6 +10,15 @@ mod merkletree; mod proof; mod tree; +macro_rules! unwrap_opt_or_return { + ($opt:expr, $err:expr) => { + match $opt { + Some(val) => val, + None => return $err, + } + }; +} + impl MerkleTree { fn count_bits(v: usize) -> usize { let mut ret = 0; @@ -23,10 +32,7 @@ impl MerkleTree { pub fn find_hash<'a>(from: &'a Tree, required_hash: &Vec) -> Option<&'a Tree> { match *from { - Tree::Empty { .. } => { - assert!(false); - None - } + Tree::Empty { .. } => None, Tree::Node { ref left, ref right, @@ -63,7 +69,7 @@ impl MerkleTree { &self, new_root_hash: &Vec, new_size: usize, - proof: &Vec>, + proof: &[Vec], ) -> Result { if self.count == 0 { // empty old tree @@ -75,7 +81,6 @@ impl MerkleTree { } if self.count > new_size { // old tree is bigger! - assert!(false); return Ok(false); } @@ -162,7 +167,7 @@ impl MerkleTree { self.nodes_count += 1; } _ => { - assert!(false); + unreachable!(); } } } else { @@ -193,7 +198,7 @@ impl MerkleTree { self.nodes_count += 1; } _ => { - assert!(false); + unreachable!(); } } self.height += 1; @@ -312,9 +317,9 @@ mod tests { assert!(mt .consistency_proof( &vec![ - 0x77 as u8, 0xf1, 0x5a, 0x58, 0x07, 0xfd, 0xaa, 0x56, 0x51, 0x28, 0xc5, 0x8f, - 0x59, 0x1f, 0x4f, 0x03, 0x25, 0x81, 0xfe, 0xe7, 0xd8, 0x61, 0x99, 0xae, 0xf8, - 0xae, 0xac, 0x7b, 0x05, 0x80, 0xbe, 0x0a + 0x77u8, 0xf1, 0x5a, 0x58, 0x07, 0xfd, 0xaa, 0x56, 0x51, 0x28, 0xc5, 0x8f, 0x59, + 0x1f, 0x4f, 0x03, 0x25, 0x81, 0xfe, 0xe7, 0xd8, 0x61, 0x99, 0xae, 0xf8, 0xae, + 0xac, 0x7b, 0x05, 0x80, 0xbe, 0x0a ], 4, &proofs @@ -335,11 +340,9 @@ mod tests { let proofs: Vec> = vec![]; - assert_eq!( - false, - mt.consistency_proof(&vec![0x77 as u8, 0xf1, 0x5a], 4, &proofs) - .unwrap() - ); + assert!(!mt + .consistency_proof(&vec![0x77u8, 0xf1, 0x5a], 4, &proofs) + .unwrap()); } #[test] @@ -355,7 +358,7 @@ mod tests { for value in values { let proof = tree.gen_proof(value).unwrap(); let is_valid = proof - .map(|p| p.validate(&root_hash).unwrap()) + .map(|p| p.validate(root_hash).unwrap()) .unwrap_or(false); assert!(is_valid); @@ -419,7 +422,7 @@ mod tests { //add 5th node mt.append(all_values[5 - 1].clone()).unwrap(); assert!(mt - .consistency_proof(&full_root_hash, 8, &proofs_for_5) + .consistency_proof(full_root_hash, 8, &proofs_for_5) .unwrap()); //try to add 6th node @@ -435,7 +438,7 @@ mod tests { //add 6th node mt.append(all_values[6 - 1].clone()).unwrap(); assert!(mt - .consistency_proof(&full_root_hash, 8, &proofs_for_6) + .consistency_proof(full_root_hash, 8, &proofs_for_6) .unwrap()); //try to add 7th node @@ -452,7 +455,7 @@ mod tests { //add 7th node mt.append(all_values[7 - 1].clone()).unwrap(); assert!(mt - .consistency_proof(&full_root_hash, 8, &proofs_for_7) + .consistency_proof(full_root_hash, 8, &proofs_for_7) .unwrap()); //try to add 8th node, empty proof @@ -460,7 +463,7 @@ mod tests { //add 7th node mt.append(all_values[8 - 1].clone()).unwrap(); assert!(mt - .consistency_proof(&full_root_hash, 8, &proofs_for_8) + .consistency_proof(full_root_hash, 8, &proofs_for_8) .unwrap()); } diff --git a/indy-data-types/src/merkle_tree/proof.rs b/indy-data-types/src/merkle_tree/proof.rs index f2c38a5..aeda1b7 100644 --- a/indy-data-types/src/merkle_tree/proof.rs +++ b/indy-data-types/src/merkle_tree/proof.rs @@ -32,30 +32,29 @@ impl Proof { if self.root_hash != root_hash || self.lemma.node_hash != root_hash { return Ok(false); } - - Ok(self.validate_lemma(&self.lemma)?) + _validate_lemma(&self.lemma) } +} - fn validate_lemma(&self, lemma: &Lemma) -> Result { - match lemma.sub_lemma { - None => Ok(lemma.sibling_hash.is_none()), - - Some(ref sub) => match lemma.sibling_hash { - None => Ok(false), - - Some(Positioned::Left(ref hash)) => { - let combined = Hash::hash_nodes(hash, &sub.node_hash)?; - let hashes_match = combined == lemma.node_hash; - Ok(hashes_match && self.validate_lemma(sub)?) - } - - Some(Positioned::Right(ref hash)) => { - let combined = Hash::hash_nodes(&sub.node_hash, hash)?; - let hashes_match = combined == lemma.node_hash; - Ok(hashes_match && self.validate_lemma(sub)?) - } - }, - } +fn _validate_lemma(lemma: &Lemma) -> Result { + match lemma.sub_lemma { + None => Ok(lemma.sibling_hash.is_none()), + + Some(ref sub) => match lemma.sibling_hash { + None => Ok(false), + + Some(Positioned::Left(ref hash)) => { + let combined = Hash::hash_nodes(hash, &sub.node_hash)?; + let hashes_match = combined == lemma.node_hash; + Ok(hashes_match && _validate_lemma(sub)?) + } + + Some(Positioned::Right(ref hash)) => { + let combined = Hash::hash_nodes(&sub.node_hash, hash)?; + let hashes_match = combined == lemma.node_hash; + Ok(hashes_match && _validate_lemma(sub)?) + } + }, } } diff --git a/indy-utils/src/qualifiable.rs b/indy-data-types/src/qualifiable.rs similarity index 90% rename from indy-utils/src/qualifiable.rs rename to indy-data-types/src/qualifiable.rs index 195f3b6..b8b3536 100644 --- a/indy-utils/src/qualifiable.rs +++ b/indy-data-types/src/qualifiable.rs @@ -2,7 +2,7 @@ use once_cell::sync::Lazy; use regex::Regex; -use super::{invalid, Validatable, ValidationError}; +use crate::{invalid, Validatable, ValidationError}; pub(crate) static REGEX: Lazy = Lazy::new(|| Regex::new("^([a-z0-9]+):([a-z0-9]+):(.*)$").unwrap()); @@ -17,7 +17,7 @@ pub fn combine(prefix: &str, method: Option<&str>, entity: &str) -> String { /// Split a qualifiable identifier into its method and value components pub fn split<'a>(prefix: &str, val: &'a str) -> (Option<&'a str>, &'a str) { - match REGEX.captures(&val) { + match REGEX.captures(val) { None => (None, val), Some(caps) => { if caps.get(1).map(|m| m.as_str()) == Some(prefix) { @@ -45,11 +45,11 @@ pub trait Qualifiable: From + std::ops::Deref + Validatabl Self::from(combine(Self::prefix(), method, entity)) } - fn split<'a>(&'a self) -> (Option<&'a str>, &'a str) { + fn split(&self) -> (Option<&str>, &str) { split(Self::prefix(), self.deref()) } - fn get_method<'a>(&'a self) -> Option<&'a str> { + fn get_method(&self) -> Option<&str> { let (method, _rest) = self.split(); method } @@ -105,14 +105,12 @@ pub trait Qualifiable: From + std::ops::Deref + Validatabl } /// Derive a new `Qualifiable` string type -#[macro_export] macro_rules! qualifiable_type { ($newtype:ident, $doc:expr) => { - $crate::serde_derive_impl! { - #[doc=$doc] - #[derive(Debug, Clone, PartialEq, Eq, Hash)] - pub struct $newtype(pub String); - } + #[doc=$doc] + #[derive(Debug, Clone, PartialEq, Eq, Hash)] + #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] + pub struct $newtype(pub String); impl From for $newtype { fn from(val: String) -> Self { @@ -137,3 +135,5 @@ macro_rules! qualifiable_type { qualifiable_type!($newtype, ""); }; } + +pub(crate) use qualifiable_type; diff --git a/indy-utils/src/base58.rs b/indy-data-types/src/utils/base58.rs similarity index 89% rename from indy-utils/src/base58.rs rename to indy-data-types/src/utils/base58.rs index 59b5570..ebbc3b2 100644 --- a/indy-utils/src/base58.rs +++ b/indy-data-types/src/utils/base58.rs @@ -1,6 +1,6 @@ use bs58; -use super::error::ConversionError; +use crate::error::ConversionError; pub fn decode>(val: T) -> Result, ConversionError> { Ok(bs58::decode(val) diff --git a/indy-data-types/src/utils/mod.rs b/indy-data-types/src/utils/mod.rs new file mode 100644 index 0000000..4f32be0 --- /dev/null +++ b/indy-data-types/src/utils/mod.rs @@ -0,0 +1 @@ +pub mod base58; diff --git a/indy-utils/src/validation.rs b/indy-data-types/src/validation.rs similarity index 100% rename from indy-utils/src/validation.rs rename to indy-data-types/src/validation.rs diff --git a/indy-test-utils/Cargo.toml b/indy-test-utils/Cargo.toml deleted file mode 100644 index 3db11af..0000000 --- a/indy-test-utils/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "indy-test-utils" -version = "0.1.0" -authors = ["Hyperledger Indy Contributors "] -description = "Utilities for testing Hyperledger Indy (https://www.hyperledger.org/projects), which provides a distributed-ledger-based foundation for self-sovereign identity (https://sovrin.org)." -edition = "2018" -license = "Apache-2.0" -readme = "../README.md" -repository = "https://github.com/hyperledger/indy-shared-rs/" -categories = ["authentication", "cryptography"] -keywords = ["hyperledger", "indy", "ssi", "verifiable", "credentials"] - -[lib] -name = "indy_test_utils" -path = "src/lib.rs" -crate-type = ["rlib"] - -[features] -default = [] - -[dependencies] -tempfile = "3.1" diff --git a/indy-test-utils/src/environment.rs b/indy-test-utils/src/environment.rs deleted file mode 100644 index 283f692..0000000 --- a/indy-test-utils/src/environment.rs +++ /dev/null @@ -1,48 +0,0 @@ -use std::env; -use std::path::PathBuf; - -pub fn tmp_path() -> PathBuf { - let mut path = env::temp_dir(); - path.push("indy_ledger_client"); - path -} - -pub fn tmp_file_path(file_name: &str) -> PathBuf { - let mut path = tmp_path(); - path.push(file_name); - path -} - -pub fn test_pool_ip() -> String { - env::var("TEST_POOL_IP").unwrap_or("127.0.0.1".to_string()) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn tmp_path_works() { - let path = tmp_path(); - - assert!(path.is_absolute()); - assert!(path.has_root()); - assert!(path.to_string_lossy().contains("indy_ledger_client")); - } - - #[test] - fn tmp_file_path_works() { - let path = tmp_file_path("test.txt"); - - assert!(path.is_absolute()); - assert!(path.has_root()); - assert!(path.to_string_lossy().contains("indy_ledger_client")); - assert!(path.to_string_lossy().contains("test.txt")); - } - - #[test] - fn test_pool_ip_works() { - let pool_ip = test_pool_ip(); - assert!(!pool_ip.is_empty()); - } -} diff --git a/indy-test-utils/src/genesis.rs b/indy-test-utils/src/genesis.rs deleted file mode 100644 index 7ba2b05..0000000 --- a/indy-test-utils/src/genesis.rs +++ /dev/null @@ -1,64 +0,0 @@ -use super::environment; - -use std::io::Write; -use std::path::PathBuf; -use tempfile::NamedTempFile; - -pub struct GenesisTransactions { - pub transactions: Vec, - pub file: Option, -} - -impl GenesisTransactions { - pub fn default_transactions() -> Vec { - let test_pool_ip = environment::test_pool_ip(); - - vec![ - format!( - r#"{{"reqSignature":{{}},"txn":{{"data":{{"data":{{"alias":"Node1","blskey":"4N8aUNHSgjQVgkpm8nhNEfDf6txHznoYREg9kirmJrkivgL4oSEimFF6nsQ6M41QvhM2Z33nves5vfSn9n1UwNFJBYtWVnHYMATn76vLuL3zU88KyeAYcHfsih3He6UHcXDxcaecHVz6jhCYz1P2UZn2bDVruL5wXpehgBfBaLKm3Ba","blskey_pop":"RahHYiCvoNCtPTrVtP7nMC5eTYrsUA8WjXbdhNc8debh1agE9bGiJxWBXYNFbnJXoXhWFMvyqhqhRoq737YQemH5ik9oL7R4NTTCz2LEZhkgLJzB3QRQqJyBNyv7acbdHrAT8nQ9UkLbaVL9NBpnWXBTw4LEMePaSHEw66RzPNdAX1","client_ip":"{}","client_port":9702,"node_ip":"{}","node_port":9701,"services":["VALIDATOR"]}},"dest":"Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv"}},"metadata":{{"from":"Th7MpTaRZVRYnPiabds81Y"}},"type":"0"}},"txnMetadata":{{"seqNo":1,"txnId":"fea82e10e894419fe2bea7d96296a6d46f50f93f9eeda954ec461b2ed2950b62"}},"ver":"1"}}"#, - test_pool_ip, test_pool_ip - ), - format!( - r#"{{"reqSignature":{{}},"txn":{{"data":{{"data":{{"alias":"Node2","blskey":"37rAPpXVoxzKhz7d9gkUe52XuXryuLXoM6P6LbWDB7LSbG62Lsb33sfG7zqS8TK1MXwuCHj1FKNzVpsnafmqLG1vXN88rt38mNFs9TENzm4QHdBzsvCuoBnPH7rpYYDo9DZNJePaDvRvqJKByCabubJz3XXKbEeshzpz4Ma5QYpJqjk","blskey_pop":"Qr658mWZ2YC8JXGXwMDQTzuZCWF7NK9EwxphGmcBvCh6ybUuLxbG65nsX4JvD4SPNtkJ2w9ug1yLTj6fgmuDg41TgECXjLCij3RMsV8CwewBVgVN67wsA45DFWvqvLtu4rjNnE9JbdFTc1Z4WCPA3Xan44K1HoHAq9EVeaRYs8zoF5","client_ip":"{}","client_port":9704,"node_ip":"{}","node_port":9703,"services":["VALIDATOR"]}},"dest":"8ECVSk179mjsjKRLWiQtssMLgp6EPhWXtaYyStWPSGAb"}},"metadata":{{"from":"EbP4aYNeTHL6q385GuVpRV"}},"type":"0"}},"txnMetadata":{{"seqNo":2,"txnId":"1ac8aece2a18ced660fef8694b61aac3af08ba875ce3026a160acbc3a3af35fc"}},"ver":"1"}}"#, - test_pool_ip, test_pool_ip - ), - format!( - r#"{{"reqSignature":{{}},"txn":{{"data":{{"data":{{"alias":"Node3","blskey":"3WFpdbg7C5cnLYZwFZevJqhubkFALBfCBBok15GdrKMUhUjGsk3jV6QKj6MZgEubF7oqCafxNdkm7eswgA4sdKTRc82tLGzZBd6vNqU8dupzup6uYUf32KTHTPQbuUM8Yk4QFXjEf2Usu2TJcNkdgpyeUSX42u5LqdDDpNSWUK5deC5","blskey_pop":"QwDeb2CkNSx6r8QC8vGQK3GRv7Yndn84TGNijX8YXHPiagXajyfTjoR87rXUu4G4QLk2cF8NNyqWiYMus1623dELWwx57rLCFqGh7N4ZRbGDRP4fnVcaKg1BcUxQ866Ven4gw8y4N56S5HzxXNBZtLYmhGHvDtk6PFkFwCvxYrNYjh","client_ip":"{}","client_port":9706,"node_ip":"{}","node_port":9705,"services":["VALIDATOR"]}},"dest":"DKVxG2fXXTU8yT5N7hGEbXB3dfdAnYv1JczDUHpmDxya"}},"metadata":{{"from":"4cU41vWW82ArfxJxHkzXPG"}},"type":"0"}},"txnMetadata":{{"seqNo":3,"txnId":"7e9f355dffa78ed24668f0e0e369fd8c224076571c51e2ea8be5f26479edebe4"}},"ver":"1"}}"#, - test_pool_ip, test_pool_ip - ), - format!( - r#"{{"reqSignature":{{}},"txn":{{"data":{{"data":{{"alias":"Node4","blskey":"2zN3bHM1m4rLz54MJHYSwvqzPchYp8jkHswveCLAEJVcX6Mm1wHQD1SkPYMzUDTZvWvhuE6VNAkK3KxVeEmsanSmvjVkReDeBEMxeDaayjcZjFGPydyey1qxBHmTvAnBKoPydvuTAqx5f7YNNRAdeLmUi99gERUU7TD8KfAa6MpQ9bw","blskey_pop":"RPLagxaR5xdimFzwmzYnz4ZhWtYQEj8iR5ZU53T2gitPCyCHQneUn2Huc4oeLd2B2HzkGnjAff4hWTJT6C7qHYB1Mv2wU5iHHGFWkhnTX9WsEAbunJCV2qcaXScKj4tTfvdDKfLiVuU2av6hbsMztirRze7LvYBkRHV3tGwyCptsrP","client_ip":"{}","client_port":9708,"node_ip":"{}","node_port":9707,"services":["VALIDATOR"]}},"dest":"4PS3EDQ3dW1tci1Bp6543CfuuebjFrg36kLAUcskGfaA"}},"metadata":{{"from":"TWwCRQRZ2ZHMJFn9TzLp7W"}},"type":"0"}},"txnMetadata":{{"seqNo":4,"txnId":"aa5e817d7cc626170eca175822029339a444eb0ee8f0bd20d3b0b76e566fb008"}},"ver":"1"}}"#, - test_pool_ip, test_pool_ip - ), - ] - } - - pub fn new(count: Option) -> GenesisTransactions { - let count = count.unwrap_or(4); - let transactions = Self::default_transactions()[0..count].to_vec(); - GenesisTransactions { - transactions, - file: None, - } - } - - pub fn from_transactions(transactions: T) -> GenesisTransactions - where - T: IntoIterator, - T::Item: ToString, - { - GenesisTransactions { - transactions: transactions.into_iter().map(|v| v.to_string()).collect(), - file: None, - } - } - - pub fn store_to_file(&mut self) -> PathBuf { - let data = self.transactions.join("\n"); - let mut file = NamedTempFile::new().unwrap(); - let path = file.path().to_owned(); - file.as_file_mut().write_all(data.as_bytes()).unwrap(); - self.file = Some(file); - path - } -} diff --git a/indy-test-utils/src/lib.rs b/indy-test-utils/src/lib.rs deleted file mode 100644 index 7ccbf57..0000000 --- a/indy-test-utils/src/lib.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod environment; -pub mod genesis; diff --git a/indy-utils/Cargo.toml b/indy-utils/Cargo.toml deleted file mode 100644 index 2a1e33d..0000000 --- a/indy-utils/Cargo.toml +++ /dev/null @@ -1,45 +0,0 @@ -[package] -name = "indy-utils" -version = "0.6.0" -authors = ["Hyperledger Indy Contributors "] -description = "Utilities for Hyperledger Indy (https://www.hyperledger.org/projects), which provides a distributed-ledger-based foundation for self-sovereign identity (https://sovrin.org)." -edition = "2018" -license = "Apache-2.0" -readme = "../README.md" -repository = "https://github.com/hyperledger/indy-shared-rs/" -categories = ["authentication", "cryptography"] -keywords = ["hyperledger", "indy", "ssi", "verifiable", "credentials"] - -[lib] -name = "indy_utils" -path = "src/lib.rs" -crate-type = ["rlib"] - -[features] -default = ["ed25519"] -ed25519 = ["curve25519-dalek", "ed25519-dalek", "rand", "sha2", "x25519-dalek"] - -[dependencies] -bs58 = "0.5" -curve25519-dalek = { version = "3.1", default-features = false, features = [ - "u64_backend", -], optional = true } -ed25519-dalek = { version = "1.0", default-features = false, features = [ - "u64_backend", -], optional = true } -once_cell = "1.9" -rand = { version = "0.8", optional = true } -regex = "1.3" -serde = { version = "1.0", optional = true, features = ["derive"] } -serde_json = { version = "1.0", optional = true } -sha2 = { version = "0.10", optional = true } -thiserror = "1.0" -x25519-dalek = { version = "1.1", default-features = false, features = [ - "u64_backend", -], optional = true } -zeroize = { version = "1.3" } - -[dev-dependencies] -async-global-executor = "2.3" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" diff --git a/indy-utils/src/lib.rs b/indy-utils/src/lib.rs deleted file mode 100644 index aed6b2b..0000000 --- a/indy-utils/src/lib.rs +++ /dev/null @@ -1,29 +0,0 @@ -#[cfg(any(feature = "serde", test))] -#[macro_use] -pub extern crate serde; - -/// Common macros -#[macro_use] -mod macros; - -mod error; -pub use error::{ConversionError, EncryptionError, UnexpectedError, ValidationError}; - -/// Trait for qualifiable identifier types, having an optional prefix and method -#[macro_use] -pub mod qualifiable; -pub use qualifiable::Qualifiable; - -/// Trait definition for validatable data types -#[macro_use] -mod validation; -pub use validation::Validatable; - -/// base58 encoding and decoding -pub mod base58; - -/// Indy DID representation and derivation -pub mod did; - -/// Indy signing keys and verification keys -pub mod keys; diff --git a/indy-utils/src/macros.rs b/indy-utils/src/macros.rs deleted file mode 100644 index 7c06770..0000000 --- a/indy-utils/src/macros.rs +++ /dev/null @@ -1,88 +0,0 @@ -macro_rules! unwrap_opt_or_return { - ($opt:expr, $err:expr) => { - match $opt { - Some(val) => val, - None => return $err, - } - }; -} - -/// Used to optionally add Serialize and Deserialize traits to Qualifiable types -#[cfg(feature = "serde")] -#[macro_export] -macro_rules! serde_derive_impl { - ($def:item) => { - #[derive(Serialize, Deserialize)] - $def - }; -} - -#[cfg(not(feature = "serde"))] -#[macro_export] -macro_rules! serde_derive_impl { - ($def:item) => { - $def - }; -} - -/// Derive a new handle type having an atomically increasing sequence number -#[macro_export] -macro_rules! new_handle_type (($newtype:ident, $counter:ident) => ( - static $counter: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0); - - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] - #[repr(transparent)] - pub struct $newtype(pub usize); - - impl $newtype { - #[allow(dead_code)] - pub fn invalid() -> $newtype { - $newtype(0) - } - - #[allow(dead_code)] - pub fn next() -> $newtype { - $newtype($counter.fetch_add(1, std::sync::atomic::Ordering::SeqCst) + 1) - } - } - - impl std::fmt::Display for $newtype { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}({})", stringify!($newtype), self.0) - } - } - - impl std::ops::Deref for $newtype { - type Target = usize; - fn deref(&self) -> &usize { - &self.0 - } - } - - impl PartialEq for $newtype { - fn eq(&self, other: &usize) -> bool { - self.0 == *other - } - } - - impl $crate::Validatable for $newtype { - fn validate(&self) -> std::result::Result<(), $crate::ValidationError> { - if(**self == 0) { - Err("Invalid handle: zero".into()) - } else { - Ok(()) - } - } - } -)); - -#[cfg(test)] -mod tests { - new_handle_type!(TestHandle, TEST_HANDLE_CTR); - - #[test] - fn test_handle_seq() { - assert_eq!(TestHandle::next(), 1); - assert_eq!(TestHandle::next(), 2); - } -}