Skip to content

uvdsl/rdf-zkp-sparql

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

35 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SPARQL on Verifiable Credentials to derive presentations with Zero-Knowledge Proofs

This work extends the prior art by dynamically generating composite proofs based on an input SPARQL query. That is, given a SPARQL query, the datasets that are used to answer the query will be selectively disclosed to the extent necessary to satisfy the query. So, rather than proving the execution of a SPARQL query in zero-knowledge or proving existence of solution bindings, we produce a result dataset that (a) contains all the solution bindings to the SPARQL query and (b) proves knowledge of undisclosed terms (i.e. not selected variables).

We can

  • hide or reveal individual terms in digitally signed datasets, and prove knowledge of the datasets' signatures
  • prove equality of (occurrences of) individual terms in and across such datasets
  • or hide that equality between occurrences of individual terms
  • prove numeric bounds (within u64 range) of xsd:integer and xsd:dateTime literals (only positive numbers supported atm)
  • prove numeric bounds (within i32 range) of xsd:integer and xsd:dateTime literals (which is a simple modification)

This is an experimental proof-of-concept, not a library.

Repository Structure

  • benches/ - Benchmark suite.
    • risc0 SPARQL verification baseline (adapted from publicly available "SPARQL-in-zkVM" implementations).
    • zkSPARQL bench suite (adapted from existing zkSPARQL benchmarks and normalized to TriG notation).
  • data/ some example datasets to play around with when executing a bin
  • src/ source code.
    • bin/ examples that you can execute.
    • poc/ proof of concept implementations of the different procedures (issue,prove,verify)
    • rdf4zkp functions for encoding RDF to field representations.
    • zkp4rdf functions for transforming zkp related variables and values to RDF.

Example

For example (assume prefixes to be set):

Assume there is a digitally signed dataset, e.g., a Verifiable Credential like

# e.g. for an internship
[] a org:Membership;
  org:member <http://example.org/users#user123>;
  org:organization <http://example.org/organisations#aCompany> ;
  time:hasBeginning "2024-01-01T00:00:00Z"^^xsd:dateTimeStamp ;
  time:hasEnd "2025-12-31T23:59:59Z"^^xsd:dateTimeStamp .

# BBS+ signature by the issuer  and additional VC terms are omitted for brevity.

and another one like

# to show range proof on integers work
<http://example.org/users#user123> foaf:age 25.

# BBS+ signature by the issuer and additional VC terms are omitted for brevity.

Now assume a SPARQL query (for the sake of the example)

SELECT ?org WHERE {
  ?user foaf:age ?age .
  ?membership org:member ?user.
  ?membership org:organization ?org .
  ?membership time:hasEnd ?endDate .
  FILTER(?endDate > xsd:dateTime("2025-10-01T00:00:00Z") )
  FILTER(?age <= 25 )
}

The full result can be found here, here an excerpt:

GRAPH _:0_4 {
	_:0_0 _:0_1 _:0_2 .
	_:0_5 _:0_6 _:0_7 .
	_:0_10 time:hasEnd _:0_12 .
	_:0_10 org:member _:0_17 .
	_:0_10 org:organization <http://example.org/organisations#aCompany> .
}
GRAPH _:2_4 {
	_:0_17 foaf:age _:2_2 .
}
GRAPH _:presentationProofGraph {
	_:cproof rdf:type zkp:CompositeProof .
	_:cproof zkp:hasComponent _:p0 .
	_:cproof zkp:hasComponent _:p1 .
	_:cproof zkp:hasComponent _:p2 .
	_:cproof zkp:hasComponent _:p3 .
	_:p0 rdf:type bbsp16:PoKS16 .
	_:p1 rdf:type lg16:LegoGroth16ProofOfRangeMembership .
	_:p2 rdf:type bbsp16:PoKS16 .
	_:p3 rdf:type lg16:LegoGroth16ProofOfRangeMembership .
	# more proof details omitted
}

Note that _:0_17 is re-used across graphs. The proof includes the fact that all occurrences of _:0_17 refers to the same underlying secret value, the identifier of the user. To this end, two proofs of knowledge of signature are needed; one for each respective original graph of _:0_4 and _:2_4. The two additional proofs are the proofs of numeric bounds of _:0_12, the end time of the membership, and of _:2_2, the age of the user.
Note that the company's identifier is revealed, as requested in the SELECT statement of the query.

All other information are only proven to be true:

  • the signatures of the graphs are proven to be valid,
  • the graphs' triples are proven to be known, without needing to reveal terms.
  • the numeric bounds as per the FILTER statements are proven to be fulfilled without revealing the literal.
  • the relations between user and organisation are proven to exist without revealing the membership identifier

Only information explicitly requested (or previously known as the IRIs) in the query are revealed, while still being proven to have been signed. For example, note that in the first two triples of graph _:0_4, we do not reveal that their subjects are actually the same value that also underlies _:0_10.

Run it yourself

# set up the repo
git clone <repo-url>
cd <repo>

cargo run --bin issuer
cargo run --bin prover
cargo run --bin verifier
# benchmark the performance 
cargo bench

# or just one at a time
cargo bench --bench risc0-bench
cargo bench --bench zkSPARQL-bench

We used the rust compiler rustc 1.88.0 (6b00bc388 2025-06-23).

Or use the Dockerfile

docker build -t sparql-zkp-demo .
docker run --rm sparql-zkp-demo

Please cite this work by referring to

Christoph H.-J. Braun, Jesse Wright, Tobias Käfer: Proving Soundness of SPARQL Query Results Using Selective Disclosure of RDF Datasets and Zero-Knowledge Proofs. ESWC (1) 2026: 297-318

or use the following BibTeX record

@inproceedings{DBLP:conf/esws/BraunWK26,
  author       = {Christoph H.{-}J. Braun and
                  Jesse Wright and
                  Tobias K{\"{a}}fer},
  editor       = {Maribel Acosta and
                  Marieke van Erp and
                  Sebastian Rudolph and
                  Olaf Hartig and
                  Blerina Spahiu and
                  Anisa Rula and
                  Daniel Garijo and
                  Francesco Osborne},
  title        = {Proving Soundness of {SPARQL} Query Results Using Selective Disclosure
                  of {RDF} Datasets and Zero-Knowledge Proofs},
  booktitle    = {The Semantic Web - 23rd European Semantic Web Conference, {ESWC} 2026,
                  Dubrovnik, Croatia, May 10-14, 2026, Proceedings, Part {I}},
  series       = {Lecture Notes in Computer Science},
  pages        = {297--318},
  publisher    = {Springer},
  year         = {2026},
  url          = {https://doi.org/10.1007/978-3-032-25156-5\_16},
  doi          = {10.1007/978-3-032-25156-5\_16},
  timestamp    = {Wed, 20 May 2026 08:34:03 +0200},
  biburl       = {https://dblp.org/rec/conf/esws/BraunWK26.bib},
  bibsource    = {dblp computer science bibliography, https://dblp.org}
}

About

Given a SPARQL query, derive composite zero-knowledge proofs (ZKPs) on the underlying RDF graphs.

Resources

Stars

Watchers

Forks

Contributors