Skip to main content

indy_crypto/cl/
mod.rs

1mod constants;
2#[macro_use]
3mod helpers;
4pub mod issuer;
5pub mod prover;
6pub mod verifier;
7
8use bn::BigNumber;
9use errors::prelude::*;
10use pair::*;
11
12use std::cmp::Ordering;
13use std::collections::{HashMap, HashSet, BTreeSet, BTreeMap};
14use std::hash::Hash;
15
16/// Creates random nonce
17///
18/// # Example
19/// ```
20/// use indy_crypto::cl::new_nonce;
21///
22/// let _nonce = new_nonce().unwrap();
23/// ```
24pub fn new_nonce() -> Result<Nonce, IndyCryptoError> {
25    Ok(helpers::bn_rand(constants::LARGE_NONCE)?)
26}
27
28/// A list of attributes a Credential is based on.
29#[derive(Debug, Clone)]
30pub struct CredentialSchema {
31    attrs: BTreeSet<String>, /* attr names */
32}
33
34/// A Builder of `Credential Schema`.
35#[derive(Debug)]
36pub struct CredentialSchemaBuilder {
37    attrs: BTreeSet<String>, /* attr names */
38}
39
40impl CredentialSchemaBuilder {
41    pub fn new() -> Result<CredentialSchemaBuilder, IndyCryptoError> {
42        Ok(CredentialSchemaBuilder { attrs: BTreeSet::new() })
43    }
44
45    pub fn add_attr(&mut self, attr: &str) -> Result<(), IndyCryptoError> {
46        self.attrs.insert(attr.to_owned());
47        Ok(())
48    }
49
50    pub fn finalize(self) -> Result<CredentialSchema, IndyCryptoError> {
51        Ok(CredentialSchema { attrs: self.attrs })
52    }
53}
54
55#[derive(Debug, Clone)]
56pub struct NonCredentialSchema {
57    attrs: BTreeSet<String>,
58}
59
60#[derive(Debug)]
61pub struct NonCredentialSchemaBuilder {
62    attrs: BTreeSet<String>,
63}
64
65impl NonCredentialSchemaBuilder {
66    pub fn new() -> Result<NonCredentialSchemaBuilder, IndyCryptoError> {
67        Ok(NonCredentialSchemaBuilder {
68            attrs: BTreeSet::new(),
69        })
70    }
71
72    pub fn add_attr(&mut self, attr: &str) -> Result<(), IndyCryptoError> {
73        self.attrs.insert(attr.to_owned());
74        Ok(())
75    }
76
77    pub fn finalize(self) -> Result<NonCredentialSchema, IndyCryptoError> {
78        Ok(NonCredentialSchema { attrs: self.attrs })
79    }
80}
81
82/// The m value for attributes,
83/// commitments also store a blinding factor
84#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
85pub enum CredentialValue {
86    Known { value: BigNumber }, //Issuer and Prover know these
87    Hidden { value: BigNumber }, //Only known to Prover who binds these into the U factor
88    Commitment {
89        value: BigNumber,
90        blinding_factor: BigNumber,
91    }, //Only known to Prover, not included in the credential, used for proving knowledge during issuance
92}
93
94impl CredentialValue {
95    pub fn clone(&self) -> Result<CredentialValue, IndyCryptoError> {
96        Ok(match *self {
97            CredentialValue::Known { ref value } => CredentialValue::Known {
98                value: value.clone()?,
99            },
100            CredentialValue::Hidden { ref value } => CredentialValue::Hidden {
101                value: value.clone()?,
102            },
103            CredentialValue::Commitment {
104                ref value,
105                ref blinding_factor,
106            } => CredentialValue::Commitment {
107                value: value.clone()?,
108                blinding_factor: blinding_factor.clone()?,
109            },
110        })
111    }
112
113    pub fn is_known(&self) -> bool {
114        match *self {
115            CredentialValue::Known { .. } => true,
116            _ => false,
117        }
118    }
119
120    pub fn is_hidden(&self) -> bool {
121        match *self {
122            CredentialValue::Hidden { .. } => true,
123            _ => false,
124        }
125    }
126
127    pub fn is_commitment(&self) -> bool {
128        match *self {
129            CredentialValue::Commitment { .. } => true,
130            _ => false,
131        }
132    }
133
134    pub fn value(&self) -> &BigNumber {
135        match *self {
136            CredentialValue::Known { ref value } => value,
137            CredentialValue::Hidden { ref value } => value,
138            CredentialValue::Commitment { ref value, .. } => value,
139        }
140    }
141}
142
143/// Values of attributes from `Claim Schema` (must be integers).
144#[derive(Debug)]
145pub struct CredentialValues {
146    attrs_values: BTreeMap<String, CredentialValue>,
147}
148
149impl CredentialValues {
150    pub fn clone(&self) -> Result<CredentialValues, IndyCryptoError> {
151        Ok(CredentialValues {
152            attrs_values: clone_credential_value_map(&self.attrs_values)?
153        })
154    }
155}
156
157/// A Builder of `Credential Values`.
158#[derive(Debug)]
159pub struct CredentialValuesBuilder {
160    attrs_values: BTreeMap<String, CredentialValue>, /* attr_name -> int representation of value */
161}
162
163impl CredentialValuesBuilder {
164    pub fn new() -> Result<CredentialValuesBuilder, IndyCryptoError> {
165        Ok(CredentialValuesBuilder { attrs_values: BTreeMap::new() })
166    }
167
168    pub fn add_dec_known(&mut self, attr: &str, value: &str) -> Result<(), IndyCryptoError> {
169        self.attrs_values.insert(
170            attr.to_owned(),
171            CredentialValue::Known { value: BigNumber::from_dec(value)? },
172        );
173        Ok(())
174    }
175
176    pub fn add_dec_hidden(&mut self, attr: &str, value: &str) -> Result<(), IndyCryptoError> {
177        self.attrs_values.insert(
178            attr.to_owned(),
179            CredentialValue::Hidden { value: BigNumber::from_dec(value)? },
180        );
181        Ok(())
182    }
183
184    pub fn add_dec_commitment(
185        &mut self,
186        attr: &str,
187        value: &str,
188        blinding_factor: &str,
189    ) -> Result<(), IndyCryptoError> {
190        self.attrs_values.insert(
191            attr.to_owned(),
192            CredentialValue::Commitment {
193                value: BigNumber::from_dec(value)?,
194                blinding_factor: BigNumber::from_dec(blinding_factor)?,
195            },
196        );
197        Ok(())
198    }
199
200    pub fn add_value_known(
201        &mut self,
202        attr: &str,
203        value: &BigNumber,
204    ) -> Result<(), IndyCryptoError> {
205        self.attrs_values.insert(
206            attr.to_owned(),
207            CredentialValue::Known { value: value.clone()? },
208        );
209        Ok(())
210    }
211
212    pub fn add_value_hidden(
213        &mut self,
214        attr: &str,
215        value: &BigNumber,
216    ) -> Result<(), IndyCryptoError> {
217        self.attrs_values.insert(
218            attr.to_owned(),
219            CredentialValue::Hidden { value: value.clone()? },
220        );
221        Ok(())
222    }
223
224    pub fn add_value_commitment(
225        &mut self,
226        attr: &str,
227        value: &BigNumber,
228        blinding_factor: &BigNumber,
229    ) -> Result<(), IndyCryptoError> {
230        self.attrs_values.insert(
231            attr.to_owned(),
232            CredentialValue::Commitment {
233                value: value.clone()?,
234                blinding_factor: blinding_factor.clone()?,
235            },
236        );
237        Ok(())
238    }
239
240    pub fn finalize(self) -> Result<CredentialValues, IndyCryptoError> {
241        Ok(CredentialValues { attrs_values: self.attrs_values })
242    }
243}
244
245/// `Issuer Public Key` contains 2 internal parts.
246/// One for signing primary credentials and second for signing non-revocation credentials.
247/// These keys are used to proof that credential was issued and doesn’t revoked by this issuer.
248/// Issuer keys have global identifier that must be known to all parties.
249#[derive(Debug, Deserialize, Serialize, PartialEq)]
250pub struct CredentialPublicKey {
251    p_key: CredentialPrimaryPublicKey,
252    r_key: Option<CredentialRevocationPublicKey>,
253}
254
255impl CredentialPublicKey {
256    pub fn clone(&self) -> Result<CredentialPublicKey, IndyCryptoError> {
257        Ok(CredentialPublicKey {
258            p_key: self.p_key.clone()?,
259            r_key: self.r_key.clone()
260        })
261    }
262
263    pub fn get_primary_key(&self) -> Result<CredentialPrimaryPublicKey, IndyCryptoError> {
264        Ok(self.p_key.clone()?)
265    }
266
267    pub fn get_revocation_key(&self) -> Result<Option<CredentialRevocationPublicKey>, IndyCryptoError> {
268        Ok(self.r_key.clone())
269    }
270
271    pub fn build_from_parts(p_key: &CredentialPrimaryPublicKey, r_key: Option<&CredentialRevocationPublicKey>) -> Result<CredentialPublicKey, IndyCryptoError> {
272        Ok(CredentialPublicKey {
273            p_key: p_key.clone()?,
274            r_key: r_key.map(|key| key.clone())
275        })
276    }
277}
278
279/// `Issuer Private Key`: contains 2 internal parts.
280/// One for signing primary credentials and second for signing non-revocation credentials.
281#[derive(Debug, Deserialize, Serialize)]
282pub struct CredentialPrivateKey {
283    p_key: CredentialPrimaryPrivateKey,
284    r_key: Option<CredentialRevocationPrivateKey>,
285}
286
287/// Issuer's "Public Key" is used to verify the Issuer's signature over the Credential's attributes' values (primary credential).
288#[derive(Debug, PartialEq, Serialize)]
289pub struct CredentialPrimaryPublicKey {
290    n: BigNumber,
291    s: BigNumber,
292    r: HashMap<String /* attr_name */, BigNumber>,
293    rctxt: BigNumber,
294    z: BigNumber
295}
296
297impl CredentialPrimaryPublicKey {
298    pub fn clone(&self) -> Result<CredentialPrimaryPublicKey, IndyCryptoError> {
299        Ok(CredentialPrimaryPublicKey {
300            n: self.n.clone()?,
301            s: self.s.clone()?,
302            r: clone_bignum_map(&self.r)?,
303            rctxt: self.rctxt.clone()?,
304            z: self.z.clone()?
305        })
306    }
307}
308
309impl <'a> ::serde::de::Deserialize<'a> for CredentialPrimaryPublicKey {
310    fn deserialize<D: ::serde::de::Deserializer<'a>>(deserializer: D) -> Result<Self, D::Error> {
311        #[derive(Deserialize)]
312        struct CredentialPrimaryPublicKeyV1 {
313            n: BigNumber,
314            s: BigNumber,
315            r: HashMap<String /* attr_name */, BigNumber>,
316            rctxt: BigNumber,
317            #[serde(default)]
318            rms: BigNumber,
319            z: BigNumber
320        }
321
322        let mut helper = CredentialPrimaryPublicKeyV1::deserialize(deserializer)?;
323        if helper.rms != BigNumber::default() {
324            helper.r.insert("master_secret".to_string(), helper.rms);
325        }
326        Ok(CredentialPrimaryPublicKey {
327            n: helper.n,
328            s: helper.s,
329            rctxt: helper.rctxt,
330            z: helper.z,
331            r: helper.r
332        })
333    }
334}
335
336/// Issuer's "Private Key" used for signing Credential's attributes' values (primary credential)
337#[derive(Debug, PartialEq, Deserialize, Serialize)]
338pub struct CredentialPrimaryPrivateKey {
339    p: BigNumber,
340    q: BigNumber
341}
342
343/// `Primary Public Key Metadata` required for building of Proof Correctness of `Issuer Public Key`
344#[derive(Debug)]
345pub struct CredentialPrimaryPublicKeyMetadata {
346    xz: BigNumber,
347    xr: HashMap<String, BigNumber>
348}
349
350/// Proof of `Issuer Public Key` correctness
351#[derive(Debug, PartialEq, Deserialize, Serialize)]
352pub struct CredentialKeyCorrectnessProof {
353    c: BigNumber,
354    xz_cap: BigNumber,
355    xr_cap: Vec<(String, BigNumber)>,
356}
357
358/// `Revocation Public Key` is used to verify that credential was'nt revoked by Issuer.
359#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
360pub struct CredentialRevocationPublicKey {
361    g: PointG1,
362    g_dash: PointG2,
363    h: PointG1,
364    h0: PointG1,
365    h1: PointG1,
366    h2: PointG1,
367    htilde: PointG1,
368    h_cap: PointG2,
369    u: PointG2,
370    pk: PointG1,
371    y: PointG2,
372}
373
374/// `Revocation Private Key` is used for signing Credential.
375#[derive(Debug, Deserialize, Serialize)]
376pub struct CredentialRevocationPrivateKey {
377    x: GroupOrderElement,
378    sk: GroupOrderElement
379}
380
381pub type Accumulator = PointG2;
382
383/// `Revocation Registry` contains accumulator.
384/// Must be published by Issuer on a tamper-evident and highly available storage
385/// Used by prover to prove that a credential hasn't revoked by the issuer
386#[derive(Debug, Clone, Deserialize, Serialize)]
387pub struct RevocationRegistry {
388    accum: Accumulator
389}
390
391impl From<RevocationRegistryDelta> for RevocationRegistry {
392    fn from(rev_reg_delta: RevocationRegistryDelta) -> RevocationRegistry {
393        RevocationRegistry { accum: rev_reg_delta.accum }
394    }
395}
396
397/// `Revocation Registry Delta` contains Accumulator changes.
398/// Must be applied to `Revocation Registry`
399#[derive(Debug, Clone, Deserialize, Serialize)]
400#[serde(rename_all = "camelCase")]
401pub struct RevocationRegistryDelta {
402    #[serde(skip_serializing_if = "Option::is_none")]
403    prev_accum: Option<Accumulator>,
404    accum: Accumulator,
405    #[serde(skip_serializing_if = "HashSet::is_empty")]
406    #[serde(default)]
407    issued: HashSet<u32>,
408    #[serde(skip_serializing_if = "HashSet::is_empty")]
409    #[serde(default)]
410    revoked: HashSet<u32>
411}
412
413impl RevocationRegistryDelta {
414    pub fn from_parts(rev_reg_from: Option<&RevocationRegistry>,
415                      rev_reg_to: &RevocationRegistry,
416                      issued: &HashSet<u32>,
417                      revoked: &HashSet<u32>) -> RevocationRegistryDelta {
418        RevocationRegistryDelta {
419            prev_accum: rev_reg_from.map(|rev_reg| rev_reg.accum),
420            accum: rev_reg_to.accum.clone(),
421            issued: issued.clone(),
422            revoked: revoked.clone()
423        }
424    }
425
426    pub fn merge(&mut self, other_delta: &RevocationRegistryDelta) -> Result<(), IndyCryptoError> {
427        if other_delta.prev_accum.is_none() || self.accum != other_delta.prev_accum.unwrap() {
428            return Err(err_msg(IndyCryptoErrorKind::InvalidStructure, "Deltas can not be merged."));
429        }
430
431        self.accum = other_delta.accum;
432
433        self.issued.extend(
434            other_delta.issued.difference(&self.revoked));
435
436        self.revoked.extend(
437            other_delta.revoked.difference(&self.issued));
438
439        for index in other_delta.revoked.iter() {
440            self.issued.remove(index);
441        }
442
443        for index in other_delta.issued.iter() {
444            self.revoked.remove(index);
445        }
446
447        Ok(())
448    }
449}
450
451/// `Revocation Key Public` Accumulator public key.
452/// Must be published together with Accumulator
453#[derive(Debug, Clone, Deserialize, Serialize)]
454pub struct RevocationKeyPublic {
455    z: Pair
456}
457
458/// `Revocation Key Private` Accumulator primate key.
459#[derive(Debug, Deserialize, Serialize)]
460pub struct RevocationKeyPrivate {
461    gamma: GroupOrderElement
462}
463
464/// `Tail` point of curve used to update accumulator.
465pub type Tail = PointG2;
466
467impl Tail {
468    fn new_tail(index: u32, g_dash: &PointG2, gamma: &GroupOrderElement) -> Result<Tail, IndyCryptoError> {
469        let i_bytes = helpers::transform_u32_to_array_of_u8(index);
470        let mut pow = GroupOrderElement::from_bytes(&i_bytes)?;
471        pow = gamma.pow_mod(&pow)?;
472        Ok(g_dash.mul(&pow)?)
473    }
474}
475
476/// Generator of `Tail's`.
477#[derive(Debug, Clone, Deserialize, Serialize)]
478pub struct RevocationTailsGenerator {
479    size: u32,
480    current_index: u32,
481    g_dash: PointG2,
482    gamma: GroupOrderElement
483}
484
485impl RevocationTailsGenerator {
486    fn new(max_cred_num: u32, gamma: GroupOrderElement, g_dash: PointG2) -> Self {
487        RevocationTailsGenerator {
488            size: 2 * max_cred_num + 1, /* Unused 0th + valuable 1..L + unused (L+1)th + valuable (L+2)..(2L) */
489            current_index: 0,
490            gamma,
491            g_dash,
492        }
493    }
494
495    pub fn count(&self) -> u32 {
496        self.size - self.current_index
497    }
498
499    pub fn next(&mut self) -> Result<Option<Tail>, IndyCryptoError> {
500        if self.current_index >= self.size {
501            return Ok(None);
502        }
503
504        let tail = Tail::new_tail(self.current_index, &self.g_dash, &self.gamma)?;
505
506        self.current_index += 1;
507
508        Ok(Some(tail))
509    }
510}
511
512pub trait RevocationTailsAccessor {
513    fn access_tail(&self, tail_id: u32, accessor: &mut FnMut(&Tail)) -> Result<(), IndyCryptoError>;
514}
515
516/// Simple implementation of `RevocationTailsAccessor` that stores all tails as BTreeMap.
517#[derive(Debug, Clone)]
518pub struct SimpleTailsAccessor {
519    tails: Vec<Tail>
520}
521
522impl RevocationTailsAccessor for SimpleTailsAccessor {
523    fn access_tail(&self, tail_id: u32, accessor: &mut FnMut(&Tail)) -> Result<(), IndyCryptoError> {
524        Ok(accessor(&self.tails[tail_id as usize]))
525    }
526}
527
528impl SimpleTailsAccessor {
529    pub fn new(rev_tails_generator: &mut RevocationTailsGenerator) -> Result<SimpleTailsAccessor, IndyCryptoError> {
530        let mut tails: Vec<Tail> = Vec::new();
531        while let Some(tail) = rev_tails_generator.next()? {
532            tails.push(tail);
533        }
534        Ok(SimpleTailsAccessor { tails })
535    }
536}
537
538
539/// Issuer's signature over Credential attribute values.
540#[derive(Debug, Deserialize, Serialize)]
541pub struct CredentialSignature {
542    p_credential: PrimaryCredentialSignature,
543    r_credential: Option<NonRevocationCredentialSignature> /* will be used to proof is credential revoked preparation */,
544}
545
546impl CredentialSignature {
547    pub fn extract_index(&self) -> Option<u32> {
548        self.r_credential
549            .as_ref()
550            .map(|r_credential| r_credential.i)
551    }
552}
553
554#[derive(Debug, PartialEq, Eq, Deserialize, Serialize)]
555pub struct PrimaryCredentialSignature {
556    m_2: BigNumber,
557    a: BigNumber,
558    e: BigNumber,
559    v: BigNumber
560}
561
562#[derive(Debug, Clone, Deserialize, Serialize)]
563pub struct NonRevocationCredentialSignature {
564    sigma: PointG1,
565    c: GroupOrderElement,
566    vr_prime_prime: GroupOrderElement,
567    witness_signature: WitnessSignature,
568    g_i: PointG1,
569    i: u32,
570    m2: GroupOrderElement
571}
572
573#[derive(Debug, PartialEq, Eq, Deserialize, Serialize)]
574pub struct SignatureCorrectnessProof {
575    se: BigNumber,
576    c: BigNumber
577}
578
579#[derive(Debug, Clone, Deserialize, Serialize)]
580pub struct Witness {
581    omega: PointG2
582}
583
584impl Witness {
585    pub fn new<RTA>(rev_idx: u32,
586                    max_cred_num: u32,
587                    issuance_by_default: bool,
588                    rev_reg_delta: &RevocationRegistryDelta,
589                    rev_tails_accessor: &RTA) -> Result<Witness, IndyCryptoError> where RTA: RevocationTailsAccessor {
590        trace!("Witness::new: >>> rev_idx: {:?}, max_cred_num: {:?}, issuance_by_default: {:?}, rev_reg_delta: {:?}",
591               rev_idx, max_cred_num, issuance_by_default, rev_reg_delta);
592
593        let mut omega = PointG2::new_inf()?;
594
595        let mut issued = if issuance_by_default {
596            (1..max_cred_num + 1).collect::<HashSet<u32>>()
597                .difference(&rev_reg_delta.revoked).cloned().collect::<HashSet<u32>>()
598        } else {
599            rev_reg_delta.issued.clone()
600        };
601
602        issued.remove(&rev_idx);
603        for j in issued.iter() {
604            let index = max_cred_num + 1 - j + rev_idx;
605            rev_tails_accessor.access_tail(index, &mut |tail| {
606                omega = omega.add(tail).unwrap();
607            })?;
608        }
609
610        let witness = Witness { omega };
611
612        trace!("Witness::new: <<< witness: {:?}", witness);
613
614        Ok(witness)
615    }
616
617    pub fn update<RTA>(&mut self,
618                       rev_idx: u32,
619                       max_cred_num: u32,
620                       rev_reg_delta: &RevocationRegistryDelta,
621                       rev_tails_accessor: &RTA) -> Result<(), IndyCryptoError> where RTA: RevocationTailsAccessor {
622        trace!("Witness::update: >>> rev_idx: {:?}, max_cred_num: {:?}, rev_reg_delta: {:?}",
623               rev_idx, max_cred_num, rev_reg_delta);
624
625        let mut omega_denom = PointG2::new_inf()?;
626        for j in rev_reg_delta.revoked.iter() {
627            if rev_idx.eq(j) { continue; }
628
629            let index = max_cred_num + 1 - j + rev_idx;
630            rev_tails_accessor.access_tail(index, &mut |tail| {
631                omega_denom = omega_denom.add(tail).unwrap();
632            })?;
633        }
634
635        let mut omega_num = PointG2::new_inf()?;
636        for j in rev_reg_delta.issued.iter() {
637            if rev_idx.eq(j) { continue; }
638
639            let index = max_cred_num + 1 - j + rev_idx;
640            rev_tails_accessor.access_tail(index, &mut |tail| {
641                omega_num = omega_num.add(tail).unwrap();
642            })?;
643        }
644
645        let new_omega: PointG2 = self.omega.add(&omega_num.sub(&omega_denom)?)?;
646
647        self.omega = new_omega;
648
649        trace!("Witness::update: <<<");
650
651        Ok(())
652    }
653}
654
655#[derive(Debug, Clone, Deserialize, Serialize)]
656pub struct WitnessSignature {
657    sigma_i: PointG2,
658    u_i: PointG2,
659    g_i: PointG1
660}
661
662/// Secret key encoded in a credential that is used to prove that prover owns the credential; can be used to
663/// prove linkage across credentials.
664/// Prover blinds master secret, generating `BlindedCredentialSecrets` and `CredentialSecretsBlindingFactors` (blinding factors)
665/// and sends the `BlindedCredentialSecrets` to Issuer who then encodes it credential creation.
666/// The blinding factors are used by Prover for post processing of issued credentials.
667#[derive(Debug, Deserialize, Serialize)]
668pub struct MasterSecret {
669    ms: BigNumber,
670}
671
672impl MasterSecret {
673    pub fn clone(&self) -> Result<MasterSecret, IndyCryptoError> {
674        Ok(MasterSecret { ms: self.ms.clone()? })
675    }
676
677    pub fn value(&self) -> Result<BigNumber, IndyCryptoError> {
678        Ok(self.ms.clone()?)
679    }
680}
681
682/// Blinded Master Secret uses by Issuer in credential creation.
683#[derive(Debug, Deserialize, Serialize)]
684pub struct BlindedCredentialSecrets {
685    u: BigNumber,
686    ur: Option<PointG1>,
687    hidden_attributes: BTreeSet<String>,
688    committed_attributes: BTreeMap<String, BigNumber>
689}
690
691/// `CredentialSecretsBlindingFactors` used by Prover for post processing of credentials received from Issuer.
692#[derive(Debug, Deserialize, Serialize)]
693pub struct CredentialSecretsBlindingFactors {
694    v_prime: BigNumber,
695    vr_prime: Option<GroupOrderElement>
696}
697
698#[derive(Eq, PartialEq, Debug)]
699pub struct PrimaryBlindedCredentialSecretsFactors {
700    u: BigNumber,
701    v_prime: BigNumber,
702    hidden_attributes: BTreeSet<String>,
703    committed_attributes: BTreeMap<String, BigNumber>,
704}
705
706#[derive(Debug)]
707pub struct RevocationBlindedCredentialSecretsFactors {
708    ur: PointG1,
709    vr_prime: GroupOrderElement,
710}
711
712#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
713pub struct BlindedCredentialSecretsCorrectnessProof {
714    c: BigNumber, // Fiat-Shamir challenge hash
715    v_dash_cap: BigNumber, // Value to prove knowledge of `u` construction in `BlindedCredentialSecrets`
716    m_caps: BTreeMap<String, BigNumber>, // Values for proving knowledge of committed values
717    r_caps: BTreeMap<String, BigNumber>, // Blinding values for m_caps
718}
719
720/// “Sub Proof Request” - input to create a Proof for a credential;
721/// Contains attributes to be revealed and predicates.
722#[derive(Debug, Clone)]
723pub struct SubProofRequest {
724    revealed_attrs: BTreeSet<String>,
725    predicates: BTreeSet<Predicate>,
726}
727
728/// Builder of “Sub Proof Request”.
729#[derive(Debug)]
730pub struct SubProofRequestBuilder {
731    value: SubProofRequest
732}
733
734impl SubProofRequestBuilder {
735    pub fn new() -> Result<SubProofRequestBuilder, IndyCryptoError> {
736        Ok(SubProofRequestBuilder {
737            value: SubProofRequest {
738                revealed_attrs: BTreeSet::new(),
739                predicates: BTreeSet::new()
740            }
741        })
742    }
743
744    pub fn add_revealed_attr(&mut self, attr: &str) -> Result<(), IndyCryptoError> {
745        self.value.revealed_attrs.insert(attr.to_owned());
746        Ok(())
747    }
748
749    pub fn add_predicate(&mut self, attr_name: &str, p_type: &str, value: i32) -> Result<(), IndyCryptoError> {
750        let p_type = match p_type {
751            "GE" => PredicateType::GE,
752            p_type => return Err(err_msg(IndyCryptoErrorKind::InvalidStructure, format!("Invalid predicate type: {:?}", p_type)))
753        };
754
755        let predicate = Predicate {
756            attr_name: attr_name.to_owned(),
757            p_type,
758            value
759        };
760
761        self.value.predicates.insert(predicate);
762        Ok(())
763    }
764
765    pub fn finalize(self) -> Result<SubProofRequest, IndyCryptoError> {
766        Ok(self.value)
767    }
768}
769
770/// Some condition that must be satisfied.
771#[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize)]
772pub struct Predicate {
773    attr_name: String,
774    p_type: PredicateType,
775    value: i32,
776}
777
778/// Condition type (Currently GE only).
779#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
780pub enum PredicateType {
781    GE
782}
783
784impl Ord for Predicate {
785    fn cmp(&self, other: &Self) -> Ordering {
786        self.attr_name.cmp(&other.attr_name)
787    }
788}
789
790impl PartialOrd for Predicate {
791    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
792        Some(self.cmp(other))
793    }
794}
795
796/// Proof is complex crypto structure created by prover over multiple credentials that allows to prove that prover:
797/// 1) Knows signature over credentials issued with specific issuer keys (identified by key id)
798/// 2) Credential contains attributes with specific values that prover wants to disclose
799/// 3) Credential contains attributes with valid predicates that verifier wants the prover to satisfy.
800#[derive(Debug, Deserialize, Serialize)]
801pub struct Proof {
802    proofs: Vec<SubProof>,
803    aggregated_proof: AggregatedProof,
804}
805
806#[derive(Debug, Deserialize, Serialize)]
807pub struct SubProof {
808    primary_proof: PrimaryProof,
809    non_revoc_proof: Option<NonRevocProof>
810}
811
812#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
813pub struct AggregatedProof {
814    c_hash: BigNumber,
815    c_list: Vec<Vec<u8>>
816}
817
818#[derive(Debug, PartialEq, Eq, Deserialize, Serialize)]
819pub struct PrimaryProof {
820    eq_proof: PrimaryEqualProof,
821    ge_proofs: Vec<PrimaryPredicateGEProof>
822}
823
824#[derive(Debug, PartialEq, Eq, Serialize)]
825pub struct PrimaryEqualProof {
826    revealed_attrs: BTreeMap<String /* attr_name of revealed */, BigNumber>,
827    a_prime: BigNumber,
828    e: BigNumber,
829    v: BigNumber,
830    m: HashMap<String /* attr_name of all except revealed */, BigNumber>,
831    m2: BigNumber
832}
833
834impl <'a> ::serde::de::Deserialize<'a> for PrimaryEqualProof {
835    fn deserialize<D: ::serde::de::Deserializer<'a>>(deserializer: D) -> Result<Self, D::Error> {
836        #[derive(Deserialize)]
837        struct PrimaryEqualProofV1 {
838            revealed_attrs: BTreeMap<String /* attr_name of revealed */, BigNumber>,
839            a_prime: BigNumber,
840            e: BigNumber,
841            v: BigNumber,
842            m: HashMap<String /* attr_name of all except revealed */, BigNumber>,
843            #[serde(default)]
844            m1: BigNumber,
845            m2: BigNumber
846        }
847
848        let mut helper = PrimaryEqualProofV1::deserialize(deserializer)?;
849        if helper.m1 != BigNumber::default() {
850            helper.m.insert("master_secret".to_string(), helper.m1);
851        }
852        Ok(PrimaryEqualProof {
853            revealed_attrs: helper.revealed_attrs,
854            a_prime: helper.a_prime,
855            e: helper.e,
856            v: helper.v,
857            m: helper.m,
858            m2: helper.m2
859        })
860    }
861}
862
863#[derive(Debug, PartialEq, Eq, Deserialize, Serialize)]
864pub struct PrimaryPredicateGEProof {
865    u: HashMap<String, BigNumber>,
866    r: HashMap<String, BigNumber>,
867    mj: BigNumber,
868    alpha: BigNumber,
869    t: HashMap<String, BigNumber>,
870    predicate: Predicate
871}
872
873#[derive(Debug, Deserialize, Serialize)]
874pub struct NonRevocProof {
875    x_list: NonRevocProofXList,
876    c_list: NonRevocProofCList
877}
878
879#[derive(Debug)]
880pub struct InitProof {
881    primary_init_proof: PrimaryInitProof,
882    non_revoc_init_proof: Option<NonRevocInitProof>,
883    credential_values: CredentialValues,
884    sub_proof_request: SubProofRequest,
885    credential_schema: CredentialSchema,
886    non_credential_schema: NonCredentialSchema,
887}
888
889
890#[derive(Debug, Eq, PartialEq)]
891pub struct PrimaryInitProof {
892    eq_proof: PrimaryEqualInitProof,
893    ge_proofs: Vec<PrimaryPredicateGEInitProof>
894}
895
896impl PrimaryInitProof {
897    pub fn as_c_list(&self) -> Result<Vec<Vec<u8>>, IndyCryptoError> {
898        let mut c_list: Vec<Vec<u8>> = self.eq_proof.as_list()?;
899        for ge_proof in self.ge_proofs.iter() {
900            c_list.append_vec(ge_proof.as_list()?)?;
901        }
902        Ok(c_list)
903    }
904
905    pub fn as_tau_list(&self) -> Result<Vec<Vec<u8>>, IndyCryptoError> {
906        let mut tau_list: Vec<Vec<u8>> = self.eq_proof.as_tau_list()?;
907        for ge_proof in self.ge_proofs.iter() {
908            tau_list.append_vec(ge_proof.as_tau_list()?)?;
909        }
910        Ok(tau_list)
911    }
912}
913
914#[derive(Debug)]
915pub struct NonRevocInitProof {
916    c_list_params: NonRevocProofXList,
917    tau_list_params: NonRevocProofXList,
918    c_list: NonRevocProofCList,
919    tau_list: NonRevocProofTauList
920}
921
922impl NonRevocInitProof {
923    pub fn as_c_list(&self) -> Result<Vec<Vec<u8>>, IndyCryptoError> {
924        let vec = self.c_list.as_list()?;
925        Ok(vec)
926    }
927
928    pub fn as_tau_list(&self) -> Result<Vec<Vec<u8>>, IndyCryptoError> {
929        let vec = self.tau_list.as_slice()?;
930        Ok(vec)
931    }
932}
933
934#[derive(Debug, Eq, PartialEq)]
935pub struct PrimaryEqualInitProof {
936    a_prime: BigNumber,
937    t: BigNumber,
938    e_tilde: BigNumber,
939    e_prime: BigNumber,
940    v_tilde: BigNumber,
941    v_prime: BigNumber,
942    m_tilde: HashMap<String, BigNumber>,
943    m2_tilde: BigNumber,
944    m2: BigNumber,
945}
946
947impl PrimaryEqualInitProof {
948    pub fn as_list(&self) -> Result<Vec<Vec<u8>>, IndyCryptoError> {
949        Ok(vec![self.a_prime.to_bytes()?])
950    }
951
952    pub fn as_tau_list(&self) -> Result<Vec<Vec<u8>>, IndyCryptoError> {
953        Ok(vec![self.t.to_bytes()?])
954    }
955}
956
957#[derive(Debug, Eq, PartialEq)]
958pub struct PrimaryPredicateGEInitProof {
959    c_list: Vec<BigNumber>,
960    tau_list: Vec<BigNumber>,
961    u: HashMap<String, BigNumber>,
962    u_tilde: HashMap<String, BigNumber>,
963    r: HashMap<String, BigNumber>,
964    r_tilde: HashMap<String, BigNumber>,
965    alpha_tilde: BigNumber,
966    predicate: Predicate,
967    t: HashMap<String, BigNumber>,
968}
969
970impl PrimaryPredicateGEInitProof {
971    pub fn as_list(&self) -> Result<&Vec<BigNumber>, IndyCryptoError> {
972        Ok(&self.c_list)
973    }
974
975    pub fn as_tau_list(&self) -> Result<&Vec<BigNumber>, IndyCryptoError> {
976        Ok(&self.tau_list)
977    }
978}
979
980#[derive(Clone, Debug, Deserialize, Serialize)]
981pub struct NonRevocProofXList {
982    rho: GroupOrderElement,
983    r: GroupOrderElement,
984    r_prime: GroupOrderElement,
985    r_prime_prime: GroupOrderElement,
986    r_prime_prime_prime: GroupOrderElement,
987    o: GroupOrderElement,
988    o_prime: GroupOrderElement,
989    m: GroupOrderElement,
990    m_prime: GroupOrderElement,
991    t: GroupOrderElement,
992    t_prime: GroupOrderElement,
993    m2: GroupOrderElement,
994    s: GroupOrderElement,
995    c: GroupOrderElement
996}
997
998impl NonRevocProofXList {
999    pub fn as_list(&self) -> Result<Vec<GroupOrderElement>, IndyCryptoError> {
1000        Ok(vec![
1001            self.rho,
1002            self.o,
1003            self.c,
1004            self.o_prime,
1005            self.m,
1006            self.m_prime,
1007            self.t,
1008            self.t_prime,
1009            self.m2,
1010            self.s,
1011            self.r,
1012            self.r_prime,
1013            self.r_prime_prime,
1014            self.r_prime_prime_prime,
1015        ])
1016    }
1017
1018    pub fn from_list(seq: Vec<GroupOrderElement>) -> NonRevocProofXList {
1019        NonRevocProofXList {
1020            rho: seq[0],
1021            r: seq[10],
1022            r_prime: seq[11],
1023            r_prime_prime: seq[12],
1024            r_prime_prime_prime: seq[13],
1025            o: seq[1],
1026            o_prime: seq[3],
1027            m: seq[4],
1028            m_prime: seq[5],
1029            t: seq[6],
1030            t_prime: seq[7],
1031            m2: seq[8],
1032            s: seq[9],
1033            c: seq[2]
1034        }
1035    }
1036}
1037
1038#[derive(Clone, Debug, Deserialize, Serialize)]
1039pub struct NonRevocProofCList {
1040    e: PointG1,
1041    d: PointG1,
1042    a: PointG1,
1043    g: PointG1,
1044    w: PointG2,
1045    s: PointG2,
1046    u: PointG2
1047}
1048
1049impl NonRevocProofCList {
1050    pub fn as_list(&self) -> Result<Vec<Vec<u8>>, IndyCryptoError> {
1051        Ok(vec![
1052            self.e.to_bytes()?,
1053            self.d.to_bytes()?,
1054            self.a.to_bytes()?,
1055            self.g.to_bytes()?,
1056            self.w.to_bytes()?,
1057            self.s.to_bytes()?,
1058            self.u.to_bytes()?,
1059        ])
1060    }
1061}
1062
1063#[derive(Clone, Debug)]
1064pub struct NonRevocProofTauList {
1065    t1: PointG1,
1066    t2: PointG1,
1067    t3: Pair,
1068    t4: Pair,
1069    t5: PointG1,
1070    t6: PointG1,
1071    t7: Pair,
1072    t8: Pair
1073}
1074
1075impl NonRevocProofTauList {
1076    pub fn as_slice(&self) -> Result<Vec<Vec<u8>>, IndyCryptoError> {
1077        Ok(vec![
1078            self.t1.to_bytes()?,
1079            self.t2.to_bytes()?,
1080            self.t3.to_bytes()?,
1081            self.t4.to_bytes()?,
1082            self.t5.to_bytes()?,
1083            self.t6.to_bytes()?,
1084            self.t7.to_bytes()?,
1085            self.t8.to_bytes()?,
1086        ])
1087    }
1088}
1089
1090/// Random BigNumber that uses `Prover` for proof generation and `Verifier` for proof verification.
1091pub type Nonce = BigNumber;
1092
1093#[derive(Debug)]
1094pub struct VerifiableCredential {
1095    pub_key: CredentialPublicKey,
1096    sub_proof_request: SubProofRequest,
1097    credential_schema: CredentialSchema,
1098    non_credential_schema: NonCredentialSchema,
1099    rev_key_pub: Option<RevocationKeyPublic>,
1100    rev_reg: Option<RevocationRegistry>
1101}
1102
1103trait BytesView {
1104    fn to_bytes(&self) -> Result<Vec<u8>, IndyCryptoError>;
1105}
1106
1107impl BytesView for BigNumber {
1108    fn to_bytes(&self) -> Result<Vec<u8>, IndyCryptoError> {
1109        Ok(self.to_bytes()?)
1110    }
1111}
1112
1113impl BytesView for PointG1 {
1114    fn to_bytes(&self) -> Result<Vec<u8>, IndyCryptoError> {
1115        Ok(self.to_bytes()?)
1116    }
1117}
1118
1119impl BytesView for GroupOrderElement {
1120    fn to_bytes(&self) -> Result<Vec<u8>, IndyCryptoError> {
1121        Ok(self.to_bytes()?)
1122    }
1123}
1124
1125impl BytesView for Pair {
1126    fn to_bytes(&self) -> Result<Vec<u8>, IndyCryptoError> {
1127        Ok(self.to_bytes()?)
1128    }
1129}
1130
1131trait AppendByteArray {
1132    fn append_vec<T: BytesView>(&mut self, other: &Vec<T>) -> Result<(), IndyCryptoError>;
1133}
1134
1135impl AppendByteArray for Vec<Vec<u8>> {
1136    fn append_vec<T: BytesView>(&mut self, other: &Vec<T>) -> Result<(), IndyCryptoError> {
1137        for el in other.iter() {
1138            self.push(el.to_bytes()?);
1139        }
1140        Ok(())
1141    }
1142}
1143
1144fn clone_bignum_map<K: Clone + Eq + Hash>(other: &HashMap<K, BigNumber>) -> Result<HashMap<K, BigNumber>, IndyCryptoError> {
1145    let mut res = HashMap::new();
1146    for (k, v) in other.iter() {
1147        res.insert(k.clone(), v.clone()?);
1148    }
1149    Ok(res)
1150}
1151
1152
1153fn clone_credential_value_map<K: Clone + Eq + Ord>(other: &BTreeMap<K, CredentialValue>) -> Result<BTreeMap<K, CredentialValue>, IndyCryptoError> {
1154    let mut res = BTreeMap::new();
1155    for (k, v) in other {
1156        res.insert(k.clone(), v.clone()?);
1157    }
1158    Ok(res)
1159}
1160
1161#[cfg(test)]
1162mod test {
1163    use super::*;
1164    use serde_json;
1165    use self::issuer::Issuer;
1166    use self::prover::Prover;
1167    use self::verifier::Verifier;
1168
1169    #[test]
1170    fn credential_primary_public_key_conversion_works() {
1171        let string1 = r#"{
1172                 "n":"94752773003676215520340390286428145970577435379747248974837494389412082076547661891067434652276048522392442077335235388384984508621151996372559370276527598415204914831299768834758349425880859567795461321350412568232531440683627330032285846734752711268206613305069973750567165548816744023441650243801226580089078611213688037852063937259593837571943085718154394160122127891902723469618952030300431400181642597638732611518885616750614674142486169255034160093153314427704384760404032620300207070597238445621198019686315730573836193179483581719638565112589368474184957790046080767607443902003396643479910885086397579016949",
1173                 "s":"69412039600361800795429063472749802282903100455399422661844374992112119187258494682747330126416608111152308407310993289705267392969490079422545377823004584691698371089275086755756916575365439635768831063415050875440259347714303092581127338698890829662982679857654396534761554232914231213603075653629534596880597317047082696083166437821687405393805812336036647064899914817619861844092002636340952247588092904075021313598848481976631171767602864723880294787434756140969093416957086578979859382777377267118038126527549503876861370823520292585383483415337137062969402135540724590433024573312636828352734474276871187481042",
1174                 "r":{
1175                    "age":"90213462228557102785520674066817329607065098280886260103565465379328385444439123494955469500769864345819799623656302322427095342533906338563811194606234218499052997878891037890681314502037670093285650999142741875494918117023196753133733183769000368858655309319559871473827485381905587653145346258174022279515774231018893119774525087260785417971477049379955435611260162822960318458092151247522911151421981946748062572207451174079699745404644326303405628719711440096340436702151418321760375229323874027809433387030362543124015034968644213166988773750220839778654632868402703075643503247560457217265822566406481434257658",
1176                    "height":"5391629214047043372090966654120333203094518833743674393685635640778311836867622750170495792524304436281896432811455146477306501487333852472234525296058562723428516533641819658096275918819548576029252844651857904411902677509566190811985500618327955392620642519618001469964706236997279744030829811760566269297728600224591162795849338756438466021999870256717098048301453122263380103723520670896747657149140787953289875480355961166269553534983692005983375091110745903845958291035125718192228291126861666488320123420563113398593180368102996188897121307947248313167444374640621348136184583596487812048321382789134349482978",
1177                    "name":"77620276231641170120118188540269028385259155493880444038204934044861538875241492581309232702380290690573764595644801264135299029620031922004969464948925209245961139274806949465303313280327009910224580146266877846633558282936147503639084871235301887617650455108586169172459479774206351621894071684884758716731250212971549835402948093455393537573942251389197338609379019568250835525301455105289583537704528678164781839386485243301381405947043141406604458853106372019953011725448481499511842635580639867624862131749700424467221215201558826025502015289693451254344465767556321748122037274143231500322140291667454975911415",
1178                    "sex":"9589127953934298285127566793382980040568251918610023890115614786922171891298122457059996745443282235104668609426602496632245081143706804923757991602521162900045665258654877250328921570207935035808607238170708932487500434929591458680514420504595293934408583558084774019418964434729989362874165849497341625769388145344718883550286508846516335790153998186614300493752317413537864956171451048868305380731285315760405126912629495204641829764230906698870575251861738847175174907714361155400020318026100833368698707674675548636610079631382774152211885405135045997623813094890524761824654025566099289284433567918244183562578"
1179                 },
1180                 "rms": "51663676247842478814965591806476166314018329779100758392678204435864101706276421100107118776199283981546682625125866769910726045178868995629346547166162207336629797340989495021248125384357605197654315399409367101440127312902706857104045262430326903112478154165057770802221835566137181123204394005042244715693211063132775814710986488082414421678086296488865286754803461178476006057306298883090062534704773627985221339716152111236985859907502262026150818487846053415153813804554830872575193396851274528558072704096323791923604931528594861707067370303707070124331485728734993074005001622035563911923643592706985074084035",
1181                 "rctxt":"60293229766149238310917923493206871325969738638348535857162249827595080348039120693847207728852550647187915587987334466582959087190830489258423645708276339586344792464665557038628519694583193692804909304334143467285824750999826903922956158114736424517794036832742439893595716442609416914557200249087236453529632524328334442017327755310827841619727229956823928475210644630763245343116656886668444813463622336899670813312626960927341115875144198394937398391514458462051400588820774593570752884252721428948286332429715774158007033348855655388287735570407811513582431434394169600082273657382209764160600063473877124656503",
1182                 "z":"70486542646006986754234343446999146345523665952265004264483059055307042644604796098478326629348068818272043688144751523020343994424262034067120716287162029288580118176972850899641747743901392814182335879624697285262287085187745166728443417803755667806532945136078671895589773743252882095592683767377435647759252676700424432160196120135306640079450582642553870190550840243254909737360996391470076977433525925799327058405911708739601511578904084479784054523375804238021939950198346585735956776232824298799161587408330541161160988641895300133750453032202142977745163418534140360029475702333980267724847703258887949227842"
1183              }"#;
1184
1185        let string2 = r#"{
1186                 "n":"94752773003676215520340390286428145970577435379747248974837494389412082076547661891067434652276048522392442077335235388384984508621151996372559370276527598415204914831299768834758349425880859567795461321350412568232531440683627330032285846734752711268206613305069973750567165548816744023441650243801226580089078611213688037852063937259593837571943085718154394160122127891902723469618952030300431400181642597638732611518885616750614674142486169255034160093153314427704384760404032620300207070597238445621198019686315730573836193179483581719638565112589368474184957790046080767607443902003396643479910885086397579016949",
1187                 "s":"69412039600361800795429063472749802282903100455399422661844374992112119187258494682747330126416608111152308407310993289705267392969490079422545377823004584691698371089275086755756916575365439635768831063415050875440259347714303092581127338698890829662982679857654396534761554232914231213603075653629534596880597317047082696083166437821687405393805812336036647064899914817619861844092002636340952247588092904075021313598848481976631171767602864723880294787434756140969093416957086578979859382777377267118038126527549503876861370823520292585383483415337137062969402135540724590433024573312636828352734474276871187481042",
1188                 "r":{
1189                    "age":"90213462228557102785520674066817329607065098280886260103565465379328385444439123494955469500769864345819799623656302322427095342533906338563811194606234218499052997878891037890681314502037670093285650999142741875494918117023196753133733183769000368858655309319559871473827485381905587653145346258174022279515774231018893119774525087260785417971477049379955435611260162822960318458092151247522911151421981946748062572207451174079699745404644326303405628719711440096340436702151418321760375229323874027809433387030362543124015034968644213166988773750220839778654632868402703075643503247560457217265822566406481434257658",
1190                    "height":"5391629214047043372090966654120333203094518833743674393685635640778311836867622750170495792524304436281896432811455146477306501487333852472234525296058562723428516533641819658096275918819548576029252844651857904411902677509566190811985500618327955392620642519618001469964706236997279744030829811760566269297728600224591162795849338756438466021999870256717098048301453122263380103723520670896747657149140787953289875480355961166269553534983692005983375091110745903845958291035125718192228291126861666488320123420563113398593180368102996188897121307947248313167444374640621348136184583596487812048321382789134349482978",
1191                    "name":"77620276231641170120118188540269028385259155493880444038204934044861538875241492581309232702380290690573764595644801264135299029620031922004969464948925209245961139274806949465303313280327009910224580146266877846633558282936147503639084871235301887617650455108586169172459479774206351621894071684884758716731250212971549835402948093455393537573942251389197338609379019568250835525301455105289583537704528678164781839386485243301381405947043141406604458853106372019953011725448481499511842635580639867624862131749700424467221215201558826025502015289693451254344465767556321748122037274143231500322140291667454975911415",
1192                    "sex":"9589127953934298285127566793382980040568251918610023890115614786922171891298122457059996745443282235104668609426602496632245081143706804923757991602521162900045665258654877250328921570207935035808607238170708932487500434929591458680514420504595293934408583558084774019418964434729989362874165849497341625769388145344718883550286508846516335790153998186614300493752317413537864956171451048868305380731285315760405126912629495204641829764230906698870575251861738847175174907714361155400020318026100833368698707674675548636610079631382774152211885405135045997623813094890524761824654025566099289284433567918244183562578",
1193                    "master_secret": "51663676247842478814965591806476166314018329779100758392678204435864101706276421100107118776199283981546682625125866769910726045178868995629346547166162207336629797340989495021248125384357605197654315399409367101440127312902706857104045262430326903112478154165057770802221835566137181123204394005042244715693211063132775814710986488082414421678086296488865286754803461178476006057306298883090062534704773627985221339716152111236985859907502262026150818487846053415153813804554830872575193396851274528558072704096323791923604931528594861707067370303707070124331485728734993074005001622035563911923643592706985074084035"
1194                 },
1195                 "rctxt":"60293229766149238310917923493206871325969738638348535857162249827595080348039120693847207728852550647187915587987334466582959087190830489258423645708276339586344792464665557038628519694583193692804909304334143467285824750999826903922956158114736424517794036832742439893595716442609416914557200249087236453529632524328334442017327755310827841619727229956823928475210644630763245343116656886668444813463622336899670813312626960927341115875144198394937398391514458462051400588820774593570752884252721428948286332429715774158007033348855655388287735570407811513582431434394169600082273657382209764160600063473877124656503",
1196                 "z":"70486542646006986754234343446999146345523665952265004264483059055307042644604796098478326629348068818272043688144751523020343994424262034067120716287162029288580118176972850899641747743901392814182335879624697285262287085187745166728443417803755667806532945136078671895589773743252882095592683767377435647759252676700424432160196120135306640079450582642553870190550840243254909737360996391470076977433525925799327058405911708739601511578904084479784054523375804238021939950198346585735956776232824298799161587408330541161160988641895300133750453032202142977745163418534140360029475702333980267724847703258887949227842"
1197              }"#;
1198
1199        let one = serde_json::from_str::<CredentialPrimaryPublicKey>(string1).unwrap();
1200        let two = serde_json::from_str::<CredentialPrimaryPublicKey>(string2).unwrap();
1201
1202        assert_eq!(two, one);
1203    }
1204
1205    #[test]
1206    fn primary_equal_proof_conversion_works() {
1207        let string1 = r#"{
1208            "revealed_attrs":{ "name":"1139481716457488690172217916278103335" },
1209            "a_prime":"73051896986344783783621559954466052240337632808477729510525777007534198657123370460809453476237905269777928500034476888078179811369103091702326392092669222868996323974762333077146800752404116534730748685092400106417894776122280960547391515814302192999142386455183675790870578615457141270148590712693325301185445330992767208427208215818892089082206123243055148017865514286222759353929656015594529211154843197464055996993778878163967106658629893439206203941596066380562586058713924055616953462170537040600604826428201808405436865130230174790116739542071871153581967170346076628186863101926791732126528122264782281465094",
1210            "e":"26894279258848531841414955598838798345606055130059418263879278878511424413654641307014787224496208858379991228288791608261549931755104416",
1211            "v":"769593829417540943566687651216000708099616242062220026508500847265211856977241087739974159673381844796906987056271685312217722655254322996792650873775611656861273544234724432321045515309211146266498852589181986850053751764534235454974453901933962390148609111520973909072559803423360526975061164422239685006387576029266210201929872373313392190241424322333321394922891207577033519614434276723347140746548441162607411616008633618021962845423830579218345578253882839612570986096830936195064001459565147361336597305783767484298283647710212770870573787603073109857430854719681849489345098539472090186844042540487233617799636327572785715912348265648433678177765454231546725849288046905854444755145184654162149010359429569273734847400697627028832950969890252877892391103230391674009825009176344665382964776819962789472959504523580584494299815960094679820651071251157496967617834816772303813309035759721203718921501821175528106375",
1212            "m":{
1213                "age":"1143281854280323408461665818853228702279803847691030529301464848501919856277927436364331044530711281448694432838145799412204154542183613877104383361274202256495017144684827419222",
1214                "sex":"13123681697669364600723785784083768668401173003182555407713667959884184961072036088391942098105496874381346284841774772987179772727928471347011107103459387881602408580853389973314",
1215                "height":"5824877563809831190436025794795529331411852203759926644567286594845018041324472260994302109635777382645241758582661313361940262319244084725507113643699421966391425299602530147274"
1216             },
1217             "m1":"8583218861046444624186479147396651631579156942204850397797096661516116684243552483174250620744158944865553535495733571632663325011575249979223204777745326895517953843420687756433",
1218             "m2":"5731555078708393357614629066851705238802823277918949054467378429261691189252606979808518037016695141384783224302687321866277811431449642994233365265728281815807346591371594096297"
1219         }"#;
1220        let string2 = r#"{
1221            "revealed_attrs":{ "name":"1139481716457488690172217916278103335" },
1222            "a_prime":"73051896986344783783621559954466052240337632808477729510525777007534198657123370460809453476237905269777928500034476888078179811369103091702326392092669222868996323974762333077146800752404116534730748685092400106417894776122280960547391515814302192999142386455183675790870578615457141270148590712693325301185445330992767208427208215818892089082206123243055148017865514286222759353929656015594529211154843197464055996993778878163967106658629893439206203941596066380562586058713924055616953462170537040600604826428201808405436865130230174790116739542071871153581967170346076628186863101926791732126528122264782281465094",
1223            "e":"26894279258848531841414955598838798345606055130059418263879278878511424413654641307014787224496208858379991228288791608261549931755104416",
1224            "v":"769593829417540943566687651216000708099616242062220026508500847265211856977241087739974159673381844796906987056271685312217722655254322996792650873775611656861273544234724432321045515309211146266498852589181986850053751764534235454974453901933962390148609111520973909072559803423360526975061164422239685006387576029266210201929872373313392190241424322333321394922891207577033519614434276723347140746548441162607411616008633618021962845423830579218345578253882839612570986096830936195064001459565147361336597305783767484298283647710212770870573787603073109857430854719681849489345098539472090186844042540487233617799636327572785715912348265648433678177765454231546725849288046905854444755145184654162149010359429569273734847400697627028832950969890252877892391103230391674009825009176344665382964776819962789472959504523580584494299815960094679820651071251157496967617834816772303813309035759721203718921501821175528106375",
1225            "m":{
1226                "age":"1143281854280323408461665818853228702279803847691030529301464848501919856277927436364331044530711281448694432838145799412204154542183613877104383361274202256495017144684827419222",
1227                "sex":"13123681697669364600723785784083768668401173003182555407713667959884184961072036088391942098105496874381346284841774772987179772727928471347011107103459387881602408580853389973314",
1228                "height":"5824877563809831190436025794795529331411852203759926644567286594845018041324472260994302109635777382645241758582661313361940262319244084725507113643699421966391425299602530147274",
1229                "master_secret":"8583218861046444624186479147396651631579156942204850397797096661516116684243552483174250620744158944865553535495733571632663325011575249979223204777745326895517953843420687756433"
1230             },
1231             "m2":"5731555078708393357614629066851705238802823277918949054467378429261691189252606979808518037016695141384783224302687321866277811431449642994233365265728281815807346591371594096297"
1232         }"#;
1233
1234        let one = serde_json::from_str::<PrimaryEqualProof>(string1).unwrap();
1235        let two = serde_json::from_str::<PrimaryEqualProof>(string2).unwrap();
1236
1237        assert_eq!(two, one);
1238    }
1239
1240    #[test]
1241    fn demo() {
1242        let mut credential_schema_builder = Issuer::new_credential_schema_builder().unwrap();
1243        credential_schema_builder.add_attr("name").unwrap();
1244        credential_schema_builder.add_attr("sex").unwrap();
1245        credential_schema_builder.add_attr("age").unwrap();
1246        credential_schema_builder.add_attr("height").unwrap();
1247        let credential_schema = credential_schema_builder.finalize().unwrap();
1248
1249        let mut non_credential_schema_builder = NonCredentialSchemaBuilder::new().unwrap();
1250        non_credential_schema_builder.add_attr("master_secret").unwrap();
1251        let non_credential_schema = non_credential_schema_builder.finalize().unwrap();
1252
1253        let (cred_pub_key, cred_priv_key, cred_key_correctness_proof) = Issuer::new_credential_def(&credential_schema, &non_credential_schema, true).unwrap();
1254
1255        let master_secret = Prover::new_master_secret().unwrap();
1256        let credential_nonce = new_nonce().unwrap();
1257
1258        let mut credential_values_builder = Issuer::new_credential_values_builder().unwrap();
1259        credential_values_builder.add_value_hidden("master_secret", &master_secret.value().unwrap()).unwrap();
1260        credential_values_builder.add_dec_known("name", "1139481716457488690172217916278103335").unwrap();
1261        credential_values_builder.add_dec_known("sex", "5944657099558967239210949258394887428692050081607692519917050011144233115103").unwrap();
1262        credential_values_builder.add_dec_known("age", "28").unwrap();
1263        credential_values_builder.add_dec_known("height", "175").unwrap();
1264        let cred_values = credential_values_builder.finalize().unwrap();
1265
1266        let (blinded_credential_secrets, credential_secrets_blinding_factors, blinded_credential_secrets_correctness_proof) =
1267            Prover::blind_credential_secrets(&cred_pub_key,
1268                                        &cred_key_correctness_proof,
1269                                        &cred_values,
1270                                        &credential_nonce).unwrap();
1271
1272
1273
1274        let cred_issuance_nonce = new_nonce().unwrap();
1275
1276        let (mut cred_signature, signature_correctness_proof) = Issuer::sign_credential("CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW",
1277                                                                                        &blinded_credential_secrets,
1278                                                                                        &blinded_credential_secrets_correctness_proof,
1279                                                                                        &credential_nonce,
1280                                                                                        &cred_issuance_nonce,
1281                                                                                        &cred_values,
1282                                                                                        &cred_pub_key,
1283                                                                                        &cred_priv_key).unwrap();
1284
1285        Prover::process_credential_signature(&mut cred_signature,
1286                                             &cred_values,
1287                                             &signature_correctness_proof,
1288                                             &credential_secrets_blinding_factors,
1289                                             &cred_pub_key,
1290                                             &cred_issuance_nonce,
1291                                             None,
1292                                             None,
1293                                             None).unwrap();
1294
1295        let mut sub_proof_request_builder = Verifier::new_sub_proof_request_builder().unwrap();
1296        sub_proof_request_builder.add_revealed_attr("name").unwrap();
1297        sub_proof_request_builder.add_predicate("age", "GE", 18).unwrap();
1298        let sub_proof_request = sub_proof_request_builder.finalize().unwrap();
1299        let mut proof_builder = Prover::new_proof_builder().unwrap();
1300        proof_builder.add_common_attribute("master_secret").unwrap();
1301        proof_builder.add_sub_proof_request(&sub_proof_request,
1302                                            &credential_schema,
1303                                            &non_credential_schema,
1304                                            &cred_signature,
1305                                            &cred_values,
1306                                            &cred_pub_key,
1307                                            None,
1308                                            None).unwrap();
1309
1310        let proof_request_nonce = new_nonce().unwrap();
1311        let proof = proof_builder.finalize(&proof_request_nonce).unwrap();
1312
1313        let mut proof_verifier = Verifier::new_proof_verifier().unwrap();
1314        proof_verifier.add_sub_proof_request(&sub_proof_request,
1315                                             &credential_schema,
1316                                             &non_credential_schema,
1317                                             &cred_pub_key,
1318                                             None,
1319                                             None).unwrap();
1320        assert!(proof_verifier.verify(&proof, &proof_request_nonce).unwrap());
1321    }
1322
1323    #[test]
1324    fn demo_revocation() {
1325        let mut credential_schema_builder = Issuer::new_credential_schema_builder().unwrap();
1326        credential_schema_builder.add_attr("name").unwrap();
1327        credential_schema_builder.add_attr("sex").unwrap();
1328        credential_schema_builder.add_attr("age").unwrap();
1329        credential_schema_builder.add_attr("height").unwrap();
1330        let credential_schema = credential_schema_builder.finalize().unwrap();
1331
1332        let mut non_credential_schema_builder = NonCredentialSchemaBuilder::new().unwrap();
1333        non_credential_schema_builder.add_attr("master_secret").unwrap();
1334        let non_credential_schema = non_credential_schema_builder.finalize().unwrap();
1335
1336        let (cred_pub_key, cred_priv_key, cred_key_correctness_proof) = Issuer::new_credential_def(&credential_schema, &non_credential_schema, true).unwrap();
1337
1338        let max_cred_num = 5;
1339        let issuance_by_default = false;
1340        let (rev_key_pub, rev_key_priv, mut rev_reg, mut rev_tails_generator) =
1341            Issuer::new_revocation_registry_def(&cred_pub_key, max_cred_num, issuance_by_default).unwrap();
1342
1343        let simple_tail_accessor = SimpleTailsAccessor::new(&mut rev_tails_generator).unwrap();
1344
1345        let master_secret = Prover::new_master_secret().unwrap();
1346
1347        let credential_nonce = new_nonce().unwrap();
1348
1349        let mut credential_values_builder = Issuer::new_credential_values_builder().unwrap();
1350        credential_values_builder.add_value_hidden("master_secret", &master_secret.value().unwrap()).unwrap();
1351        credential_values_builder.add_dec_known("name", "1139481716457488690172217916278103335").unwrap();
1352        credential_values_builder.add_dec_known("sex", "5944657099558967239210949258394887428692050081607692519917050011144233115103").unwrap();
1353        credential_values_builder.add_dec_known("age", "28").unwrap();
1354        credential_values_builder.add_dec_known("height", "175").unwrap();
1355        let cred_values = credential_values_builder.finalize().unwrap();
1356
1357        let (blinded_credential_secrets, credential_secrets_blinding_factors, blinded_credential_secrets_correctness_proof) =
1358            Prover::blind_credential_secrets(&cred_pub_key,
1359                                        &cred_key_correctness_proof,
1360                                        &cred_values,
1361                                        &credential_nonce).unwrap();
1362
1363
1364
1365        let credential_issuance_nonce = new_nonce().unwrap();
1366
1367        let rev_idx = 1;
1368        let (mut cred_signature, signature_correctness_proof, rev_reg_delta) =
1369            Issuer::sign_credential_with_revoc("CnEDk9HrMnmiHXEV1WFgbVCRteYnPqsJwrTdcZaNhFVW",
1370                                               &blinded_credential_secrets,
1371                                               &blinded_credential_secrets_correctness_proof,
1372                                               &credential_nonce,
1373                                               &credential_issuance_nonce,
1374                                               &cred_values,
1375                                               &cred_pub_key,
1376                                               &cred_priv_key,
1377                                               rev_idx,
1378                                               max_cred_num,
1379                                               issuance_by_default,
1380                                               &mut rev_reg,
1381                                               &rev_key_priv,
1382                                               &simple_tail_accessor).unwrap();
1383
1384        let witness = Witness::new(rev_idx, max_cred_num, issuance_by_default, &rev_reg_delta.unwrap(), &simple_tail_accessor).unwrap();
1385
1386        Prover::process_credential_signature(&mut cred_signature,
1387                                             &cred_values,
1388                                             &signature_correctness_proof,
1389                                             &credential_secrets_blinding_factors,
1390                                             &cred_pub_key,
1391                                             &credential_issuance_nonce,
1392                                             Some(&rev_key_pub),
1393                                             Some(&rev_reg),
1394                                             Some(&witness)).unwrap();
1395
1396        let mut sub_proof_request_builder = Verifier::new_sub_proof_request_builder().unwrap();
1397        sub_proof_request_builder.add_revealed_attr("name").unwrap();
1398        sub_proof_request_builder.add_predicate("age", "GE", 18).unwrap();
1399        let sub_proof_request = sub_proof_request_builder.finalize().unwrap();
1400        let mut proof_builder = Prover::new_proof_builder().unwrap();
1401        proof_builder.add_common_attribute("master_secret").unwrap();
1402        proof_builder.add_sub_proof_request(&sub_proof_request,
1403                                            &credential_schema,
1404                                            &non_credential_schema,
1405                                            &cred_signature,
1406                                            &cred_values,
1407                                            &cred_pub_key,
1408                                            Some(&rev_reg),
1409                                            Some(&witness)).unwrap();
1410        let proof_request_nonce = new_nonce().unwrap();
1411        let proof = proof_builder.finalize(&proof_request_nonce).unwrap();
1412
1413        let mut proof_verifier = Verifier::new_proof_verifier().unwrap();
1414        proof_verifier.add_sub_proof_request(&sub_proof_request,
1415                                             &credential_schema,
1416                                             &non_credential_schema,
1417                                             &cred_pub_key,
1418                                             Some(&rev_key_pub),
1419                                             Some(&rev_reg)).unwrap();
1420        assert_eq!(true, proof_verifier.verify(&proof, &proof_request_nonce).unwrap());
1421    }
1422}