Concepts
Anonymous credentials in OpenAC
OpenAC is a proof layer over existing issuer-signed credentials. The credential (today: SD-JWT VC in the PoC) is issued and signed by an existing issuer — OpenAC does not change that. What OpenAC adds is zero-knowledge so verifiers learn only policy outputs and agreed public data, not raw attributes.
The three-phase pipeline: Prepare → Reblind → Show
OpenAC splits credential-dependent proof work from request-dependent proof work:
| Phase | What happens | When | In SDK (openac-sdk 0.1.0) | In Rust CLI |
|---|---|---|---|---|
| Prepare | Parse credential, verify issuer signature, commit to message vector. Independent of any specific request or verifier. | Once per credential (offline, cacheable). | precompute(...) | prepare … |
| Reblind | Re-randomize the prepared state. Refreshes the hidden representation before presentation to break cross-session linkability. | Before each Show. | Inside present(...) | prepare reblind / show reblind |
| Show | Bind to verifier nonce, prove device key ownership, evaluate predicates, link to Prepare commitment. | Per presentation (online). | present(...) | show … |
The Prepare–Reblind–Show pipeline is described in Paper §3 and specified in Implementation profile §4.3.
Prepare output is wallet-local state. It is never sent to the verifier as a standalone artifact. Only the Show output (the OpenAC response) reaches the verifier.
OpenAC acceptance vs final relying-party acceptance
This distinction matters for verifier integration:
| Result | Meaning |
|---|---|
| OpenAC acceptance | The proof verifies, the response is bound to the request, freshness checks pass, and the proven statement has the defined meaning. This is the proof-layer result. |
| Final relying-party acceptance | Also requires: issuer trust validation, credential status/revocation check, relying-party authentication, user approval, and service policy. OpenAC acceptance is necessary but not sufficient. |
For the full boundary definition see Implementation profile §1.3 and §10.
Commitments and Prepare–Show linking
The paper's preliminaries / commitments section describes Hyrax-style Pedersen vector commitments that link Prepare and Show. Prepare commits to the message vector; Show proves predicates over that same vector without re-revealing it. The verifier checks that the Show proof uses the same credential-derived messages accepted by Prepare by comparing these commitments.
See Prepare phase for the commitment notation.
Credential bindings
Before OpenAC can process a credential, the wallet must bind it: identify which values are covered by issuer authentication. Only those values can become OpenAC statement input. Values used for trust validation, status checks, validity, or device binding remain separate.
Supported credential families:
- SD-JWT VC — the PoC's primary path; Prepare parses the SD-JWT into messages, salts, hashes, and issuer signature.
- ISO/IEC 18013-5 (mdoc) — experimental;
wallet-unit-poc/circomincludes anmdoccompile target.
See Credential formats and Implementation profile §5.
Predicates
Claims are mapped to field elements for the Show circuit. Predicate operations match the Circom circuit (LE, GE, EQ) via numeric codes in PredicateOp. Boolean structure uses postfix tokens (LogicToken).
Predicate success is not disclosure — the verifier learns only the evaluation result, not the underlying claim value. See Generalized predicates.
Revocation (status)
In-wallet scenario tooling distinguishes no revocation, out-of-band, and in-proof (future) — see openac-studio rules. There is no integrated cryptographic revocation tree in this repository yet; see Revocation overview.
A valid OpenAC proof does not by itself imply a non-revoked credential unless a revocation statement type is explicitly declared and included.
EUDI mapping
OpenAC is positioned for EUDI ARF compatibility. OpenAC does not replace any part of the EUDI Wallet transaction; it adds a proof layer inside it. A reading guide and requirement-family table live at EUDI mapping.
Glossary
| Term | Meaning |
|---|---|
| SD-JWT / SD-JWT VC | Selective-disclosure JWT; disclosures are separate base64url blobs ([salt, name, value] triples). Defined by draft-ietf-oauth-sd-jwt-vc. |
cnf.jwk | Holder device binding public key inside the JWT payload. Required for precompute in the SDK. |
VcSize | JWT circuit payload bucket: '1k', '2k', '4k', '8k' for key loading. Choose based on worst-case JWT length. |
| Spartan2 | Transparent zkSNARK used by ecdsa-spartan2 (Setty, CRYPTO 2020). |
| prepared state | Wallet-local output of Prepare. Not sent to verifiers. Must be refreshed before each Show. |
| prepared-state pool | Stored collection of prepared states produced by offline Prepare and re-randomization. |
| Reblind | Re-randomization of prepared state before Show. Breaks cross-session linkability. |
| OpenAC acceptance | Proof-layer result: the proof verifies, request binding holds, freshness passes, statement meaning is defined. Not equal to final relying-party acceptance. |
| predicate proof | A verifiable computation where only the result (pass/fail) is shared, not the underlying claim value. |
| witness | Private prover data used to prove a relation is satisfied. Never sent to the verifier. |
| PID | Person Identification Data (ARF §5.2.2). External credential input; OpenAC does not redefine it. |
| Wallet Unit | EUDI deployment role for OpenAC proof generation (ARF §4.3.2). |
| Relying Party Instance | Technical endpoint that interacts with the Wallet Unit (ARF §3.11.2). |
| nullifier | A value derived from a credential and application scope used to prevent duplicate acceptance. Not part of baseline OpenAC — a declared extension. |
Commitment notation
The exact Pedersen vector commitment used by Prepare/Show is defined on the Prepare phase page, matching Paper §Preliminaries.