Longfellow ZK 0290cb32
Loading...
Searching...
No Matches
mdoc_zk.h
1// Copyright 2025 Google LLC.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef PRIVACY_PROOFS_ZK_LIB_CIRCUITS_MDOC_MDOC_ZK_H_
16#define PRIVACY_PROOFS_ZK_LIB_CIRCUITS_MDOC_MDOC_ZK_H_
17
18#include <stddef.h>
19#include <stdint.h>
20
21#ifdef __cplusplus
22extern "C" {
23#endif
24
25// This package implements C interfaces that allow external programs to call
26// the zk mdoc-based prover and verifier.
27//
28// It also contains a helper method that produces a byte representation
29// of a circuit which verifies the mdoc with regards to specific properties,
30// for example age_over_18. The circuit generation can be run once, and the
31// result cached for subsequent use in the prover and verifier.
32
33enum CborAttributeType { kPrimitive, kString, kBytes, kDate, kInt };
34
35/* This struct allows a verifier to express which attribute and value the prover
36 * must claim. */
37typedef struct {
38 uint8_t id[32];
39 uint8_t value[64];
40 size_t id_len, value_len;
41 CborAttributeType type;
43
44// Return codes for the run_mdoc2_prover method.
45typedef enum {
46 MDOC_PROVER_SUCCESS = 0,
47 MDOC_PROVER_NULL_INPUT,
48 MDOC_PROVER_INVALID_INPUT,
49 MDOC_PROVER_CIRCUIT_PARSING_FAILURE,
50 MDOC_PROVER_HASH_PARSING_FAILURE,
51 MDOC_PROVER_WITNESS_CREATION_FAILURE,
52 MDOC_PROVER_GENERAL_FAILURE,
53 MDOC_PROVER_MEMORY_ALLOCATION_FAILURE,
54 MDOC_PROVER_INVALID_ZK_SPEC_VERSION,
55} MdocProverErrorCode;
56
57// Return codes for the run_mdoc2_verifier method.
58typedef enum {
59 MDOC_VERIFIER_SUCCESS = 0,
60 MDOC_VERIFIER_CIRCUIT_PARSING_FAILURE,
61 MDOC_VERIFIER_PROOF_TOO_SMALL,
62 MDOC_VERIFIER_HASH_PARSING_FAILURE,
63 MDOC_VERIFIER_SIGNATURE_PARSING_FAILURE,
64 MDOC_VERIFIER_GENERAL_FAILURE,
65 MDOC_VERIFIER_NULL_INPUT,
66 MDOC_VERIFIER_INVALID_INPUT,
67 MDOC_VERIFIER_ARGUMENTS_TOO_SMALL,
68 MDOC_VERIFIER_ATTRIBUTE_NUMBER_MISMATCH,
69 MDOC_VERIFIER_INVALID_ZK_SPEC_VERSION,
70} MdocVerifierErrorCode;
71
72// Return codes for the generate_circuit method.
73typedef enum {
74 CIRCUIT_GENERATION_SUCCESS = 0,
75 CIRCUIT_GENERATION_NULL_INPUT,
76 CIRCUIT_GENERATION_ZLIB_FAILURE,
77 CIRCUIT_GENERATION_GENERAL_FAILURE,
78 CIRCUIT_GENERATION_INVALID_ZK_SPEC_VERSION,
79} CircuitGenerationErrorCode;
80
81// This structure represents a version of ZK specification supported by this
82// library. It is passed into all the methods for circuit generation, running
83// the prover and verifier.
84// It allows us to version the specification of the ZK system. The prover and
85// the verifier are supposed to negotiate the version of the specification they
86// both support before executing digital credential presentment.
87typedef struct {
88 // The ZK system name and version- "longfellow-libzk-v*" for Google library.
89 const char* system;
90 // The hash of the compressed circuit (the way it's generated and passed to
91 // prover/verifier)
92 const char circuit_hash[65];
93 // The number of attributes that the circuit supports.
94 size_t num_attributes;
95 // The version of the ZK specification.
96 size_t version;
98
99static const char kDefaultDocType[] = "org.iso.18013.5.1.mDL";
100
101// The run_mdoc2_prover method takes byte-oriented inputs that describe a
102// circuit, mdoc, the public key of the issuer for the mdoc, a transcript
103// for the mdoc request operation, an array of RequestedAttribute that
104// represents claims that you want to prove, and a 20-char representation of the
105// current time. It writes the proof and its length into the input parameter prf
106// and proof_len. It is the responsibility of the caller to later free the proof
107// memory. If the prover fails to produce a proof, e.g., because the mdoc is
108// invalid, or the now time does not satisfy the validFrom and validUntil
109// constraints, then the prover returns an error code.
110// The following lines document how attributes can be opened in ZK.
111// {(uint8_t *)"family_name", 11, (uint8_t *)"Mustermann", 10},
112// {(uint8_t *)"height", 6, (uint8_t *)"\x18\xaf", 2},
113// {(uint8_t *)"birth_date", 10, (uint8_t *)"\xD9\x03\xEC\x6A" "1971-09-01",
114// 14},
115// {(uint8_t *)"issue_date", 10, (uint8_t *)"\xD9\x03\xEC\x6A" "2024-03-15",
116// 14},
117MdocProverErrorCode run_mdoc_prover(
118 const uint8_t* bcp, size_t bcsz, /* circuit data */
119 const uint8_t* mdoc, size_t mdoc_len, /* full mdoc */
120 const char* pkx, const char* pky, /* string rep of public key */
121 const uint8_t* transcript, size_t tr_len, /* session transcript */
122 const RequestedAttribute* attrs, size_t attrs_len,
123 const char* now, /* time formatted as "2023-11-02T09:00:00Z" */
124 uint8_t** prf, size_t* proof_len, const ZkSpecStruct* zk_spec_version);
125
126// The run_mdoc2_verifier method accepts a byte representation of the circuit,
127// the public key of the issuer, the transcript, an array of RequestedAttribute
128// that represents claims that you want to verify, and a 20-char representation
129// of the time, as well as the proof and its length.
130MdocVerifierErrorCode run_mdoc_verifier(
131 const uint8_t* bcp, size_t bcsz, /* circuit data */
132 const char* pkx, const char* pky, /* string rep of public key */
133 const uint8_t* transcript, size_t tr_len, /* session transcript */
134 const RequestedAttribute* attrs, size_t attrs_len,
135 const char* now, /* time formatted as "2023-11-02T09:00:00Z" */
136 const uint8_t* zkproof, size_t proof_len, const char* docType,
137 const ZkSpecStruct* zk_spec_version);
138
139// Produces a compressed version of the circuit bytes for the specified number
140// of attributes.
141CircuitGenerationErrorCode generate_circuit(const ZkSpecStruct* zk_spec_version,
142 uint8_t** cb, size_t* clen);
143
144// Produces an identifier for a pair of circuits (c_1, c_2) over (Fp256, f_128)
145// respectively. This method parses the input bytes into two circuits, computes
146// the circuit's ids of each, and then computes the SHA256 hash of the two ids.
147// This method is used to identify "circuit bundles" consisting of multiple
148// circuits.
149int circuit_id(uint8_t id[/*kSHA256DigestSize*/], const uint8_t* bcp,
150 size_t bcsz, const ZkSpecStruct* zk_spec);
151
152enum { kNumZkSpecs = 12 };
153// This is a hardcoded list of all the ZK specifications supported by this
154// library. Every time a new breaking change is introduced in either the circuit
155// format or its interpretation, a new version must be added here.
156// It is possible to remove old versions, if we're sure that they are not used
157// by either provers of verifiers in the wild.
158extern const ZkSpecStruct kZkSpecs[kNumZkSpecs];
159
160// Returns a static pointer to the ZkSpecStruct that matches the given system
161// name and circuit hash. Returns nullptr if no matching ZkSpecStruct is found.
162const ZkSpecStruct* find_zk_spec(const char* system_name,
163 const char* circuit_hash);
164
165#ifdef __cplusplus
166}
167#endif
168
169#endif // PRIVACY_PROOFS_ZK_LIB_CIRCUITS_MDOC_MDOC_ZK_H_
Definition mdoc_zk.h:37
Definition mdoc_zk.h:87