diff --git a/Cargo.toml b/Cargo.toml index e5a631a..5ddbbdf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ env_logger = "0.4.2" libc = "0.2.21" log = "0.3.7" openssl = { version = "0.9.11", optional = true } -milagro-crypto = { version = "0.1.7", optional = true } +milagro-crypto = { version = "0.1.11", optional = true } rand = "0.3" rusqlite = "0.10.1" rust-base58 = {version = "0.0.4", optional = true} diff --git a/src/commands/anoncreds/issuer.rs b/src/commands/anoncreds/issuer.rs index 08e946a..ccfdc31 100644 --- a/src/commands/anoncreds/issuer.rs +++ b/src/commands/anoncreds/issuer.rs @@ -269,8 +269,9 @@ impl IssuerCommandExecutor { self.anoncreds_service.issuer.revoke( &revocation_registry, - &revocation_registry_private.tails, - user_revoc_index)?; + &revocation_registry_private.tails_dash, + user_revoc_index + )?; let revoc_reg_update_json = RevocationRegistry::to_json(&revocation_registry.borrow()) .map_err(|err| CommonError::InvalidState(format!("Invalid revocation registry: {}", err.to_string())))?; diff --git a/src/commands/anoncreds/prover.rs b/src/commands/anoncreds/prover.rs index a5abb0e..9284cdb 100644 --- a/src/commands/anoncreds/prover.rs +++ b/src/commands/anoncreds/prover.rs @@ -29,7 +29,7 @@ use services::anoncreds::types::{ ClaimRequestJson }; use std::collections::HashMap; -use utils::crypto::pair::PointG1; +use utils::crypto::pair::PointG2; use std::cell::RefCell; pub enum ProverCommand { @@ -448,7 +448,7 @@ impl ProverCommandExecutor { let ms: BigNumber = BigNumber::from_dec(&ms)?; - let mut tails: HashMap = HashMap::new(); + let mut tails: HashMap = HashMap::new(); if revoc_regs.len() > 0 { let tails_json = self.wallet_service.get(wallet_handle, &format!("tails"))?; tails = serde_json::from_str(&tails_json) diff --git a/src/services/anoncreds/issuer.rs b/src/services/anoncreds/issuer.rs index bbfce9e..881b496 100644 --- a/src/services/anoncreds/issuer.rs +++ b/src/services/anoncreds/issuer.rs @@ -37,7 +37,7 @@ use services::anoncreds::helpers::{ transform_u32_to_array_of_u8 }; use utils::crypto::bn::BigNumber; -use utils::crypto::pair::{GroupOrderElement, PointG1, Pair}; +use utils::crypto::pair::{GroupOrderElement, PointG1, PointG2, Pair}; use std::collections::{HashMap, HashSet}; use std::cell::RefCell; @@ -115,17 +115,22 @@ impl Issuer { let h0 = PointG1::new()?; let h1 = PointG1::new()?; let h2 = PointG1::new()?; - let g = PointG1::new()?; let htilde = PointG1::new()?; - let u = PointG1::new()?; + let g = PointG1::new()?; + + let u = PointG2::new()?; + let hcap = PointG2::new()?; + let x = GroupOrderElement::new()?; let sk = GroupOrderElement::new()?; + let gdash = PointG2::new()?; + let pk = g.mul(&sk)?; - let y = h.mul(&x)?; + let y = hcap.mul(&x)?; info!(target: "anoncreds_service", "Issuer generate revocation keys -> done"); Ok(( - Some(RevocationPublicKey::new(g, h, h0, h1, h2, htilde, u, pk, y, x)), + Some(RevocationPublicKey::new(g, gdash, h, h0, h1, h2, htilde, hcap, u, pk, y, x)), Some(RevocationSecretKey::new(x, sk)) )) } @@ -151,6 +156,8 @@ impl Issuer { info!(target: "anoncreds_service", "Issuer create accumulator for claim_def_seq_no {} -> start", claim_def_seq_no); let gamma = GroupOrderElement::new()?; let mut g: HashMap = HashMap::new(); + let mut g_dash: HashMap = HashMap::new(); + let g_count = 2 * max_claim_num; for i in 0..g_count { @@ -159,14 +166,15 @@ impl Issuer { let mut pow = GroupOrderElement::from_bytes(&i_bytes)?; pow = gamma.pow_mod(&pow)?; g.insert(i, pk_r.g.mul(&pow)?); + g_dash.insert(i, pk_r.g_dash.mul(&pow)?); } } - let mut z = Pair::pair(&pk_r.g, &pk_r.g)?; + let mut z = Pair::pair(&pk_r.g, &pk_r.g_dash)?; let mut pow = GroupOrderElement::from_bytes(&transform_u32_to_array_of_u8((max_claim_num + 1) as u32))?; pow = gamma.pow_mod(&pow)?; z = z.pow(&pow)?; - let acc = PointG1::new_inf()?; + let acc = PointG2::new_inf()?; let v: HashSet = HashSet::new(); let acc = Accumulator::new(acc, v, max_claim_num, 1); @@ -174,7 +182,7 @@ impl Issuer { let acc_sk = AccumulatorSecretKey::new(gamma); let revocation_registry = RevocationRegistry::new(acc, acc_pk, claim_def_seq_no); - let revocation_registry_private = RevocationRegistryPrivate::new(acc_sk, g); + let revocation_registry_private = RevocationRegistryPrivate::new(acc_sk, g, g_dash); info!(target: "anoncreds_service", "Issuer create accumulator for claim_def_seq_no {} -> done", claim_def_seq_no); Ok((revocation_registry, revocation_registry_private)) @@ -210,6 +218,7 @@ impl Issuer { &pk_r, &sk_r, &revoc_reg_priv.tails, + &revoc_reg_priv.tails_dash, &revoc_reg_priv.acc_sk, &context_attribute, &ur, @@ -305,7 +314,8 @@ impl Issuer { fn _issue_non_revocation_claim(revocation_registry: &RefCell, pk_r: &RevocationPublicKey, sk_r: &RevocationSecretKey, g: &HashMap, - sk_accum: &AccumulatorSecretKey, context_attribute: &BigNumber, + g_dash: &HashMap, sk_accum: &AccumulatorSecretKey, + context_attribute: &BigNumber, ur: &PointG1, seq_number: Option) -> Result<(NonRevocationClaim, i64), CryptoError> { info!(target: "anoncreds_service", "Issuer issue non-revocation claim -> start"); @@ -336,15 +346,15 @@ impl Issuer { .add(&pk_r.h2.mul(&vr_prime_prime)?)? .mul(&sk_r.x.add_mod(&c)?.inverse()?)?; - let mut omega = PointG1::new_inf()?; + let mut omega = PointG2::new_inf()?; for j in &accumulator.v { let index = accumulator.max_claim_num + 1 - j + i; - omega = omega.add(g.get(&index) + omega = omega.add(g_dash.get(&index) .ok_or(CryptoError::InvalidStructure(format!("Value by key '{}' not found in g", index)))?)?; } - let sigma_i = pk_r.g + let sigma_i = pk_r.g_dash .mul(&sk_r.sk .add_mod(&sk_accum.gamma .pow_mod(&GroupOrderElement::from_bytes(&transform_u32_to_array_of_u8(i as u32))?)?)? @@ -354,7 +364,7 @@ impl Issuer { .pow_mod(&GroupOrderElement::from_bytes(&transform_u32_to_array_of_u8(i as u32))?)?)?; let index = accumulator.max_claim_num + 1 - i; - accumulator.acc = accumulator.acc.add(g.get(&index) + accumulator.acc = accumulator.acc.add(g_dash.get(&index) .ok_or(CryptoError::InvalidStructure(format!("Value by key '{}' not found in g", index)))?)?; accumulator.v.insert(i); @@ -392,13 +402,13 @@ impl Issuer { } pub fn revoke(&self, revocation_registry: &RefCell, - g: &HashMap, i: i32) -> Result { + g_dash: &HashMap, i: i32) -> Result { info!(target: "anoncreds_service", "Issuer revoke claim by index {} -> start", i); let ref mut accumulator = revocation_registry.borrow_mut().accumulator; accumulator.v.remove(&i); let index: i32 = accumulator.max_claim_num + 1 - i; - let element = g.get(&index) + let element = g_dash.get(&index) .ok_or(CryptoError::InvalidStructure(format!("Value by key '{}' not found in g", index)))?; accumulator.acc = accumulator.acc.sub(element)?; let timestamp = time::now_utc().to_timespec().sec; @@ -413,24 +423,24 @@ impl Issuer { let t2 = proof_c.e.mul(¶ms.c)? .add(&pk_r.h.mul(¶ms.m.mod_neg()?)?)? .add(&pk_r.htilde.mul(¶ms.t.mod_neg()?)?)?; - let t3 = Pair::pair(&proof_c.a, &pk_r.h)?.pow(¶ms.c)? - .mul(&Pair::pair(&pk_r.htilde, &pk_r.h)?.pow(¶ms.r)?)? + let t3 = Pair::pair(&proof_c.a, &pk_r.h_cap)?.pow(¶ms.c)? + .mul(&Pair::pair(&pk_r.htilde, &pk_r.h_cap)?.pow(¶ms.r)?)? .mul(&Pair::pair(&pk_r.htilde, &pk_r.y)?.pow(¶ms.rho)? - .mul(&Pair::pair(&pk_r.htilde, &pk_r.h)?.pow(¶ms.m)?)? - .mul(&Pair::pair(&pk_r.h1, &pk_r.h)?.pow(¶ms.m2)?)? - .mul(&Pair::pair(&pk_r.h2, &pk_r.h)?.pow(¶ms.s)?)?)?.inverse()?; + .mul(&Pair::pair(&pk_r.htilde, &pk_r.h_cap)?.pow(¶ms.m)?)? + .mul(&Pair::pair(&pk_r.h1, &pk_r.h_cap)?.pow(¶ms.m2)?)? + .mul(&Pair::pair(&pk_r.h2, &pk_r.h_cap)?.pow(¶ms.s)?)?)?.inverse()?; let t4 = Pair::pair(&pk_r.htilde, &accumulator.acc)? .pow(¶ms.r)? - .mul(&Pair::pair(&pk_r.g.neg()?, &pk_r.htilde)?.pow(¶ms.r_prime)?)?; + .mul(&Pair::pair(&pk_r.g.neg()?, &pk_r.h_cap)?.pow(¶ms.r_prime)?)?; let t5 = pk_r.g.mul(¶ms.r)?.add(&pk_r.htilde.mul(¶ms.o_prime)?)?; let t6 = proof_c.d.mul(¶ms.r_prime_prime)? .add(&pk_r.g.mul(¶ms.m_prime.mod_neg()?)?)? .add(&pk_r.htilde.mul(¶ms.t_prime.mod_neg()?)?)?; - let t7 = Pair::pair(&pk_r.pk.add(&proof_c.g)?, &pk_r.htilde)?.pow(¶ms.r_prime_prime)? - .mul(&Pair::pair(&pk_r.htilde, &pk_r.htilde)?.pow(¶ms.m_prime.mod_neg()?)?)? + let t7 = Pair::pair(&pk_r.pk.add(&proof_c.g)?, &pk_r.h_cap)?.pow(¶ms.r_prime_prime)? + .mul(&Pair::pair(&pk_r.htilde, &pk_r.h_cap)?.pow(¶ms.m_prime.mod_neg()?)?)? .mul(&Pair::pair(&pk_r.htilde, &proof_c.s)?.pow(¶ms.r)?)?; let t8 = Pair::pair(&pk_r.htilde, &pk_r.u)?.pow(¶ms.r)? - .mul(&Pair::pair(&pk_r.g.neg()?, &pk_r.htilde)?.pow(¶ms.r_prime_prime_prime)?)?; + .mul(&Pair::pair(&pk_r.g.neg()?, &pk_r.h_cap)?.pow(¶ms.r_prime_prime_prime)?)?; Ok(NonRevocProofTauList::new(t1, t2, t3, t4, t5, t6, t7, t8)) } @@ -439,14 +449,14 @@ impl Issuer { accum_pk: &AccumulatorPublicKey, proof_c: &NonRevocProofCList) -> Result { let t1 = proof_c.e; let t2 = PointG1::new_inf()?; - let t3 = Pair::pair(&pk_r.h0.add(&proof_c.g)?, &pk_r.h)? + let t3 = Pair::pair(&pk_r.h0.add(&proof_c.g)?, &pk_r.h_cap)? .mul(&Pair::pair(&proof_c.a, &pk_r.y)?.inverse()?)?; let t4 = Pair::pair(&proof_c.g, &accumulator.acc)? .mul(&Pair::pair(&pk_r.g, &proof_c.w)?.mul(&accum_pk.z)?.inverse()?)?; let t5 = proof_c.d; let t6 = PointG1::new_inf()?; let t7 = Pair::pair(&pk_r.pk.add(&proof_c.g)?, &proof_c.s)? - .mul(&Pair::pair(&pk_r.g, &pk_r.g)?.inverse()?)?; + .mul(&Pair::pair(&pk_r.g, &pk_r.g_dash)?.inverse()?)?; let t8 = Pair::pair(&proof_c.g, &pk_r.u)? .mul(&Pair::pair(&pk_r.g, &proof_c.u)?.inverse()?)?; diff --git a/src/services/anoncreds/prover.rs b/src/services/anoncreds/prover.rs index c1c75e5..66a924a 100644 --- a/src/services/anoncreds/prover.rs +++ b/src/services/anoncreds/prover.rs @@ -48,7 +48,6 @@ use services::anoncreds::types::{ ProofJson }; use services::anoncreds::helpers::{ - AppendByteArray, get_mtilde, four_squares, get_hash_as_int, @@ -59,7 +58,7 @@ use services::anoncreds::helpers::{ use services::anoncreds::verifier::Verifier; use services::anoncreds::issuer::Issuer; use utils::crypto::bn::BigNumber; -use utils::crypto::pair::{GroupOrderElement, PointG1, Pair}; +use utils::crypto::pair::{GroupOrderElement, PointG1, PointG2, Pair}; use std::collections::{HashMap, HashSet}; use std::cell::RefCell; use services::anoncreds::types::{AttributeInfo, ClaimInfo, RequestedClaimsJson, ProofRequestJson}; @@ -166,20 +165,20 @@ impl Prover { } let pair_gg_calc = Pair::pair(&pkr.pk.add(&claim.borrow().g_i)?, &claim.borrow().witness.sigma_i)?; - let pair_gg = Pair::pair(&pkr.g, &pkr.g)?; + let pair_gg = Pair::pair(&pkr.g, &pkr.g_dash)?; if pair_gg_calc != pair_gg { return Err(CryptoError::InvalidStructure("issuer is sending incorrect data".to_string())); } let m2 = GroupOrderElement::from_bytes(&context_attribute.to_bytes()?)?; - let pair_h1 = Pair::pair(&claim.borrow().sigma, &pkr.y.add(&pkr.h.mul(&claim.borrow().c)?)?)?; + let pair_h1 = Pair::pair(&claim.borrow().sigma, &pkr.y.add(&pkr.h_cap.mul(&claim.borrow().c)?)?)?; let pair_h2 = Pair::pair( &pkr.h0 .add(&pkr.h1.mul(&m2)?)? .add(&pkr.h2.mul(&claim.borrow().vr_prime_prime)?)? .add(&claim.borrow().g_i)?, - &pkr.h + &pkr.h_cap )?; if pair_h1 != pair_h2 { @@ -323,7 +322,7 @@ impl Prover { revoc_regs: &HashMap, requested_claims: &RequestedClaimsJson, ms: &BigNumber, - tails: &HashMap) + tails: &HashMap) -> Result { info!(target: "anoncreds_service", "Prover create proof -> start"); @@ -353,7 +352,7 @@ impl Prover { .ok_or(CryptoError::InvalidStructure("Field public_key_revocation not found".to_string()))?, tails)?; - c_list.append_vec(&proof.as_c_list()?)?; + c_list.extend_from_slice(&proof.as_c_list()?); tau_list.extend_from_slice(&proof.as_tau_list()?); m2_tilde = Some(group_element_to_bignum(&proof.tau_list_params.m2)?); non_revoc_init_proof = Some(proof); @@ -448,7 +447,7 @@ impl Prover { } fn _init_non_revocation_proof(claim: &RefCell, accum: &Accumulator, - pkr: &RevocationPublicKey, tails: &HashMap) + pkr: &RevocationPublicKey, tails: &HashMap) -> Result { info!(target: "anoncreds_service", "Prover init non-revocation proof -> start"); Prover::_update_non_revocation_claim(claim, accum, tails)?; @@ -464,7 +463,7 @@ impl Prover { } fn _update_non_revocation_claim(claim: &RefCell, - accum: &Accumulator, tails: &HashMap) + accum: &Accumulator, tails: &HashMap) -> Result<(), CryptoError> { if !accum.v.contains(&claim.borrow().i) { return Err(CryptoError::InvalidStructure("Can not update Witness. I'm revoced.".to_string())) @@ -477,14 +476,14 @@ impl Prover { mut_claim.witness.v.difference(&accum.v).cloned().collect(); let v_new_minus_old: HashSet = accum.v.difference(&mut_claim.witness.v).cloned().collect(); - let mut omega_denom = PointG1::new_inf()?; + let mut omega_denom = PointG2::new_inf()?; for j in v_old_minus_new.iter() { omega_denom = omega_denom.add( tails.get(&(accum.max_claim_num + 1 - j + mut_claim.i)) .ok_or(CryptoError::InvalidStructure(format!("Key not found {} in tails", accum.max_claim_num + 1 - j + mut_claim.i)))?)?; } - let mut omega_num = PointG1::new_inf()?; - let mut new_omega: PointG1 = mut_claim.witness.omega.clone(); + let mut omega_num = PointG2::new_inf()?; + let mut new_omega: PointG2 = mut_claim.witness.omega.clone(); for j in v_old_minus_new.iter() { omega_num = omega_num.add( tails.get(&(accum.max_claim_num + 1 - j + mut_claim.i)) @@ -815,17 +814,17 @@ impl Prover { let w = claim.witness.omega .add( - &pkr.htilde.mul(¶ms.r_prime)? + &pkr.h_cap.mul(¶ms.r_prime)? )?; let s = claim.witness.sigma_i .add( - &pkr.htilde.mul(¶ms.r_prime_prime)? + &pkr.h_cap.mul(¶ms.r_prime_prime)? )?; let u = claim.witness.u_i .add( - &pkr.htilde.mul(¶ms.r_prime_prime_prime)? + &pkr.h_cap.mul(¶ms.r_prime_prime_prime)? )?; Ok(NonRevocProofCList::new(e, d, a, g, w, s, u)) @@ -1332,8 +1331,8 @@ pub mod mocks { pub fn get_non_revocation_proof_c_list() -> NonRevocProofCList { NonRevocProofCList::new(PointG1::new().unwrap(), PointG1::new().unwrap(), PointG1::new().unwrap(), PointG1::new().unwrap(), - PointG1::new().unwrap(), PointG1::new().unwrap(), - PointG1::new().unwrap() + PointG2::new().unwrap(), PointG2::new().unwrap(), + PointG2::new().unwrap() ) } @@ -1498,17 +1497,19 @@ pub mod mocks { } pub fn get_public_key_revocation() -> RevocationPublicKey { - RevocationPublicKey::new(PointG1::new().unwrap(), PointG1::new().unwrap(), - PointG1::new().unwrap(), PointG1::new().unwrap(), + RevocationPublicKey::new(PointG1::new().unwrap(), PointG2::new().unwrap(), PointG1::new().unwrap(), PointG1::new().unwrap(), PointG1::new().unwrap(), PointG1::new().unwrap(), - PointG1::new().unwrap(), GroupOrderElement::new().unwrap()) + PointG1::new().unwrap(), PointG2::new().unwrap(), + PointG2::new().unwrap(), PointG1::new().unwrap(), + PointG2::new().unwrap(), + GroupOrderElement::new().unwrap()) } pub fn get_accumulator() -> Accumulator { let mut v: HashSet = HashSet::new(); v.insert(1); - Accumulator::new(PointG1::new().unwrap(), v, 5, 2) + Accumulator::new(PointG2::new().unwrap(), v, 5, 2) } pub fn get_tails() -> HashMap { @@ -1519,8 +1520,8 @@ pub mod mocks { pub fn get_witness() -> Witness { Witness::new( - PointG1::new().unwrap(), PointG1::new().unwrap(), PointG1::new().unwrap(), - PointG1::new().unwrap(), HashSet::from_iter(vec![1].iter().cloned() + PointG2::new().unwrap(), PointG2::new().unwrap(), PointG1::new().unwrap(), + PointG2::new().unwrap(), HashSet::from_iter(vec![1].iter().cloned() ) ) } diff --git a/src/services/anoncreds/types.rs b/src/services/anoncreds/types.rs index 035518a..17c81a9 100644 --- a/src/services/anoncreds/types.rs +++ b/src/services/anoncreds/types.rs @@ -1,5 +1,5 @@ use utils::crypto::bn::BigNumber; -use utils::crypto::pair::{GroupOrderElement, PointG1, Pair}; +use utils::crypto::pair::{GroupOrderElement, PointG1, PointG2, Pair}; use errors::crypto::CryptoError; use services::anoncreds::helpers::{AppendByteArray, clone_bignum_map}; use std::collections::{HashMap, HashSet}; @@ -18,14 +18,14 @@ pub enum PredicateType { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Accumulator { - pub acc: PointG1, + pub acc: PointG2, pub v: HashSet, pub max_claim_num: i32, pub current_i: i32 } impl Accumulator { - pub fn new(acc: PointG1, v: HashSet, max_claim_num: i32, + pub fn new(acc: PointG2, v: HashSet, max_claim_num: i32, current_i: i32) -> Accumulator { Accumulator { acc: acc, @@ -484,14 +484,14 @@ pub struct NonRevocProofCList { pub d: PointG1, pub a: PointG1, pub g: PointG1, - pub w: PointG1, - pub s: PointG1, - pub u: PointG1 + pub w: PointG2, + pub s: PointG2, + pub u: PointG2 } impl NonRevocProofCList { - pub fn new(e: PointG1, d: PointG1, a: PointG1, g: PointG1, w: PointG1, s: PointG1, - u: PointG1) -> NonRevocProofCList { + pub fn new(e: PointG1, d: PointG1, a: PointG1, g: PointG1, w: PointG2, s: PointG2, + u: PointG2) -> NonRevocProofCList { NonRevocProofCList { e: e, d: d, @@ -503,8 +503,9 @@ impl NonRevocProofCList { } } - pub fn as_list(&self) -> Result, CryptoError> { - Ok(vec![self.e, self.d, self.a, self.g, self.w, self.s, self.u]) + pub fn as_list(&self) -> Result>, CryptoError> { + Ok(vec![self.e.to_bytes()?, self.d.to_bytes()?, self.a.to_bytes()?, self.g.to_bytes()?, + self.w.to_bytes()?, self.s.to_bytes()?, self.u.to_bytes()?]) } } @@ -530,7 +531,7 @@ impl NonRevocInitProof { } } - pub fn as_c_list(&self) -> Result, CryptoError> { + pub fn as_c_list(&self) -> Result>, CryptoError> { let vec = self.c_list.as_list()?; Ok(vec) } @@ -937,14 +938,17 @@ impl<'a> JsonDecodable<'a> for RevocationRegistry {} #[derive(Deserialize, Debug, Serialize, Clone)] pub struct RevocationRegistryPrivate { pub acc_sk: AccumulatorSecretKey, - pub tails: HashMap + pub tails: HashMap, + pub tails_dash: HashMap } impl RevocationRegistryPrivate { - pub fn new(acc_sk: AccumulatorSecretKey, tails: HashMap) -> RevocationRegistryPrivate { + pub fn new(acc_sk: AccumulatorSecretKey, tails: HashMap, + tails_dash: HashMap) -> RevocationRegistryPrivate { RevocationRegistryPrivate { acc_sk: acc_sk, - tails: tails + tails: tails, + tails_dash: tails_dash } } } @@ -956,27 +960,31 @@ impl<'a> JsonDecodable<'a> for RevocationRegistryPrivate {} #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] pub struct RevocationPublicKey { pub g: PointG1, + pub g_dash: PointG2, pub h: PointG1, pub h0: PointG1, pub h1: PointG1, pub h2: PointG1, pub htilde: PointG1, - pub u: PointG1, + pub h_cap: PointG2, + pub u: PointG2, pub pk: PointG1, - pub y: PointG1, + pub y: PointG2, pub x: GroupOrderElement } impl RevocationPublicKey { - pub fn new(g: PointG1, h: PointG1, h0: PointG1, h1: PointG1, h2: PointG1, htilde: PointG1, - u: PointG1, pk: PointG1, y: PointG1, x: GroupOrderElement) -> RevocationPublicKey { + pub fn new(g: PointG1, g_dash: PointG2, h: PointG1, h0: PointG1, h1: PointG1, h2: PointG1, htilde: PointG1, + h_cap: PointG2, u: PointG2, pk: PointG1, y: PointG2, x: GroupOrderElement) -> RevocationPublicKey { RevocationPublicKey { g: g, + g_dash: g_dash, h: h, h0: h0, h1: h1, h2: h2, htilde: htilde, + h_cap: h_cap, u: u, pk: pk, y: y, @@ -1115,15 +1123,15 @@ impl<'a> JsonDecodable<'a> for SecretKey {} #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Witness { - pub sigma_i: PointG1, - pub u_i: PointG1, + pub sigma_i: PointG2, + pub u_i: PointG2, pub g_i: PointG1, - pub omega: PointG1, + pub omega: PointG2, pub v: HashSet } impl Witness { - pub fn new(sigma_i: PointG1, u_i: PointG1, g_i: PointG1, omega: PointG1, + pub fn new(sigma_i: PointG2, u_i: PointG2, g_i: PointG1, omega: PointG2, v: HashSet) -> Witness { Witness { sigma_i: sigma_i, diff --git a/src/services/anoncreds/verifier.rs b/src/services/anoncreds/verifier.rs index 6be349b..bd0040f 100644 --- a/src/services/anoncreds/verifier.rs +++ b/src/services/anoncreds/verifier.rs @@ -18,7 +18,7 @@ use services::anoncreds::helpers::{AppendByteArray, get_hash_as_int, bignum_to_g use utils::crypto::bn::BigNumber; use std::collections::{HashMap, HashSet}; use errors::crypto::CryptoError; -use utils::crypto::pair::{Pair, PointG1}; +use utils::crypto::pair::{Pair, PointG1, PointG2}; use services::anoncreds::issuer::Issuer; pub struct Verifier {} @@ -452,7 +452,7 @@ pub mod mocks { pub fn get_accum_publick_key() -> AccumulatorPublicKey { AccumulatorPublicKey::new( - Pair::pair(&PointG1::new().unwrap(), &PointG1::new().unwrap()).unwrap() + Pair::pair(&PointG1::new().unwrap(), &PointG2::new().unwrap()).unwrap() ) } } \ No newline at end of file diff --git a/src/utils/crypto/pair/milagro.rs b/src/utils/crypto/pair/milagro.rs index 8846f38..3bc1e4b 100644 --- a/src/utils/crypto/pair/milagro.rs +++ b/src/utils/crypto/pair/milagro.rs @@ -1,9 +1,21 @@ extern crate milagro_crypto; extern crate serde; -use self::milagro_crypto::big::wrappers::{CURVE_Gx, CURVE_Gy, CURVE_Order, BIG}; +use self::milagro_crypto::big::wrappers::{ + CURVE_Gx, + CURVE_Gy, + CURVE_Order, + CURVE_Pxa, + CURVE_Pya, + CURVE_Pxb, + CURVE_Pyb, + BIG +}; use self::milagro_crypto::ecp::wrappers::ECP; +use self::milagro_crypto::ecp2::wrappers::ECP2; use self::milagro_crypto::fp12::wrappers::FP12; +use self::milagro_crypto::fp2::wrappers::FP2; +use self::milagro_crypto::pair::PAIR; use errors::crypto::CryptoError; use services::anoncreds::helpers::BytesView; @@ -14,8 +26,9 @@ extern crate rand; use self::rand::os::{OsRng}; use self::rand::Rng; -use self::serde::ser::{Serialize, Serializer}; -use self::serde::de::{Deserialize, Deserializer}; +use self::serde::ser::{Serialize, Serializer, Error as SError}; +use self::serde::de::{Deserialize, Deserializer, Visitor, Error as DError}; +use std::fmt; fn random_mod_order() -> Result { let mut seed = vec![0; 32]; @@ -30,26 +43,14 @@ pub struct PointG1 { point: ECP } -pub struct PointG2 {} - -#[derive(Debug, Copy, Clone, PartialEq)] -pub struct GroupOrderElement { - bn: BIG -} - -#[derive(Debug, Copy, Clone, PartialEq)] -pub struct Pair { - pair: FP12 -} - impl PointG1 { pub fn new() -> Result { // generate random point from the group G1 - let gen_g1: ECP = ECP::new_bigs(&unsafe { CURVE_Gx }.clone(), &unsafe { CURVE_Gy }.clone()); - let mut point = gen_g1; - ECP::mul(&mut point, &random_mod_order()?); + let mut gen_g1: ECP = ECP::new_bigs(&unsafe { CURVE_Gx }.clone(), &unsafe { CURVE_Gy }.clone()); + + ECP::mul(&mut gen_g1, &random_mod_order()?); Ok(PointG1 { - point: point + point: gen_g1 }) } @@ -94,18 +95,168 @@ impl PointG1 { } pub fn to_string(&self) -> Result { - unimplemented!(); + Ok(ECP::to_hex(&self.point)) + } + + pub fn from_string(str: &str) -> Result { + Ok(PointG1 { + point: ECP::from_hex(str.to_string()) + }) } pub fn to_bytes(&self) -> Result, CryptoError> { + let str = self.to_string()?; + + Ok(str.into_bytes()) + } + + pub fn from_bytes(b: &[u8]) -> Result { unimplemented!(); } +} + +impl BytesView for PointG1 { + fn to_bytes(&self) -> Result, CryptoError> { + Ok(self.to_bytes()?) + } +} + +impl Serialize for PointG1 { + fn serialize(&self, serializer: S) -> Result where S: Serializer { + serializer.serialize_newtype_struct("PointG1", &self.to_string().map_err(SError::custom)?) + } +} + +impl<'a> Deserialize<'a> for PointG1 { + fn deserialize(deserializer: D) -> Result where D: Deserializer<'a> { + struct PointG1Visitor; + + impl<'a> Visitor<'a> for PointG1Visitor { + type Value = PointG1; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("expected PointG1") + } + + fn visit_str(self, value: &str) -> Result + where E: DError + { + Ok(PointG1::from_string(value).map_err(DError::custom)?) + } + } + + deserializer.deserialize_str(PointG1Visitor) + } +} + +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct PointG2 { + point: ECP2 +} + +impl PointG2 { + pub fn new() -> Result { + let mut point_x = FP2::default(); + let mut point_y = FP2::default(); + let mut point_z = FP2::default(); + FP2::from_BIGs(&mut point_x, &unsafe { CURVE_Pxa }.clone(), &unsafe { CURVE_Pxb }.clone()); + FP2::from_BIGs(&mut point_y, &unsafe { CURVE_Pya }.clone(), &unsafe { CURVE_Pyb }.clone()); + FP2::from_BIGs(&mut point_z, &BIG::from_hex("1".to_string()), &BIG::from_hex("0".to_string())); + let mut gen_g2: ECP2 = ECP2::new_fp2s(point_x, point_y, point_z); + + ECP2::mul(&mut gen_g2, &random_mod_order()?); + Ok(PointG2 { + point: gen_g2 + }) + } + + pub fn new_inf() -> Result { + let mut point = ECP2::default(); + ECP2::inf(&mut point); + + Ok(PointG2 { + point: point + }) + } + + pub fn add(&self, q: &PointG2) -> Result { + let mut r = self.point; + ECP2::add(&mut r, &q.point); + Ok(PointG2 { + point: r + }) + } + + pub fn sub(&self, q: &PointG2) -> Result { + let mut r = self.point; + ECP2::sub(&mut r, &q.point); + Ok(PointG2 { + point: r + }) + } + + pub fn mul(&self, e: &GroupOrderElement) -> Result { + let mut r = self.point; + ECP2::mul(&mut r, &e.bn); + Ok(PointG2 { + point: r + }) + } + + pub fn to_string(&self) -> Result { + Ok(ECP2::to_hex(&self.point)) + } + + pub fn from_string(str: &str) -> Result { + Ok(PointG2 { + point: ECP2::from_hex(str.to_string()) + }) + } + + pub fn to_bytes(&self) -> Result, CryptoError> { + let str = self.to_string()?; + + Ok(str.into_bytes()) + } pub fn from_bytes(b: &[u8]) -> Result { unimplemented!(); } } +impl Serialize for PointG2 { + fn serialize(&self, serializer: S) -> Result where S: Serializer { + serializer.serialize_newtype_struct("PointG2", &self.to_string().map_err(SError::custom)?) + } +} + +impl<'a> Deserialize<'a> for PointG2 { + fn deserialize(deserializer: D) -> Result where D: Deserializer<'a> { + struct PointG2Visitor; + + impl<'a> Visitor<'a> for PointG2Visitor { + type Value = PointG2; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("expected PointG2") + } + + fn visit_str(self, value: &str) -> Result + where E: DError + { + Ok(PointG2::from_string(value).map_err(DError::custom)?) + } + } + + deserializer.deserialize_str(PointG2Visitor) + } +} + +#[derive(Debug, Copy, Clone, PartialEq)] +pub struct GroupOrderElement { + bn: BIG +} + impl GroupOrderElement { pub fn new() -> Result { // returns random element in 0, ..., GroupOrder-1 @@ -168,7 +319,13 @@ impl GroupOrderElement { } pub fn to_string(&self) -> Result { - unimplemented!(); + Ok(BIG::to_hex(&self.bn)) + } + + pub fn from_string(str: &str) -> Result { + Ok(GroupOrderElement { + bn: BIG::from_hex(str.to_string()) + }) } pub fn to_bytes(&self) -> Result, CryptoError> { @@ -186,9 +343,55 @@ impl GroupOrderElement { } } +impl BytesView for GroupOrderElement { + fn to_bytes(&self) -> Result, CryptoError> { + Ok(self.to_bytes()?) + } +} + +impl Serialize for GroupOrderElement { + fn serialize(&self, serializer: S) -> Result where S: Serializer { + serializer.serialize_newtype_struct("GroupOrderElement", &self.to_string().map_err(SError::custom)?) + } +} + +impl<'a> Deserialize<'a> for GroupOrderElement { + fn deserialize(deserializer: D) -> Result where D: Deserializer<'a> { + struct GroupOrderElementVisitor; + + impl<'a> Visitor<'a> for GroupOrderElementVisitor { + type Value = GroupOrderElement; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("expected GroupOrderElement") + } + + fn visit_str(self, value: &str) -> Result + where E: DError + { + Ok(GroupOrderElement::from_string(value).map_err(DError::custom)?) + } + } + + deserializer.deserialize_str(GroupOrderElementVisitor) + } +} + +#[derive(Debug, Copy, Clone, PartialEq)] +pub struct Pair { + pair: FP12 +} + impl Pair { - pub fn pair(p: &PointG1, q: &PointG1) -> Result { - unimplemented!(); + pub fn pair(p: &PointG1, q: &PointG2) -> Result { + let mut pair = FP12::default(); + let mut p_new = *p; + let mut q_new = *q; + + PAIR::ate(&mut pair, &mut q_new.point, &mut p_new.point); + Ok(Pair { + pair: pair + }) } pub fn mul(&self, b: &Pair) -> Result { @@ -216,7 +419,13 @@ impl Pair { } pub fn to_string(&self) -> Result { - unimplemented!(); + Ok(FP12::to_hex(&self.pair)) + } + + pub fn from_string(str: &str) -> Result { + Ok(Pair { + pair: FP12::from_hex(str.to_string()) + }) } pub fn to_bytes(&self) -> Result, CryptoError> { @@ -234,50 +443,165 @@ impl BytesView for Pair { } } -impl BytesView for PointG1 { - fn to_bytes(&self) -> Result, CryptoError> { - Ok(self.to_bytes()?) +impl Serialize for Pair { + fn serialize(&self, serializer: S) -> Result where S: Serializer { + serializer.serialize_newtype_struct("Pair", &self.to_string().map_err(SError::custom)?) } } -impl BytesView for GroupOrderElement { - fn to_bytes(&self) -> Result, CryptoError> { - Ok(self.to_bytes()?) +impl<'a> Deserialize<'a> for Pair { + fn deserialize(deserializer: D) -> Result where D: Deserializer<'a> { + struct PairVisitor; + + impl<'a> Visitor<'a> for PairVisitor { + type Value = Pair; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("expected Pair") + } + + fn visit_str(self, value: &str) -> Result + where E: DError + { + Ok(Pair::from_string(value).map_err(DError::custom)?) + } + } + + deserializer.deserialize_str(PairVisitor) } } -impl Serialize for GroupOrderElement { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - unimplemented!(); +#[cfg(test)] +mod tests { + use super::*; + use utils::logger::LoggerUtils; + + extern crate serde_json; + + #[derive(Serialize, Deserialize, Debug, PartialEq)] + struct TestGroupOrderElementStructure { + field: GroupOrderElement } -} -impl<'a> Deserialize<'a> for GroupOrderElement { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'a> { - unimplemented!(); + #[derive(Serialize, Deserialize, Debug, PartialEq)] + struct TestPointG1Structure { + field: PointG1 } -} -impl Serialize for Pair { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - unimplemented!(); + #[derive(Serialize, Deserialize, Debug, PartialEq)] + struct TestPointG2Structure { + field: PointG2 } -} -impl<'a> Deserialize<'a> for Pair { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'a> { - unimplemented!(); + #[derive(Serialize, Deserialize, Debug, PartialEq)] + struct TestPairStructure { + field: Pair } -} -impl Serialize for PointG1 { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - unimplemented!(); + #[test] + fn serialize_works_for_group_order_element() { + let structure = TestGroupOrderElementStructure { + field: GroupOrderElement::from_string("C4D05C20EC7BAC 2FBB155341552D 6AA4C1EA344257 E84BFFBF1408B3 194D3FBA").unwrap() + }; + let str = r#"{"field":"C4D05C20EC7BAC 2FBB155341552D 6AA4C1EA344257 E84BFFBF1408B3 194D3FBA"}"#; + + let serialized = serde_json::to_string(&structure).unwrap(); + assert_eq!(str, serialized); } -} -impl<'a> Deserialize<'a> for PointG1 { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'a> { - unimplemented!(); + #[test] + fn deserialize_works_for_group_order_element() { + let structure = TestGroupOrderElementStructure { + field: GroupOrderElement::from_string("C4D05C20EC7BAC 2FBB155341552D 6AA4C1EA344257 E84BFFBF1408B3 194D3FBA").unwrap() + }; + let str = r#"{"field":"C4D05C20EC7BAC 2FBB155341552D 6AA4C1EA344257 E84BFFBF1408B3 194D3FBA"}"#; + let deserialized: TestGroupOrderElementStructure = serde_json::from_str(&str).unwrap(); + + assert_eq!(structure, deserialized); + } + + #[test] + fn serialize_works_for_point_g1() { + let structure = TestPointG1Structure { + field: PointG1::from_string("1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0").unwrap() + }; + let str = r#"{"field":"1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0"}"#; + + let serialized = serde_json::to_string(&structure).unwrap(); + assert_eq!(str, serialized); + } + + #[test] + fn deserialize_works_for_point_g1() { + let structure = TestPointG1Structure { + field: PointG1::from_string("1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0").unwrap() + }; + + let str = r#"{"field":"1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0"}"#; + let deserialized: TestPointG1Structure = serde_json::from_str(&str).unwrap(); + + assert_eq!(structure, deserialized); + } + + #[test] + fn serialize_works_for_point_g2() { + let structure = TestPointG2Structure { + field: PointG2::from_string("0 53104BD1A92BE9 4CBF937B44DAA 1D191B0496A14B 276529199F4D1B 4A996C2 3B2712E2EC37FF CF7C4390E8071C EF8C973AD5EDAA 547DD84375861 169CBAC9 5224321CF032B7 B9D2063515A045 9833D500F6EEBE DB9D00AED36ED2 7916166 22D7513761F614 4CD0E53D855FC3 950F3C38908717 A0261AC49D33A0 1B221531 A96F211585EDB F2942F28DB526F 2FF74229029FCD F4EABE779E75E4 3C3FED4 0 0 0 0 0").unwrap() + }; + + let str = r#"{"field":"0 53104BD1A92BE9 4CBF937B44DAA 1D191B0496A14B 276529199F4D1B 4A996C2 3B2712E2EC37FF CF7C4390E8071C EF8C973AD5EDAA 547DD84375861 169CBAC9 5224321CF032B7 B9D2063515A045 9833D500F6EEBE DB9D00AED36ED2 7916166 22D7513761F614 4CD0E53D855FC3 950F3C38908717 A0261AC49D33A0 1B221531 A96F211585EDB F2942F28DB526F 2FF74229029FCD F4EABE779E75E4 3C3FED4 0 0 0 0 0"}"#; + let serialized = serde_json::to_string(&structure).unwrap(); + + assert_eq!(str, serialized); + } + + #[test] + fn deserialize_works_for_point_g2() { + let structure = TestPointG2Structure { + field: PointG2::from_string("0 53104BD1A92BE9 4CBF937B44DAA 1D191B0496A14B 276529199F4D1B 4A996C2 3B2712E2EC37FF CF7C4390E8071C EF8C973AD5EDAA 547DD84375861 169CBAC9 5224321CF032B7 B9D2063515A045 9833D500F6EEBE DB9D00AED36ED2 7916166 22D7513761F614 4CD0E53D855FC3 950F3C38908717 A0261AC49D33A0 1B221531 A96F211585EDB F2942F28DB526F 2FF74229029FCD F4EABE779E75E4 3C3FED4 0 0 0 0 0").unwrap() + }; + let str = r#"{"field":"0 53104BD1A92BE9 4CBF937B44DAA 1D191B0496A14B 276529199F4D1B 4A996C2 3B2712E2EC37FF CF7C4390E8071C EF8C973AD5EDAA 547DD84375861 169CBAC9 5224321CF032B7 B9D2063515A045 9833D500F6EEBE DB9D00AED36ED2 7916166 22D7513761F614 4CD0E53D855FC3 950F3C38908717 A0261AC49D33A0 1B221531 A96F211585EDB F2942F28DB526F 2FF74229029FCD F4EABE779E75E4 3C3FED4 0 0 0 0 0"}"#; + let deserialized: TestPointG2Structure = serde_json::from_str(&str).unwrap(); + + assert_eq!(structure, deserialized); + } + #[test] + fn serialize_works_for_pair() { + let point_g1 = PointG1 { + point: PointG1::from_string("1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0").unwrap().point + }; + let point_g2 = PointG2 { + point: PointG2::from_string("0 53104BD1A92BE9 4CBF937B44DAA 1D191B0496A14B 276529199F4D1B 4A996C2 3B2712E2EC37FF CF7C4390E8071C EF8C973AD5EDAA 547DD84375861 169CBAC9 5224321CF032B7 B9D2063515A045 9833D500F6EEBE DB9D00AED36ED2 7916166 22D7513761F614 4CD0E53D855FC3 950F3C38908717 A0261AC49D33A0 1B221531 A96F211585EDB F2942F28DB526F 2FF74229029FCD F4EABE779E75E4 3C3FED4 0 0 0 0 0").unwrap().point + }; + let pair = TestPairStructure { + field: Pair::pair(&point_g1, &point_g2).unwrap() + }; + let str = r#"{"field":"70CC65D2371808 FD4F75244E5B72 40359FC95F7204 FA308613F34F1D 551BB55FA 7CB294CCE69B4A AE3C7228995A41 F27CD79430990 DE04BB58428296 5303A03BD 7FFA8A31C72E82 A8E1AA2E51D4B2 87B33F735B7ADF 19EADA0B95227E 392C800DC 74571A20806B80 ABDB72819D0A70 D4B1EDF5A54E6F FAF8EA4B2EFC2D 3CE6F2507 1EF2EE10541C8A 7C8B52D128C803 9D4A4954550B73 922CD02BD9DA10 AF8000002 1EF2EE10541C8A 7C8B52D128C803 9D4A4954550B73 922CD02BD9DA10 AF8000002 1EF2EE10541C8A 7C8B52D128C803 9D4A4954550B73 922CD02BD9DA10 AF8000002 1EF2EE10541C8A 7C8B52D128C803 9D4A4954550B73 922CD02BD9DA10 AF8000002 5543B5BF0C1826 69623262363316 E78DA0826F5875 2CEAD78790F397 948000002 5543B5BF0C1826 69623262363316 E78DA0826F5875 2CEAD78790F397 948000002 5543B5BF0C1826 69623262363316 E78DA0826F5875 2CEAD78790F397 948000002 5543B5BF0C1826 69623262363316 E78DA0826F5875 2CEAD78790F397 948000002"}"#; + let serialized = serde_json::to_string(&pair).unwrap(); + + assert_eq!(str, serialized); + } + + #[test] + fn deserialize_works_for_pair() { + let point_g1 = PointG1 { + point: PointG1::from_string("1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0").unwrap().point + }; + let point_g2 = PointG2 { + point: PointG2::from_string("0 53104BD1A92BE9 4CBF937B44DAA 1D191B0496A14B 276529199F4D1B 4A996C2 3B2712E2EC37FF CF7C4390E8071C EF8C973AD5EDAA 547DD84375861 169CBAC9 5224321CF032B7 B9D2063515A045 9833D500F6EEBE DB9D00AED36ED2 7916166 22D7513761F614 4CD0E53D855FC3 950F3C38908717 A0261AC49D33A0 1B221531 A96F211585EDB F2942F28DB526F 2FF74229029FCD F4EABE779E75E4 3C3FED4 0 0 0 0 0").unwrap().point + }; + let pair = TestPairStructure { + field: Pair::pair(&point_g1, &point_g2).unwrap() + }; + let str = r#"{"field":"70CC65D2371808 FD4F75244E5B72 40359FC95F7204 FA308613F34F1D 551BB55FA 7CB294CCE69B4A AE3C7228995A41 F27CD79430990 DE04BB58428296 5303A03BD 7FFA8A31C72E82 A8E1AA2E51D4B2 87B33F735B7ADF 19EADA0B95227E 392C800DC 74571A20806B80 ABDB72819D0A70 D4B1EDF5A54E6F FAF8EA4B2EFC2D 3CE6F2507 1EF2EE10541C8A 7C8B52D128C803 9D4A4954550B73 922CD02BD9DA10 AF8000002 1EF2EE10541C8A 7C8B52D128C803 9D4A4954550B73 922CD02BD9DA10 AF8000002 1EF2EE10541C8A 7C8B52D128C803 9D4A4954550B73 922CD02BD9DA10 AF8000002 1EF2EE10541C8A 7C8B52D128C803 9D4A4954550B73 922CD02BD9DA10 AF8000002 5543B5BF0C1826 69623262363316 E78DA0826F5875 2CEAD78790F397 948000002 5543B5BF0C1826 69623262363316 E78DA0826F5875 2CEAD78790F397 948000002 5543B5BF0C1826 69623262363316 E78DA0826F5875 2CEAD78790F397 948000002 5543B5BF0C1826 69623262363316 E78DA0826F5875 2CEAD78790F397 948000002"}"#; + let deserialized: TestPairStructure = serde_json::from_str(&str).unwrap(); + + assert_eq!(pair, deserialized); + } + + #[test] //TODO: remove it + fn stack_smashing_detected() { + let point = PointG2::new().unwrap(); + println!("pstr: {}", point.to_string().unwrap()); } } \ No newline at end of file diff --git a/tests/demo.rs b/tests/demo.rs index c0a6035..2542d73 100644 --- a/tests/demo.rs +++ b/tests/demo.rs @@ -23,6 +23,7 @@ use sovrin::api::ErrorCode; use sovrin::api::anoncreds::{ sovrin_issuer_create_and_store_claim_def, sovrin_issuer_create_claim, + sovrin_issuer_create_and_store_revoc_reg, sovrin_prover_create_master_secret, sovrin_prover_create_and_store_claim_req, sovrin_prover_store_claim, @@ -70,6 +71,7 @@ fn anoncreds_demo_works() { let (open_wallet_sender, open_wallet_receiver) = channel(); let (issuer_create_claim_definition_sender, issuer_create_claim_definition_receiver) = channel(); let (wallet_set_seq_no_for_value_sender, wallet_set_seq_no_for_value_receiver) = channel(); + let (issuer_create_and_store_revoc_reg_sender, issuer_create_and_store_revoc_reg_receiver) = channel(); let (prover_create_master_secret_sender, prover_create_master_secret_receiver) = channel(); let (prover_create_claim_req_sender, prover_create_claim_req_receiver) = channel(); let (issuer_create_claim_sender, issuer_create_claim_receiver) = channel(); @@ -90,6 +92,9 @@ fn anoncreds_demo_works() { let wallet_set_seq_no_for_value_cb = Box::new(move |err| { wallet_set_seq_no_for_value_sender.send(err).unwrap(); }); + let issuer_create_and_store_revoc_reg_cb = Box::new(move |err, revoc_reg_json, revoc_reg_uuid| { + issuer_create_and_store_revoc_reg_sender.send((err, revoc_reg_json, revoc_reg_uuid)).unwrap(); + }); let prover_create_master_secret_cb = Box::new(move |err| { prover_create_master_secret_sender.send(err).unwrap(); }); @@ -116,6 +121,7 @@ fn anoncreds_demo_works() { let (create_wallet_command_handle, create_wallet_callback) = CallbackUtils::closure_to_create_wallet_cb(create_wallet_cb); let (open_wallet_command_handle, open_wallet_callback) = CallbackUtils::closure_to_open_wallet_cb(open_wallet_cb); let (wallet_set_seq_no_for_value_command_handle, wallet_set_seq_no_for_value_callback) = CallbackUtils::closure_to_wallet_set_seq_no_for_value_cb(wallet_set_seq_no_for_value_cb); + let (issuer_create_and_store_revoc_reg_command_handle, issuer_create_and_store_revoc_reg_callback) = CallbackUtils::closure_to_issuer_create_and_store_revoc_reg_cb(issuer_create_and_store_revoc_reg_cb); let (prover_create_master_secret_command_handle, prover_create_master_secret_callback) = CallbackUtils::closure_to_prover_create_master_secret_cb(prover_create_master_secret_cb); let (prover_create_claim_req_command_handle, prover_create_claim_req_callback) = CallbackUtils::closure_to_prover_create_claim_req_cb(prover_create_claim_req_cb); let (issuer_create_claim_command_handle, issuer_create_claim_callback) = CallbackUtils::closure_to_issuer_create_claim_cb(issuer_create_claim_cb); @@ -169,7 +175,7 @@ fn anoncreds_demo_works() { wallet_handle, CString::new(schema.clone()).unwrap().as_ptr(), null(), - false, + true, create_claim_definition_callback); assert_eq!(ErrorCode::Success, err); @@ -192,6 +198,20 @@ fn anoncreds_demo_works() { let master_secret_name = "master_secret"; +// // Issuer creates a revocation registry +// let max_claim_num: i32 = 1000; +// +// let err = sovrin_issuer_create_and_store_revoc_reg(issuer_create_and_store_revoc_reg_command_handle, +// wallet_handle, +// claim_def_seq_no, +// max_claim_num, +// issuer_create_and_store_revoc_reg_callback); +// +// assert_eq!(ErrorCode::Success, err); +// let (err, revoc_reg_json, revoc_reg_uuid) = issuer_create_and_store_revoc_reg_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); +// println!("revocation_reg_json: {:?}", revoc_reg_json); +// assert_eq!(ErrorCode::Success, err); + // 5. Prover create Master Secret let err = sovrin_prover_create_master_secret(prover_create_master_secret_command_handle, diff --git a/tests/utils/callback.rs b/tests/utils/callback.rs index 741a817..abeb391 100644 --- a/tests/utils/callback.rs +++ b/tests/utils/callback.rs @@ -167,6 +167,32 @@ impl CallbackUtils { (command_handle, Some(closure_to_wallet_set_seq_no_for_value_callback)) } + pub fn closure_to_issuer_create_and_store_revoc_reg_cb(closure: Box) -> (i32, + Option) { + lazy_static! { + static ref ISSUER_CREATE_AND_STORE_REVOC_REG_CALLBACKS: Mutex < HashMap < i32, Box < FnMut(ErrorCode, String, String) + Send > >> = Default::default(); + } + + extern "C" fn issuer_create_and_store_revoc_reg_callback(command_handle: i32, err: ErrorCode, + revoc_reg_json: *const c_char, + revoc_reg_uuid: *const c_char) { + let mut callbacks = ISSUER_CREATE_AND_STORE_REVOC_REG_CALLBACKS.lock().unwrap(); + let mut cb = callbacks.remove(&command_handle).unwrap(); + let revoc_reg_json = unsafe { CStr::from_ptr(revoc_reg_json).to_str().unwrap().to_string() }; + let revoc_reg_uuid = unsafe { CStr::from_ptr(revoc_reg_uuid).to_str().unwrap().to_string() }; + cb(err, revoc_reg_json, revoc_reg_uuid) + } + + let mut callbacks = ISSUER_CREATE_AND_STORE_REVOC_REG_CALLBACKS.lock().unwrap(); + let command_handle = (COMMAND_HANDLE_COUNTER.fetch_add(1, Ordering::SeqCst) + 1) as i32; + callbacks.insert(command_handle, closure); + + (command_handle, Some(issuer_create_and_store_revoc_reg_callback)) + } + pub fn closure_to_prover_create_master_secret_cb(closure: Box) -> (i32, Option) {