From e10e6d74b11face219d2e935417926e7cb361bf2 Mon Sep 17 00:00:00 2001 From: blu3beri Date: Wed, 17 May 2023 21:55:47 +0200 Subject: [PATCH] chore: use crypto-bigint instead of ursa Signed-off-by: blu3beri --- Cargo.toml | 6 +- src/data_types/cred_request.rs | 2 +- src/data_types/link_secret.rs | 102 ++++++++++++--------------------- src/ffi/cred_req.rs | 11 ++-- src/ffi/credential.rs | 11 ++-- src/ffi/link_secret.rs | 5 +- src/ffi/presentation.rs | 11 ++-- src/services/prover.rs | 17 +++--- tests/utils/storage.rs | 2 +- 9 files changed, 75 insertions(+), 92 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ac1cd38d..5e93b3a7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ vendored = ["openssl", "openssl/vendored"] [dependencies] bs58 = "0.4.0" +crypto-bigint = { version = "0.5.2", features = ["zeroize", "serde", "alloc"] } env_logger = { version = "0.9.3", optional = true } ffi-support = { version = "0.4.0", optional = true } log = "0.4.17" @@ -32,7 +33,7 @@ rand = "0.8.5" regex = "1.7.1" serde = { version = "1.0.155", features = ["derive"] } bitvec = { version = "1.0.1", features = ["serde"] } -serde_json = { version = "1.0.94", features = ["raw_value"]} +serde_json = { version = "1.0.94", features = ["raw_value", "arbitrary_precision"]} sha2 = "0.10.6" tempfile = "3.4.0" thiserror = "1.0.39" @@ -44,6 +45,9 @@ zeroize = { version = "1.5.7", optional = true, features = ["zeroize_derive"] } # the new exposed "vendored" feature openssl = { version = "0.10.45", optional = true } +# This needs to be added because the 'alloc' feature from 'crypto-bigint' does not enable the 'serdect/alloc' which is needed to transform +serdect = { version = "0.2.0", features = ["alloc", "zeroize"] } + [profile.release] lto = true codegen-units = 1 diff --git a/src/data_types/cred_request.rs b/src/data_types/cred_request.rs index ccf42921..ac11f911 100644 --- a/src/data_types/cred_request.rs +++ b/src/data_types/cred_request.rs @@ -137,7 +137,7 @@ mod cred_req_tests { } fn link_secret() -> LinkSecret { - LinkSecret::new().unwrap() + LinkSecret::new() } fn credential_offer( diff --git a/src/data_types/link_secret.rs b/src/data_types/link_secret.rs index eded7db4..bd10e626 100644 --- a/src/data_types/link_secret.rs +++ b/src/data_types/link_secret.rs @@ -1,28 +1,18 @@ use crate::error::ConversionError; +use crypto_bigint::{self, rand_core::OsRng, Encoding, Random, U256}; +use serde::Serialize; +use zeroize::Zeroize; use std::fmt; -use ursa::{ - bn::BigNumber, - cl::{prover::Prover as UrsaProver, MasterSecret}, -}; -pub struct LinkSecret(pub ursa::bn::BigNumber); +use ursa::cl::MasterSecret; -impl LinkSecret { - pub fn new() -> Result { - let value = UrsaProver::new_master_secret() - .and_then(|v| v.value()) - .map_err(|err| { - ConversionError::from_msg(format!("Error creating link secret: {err}")) - })?; - - Ok(Self(value)) - } - - pub fn try_clone(&self) -> Result { - let cloned = self.0.try_clone().map_err(|err| { - ConversionError::from_msg(format!("Error cloning link secret: {err}")) - })?; +// TODO: This should serialize to decimal and not lower le hex +#[derive(Zeroize, Clone, Copy, Serialize)] +pub struct LinkSecret(pub U256); - Ok(Self(cloned)) +impl LinkSecret { + pub fn new() -> Self { + let bn = U256::random(&mut OsRng); + Self(bn) } } @@ -46,36 +36,28 @@ impl TryInto for LinkSecret { } } -impl TryInto for &LinkSecret { +impl TryInto for LinkSecret { type Error = ConversionError; - fn try_into(self) -> Result { - let j = serde_json::json!({ - "ms": self.0 - }); - - serde_json::from_value(j) - .map_err(|err| ConversionError::from_msg(format!("Error creating link secret: {err}"))) + fn try_into(self) -> Result { + let b = self.0.to_be_bytes(); + ursa::bn::BigNumber::from_bytes(&b).map_err(|err| { + ConversionError::from_msg(format!( + "Error transforming link secret into bignumber: {err}" + )) + }) } } -impl TryInto for LinkSecret { - type Error = ConversionError; - - fn try_into(self) -> Result { - self.0 - .to_dec() - .map_err(|err| ConversionError::from_msg(format!("Error creating link secret: {err}"))) +impl Into for LinkSecret { + fn into(self) -> String { + self.0.to_string() } } -impl TryFrom<&str> for LinkSecret { - type Error = ConversionError; - - fn try_from(value: &str) -> Result { - Ok(Self(BigNumber::from_dec(value).map_err(|err| { - ConversionError::from_msg(format!("Error creating link secret: {err}")) - })?)) +impl From<&str> for LinkSecret { + fn from(value: &str) -> Self { + Self(U256::from_be_hex(value)) } } @@ -85,13 +67,19 @@ mod link_secret_tests { #[test] fn should_create_new_link_secret() { + let _ = LinkSecret::new(); + } + + #[test] + fn should_convert_between_link_secret_and_ursa_bignumber() { let link_secret = LinkSecret::new(); - assert!(link_secret.is_ok()); + let bn: ursa::bn::BigNumber = link_secret.try_into().expect("Unable to convert between link secret and ursa bn"); + let s = serde_json::to_string(&link_secret).unwrap(); } #[test] fn should_convert_between_string_and_link_secret_roundtrip() { - let ls = "123"; + let ls = "663D8C61E2F5DE3B00FDFB3F43C593B4BA8BAD2CF7178E65D89BFE1A817FB177"; let link_secret = LinkSecret::try_from(ls).expect("Error creating link secret"); let link_secret_str: String = link_secret.try_into().expect("Error creating link secret"); assert_eq!(link_secret_str, ls); @@ -99,28 +87,10 @@ mod link_secret_tests { #[test] fn should_convert_between_master_secret() { - let link_secret = LinkSecret::new().expect("Unable to create link secret"); + let link_secret = LinkSecret::new(); + println!("{link_secret:?}"); let master_secret: MasterSecret = link_secret - .try_clone() - .expect("Error cloning link secret") .try_into() - .expect("error converting to master secret"); - - assert_eq!( - link_secret.0, - master_secret - .value() - .expect("Error getting value from master secret") - ); - } - - #[test] - fn should_clone_link_secret() { - let link_secret = LinkSecret::new().expect("Unable to create link secret"); - let cloned_link_secret = link_secret - .try_clone() - .expect("Unable to clone link secret"); - - assert_eq!(link_secret.0, cloned_link_secret.0); + .expect("Unable to tranform link secret into master secret"); } } diff --git a/src/ffi/cred_req.rs b/src/ffi/cred_req.rs index 3e5625f5..128eb0fc 100644 --- a/src/ffi/cred_req.rs +++ b/src/ffi/cred_req.rs @@ -24,10 +24,13 @@ pub extern "C" fn anoncreds_create_credential_request( check_useful_c_ptr!(cred_req_p); check_useful_c_ptr!(cred_req_meta_p); - let link_secret = link_secret - .as_opt_str() - .ok_or_else(|| err_msg!("Missing link secret"))?; - let link_secret = LinkSecret::try_from(link_secret)?; + let link_secret = { + let ls = link_secret + .as_opt_str() + .ok_or_else(|| err_msg!("Missing link secret"))?; + + LinkSecret::from(ls) + }; let link_secret_id = link_secret_id .as_opt_str() diff --git a/src/ffi/credential.rs b/src/ffi/credential.rs index eb10d1d3..73eb1e35 100644 --- a/src/ffi/credential.rs +++ b/src/ffi/credential.rs @@ -179,10 +179,13 @@ pub extern "C" fn anoncreds_process_credential( catch_error(|| { check_useful_c_ptr!(cred_p); - let link_secret = link_secret - .as_opt_str() - .ok_or_else(|| err_msg!("Missing link secret"))?; - let link_secret = LinkSecret::try_from(link_secret)?; + let link_secret = { + let ls = link_secret + .as_opt_str() + .ok_or_else(|| err_msg!("Missing link secret"))?; + + LinkSecret::from(ls) + }; let mut cred = cred .load()? diff --git a/src/ffi/link_secret.rs b/src/ffi/link_secret.rs index d99cb310..5852c4ae 100644 --- a/src/ffi/link_secret.rs +++ b/src/ffi/link_secret.rs @@ -7,9 +7,8 @@ use std::os::raw::c_char; pub extern "C" fn anoncreds_create_link_secret(link_secret_p: *mut *const c_char) -> ErrorCode { catch_error(|| { check_useful_c_ptr!(link_secret_p); - let secret = create_link_secret()?; - let dec_secret: String = secret.try_into()?; - unsafe { *link_secret_p = rust_string_to_c(dec_secret) }; + let secret = create_link_secret(); + unsafe { *link_secret_p = rust_string_to_c(secret) }; Ok(()) }) } diff --git a/src/ffi/presentation.rs b/src/ffi/presentation.rs index 7c980300..d4af11bb 100644 --- a/src/ffi/presentation.rs +++ b/src/ffi/presentation.rs @@ -75,10 +75,13 @@ pub extern "C" fn anoncreds_create_presentation( catch_error(|| { check_useful_c_ptr!(presentation_p); - let link_secret = link_secret - .as_opt_str() - .ok_or_else(|| err_msg!("Missing link secret"))?; - let link_secret = LinkSecret::try_from(link_secret)?; + let link_secret = { + let ls = link_secret + .as_opt_str() + .ok_or_else(|| err_msg!("Missing link secret"))?; + + LinkSecret::from(ls) + }; if self_attest_names.len() != self_attest_values.len() { return Err(err_msg!( diff --git a/src/services/prover.rs b/src/services/prover.rs index 7c01057a..c7354fd1 100644 --- a/src/services/prover.rs +++ b/src/services/prover.rs @@ -42,12 +42,11 @@ use std::ops::BitXor; /// ```rust /// use anoncreds::prover; /// -/// let link_secret = prover::create_link_secret() -/// .expect("Unable to create link secret"); +/// let link_secret = prover::create_link_secret(); /// /// ``` -pub fn create_link_secret() -> Result { - LinkSecret::new().map_err(err_map!(Unexpected)) +pub fn create_link_secret() -> LinkSecret { + LinkSecret::new() } /// Create an Anoncreds credential request according to the [Anoncreds v1.0 specification - @@ -122,7 +121,9 @@ pub fn create_credential_request( )?; let mut credential_values_builder = CryptoIssuer::new_credential_values_builder()?; - credential_values_builder.add_value_hidden("master_secret", &link_secret.0)?; + + let bn: ursa::bn::BigNumber = (*link_secret).try_into().unwrap(); + credential_values_builder.add_value_hidden("master_secret", &bn)?; let cred_values = credential_values_builder.finalize()?; let nonce = new_nonce()?; @@ -243,7 +244,7 @@ pub fn process_credential( cred_def.value.revocation.as_ref(), )?; let credential_values = - build_credential_values(&credential.values.0, Some(&link_secret.try_into()?))?; + build_credential_values(&credential.values.0, Some(&(*link_secret).try_into()?))?; let rev_pub_key = rev_reg_def.map(|d| &d.value.public_keys.accum_key); CryptoProver::process_credential_signature( @@ -438,7 +439,7 @@ pub fn create_presentation( let credential_schema = build_credential_schema(&schema.attr_names.0)?; let credential_values = - build_credential_values(&credential.values.0, Some(&link_secret.try_into()?))?; + build_credential_values(&credential.values.0, Some(&(*link_secret).try_into()?))?; let (req_attrs, req_predicates) = prepare_credential_for_proving( present.requested_attributes, present.requested_predicates, @@ -1131,7 +1132,7 @@ mod tests { const LEGACY_CRED_DEF_IDENTIFIER: &str = "DXoTtQJNtXtiwWaZAK3rB1:3:CL:98153:default"; fn _link_secret() -> LinkSecret { - LinkSecret::new().expect("Error creating prover link secret") + LinkSecret::new() } fn _schema() -> Schema { diff --git a/tests/utils/storage.rs b/tests/utils/storage.rs index adbffab5..3c102762 100644 --- a/tests/utils/storage.rs +++ b/tests/utils/storage.rs @@ -64,7 +64,7 @@ pub struct ProverWallet<'a> { impl<'a> Default for ProverWallet<'a> { fn default() -> Self { - let link_secret = LinkSecret::new().expect("Error creating prover link secret"); + let link_secret = LinkSecret::new(); Self { credentials: vec![], rev_states: HashMap::new(),