diff --git a/spec/anoncreds_conventions.md b/spec/anoncreds_conventions.md index 96cbbb3..1ebc107 100644 --- a/spec/anoncreds_conventions.md +++ b/spec/anoncreds_conventions.md @@ -1,5 +1,69 @@ ## AnonCreds Conventions -::: todo -Cover conventions like encoding claims, date handling for predicates and revocation status requests -::: +Over the years of using Hyperledger AnonCreds, several conventions (listed here) have been defined can or must be used +in deploying AnonCreds. The conventions are not required in the current [AnonCreds implementation], but +are necessary to follow for interoperability with other AnonCreds implementations. + +[AnonCreds implementation]: https://github.com/hyperledger/anoncreds-rs + +### Encoding Credential Claims + +As described in this specification, the claim data that is actually signed in +producing an AnonCreds verifiable credential is not the "raw", human-readable +data of the claims, but rather an integer derived from the raw data. The act of +encoding the data was defined to be done by the issuer. However, unless the +issuer implements exactly the encoding expected by all others in an ecosystem, +the signatures produced for a presentation will not verify. Thus, although the +issuer is nominally in control of the encoding, practically, all issuers MUST +follow the [encoding defined in this specification](#encoding-attribute-data). + +In a future version of AnonCreds we expect to move the encoding process away +from the issuer and into AnonCreds. + +### Date and Date/Time Predicates + +A powerful capability in AnonCreds is the ability to use predicates on dates, +such as proving based on a date of birth (a strongly correlatable value) that a +person is older than a certain age without revealing the date of birth. However, +because of [how credential claims are encoded](#encoding-credential-claims) +(above), for a date-based predicate to work, the date must be an integer. Thus, +a "date of birth" claim in an [ISO 8601 Standard Date +String](https://www.iso.org/iso-8601-date-and-time-format.html) will not be able +to be used in a predicate. Rather, the convention of the AnonCreds community has +been to put the data into the form of the date as an integer of value `YYYYMMDD` +This convention was initially defined +[here](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0441-present-proof-best-practices#dates-and-predicates) +by the [Hyperledger Aries](https://www.hyperledger.org/projects/aries) +community. + +For the same reasons, AnonCreds `datetime` claims that are to be used in predicates +SHOULD be issued in [Unix Time](https://en.wikipedia.org/wiki/Unix_time) format. + +In a future version of AnonCreds we expect to define the type of each claim in a +credential so that the `date` and `datetime` values as strings can be +automatically encoded as integers and Unix Time values (respectively). This +enables supporting both human-friendly displaying of the claims as well as +support for predicates. + +### Presentation Request Revocation Intervals + +While the AnonCreds [[ref: Presentation Request]] format allows the flexible +application of `from` to `to` ranges for when the [[ref: Holder]] must prove +their credential was not revoked, those deploying AnonCreds have found that it is +rarely practical or necessary to use such flexibility, and the best practices +are to set the two values (`from`, `to`) to be the same in [[ref: Presentation +Requests]]. For [[ref: Verifiers]] interested in the current revocation status +of the credential, both values should be set to the current time, while if the +verifier wants to see the revocation status of the credential at some point in +the past, both values should be set to point in time. + +Details about this convention can be found in the [Presentation Request section +of this specification](#request-non-revocation-proofs). + +Since the [[ref:Holder]] must prove non-revocation based on a [[ref: Revocation +Registry Entry]] published by the issuer, the actual interval that the [[ref: +Holder]] must use is not `from` to `to`, but rather from the [[ref: Revocation +Registry Entry]] active at time `from` to the [[ref: Revocation Registry Entry]] +active at time `to`, where "time" is as determined by the transaction times +recorded at the location on which the issuer published the [[ref: Revocation +Registry]]. diff --git a/spec/data_flow_presentation_verify.md b/spec/data_flow_presentation_verify.md index eef8312..e5364c2 100644 --- a/spec/data_flow_presentation_verify.md +++ b/spec/data_flow_presentation_verify.md @@ -29,43 +29,44 @@ verification process, as noted below. Finally, an important part of the verification process is **not** carried out in AnonCreds v1.0 and must be performed by the calling [[ref: verifier]]. We highlight that as well. -#### Verify `eq_proof` - -An AnoncCreds `eq_proof` is the proof of the signature over the entire source credential. -As noted, there is one `eq_proof` for each source credential in the -presentation. The cryptographic processing that verifies the signature over the -encoded data values is described here. - -::: todo - -Add the eq_proof verification process - -::: - -#### Verify `ge_proof` - -An AnoncCreds `ge_proof` is the proof of the predicates (if any) derived from the source credential. -As noted, there is one `ge_proof` for each predicate from each source credential in the -presentation. The cryptographic processing that verifies the predicate is described here. - -::: todo - -Add the ge_proof verification process - -::: - -#### Verify `aggregate_proof` - -The AnoncCreds `aggregate_proof` is the proof that the blinded link secrets in -each of the source credentials were derived from the same link secret, binding -credentials to that one linked secret. The cryptographic processing that verifies -the predicate is described here. - -::: todo - -Add the aggregate_proof verification process - -::: +#### Verify Validity Proofs + +An AnoncCreds validity proof is the combination of both equality and inequality predicate proofs. The validity proof is bound to the primary credential by the $\widehat{m_2}$ value that is presented in both proofs. The validity proof is verified by the following steps: + +- For each credential $C_p$, take each sub-proof $Pr_C$ and compute +$$ \widehat{T} \leftarrow \left( + \frac{Z} + { \left( + \prod_{j \in \mathcal{A}_r}{R_j}^{m_j} + \right) + (A')^{2^{596}} + }\right)^{-c} + (A')^{\widehat{e}} + \left(\prod_{j\in (\mathcal{A}_{\widetilde{r}})}{R_j}^{\widehat{m_j}}\right) + (S^{\widehat{v}})\pmod{n}. $$ +Add $\widehat{T}$ to $\widehat{\mathcal{T}}$ . + +- For each predicate $p$: +$$ \Delta' \leftarrow \begin{cases} +z_j; & if\ * \equiv\ \leq +z_j-1; & if\ * \equiv\ < +z_j; & if\ * \equiv\ \geq +z_j+1; & if\ * \equiv\ > +\end{cases} $$ +$$ +a \leftarrow \begin{cases} +-1 & if\ * \equiv \leq or < +1 & if\ * \equiv \geq or > +\end{cases} +$$ + +- Using $Pr_p$ and $\mathcal{C}$ compute +$$ +\widehat{T_i} \leftarrow T_i^{-c}Z^{\widehat{u_i}} S^{\widehat{r_i}}\pmod{n}_{1\leq i \leq 4}; +\widehat{T_{\Delta}} \leftarrow \left(T_{\Delta}^{a}Z^{\Delta'}\right)^{-c}Z^{\widehat{m_j}}S^{a\widehat{r_{\Delta}}}\pmod{n}; +\widehat{Q}\leftarrow (T_{\Delta}^{-c})\prod_{i=1}^{4}T_i^{\widehat{u_i}}(S^{\widehat{\alpha}})\pmod{n}, +$$ +and add these values to $\widehat{\mathcal{T}}$ in the order $\widehat{T_1},\widehat{T_2} ,\widehat{T_3},\widehat{T_4},\widehat{T_{\Delta}},\widehat{Q}$. #### Verify Non-Revocation Proof @@ -104,7 +105,7 @@ $$\widehat{T_6} \leftarrow D^{\widehat{r''}}\cdot g^{-\widehat{m'}} \widetilde{ $$\widehat{T_7} \leftarrow \left(\frac{e(pk\cdot\mathcal{G},\mathcal{S})}{e(g,g')}\right)^{c_H}\cdot e(pk\cdot \mathcal{G},\widehat{h})^{\widehat{r''}}\cdot e(\widetilde{h},\widehat{h})^{-\widehat{m'}}\cdot e(\widetilde{h},\mathcal{S})^{\widehat{r}}$$ $$\widehat{T_8} \leftarrow \left(\frac{e(\mathcal{G},u)}{e(g,\mathcal{U})}\right)^{c_H}\cdot e(\widetilde{h},u)^{\widehat{r}}\cdot e(1/g,\widehat{h})^{\widehat{r'''}}$$ -Then all these values are added to $\widehat{T}$. This is then added with the validity proof which when hashed with $\mathcal{C}$ and $n_1$(recieved from [[ref: holder]]) re constructs the challenge hash $\widehat{c_H}$ +Then all these values are added to $\widehat{T}$. This is then added with the validity proof which when hashed with $\mathcal{C}$ and $n_1$(received from [[ref: holder]]) re constructs the challenge hash $\widehat{c_H}$. If $\widehat{c_H} = c_H$, then the proof is valid. The NRP is bound to the primary credential by the $\widehat{m_2}$ value that is presented in both proofs.