From 50f22a2eca170ccdd7c49cfd0e25654a63460087 Mon Sep 17 00:00:00 2001 From: Luca Giussani Date: Fri, 2 Aug 2024 18:05:05 +0200 Subject: [PATCH 01/19] Initial implementation --- .gitignore | 2 + Cargo.toml | 17 ++++++ src/client.rs | 17 ++++++ src/dory.rs | 23 +++++++++ src/error.rs | 11 ++++ src/inner_product.rs | 22 ++++++++ src/lib.rs | 17 ++++++ src/verify_generic.rs | 35 +++++++++++++ tests/integration.rs | 117 ++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 261 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/client.rs create mode 100644 src/dory.rs create mode 100644 src/error.rs create mode 100644 src/inner_product.rs create mode 100644 src/lib.rs create mode 100644 src/verify_generic.rs create mode 100644 tests/integration.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..869df07 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..5dd0ec2 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "proof-of-sql-verifier" +version = "0.1.0" +edition = "2021" + +[dependencies] +blitzar = { version = "3.1.0", default-features = false, optional = true } +curve25519-dalek = { version = "4", optional = true } +proof-of-sql = { version = "0.6.4", default-features = false } +proof-of-sql-parser = { version = "0.6.4" } + +[dev-dependencies] +proof-of-sql = { version = "0.6.4", default-features = false, features = ["test"] } + +[features] +dory = ["proof-of-sql/test"] +inner-product = ["dep:blitzar", "dep:curve25519-dalek", "proof-of-sql/blitzar"] diff --git a/src/client.rs b/src/client.rs new file mode 100644 index 0000000..c8864d6 --- /dev/null +++ b/src/client.rs @@ -0,0 +1,17 @@ +use crate::QueryCommitments; +use proof_of_sql::{ + base::{ + commitment::{Commitment, QueryCommitmentsExt, VecCommitmentExt}, + database::{CommitmentAccessor, SchemaAccessor}, + }, + sql::{parse::QueryExpr, proof::ProofExpr}, +}; + +pub fn compute_query_commitments( + query_expr: &QueryExpr, + accessor: &(impl CommitmentAccessor< as VecCommitmentExt>::DecompressedCommitment> + + SchemaAccessor), +) -> QueryCommitments { + let columns = query_expr.proof_expr().get_column_references(); + QueryCommitments::from_accessor_with_max_bounds(columns, accessor) +} diff --git a/src/dory.rs b/src/dory.rs new file mode 100644 index 0000000..766f5d8 --- /dev/null +++ b/src/dory.rs @@ -0,0 +1,23 @@ +use proof_of_sql::{ + base::commitment::QueryCommitments, + sql::{ + ast::ProofPlan, + proof::{QueryData, VerifiableQueryResult}, + }, +}; + +pub use proof_of_sql::proof_primitive::dory::{ + DoryCommitment, DoryEvaluationProof, DoryScalar, DoryVerifierPublicSetup, +}; + +use crate::{error::VerifyError, verify_generic::verify_proof}; + +pub fn verify_dory_proof( + proof: VerifiableQueryResult, + expr: &ProofPlan, + commitments: &QueryCommitments, + query_data: &QueryData, + setup: &DoryVerifierPublicSetup<'_>, +) -> Result<(), VerifyError> { + verify_proof(proof, expr, commitments, query_data, setup) +} diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..c87080d --- /dev/null +++ b/src/error.rs @@ -0,0 +1,11 @@ +#[derive(Debug, PartialEq)] +pub enum VerifyError { + /// Provided data has not valid public inputs. + InvalidInput, + /// Provided data has not valid proof. + InvalidProofData, + /// Verify proof failed. + VerifyError, + /// Provided an invalid verification key. + InvalidVerificationKey, +} diff --git a/src/inner_product.rs b/src/inner_product.rs new file mode 100644 index 0000000..5900340 --- /dev/null +++ b/src/inner_product.rs @@ -0,0 +1,22 @@ +use proof_of_sql::{ + base::commitment::QueryCommitments, + sql::{ + ast::ProofPlan, + proof::{QueryData, VerifiableQueryResult}, + }, +}; + +use crate::{error::VerifyError, verify_generic::verify_proof}; + +pub use blitzar::proof::InnerProductProof; +pub use curve25519_dalek::RistrettoPoint; +pub use proof_of_sql::base::scalar::Curve25519Scalar; + +pub fn verify_inner_product_proof( + proof: VerifiableQueryResult, + expr: &ProofPlan, + commitments: &QueryCommitments, + query_data: &QueryData, +) -> Result<(), VerifyError> { + verify_proof(proof, expr, commitments, query_data, &()) +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..790bbc0 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,17 @@ +mod client; +mod error; +mod verify_generic; + +#[cfg(feature = "dory")] +pub mod dory; +#[cfg(feature = "inner-product")] +pub mod inner_product; + +pub use client::*; +pub use error::*; +pub use verify_generic::*; + +#[cfg(feature = "dory")] +pub use dory::*; +#[cfg(feature = "inner-product")] +pub use inner_product::*; diff --git a/src/verify_generic.rs b/src/verify_generic.rs new file mode 100644 index 0000000..5d14a64 --- /dev/null +++ b/src/verify_generic.rs @@ -0,0 +1,35 @@ +use proof_of_sql::base::commitment::CommitmentEvaluationProof; + +use crate::error::VerifyError; + +pub use proof_of_sql::{ + base::commitment::QueryCommitments, + sql::{ + ast::ProofPlan, + proof::{QueryData, VerifiableQueryResult}, + }, +}; + +pub fn verify_proof( + proof: VerifiableQueryResult, + expr: &ProofPlan, + commitments: &QueryCommitments, + query_data: &QueryData, + setup: &CP::VerifierPublicSetup<'_>, +) -> Result<(), VerifyError> { + // TODO check that the provided `commitments` contain all the necessary data. + // This should be possible by replicating the same logic as + // `proof_of_sql::base::commitment::query_commitments::QueryCommitments::from_accessor_with_max_bounds` + // If this check is not done, then the `verify` method could panic if the accessor tries to access + // data which does not exist inside teh `QueryCommitments` struct. + let result = proof + .verify(expr, commitments, setup) + .map_err(|_| VerifyError::VerifyError)?; + + if result.table != query_data.table || result.verification_hash != query_data.verification_hash + { + Err(VerifyError::VerifyError) + } else { + Ok(()) + } +} diff --git a/tests/integration.rs b/tests/integration.rs new file mode 100644 index 0000000..fcf8148 --- /dev/null +++ b/tests/integration.rs @@ -0,0 +1,117 @@ +#[cfg(any(feature = "inner-product", feature = "dory"))] +pub mod common { + pub use proof_of_sql::{ + base::{ + commitment::{Commitment, CommitmentEvaluationProof}, + database::{ + owned_table_utility::*, OwnedTableTestAccessor, SchemaAccessor, TestAccessor, + }, + }, + sql::{parse::QueryExpr, proof::VerifiableQueryResult}, + }; + + pub fn build_accessor( + setup: ::ProverPublicSetup<'_>, + ) -> OwnedTableTestAccessor { + let mut accessor = OwnedTableTestAccessor::::new_empty_with_setup(setup); + accessor.add_table( + "sxt.table".parse().unwrap(), + owned_table([ + bigint("a", [1, 2, 3, 2]), + varchar("b", ["hi", "hello", "there", "world"]), + ]), + 0, + ); + accessor + } + + pub fn build_query(accessor: &impl SchemaAccessor) -> QueryExpr { + QueryExpr::try_new( + "SELECT b FROM table WHERE a = 2".parse().unwrap(), + "sxt".parse().unwrap(), + accessor, + ) + .unwrap() + } +} + +#[cfg(feature = "inner-product")] +mod inner_product { + use super::common::*; + + use blitzar::{self, proof::InnerProductProof}; + + #[test] + fn generate_and_verify_proof() { + blitzar::compute::init_backend(); + + let prover_setup = (); + let verifier_setup = (); + + let accessor: OwnedTableTestAccessor = build_accessor(prover_setup); + let query = build_query(&accessor); + + let proof = VerifiableQueryResult::::new( + query.proof_expr(), + &accessor, + &prover_setup, + ); + + let query_data = proof + .verify(query.proof_expr(), &accessor, &verifier_setup) + .unwrap(); + let query_commitments = proof_of_sql_verifier::compute_query_commitments(&query, &accessor); + + let result = proof_of_sql_verifier::verify_inner_product_proof( + proof, + query.proof_expr(), + &query_commitments, + &query_data, + ); + + assert!(result.is_ok()); + } +} + +#[cfg(feature = "dory")] +mod dory { + use super::common::*; + + use proof_of_sql::proof_primitive::dory::{ + test_rng, DoryEvaluationProof, DoryProverPublicSetup, DoryVerifierPublicSetup, ProverSetup, + PublicParameters, VerifierSetup, + }; + + #[test] + fn generate_and_verify_proof() { + let public_parameters = PublicParameters::rand(4, &mut test_rng()); + let ps = ProverSetup::from(&public_parameters); + let vs = VerifierSetup::from(&public_parameters); + let prover_setup = DoryProverPublicSetup::new(&ps, 4); + let verifier_setup = DoryVerifierPublicSetup::new(&vs, 4); + + let accessor: OwnedTableTestAccessor = build_accessor(prover_setup); + let query = build_query(&accessor); + + let proof = VerifiableQueryResult::::new( + query.proof_expr(), + &accessor, + &prover_setup, + ); + + let query_data = proof + .verify(query.proof_expr(), &accessor, &verifier_setup) + .unwrap(); + let query_commitments = proof_of_sql_verifier::compute_query_commitments(&query, &accessor); + + let result = proof_of_sql_verifier::verify_dory_proof( + proof, + query.proof_expr(), + &query_commitments, + &query_data, + &verifier_setup, + ); + + assert!(result.is_ok()); + } +} From c9206566132fbeab681480b08330591eeb047533 Mon Sep 17 00:00:00 2001 From: DanieleDiBenedetto Date: Mon, 5 Aug 2024 16:18:42 +0200 Subject: [PATCH 02/19] Add CI --- .github/workflows/CI-ci-remote.yml | 42 ++++++ .github/workflows/CI-coverage.yml | 41 ++++++ .github/workflows/CI-rustdoc.yml | 50 +++++++ .gitignore | 3 +- HEADER-APACHE2 | 14 ++ LICENSE-APACHE2 | 211 +++++++++++++++++++++++++++++ Makefile.toml | 79 +++++++++++ 7 files changed, 439 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/CI-ci-remote.yml create mode 100644 .github/workflows/CI-coverage.yml create mode 100644 .github/workflows/CI-rustdoc.yml create mode 100644 HEADER-APACHE2 create mode 100644 LICENSE-APACHE2 create mode 100644 Makefile.toml diff --git a/.github/workflows/CI-ci-remote.yml b/.github/workflows/CI-ci-remote.yml new file mode 100644 index 0000000..5a80a2d --- /dev/null +++ b/.github/workflows/CI-ci-remote.yml @@ -0,0 +1,42 @@ +name: CI-build-test-lint-fmt-deps + +run-name: "Workflow performing CI steps: build, testing, check format, check linting, check headers and check dependencies" + +on: + pull_request: + types: [opened, synchronize] + push: + branches: + - main + workflow_dispatch: + +env: + RUST_BACKTRACE: 1 + +jobs: + build-test-check: + runs-on: ubuntu-latest + steps: + - name: Checkout branch + uses: actions/checkout@v4 + - name: Install cargo-make + uses: actions-rs/cargo@v1 + with: + command: install + args: --debug cargo-make + - name: Run CI full (stable) + uses: actions-rs/cargo@v1 + with: + toolchain: stable + command: make + args: ci-remote + - name: Install latest nightly + uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + - name: Run CI check-deps only (nightly) + uses: actions-rs/cargo@v1 + with: + toolchain: nightly + command: make + args: udeps \ No newline at end of file diff --git a/.github/workflows/CI-coverage.yml b/.github/workflows/CI-coverage.yml new file mode 100644 index 0000000..dc473b5 --- /dev/null +++ b/.github/workflows/CI-coverage.yml @@ -0,0 +1,41 @@ +name: CI-coverage + +run-name: "Workflow performing CI step: coverage" + +on: + pull_request: + types: [opened, synchronize] + push: + branches: + - main + workflow_dispatch: + +env: + RUST_BACKTRACE: 1 + +jobs: + coverage: + runs-on: ubuntu-latest + steps: + - name: Checkout branch + uses: actions/checkout@v4 + - name: Install coverage tools + run: | + cargo install --force cargo-llvm-cov + - name: Coverage tasks + run: | + cargo llvm-cov --workspace --lcov --output-path lcov.info + cargo llvm-cov report --json --output-path coverage_report.json --summary-only + cargo llvm-cov report > coverage-summary.txt + cat coverage-summary.txt + - name: Upload json summary as Artifact + uses: actions/upload-artifact@v4 + with: + name: coverage-output + path: ./coverage_report.json + if-no-files-found: warn + retention-days: 1 + compression-level: 0 + overwrite: true + # It is also possible to upload the generated lcov.info for later use with Codecov + # (see https://llvm.org/docs/CommandGuide/llvm-profdata.html) diff --git a/.github/workflows/CI-rustdoc.yml b/.github/workflows/CI-rustdoc.yml new file mode 100644 index 0000000..0cac622 --- /dev/null +++ b/.github/workflows/CI-rustdoc.yml @@ -0,0 +1,50 @@ +name: CI-rustdoc + +run-name: "Rust doc generation" + +on: + push: + tags: + - v[0-9]+.[0-9]+.[0-9]+* + workflow_dispatch: + +env: + RUST_BACKTRACE: 1 + +jobs: + rustdoc-generation: + runs-on: ubuntu-latest + steps: + - name: Checkout branch + uses: actions/checkout@v4 + + - name: Generate Rust documentation + run: cargo doc --no-deps + + - name: Remove lock file + run: rm target/doc/.lock + + - name: Add redirect + run: echo '' > target/doc/index.html + + - name: Upload documentation + uses: actions/upload-pages-artifact@v3 + with: + path: target/doc + + rustdoc-deployment: + needs: rustdoc-generation + + permissions: + pages: write + id-token: write + + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + + runs-on: ubuntu-latest + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 869df07..32a86fc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target -Cargo.lock \ No newline at end of file +Cargo.lock +lcov.info diff --git a/HEADER-APACHE2 b/HEADER-APACHE2 new file mode 100644 index 0000000..d4fdff5 --- /dev/null +++ b/HEADER-APACHE2 @@ -0,0 +1,14 @@ +// Copyright 2024, Horizen Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. diff --git a/LICENSE-APACHE2 b/LICENSE-APACHE2 new file mode 100644 index 0000000..fbb0616 --- /dev/null +++ b/LICENSE-APACHE2 @@ -0,0 +1,211 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + + NOTE + +Individual files contain the following tag instead of the full license +text. + + SPDX-License-Identifier: Apache-2.0 + +This enables machine processing of license information based on the SPDX +License Identifiers that are here available: http://spdx.org/licenses/ \ No newline at end of file diff --git a/Makefile.toml b/Makefile.toml new file mode 100644 index 0000000..2ba8629 --- /dev/null +++ b/Makefile.toml @@ -0,0 +1,79 @@ +[config] +default_to_workspace = false + +[tasks.ignore-members] +workspace = false + +[tasks.clean] +command = "cargo" +args = ["clean"] + +[tasks.build] +dependencies = ["clean"] +command = "cargo" +args = ["build"] + +[tasks.test] +dependencies = ["clean"] +command = "cargo" +args = ["test"] + +[tasks.format_inst] +[tasks.format-inst] +install_crate = { crate_name = "rustfmt", rustup_component_name = "rustfmt", binary = "rustfmt", test_arg = "--help" } + +[tasks.format] +dependencies = ["format-inst"] +command = "cargo" +args = ["fmt"] + +[tasks.format-check] +dependencies = ["format-inst"] +command = "cargo" +args = ["fmt", "--check"] + +[tasks.clippy-inst] +install_crate = { crate_name = "clippy", rustup_component_name = "clippy", binary = "clippy", test_arg = "--help" } + +[tasks.clippy] +dependencies = ["clippy-inst"] +command = "cargo" +args = ["clippy", "--", "--deny", "warnings"] + +[tasks.header-add] +script = { file = "./scripts/add_header_if_missing.sh" } +args = ["HEADER-APACHE2", "./!(target)/**/*.rs"] + +[tasks.header-check] +env = { CHECK_DIRTY = "true", DRY_RUN = "true" } +run_task = "header-add" + +[tasks.audit-inst] +command = "cargo" +args = ["install", "cargo-audit"] + +[tasks.audit] +dependencies = ["audit-inst"] +command = "cargo" +args = ["audit"] + +[tasks.cov] +command = "cargo" +args = ["llvm-cov", "--workspace", "--lcov", "--output-path", "lcov.info"] + +[tasks.udeps-inst] +command = "cargo" +args = ["install", "cargo-udeps", "--locked"] + +[tasks.udeps] +dependencies = ["udeps-inst"] +command = "cargo" +args = ["udeps", "--all-targets"] + + + +[tasks.ci] +dependencies = ["build", "test", "format", "header-add", "clippy", "audit"] + +[tasks.ci-remote] +dependencies = ["build", "test", "format-check", "header-check", "clippy", "audit"] \ No newline at end of file From a408fcd4b8fd5951b471388eb7daedf9c874e173 Mon Sep 17 00:00:00 2001 From: tarassh Date: Thu, 8 Aug 2024 07:21:07 -0700 Subject: [PATCH 03/19] update dependencies --- Cargo.toml | 6 +++--- src/client.rs | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5dd0ec2..272c14a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,11 +6,11 @@ edition = "2021" [dependencies] blitzar = { version = "3.1.0", default-features = false, optional = true } curve25519-dalek = { version = "4", optional = true } -proof-of-sql = { version = "0.6.4", default-features = false } -proof-of-sql-parser = { version = "0.6.4" } +proof-of-sql = { version = "0.9.1", default-features = false } +proof-of-sql-parser = { version = "0.9.1" } [dev-dependencies] -proof-of-sql = { version = "0.6.4", default-features = false, features = ["test"] } +proof-of-sql = { version = "0.9.1", default-features = false, features = ["test"] } [features] dory = ["proof-of-sql/test"] diff --git a/src/client.rs b/src/client.rs index c8864d6..3edc1e6 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,7 +1,7 @@ use crate::QueryCommitments; use proof_of_sql::{ base::{ - commitment::{Commitment, QueryCommitmentsExt, VecCommitmentExt}, + commitment::{Commitment, QueryCommitmentsExt}, database::{CommitmentAccessor, SchemaAccessor}, }, sql::{parse::QueryExpr, proof::ProofExpr}, @@ -9,8 +9,7 @@ use proof_of_sql::{ pub fn compute_query_commitments( query_expr: &QueryExpr, - accessor: &(impl CommitmentAccessor< as VecCommitmentExt>::DecompressedCommitment> - + SchemaAccessor), + accessor: &(impl CommitmentAccessor + SchemaAccessor), ) -> QueryCommitments { let columns = query_expr.proof_expr().get_column_references(); QueryCommitments::from_accessor_with_max_bounds(columns, accessor) From c797b14cb28b6e4dcbf38cf45b8be818d03ae678 Mon Sep 17 00:00:00 2001 From: tarassh Date: Sun, 11 Aug 2024 19:00:45 -0700 Subject: [PATCH 04/19] update dependencies --- Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 272c14a..3223d2a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,11 +6,11 @@ edition = "2021" [dependencies] blitzar = { version = "3.1.0", default-features = false, optional = true } curve25519-dalek = { version = "4", optional = true } -proof-of-sql = { version = "0.9.1", default-features = false } -proof-of-sql-parser = { version = "0.9.1" } +proof-of-sql = { version = "0.10.1", default-features = false } +proof-of-sql-parser = { version = "0.10.1" } [dev-dependencies] -proof-of-sql = { version = "0.9.1", default-features = false, features = ["test"] } +proof-of-sql = { version = "0.10.1", default-features = false, features = ["test"] } [features] dory = ["proof-of-sql/test"] From 5b6ec6f7afc68bb112e2942c1032da4727946439 Mon Sep 17 00:00:00 2001 From: tarassh Date: Sun, 11 Aug 2024 21:49:52 -0700 Subject: [PATCH 05/19] working on commitment checks --- src/verify_generic.rs | 5 +++ tests/integration.rs | 80 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/src/verify_generic.rs b/src/verify_generic.rs index 5d14a64..249cccd 100644 --- a/src/verify_generic.rs +++ b/src/verify_generic.rs @@ -22,6 +22,11 @@ pub fn verify_proof( // `proof_of_sql::base::commitment::query_commitments::QueryCommitments::from_accessor_with_max_bounds` // If this check is not done, then the `verify` method could panic if the accessor tries to access // data which does not exist inside teh `QueryCommitments` struct. + + if commitments.is_empty() { + return Err(VerifyError::VerifyError); + } + let result = proof .verify(expr, commitments, setup) .map_err(|_| VerifyError::VerifyError)?; diff --git a/tests/integration.rs b/tests/integration.rs index fcf8148..2084feb 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -19,6 +19,7 @@ pub mod common { owned_table([ bigint("a", [1, 2, 3, 2]), varchar("b", ["hi", "hello", "there", "world"]), + boolean("c", [true, false, true, false]), ]), 0, ); @@ -33,6 +34,15 @@ pub mod common { ) .unwrap() } + + pub fn build_missing_query(accessor: &impl SchemaAccessor) -> QueryExpr { + QueryExpr::try_new( + "SELECT b FROM table WHERE a = 4".parse().unwrap(), + "sxt".parse().unwrap(), + accessor, + ) + .unwrap() + } } #[cfg(feature = "inner-product")] @@ -75,6 +85,7 @@ mod inner_product { #[cfg(feature = "dory")] mod dory { + use super::common::*; use proof_of_sql::proof_primitive::dory::{ @@ -82,6 +93,8 @@ mod dory { PublicParameters, VerifierSetup, }; + use proof_of_sql::base::commitment::QueryCommitments; + #[test] fn generate_and_verify_proof() { let public_parameters = PublicParameters::rand(4, &mut test_rng()); @@ -114,4 +127,71 @@ mod dory { assert!(result.is_ok()); } + + #[test] + fn generate_and_verify_proof_missing_data() { + let public_parameters = PublicParameters::rand(4, &mut test_rng()); + let ps = ProverSetup::from(&public_parameters); + let vs = VerifierSetup::from(&public_parameters); + let prover_setup = DoryProverPublicSetup::new(&ps, 4); + let verifier_setup = DoryVerifierPublicSetup::new(&vs, 4); + + let accessor: OwnedTableTestAccessor = build_accessor(prover_setup); + let query = build_missing_query(&accessor); + + let proof = VerifiableQueryResult::::new( + query.proof_expr(), + &accessor, + &prover_setup, + ); + + let query_data = proof + .verify(query.proof_expr(), &accessor, &verifier_setup) + .unwrap(); + let query_commitments = proof_of_sql_verifier::compute_query_commitments(&query, &accessor); + + let result = proof_of_sql_verifier::verify_dory_proof( + proof, + query.proof_expr(), + &query_commitments, + &query_data, + &verifier_setup, + ); + + assert!(result.is_ok()); + } + + #[test] + fn generate_and_verify_proof_missing_commitments() { + let public_parameters = PublicParameters::rand(4, &mut test_rng()); + let ps = ProverSetup::from(&public_parameters); + let vs = VerifierSetup::from(&public_parameters); + let prover_setup = DoryProverPublicSetup::new(&ps, 4); + let verifier_setup = DoryVerifierPublicSetup::new(&vs, 4); + + let accessor: OwnedTableTestAccessor = build_accessor(prover_setup); + let query = build_query(&accessor); + + let proof = VerifiableQueryResult::::new( + query.proof_expr(), + &accessor, + &prover_setup, + ); + + let query_data = proof + .verify(query.proof_expr(), &accessor, &verifier_setup) + .unwrap(); + + let query_commitments = QueryCommitments::new(); + + let result = proof_of_sql_verifier::verify_dory_proof( + proof, + query.proof_expr(), + &query_commitments, + &query_data, + &verifier_setup, + ); + + assert!(result.is_err()); + } } From a153b5afafb4a6ff40c917fbc1221a6fe4d04f93 Mon Sep 17 00:00:00 2001 From: tarassh Date: Sun, 11 Aug 2024 22:46:06 -0700 Subject: [PATCH 06/19] add more commitment tests --- tests/integration.rs | 52 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/tests/integration.rs b/tests/integration.rs index 2084feb..8be9557 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -19,7 +19,21 @@ pub mod common { owned_table([ bigint("a", [1, 2, 3, 2]), varchar("b", ["hi", "hello", "there", "world"]), - boolean("c", [true, false, true, false]), + ]), + 0, + ); + accessor + } + + pub fn build_alternative_accessor( + setup: ::ProverPublicSetup<'_>, + ) -> OwnedTableTestAccessor { + let mut accessor = OwnedTableTestAccessor::::new_empty_with_setup(setup); + accessor.add_table( + "sxt.table".parse().unwrap(), + owned_table([ + bigint("a", [1, 2, 3, 2]), + varchar("b", ["hi", "hello", "there", "zkVerify"]), ]), 0, ); @@ -194,4 +208,40 @@ mod dory { assert!(result.is_err()); } + + #[test] + fn generate_and_verify_proof_alternative_data() { + let public_parameters = PublicParameters::rand(4, &mut test_rng()); + let ps = ProverSetup::from(&public_parameters); + let vs = VerifierSetup::from(&public_parameters); + let prover_setup = DoryProverPublicSetup::new(&ps, 4); + let verifier_setup = DoryVerifierPublicSetup::new(&vs, 4); + + let accessor: OwnedTableTestAccessor = build_accessor(prover_setup); + let query = build_query(&accessor); + + let proof = VerifiableQueryResult::::new( + query.proof_expr(), + &accessor, + &prover_setup, + ); + + let query_data = proof + .verify(query.proof_expr(), &accessor, &verifier_setup) + .unwrap(); + + let accessor: OwnedTableTestAccessor = + build_alternative_accessor(prover_setup); + let query_commitments = proof_of_sql_verifier::compute_query_commitments(&query, &accessor); + + let result = proof_of_sql_verifier::verify_dory_proof( + proof, + query.proof_expr(), + &query_commitments, + &query_data, + &verifier_setup, + ); + + assert!(result.is_err()); + } } From 3366b1d1aa87cb93e78f93eff5a1c74785382bff Mon Sep 17 00:00:00 2001 From: tarassh Date: Sun, 18 Aug 2024 09:58:30 -0700 Subject: [PATCH 07/19] update the dependencies --- Cargo.toml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3223d2a..3969fbc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,12 +6,13 @@ edition = "2021" [dependencies] blitzar = { version = "3.1.0", default-features = false, optional = true } curve25519-dalek = { version = "4", optional = true } -proof-of-sql = { version = "0.10.1", default-features = false } -proof-of-sql-parser = { version = "0.10.1" } +proof-of-sql = { version = "0.15.0", default-features = false } +proof-of-sql-parser = { version = "0.15.0" } [dev-dependencies] -proof-of-sql = { version = "0.10.1", default-features = false, features = ["test"] } +proof-of-sql = { version = "0.15.0", default-features = false, features = ["test"] } [features] +default = ["dory"] dory = ["proof-of-sql/test"] inner-product = ["dep:blitzar", "dep:curve25519-dalek", "proof-of-sql/blitzar"] From e361586697f6dacd5ed6c16eab2c5ac00c67067f Mon Sep 17 00:00:00 2001 From: tarassh Date: Mon, 19 Aug 2024 23:51:55 -0700 Subject: [PATCH 08/19] make dory default, and add check for the commitments. --- Cargo.toml | 5 +- src/lib.rs | 4 +- src/verification_key.rs | 52 +++++++++++++++++ src/verify_generic.rs | 23 +++++--- tests/integration.rs | 124 +++++++++++++++++++++++++++++++++------- 5 files changed, 176 insertions(+), 32 deletions(-) create mode 100644 src/verification_key.rs diff --git a/Cargo.toml b/Cargo.toml index 3969fbc..b28b821 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,9 @@ version = "0.1.0" edition = "2021" [dependencies] +ark-serialize = { version = "0.4.0", default-features = false } +bincode = "1" +serde = { version = "1", features = ["derive"] } blitzar = { version = "3.1.0", default-features = false, optional = true } curve25519-dalek = { version = "4", optional = true } proof-of-sql = { version = "0.15.0", default-features = false } @@ -13,6 +16,4 @@ proof-of-sql-parser = { version = "0.15.0" } proof-of-sql = { version = "0.15.0", default-features = false, features = ["test"] } [features] -default = ["dory"] -dory = ["proof-of-sql/test"] inner-product = ["dep:blitzar", "dep:curve25519-dalek", "proof-of-sql/blitzar"] diff --git a/src/lib.rs b/src/lib.rs index 790bbc0..db9c724 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,9 @@ mod client; mod error; +mod proof; +mod verification_key; mod verify_generic; -#[cfg(feature = "dory")] pub mod dory; #[cfg(feature = "inner-product")] pub mod inner_product; @@ -11,7 +12,6 @@ pub use client::*; pub use error::*; pub use verify_generic::*; -#[cfg(feature = "dory")] pub use dory::*; #[cfg(feature = "inner-product")] pub use inner_product::*; diff --git a/src/verification_key.rs b/src/verification_key.rs new file mode 100644 index 0000000..14b9f33 --- /dev/null +++ b/src/verification_key.rs @@ -0,0 +1,52 @@ +use ark_serialize::CanonicalDeserialize; +use proof_of_sql::proof_primitive::dory::{DoryVerifierPublicSetup, VerifierSetup}; + +use crate::VerifyError; + +pub struct VerificationKey(VerifierSetup); + +impl TryFrom<&[u8]> for VerificationKey { + type Error = VerifyError; + + fn try_from(value: &[u8]) -> Result { + if value.len() != 15408 { + return Err(VerifyError::InvalidVerificationKey); + } + + let setup: VerifierSetup = CanonicalDeserialize::deserialize_compressed(value) + .map_err(|_| VerifyError::InvalidVerificationKey)?; + + Ok(Self(setup)) + } +} + +impl VerificationKey { + pub fn new(setup: VerifierSetup) -> Self { + Self(setup) + } + + pub fn into_dory_verifier_public_setup(&self) -> DoryVerifierPublicSetup<'_> { + DoryVerifierPublicSetup::new(&self.0, N) + } +} + +#[cfg(test)] +mod test { + use ark_serialize::CanonicalSerialize; + use proof_of_sql::proof_primitive::dory::{test_rng, PublicParameters}; + + use super::*; + + #[test] + fn test_verification_key() { + let public_parameters = PublicParameters::rand(4, &mut test_rng()); + let vs: VerifierSetup = VerifierSetup::from(&public_parameters); + let mut writer = Vec::new(); + vs.serialize_compressed(&mut writer).unwrap(); + + let verification_key = VerificationKey::<4>::try_from(writer.as_ref()).unwrap(); + let dory_key = verification_key.into_dory_verifier_public_setup(); + + assert_eq!(dory_key.verifier_setup(), &vs); + } +} diff --git a/src/verify_generic.rs b/src/verify_generic.rs index 249cccd..4d26d80 100644 --- a/src/verify_generic.rs +++ b/src/verify_generic.rs @@ -1,4 +1,5 @@ use proof_of_sql::base::commitment::CommitmentEvaluationProof; +use proof_of_sql::sql::proof::ProofExpr; use crate::error::VerifyError; @@ -17,14 +18,20 @@ pub fn verify_proof( query_data: &QueryData, setup: &CP::VerifierPublicSetup<'_>, ) -> Result<(), VerifyError> { - // TODO check that the provided `commitments` contain all the necessary data. - // This should be possible by replicating the same logic as - // `proof_of_sql::base::commitment::query_commitments::QueryCommitments::from_accessor_with_max_bounds` - // If this check is not done, then the `verify` method could panic if the accessor tries to access - // data which does not exist inside teh `QueryCommitments` struct. - - if commitments.is_empty() { - return Err(VerifyError::VerifyError); + // Check that the columns in the proof match the columns in the commitments + for column in expr.get_column_references() { + if let Some(commitment) = commitments.get(&column.table_ref()) { + if let Some(metadata) = commitment + .column_commitments() + .get_metadata(&column.column_id()) + { + if metadata.column_type() != column.column_type() { + return Err(VerifyError::VerifyError); + } + } + } else { + return Err(VerifyError::VerifyError); + } } let result = proof diff --git a/tests/integration.rs b/tests/integration.rs index 8be9557..b5f4683 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -1,4 +1,3 @@ -#[cfg(any(feature = "inner-product", feature = "dory"))] pub mod common { pub use proof_of_sql::{ base::{ @@ -25,7 +24,7 @@ pub mod common { accessor } - pub fn build_alternative_accessor( + pub fn build_altered_accessor( setup: ::ProverPublicSetup<'_>, ) -> OwnedTableTestAccessor { let mut accessor = OwnedTableTestAccessor::::new_empty_with_setup(setup); @@ -40,6 +39,21 @@ pub mod common { accessor } + pub fn build_alien_accessor( + setup: ::ProverPublicSetup<'_>, + ) -> OwnedTableTestAccessor { + let mut accessor = OwnedTableTestAccessor::::new_empty_with_setup(setup); + accessor.add_table( + "sxt.table2".parse().unwrap(), + owned_table([ + bigint("c", [1, 2, 3, 2]), + varchar("d", ["hi", "hello", "there", "world"]), + ]), + 0, + ); + accessor + } + pub fn build_query(accessor: &impl SchemaAccessor) -> QueryExpr { QueryExpr::try_new( "SELECT b FROM table WHERE a = 2".parse().unwrap(), @@ -49,7 +63,18 @@ pub mod common { .unwrap() } - pub fn build_missing_query(accessor: &impl SchemaAccessor) -> QueryExpr { + pub fn build_alien_query(accessor: &impl SchemaAccessor) -> QueryExpr { + QueryExpr::try_new( + "SELECT d FROM table2 WHERE c = 2".parse().unwrap(), + "sxt".parse().unwrap(), + accessor, + ) + .unwrap() + } + + pub fn build_query_non_existant_record( + accessor: &impl SchemaAccessor, + ) -> QueryExpr { QueryExpr::try_new( "SELECT b FROM table WHERE a = 4".parse().unwrap(), "sxt".parse().unwrap(), @@ -97,7 +122,6 @@ mod inner_product { } } -#[cfg(feature = "dory")] mod dory { use super::common::*; @@ -111,26 +135,31 @@ mod dory { #[test] fn generate_and_verify_proof() { + // Initialize setup let public_parameters = PublicParameters::rand(4, &mut test_rng()); let ps = ProverSetup::from(&public_parameters); let vs = VerifierSetup::from(&public_parameters); let prover_setup = DoryProverPublicSetup::new(&ps, 4); let verifier_setup = DoryVerifierPublicSetup::new(&vs, 4); - let accessor: OwnedTableTestAccessor = build_accessor(prover_setup); + // Build table accessor and query + let accessor = build_accessor::(prover_setup); let query = build_query(&accessor); + // Generate proof let proof = VerifiableQueryResult::::new( query.proof_expr(), &accessor, &prover_setup, ); + // Get query data and commitments let query_data = proof .verify(query.proof_expr(), &accessor, &verifier_setup) .unwrap(); let query_commitments = proof_of_sql_verifier::compute_query_commitments(&query, &accessor); + // Verify proof let result = proof_of_sql_verifier::verify_dory_proof( proof, query.proof_expr(), @@ -143,65 +172,114 @@ mod dory { } #[test] - fn generate_and_verify_proof_missing_data() { + fn generate_and_verify_proof_for_non_existant_record() { + // Initialize setup let public_parameters = PublicParameters::rand(4, &mut test_rng()); let ps = ProverSetup::from(&public_parameters); let vs = VerifierSetup::from(&public_parameters); let prover_setup = DoryProverPublicSetup::new(&ps, 4); let verifier_setup = DoryVerifierPublicSetup::new(&vs, 4); - let accessor: OwnedTableTestAccessor = build_accessor(prover_setup); - let query = build_missing_query(&accessor); + // Build table accessor and query + let accessor = build_accessor::(prover_setup); + let non_existant_query = build_query_non_existant_record(&accessor); + let proof = VerifiableQueryResult::::new( + non_existant_query.proof_expr(), + &accessor, + &prover_setup, + ); + + let query_data = proof + .verify(non_existant_query.proof_expr(), &accessor, &verifier_setup) + .unwrap(); + let query_commitments = + proof_of_sql_verifier::compute_query_commitments(&non_existant_query, &accessor); + + let result = proof_of_sql_verifier::verify_dory_proof( + proof, + non_existant_query.proof_expr(), + &query_commitments, + &query_data, + &verifier_setup, + ); + + assert!(result.is_ok()); + } + + #[test] + fn generate_and_verify_proof_without_commitments() { + // Initialize setup + let public_parameters = PublicParameters::rand(4, &mut test_rng()); + let ps = ProverSetup::from(&public_parameters); + let vs = VerifierSetup::from(&public_parameters); + let prover_setup = DoryProverPublicSetup::new(&ps, 4); + let verifier_setup = DoryVerifierPublicSetup::new(&vs, 4); + + // Build table accessor and query + let accessor = build_accessor::(prover_setup); + let query = build_query(&accessor); + + // Generate proof let proof = VerifiableQueryResult::::new( query.proof_expr(), &accessor, &prover_setup, ); + // Get query data and commitments let query_data = proof .verify(query.proof_expr(), &accessor, &verifier_setup) .unwrap(); - let query_commitments = proof_of_sql_verifier::compute_query_commitments(&query, &accessor); + let no_commitments = QueryCommitments::new(); let result = proof_of_sql_verifier::verify_dory_proof( proof, query.proof_expr(), - &query_commitments, + &no_commitments, &query_data, &verifier_setup, ); - assert!(result.is_ok()); + assert!(result.is_err()); } #[test] - fn generate_and_verify_proof_missing_commitments() { + fn generate_and_verify_proof_for_altered_data() { + // Initialize setup let public_parameters = PublicParameters::rand(4, &mut test_rng()); let ps = ProverSetup::from(&public_parameters); let vs = VerifierSetup::from(&public_parameters); let prover_setup = DoryProverPublicSetup::new(&ps, 4); let verifier_setup = DoryVerifierPublicSetup::new(&vs, 4); - let accessor: OwnedTableTestAccessor = build_accessor(prover_setup); + // Build table accessor and query + let accessor = build_accessor::(prover_setup); let query = build_query(&accessor); + // Generate proof let proof = VerifiableQueryResult::::new( query.proof_expr(), &accessor, &prover_setup, ); + // Get query data and commitments let query_data = proof .verify(query.proof_expr(), &accessor, &verifier_setup) .unwrap(); - let query_commitments = QueryCommitments::new(); + // Alter the data + let altered_accessor: OwnedTableTestAccessor = + build_altered_accessor(prover_setup); + let altered_query_commitments = + proof_of_sql_verifier::compute_query_commitments(&query, &altered_accessor); + // Verify proof let result = proof_of_sql_verifier::verify_dory_proof( proof, query.proof_expr(), - &query_commitments, + &altered_query_commitments, &query_data, &verifier_setup, ); @@ -210,29 +288,35 @@ mod dory { } #[test] - fn generate_and_verify_proof_alternative_data() { + fn generate_and_verify_proof_from_alien_accessor() { + // Initialize setup let public_parameters = PublicParameters::rand(4, &mut test_rng()); let ps = ProverSetup::from(&public_parameters); let vs = VerifierSetup::from(&public_parameters); let prover_setup = DoryProverPublicSetup::new(&ps, 4); let verifier_setup = DoryVerifierPublicSetup::new(&vs, 4); - let accessor: OwnedTableTestAccessor = build_accessor(prover_setup); + // Build table accessors and queries + let accessor = build_accessor::(prover_setup); + let alien_accessor = build_alien_accessor::(prover_setup); let query = build_query(&accessor); + let alient_query = build_alien_query(&alien_accessor); + // Generate proof for original accessor and query let proof = VerifiableQueryResult::::new( query.proof_expr(), &accessor, &prover_setup, ); + // Get the result let query_data = proof .verify(query.proof_expr(), &accessor, &verifier_setup) .unwrap(); - let accessor: OwnedTableTestAccessor = - build_alternative_accessor(prover_setup); - let query_commitments = proof_of_sql_verifier::compute_query_commitments(&query, &accessor); + // Compute query commitments for alien accessor + let query_commitments = + proof_of_sql_verifier::compute_query_commitments(&alient_query, &alien_accessor); let result = proof_of_sql_verifier::verify_dory_proof( proof, From bbf30148bee1f3c28f47eaf7565e1c948658eb69 Mon Sep 17 00:00:00 2001 From: tarassh Date: Tue, 20 Aug 2024 06:34:08 -0700 Subject: [PATCH 09/19] CI: fix --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index db9c724..f448320 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,5 @@ mod client; mod error; -mod proof; mod verification_key; mod verify_generic; From 1e5f51cc9c9ed36003d2c0d0c2d3bdca8a3085de Mon Sep 17 00:00:00 2001 From: tarassh Date: Tue, 20 Aug 2024 19:32:56 -0700 Subject: [PATCH 10/19] Add license header; Use Vk structure instead of setup --- src/client.rs | 17 +++- src/dory.rs | 25 ++++- src/error.rs | 15 +++ src/inner_product.rs | 15 +++ src/lib.rs | 26 ++++- src/verification_key.rs | 58 +++++++++-- src/verify_generic.rs | 15 +++ tests/integration.rs | 214 +++++++++++++++++++++------------------- 8 files changed, 263 insertions(+), 122 deletions(-) diff --git a/src/client.rs b/src/client.rs index 3edc1e6..edee67a 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,3 +1,18 @@ +// Copyright 2024, The Horizen Foundation +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + use crate::QueryCommitments; use proof_of_sql::{ base::{ @@ -13,4 +28,4 @@ pub fn compute_query_commitments( ) -> QueryCommitments { let columns = query_expr.proof_expr().get_column_references(); QueryCommitments::from_accessor_with_max_bounds(columns, accessor) -} +} \ No newline at end of file diff --git a/src/dory.rs b/src/dory.rs index 766f5d8..fd6c83d 100644 --- a/src/dory.rs +++ b/src/dory.rs @@ -1,3 +1,18 @@ +// Copyright 2024, The Horizen Foundation +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + use proof_of_sql::{ base::commitment::QueryCommitments, sql::{ @@ -10,14 +25,14 @@ pub use proof_of_sql::proof_primitive::dory::{ DoryCommitment, DoryEvaluationProof, DoryScalar, DoryVerifierPublicSetup, }; -use crate::{error::VerifyError, verify_generic::verify_proof}; +use crate::{error::VerifyError, verify_generic::verify_proof, VerificationKey}; -pub fn verify_dory_proof( +pub fn verify_dory_proof( proof: VerifiableQueryResult, expr: &ProofPlan, commitments: &QueryCommitments, query_data: &QueryData, - setup: &DoryVerifierPublicSetup<'_>, + vk: &VerificationKey, ) -> Result<(), VerifyError> { - verify_proof(proof, expr, commitments, query_data, setup) -} + verify_proof(proof, expr, commitments, query_data, &vk.into_dory()) +} \ No newline at end of file diff --git a/src/error.rs b/src/error.rs index c87080d..1a787b6 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,3 +1,18 @@ +// Copyright 2024, The Horizen Foundation +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #[derive(Debug, PartialEq)] pub enum VerifyError { /// Provided data has not valid public inputs. diff --git a/src/inner_product.rs b/src/inner_product.rs index 5900340..f25ce78 100644 --- a/src/inner_product.rs +++ b/src/inner_product.rs @@ -1,3 +1,18 @@ +// Copyright 2024, The Horizen Foundation +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + use proof_of_sql::{ base::commitment::QueryCommitments, sql::{ diff --git a/src/lib.rs b/src/lib.rs index f448320..97d76d1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,16 +1,34 @@ +// Copyright 2024, The Horizen Foundation +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + mod client; mod error; + mod verification_key; mod verify_generic; pub mod dory; -#[cfg(feature = "inner-product")] -pub mod inner_product; +pub use dory::*; pub use client::*; pub use error::*; +pub use verification_key::*; pub use verify_generic::*; -pub use dory::*; #[cfg(feature = "inner-product")] -pub use inner_product::*; +pub mod inner_product; + +#[cfg(feature = "inner-product")] +pub use inner_product::*; \ No newline at end of file diff --git a/src/verification_key.rs b/src/verification_key.rs index 14b9f33..e9026c8 100644 --- a/src/verification_key.rs +++ b/src/verification_key.rs @@ -1,5 +1,20 @@ +// Copyright 2024, The Horizen Foundation +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + use ark_serialize::CanonicalDeserialize; -use proof_of_sql::proof_primitive::dory::{DoryVerifierPublicSetup, VerifierSetup}; +use proof_of_sql::proof_primitive::dory::{DoryVerifierPublicSetup, VerifierSetup, PublicParameters}; use crate::VerifyError; @@ -9,27 +24,39 @@ impl TryFrom<&[u8]> for VerificationKey { type Error = VerifyError; fn try_from(value: &[u8]) -> Result { - if value.len() != 15408 { + let setup = VerifierSetup::deserialize_compressed(value) + .map_err(|_| VerifyError::InvalidVerificationKey)?; + + // read last usize from the buffer as max_nu is the last field in the struct, and check if it matches N + // max_nu is not accessible from the VerifierSetup struct, so we need to check it from the buffer + let max_nu = slice_to_usize(&value[value.len() - std::mem::size_of::()..]); + if max_nu != N { return Err(VerifyError::InvalidVerificationKey); } - let setup: VerifierSetup = CanonicalDeserialize::deserialize_compressed(value) - .map_err(|_| VerifyError::InvalidVerificationKey)?; - Ok(Self(setup)) } } impl VerificationKey { - pub fn new(setup: VerifierSetup) -> Self { - Self(setup) + pub fn new(params: &PublicParameters) -> Self { + Self(VerifierSetup::from(params)) } - pub fn into_dory_verifier_public_setup(&self) -> DoryVerifierPublicSetup<'_> { + pub fn into_dory(&self) -> DoryVerifierPublicSetup<'_> { DoryVerifierPublicSetup::new(&self.0, N) } } + +fn slice_to_usize(slice: &[u8]) -> usize { + let mut array = [0u8; std::mem::size_of::()]; + let len = slice.len().min(std::mem::size_of::()); + array[..len].copy_from_slice(&slice[..len]); + + usize::from_le_bytes(array) +} + #[cfg(test)] mod test { use ark_serialize::CanonicalSerialize; @@ -45,8 +72,19 @@ mod test { vs.serialize_compressed(&mut writer).unwrap(); let verification_key = VerificationKey::<4>::try_from(writer.as_ref()).unwrap(); - let dory_key = verification_key.into_dory_verifier_public_setup(); + let dory_key = verification_key.into_dory(); assert_eq!(dory_key.verifier_setup(), &vs); } -} + + #[test] + fn test_verification_key_short_buffer() { + let public_parameters = PublicParameters::rand(4, &mut test_rng()); + let vs: VerifierSetup = VerifierSetup::from(&public_parameters); + let mut writer = Vec::new(); + vs.serialize_compressed(&mut writer).unwrap(); + + let verification_key = VerificationKey::<4>::try_from(&writer[..writer.len() - 1]); + assert!(verification_key.is_err()); + } +} \ No newline at end of file diff --git a/src/verify_generic.rs b/src/verify_generic.rs index 4d26d80..b24e699 100644 --- a/src/verify_generic.rs +++ b/src/verify_generic.rs @@ -1,3 +1,18 @@ +// Copyright 2024, The Horizen Foundation +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + use proof_of_sql::base::commitment::CommitmentEvaluationProof; use proof_of_sql::sql::proof::ProofExpr; diff --git a/tests/integration.rs b/tests/integration.rs index b5f4683..e627305 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -1,92 +1,105 @@ -pub mod common { - pub use proof_of_sql::{ - base::{ - commitment::{Commitment, CommitmentEvaluationProof}, - database::{ - owned_table_utility::*, OwnedTableTestAccessor, SchemaAccessor, TestAccessor, - }, +// Copyright 2024, The Horizen Foundation +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub use proof_of_sql::{ + base::{ + commitment::{Commitment, CommitmentEvaluationProof}, + database::{ + owned_table_utility::*, OwnedTableTestAccessor, SchemaAccessor, TestAccessor, }, - sql::{parse::QueryExpr, proof::VerifiableQueryResult}, - }; - - pub fn build_accessor( - setup: ::ProverPublicSetup<'_>, - ) -> OwnedTableTestAccessor { - let mut accessor = OwnedTableTestAccessor::::new_empty_with_setup(setup); - accessor.add_table( - "sxt.table".parse().unwrap(), - owned_table([ - bigint("a", [1, 2, 3, 2]), - varchar("b", ["hi", "hello", "there", "world"]), - ]), - 0, - ); - accessor - } + }, + sql::{parse::QueryExpr, proof::VerifiableQueryResult}, +}; + +fn build_accessor( + setup: ::ProverPublicSetup<'_>, +) -> OwnedTableTestAccessor { + let mut accessor = OwnedTableTestAccessor::::new_empty_with_setup(setup); + accessor.add_table( + "sxt.table".parse().unwrap(), + owned_table([ + bigint("a", [1, 2, 3, 2]), + varchar("b", ["hi", "hello", "there", "world"]), + ]), + 0, + ); + accessor +} - pub fn build_altered_accessor( - setup: ::ProverPublicSetup<'_>, - ) -> OwnedTableTestAccessor { - let mut accessor = OwnedTableTestAccessor::::new_empty_with_setup(setup); - accessor.add_table( - "sxt.table".parse().unwrap(), - owned_table([ - bigint("a", [1, 2, 3, 2]), - varchar("b", ["hi", "hello", "there", "zkVerify"]), - ]), - 0, - ); - accessor - } +fn build_altered_accessor( + setup: ::ProverPublicSetup<'_>, +) -> OwnedTableTestAccessor { + let mut accessor = OwnedTableTestAccessor::::new_empty_with_setup(setup); + accessor.add_table( + "sxt.table".parse().unwrap(), + owned_table([ + bigint("a", [1, 2, 3, 2]), + varchar("b", ["hi", "hello", "there", "zkVerify"]), + ]), + 0, + ); + accessor +} - pub fn build_alien_accessor( - setup: ::ProverPublicSetup<'_>, - ) -> OwnedTableTestAccessor { - let mut accessor = OwnedTableTestAccessor::::new_empty_with_setup(setup); - accessor.add_table( - "sxt.table2".parse().unwrap(), - owned_table([ - bigint("c", [1, 2, 3, 2]), - varchar("d", ["hi", "hello", "there", "world"]), - ]), - 0, - ); - accessor - } +fn build_alien_accessor( + setup: ::ProverPublicSetup<'_>, +) -> OwnedTableTestAccessor { + let mut accessor = OwnedTableTestAccessor::::new_empty_with_setup(setup); + accessor.add_table( + "sxt.table2".parse().unwrap(), + owned_table([ + bigint("c", [1, 2, 3, 2]), + varchar("d", ["hi", "hello", "there", "world"]), + ]), + 0, + ); + accessor +} - pub fn build_query(accessor: &impl SchemaAccessor) -> QueryExpr { - QueryExpr::try_new( - "SELECT b FROM table WHERE a = 2".parse().unwrap(), - "sxt".parse().unwrap(), - accessor, - ) - .unwrap() - } +fn build_query(accessor: &impl SchemaAccessor) -> QueryExpr { + QueryExpr::try_new( + "SELECT b FROM table WHERE a = 2".parse().unwrap(), + "sxt".parse().unwrap(), + accessor, + ) + .unwrap() +} - pub fn build_alien_query(accessor: &impl SchemaAccessor) -> QueryExpr { - QueryExpr::try_new( - "SELECT d FROM table2 WHERE c = 2".parse().unwrap(), - "sxt".parse().unwrap(), - accessor, - ) - .unwrap() - } +fn build_alien_query(accessor: &impl SchemaAccessor) -> QueryExpr { + QueryExpr::try_new( + "SELECT d FROM table2 WHERE c = 2".parse().unwrap(), + "sxt".parse().unwrap(), + accessor, + ) + .unwrap() +} - pub fn build_query_non_existant_record( - accessor: &impl SchemaAccessor, - ) -> QueryExpr { - QueryExpr::try_new( - "SELECT b FROM table WHERE a = 4".parse().unwrap(), - "sxt".parse().unwrap(), - accessor, - ) - .unwrap() - } +fn build_query_non_existant_record( + accessor: &impl SchemaAccessor, +) -> QueryExpr { + QueryExpr::try_new( + "SELECT b FROM table WHERE a = 4".parse().unwrap(), + "sxt".parse().unwrap(), + accessor, + ) + .unwrap() } #[cfg(feature = "inner-product")] mod inner_product { - use super::common::*; + use super::*; use blitzar::{self, proof::InnerProductProof}; @@ -124,23 +137,22 @@ mod inner_product { mod dory { - use super::common::*; + use super::*; use proof_of_sql::proof_primitive::dory::{ - test_rng, DoryEvaluationProof, DoryProverPublicSetup, DoryVerifierPublicSetup, ProverSetup, - PublicParameters, VerifierSetup, + test_rng, DoryEvaluationProof, DoryProverPublicSetup, ProverSetup, + PublicParameters, }; use proof_of_sql::base::commitment::QueryCommitments; + use proof_of_sql_verifier::VerificationKey; #[test] fn generate_and_verify_proof() { // Initialize setup let public_parameters = PublicParameters::rand(4, &mut test_rng()); let ps = ProverSetup::from(&public_parameters); - let vs = VerifierSetup::from(&public_parameters); let prover_setup = DoryProverPublicSetup::new(&ps, 4); - let verifier_setup = DoryVerifierPublicSetup::new(&vs, 4); // Build table accessor and query let accessor = build_accessor::(prover_setup); @@ -154,8 +166,9 @@ mod dory { ); // Get query data and commitments + let vk = VerificationKey::<4>::new(&public_parameters); let query_data = proof - .verify(query.proof_expr(), &accessor, &verifier_setup) + .verify(query.proof_expr(), &accessor, &vk.into_dory()) .unwrap(); let query_commitments = proof_of_sql_verifier::compute_query_commitments(&query, &accessor); @@ -165,7 +178,7 @@ mod dory { query.proof_expr(), &query_commitments, &query_data, - &verifier_setup, + &vk, ); assert!(result.is_ok()); @@ -176,9 +189,7 @@ mod dory { // Initialize setup let public_parameters = PublicParameters::rand(4, &mut test_rng()); let ps = ProverSetup::from(&public_parameters); - let vs = VerifierSetup::from(&public_parameters); let prover_setup = DoryProverPublicSetup::new(&ps, 4); - let verifier_setup = DoryVerifierPublicSetup::new(&vs, 4); // Build table accessor and query let accessor = build_accessor::(prover_setup); @@ -190,8 +201,10 @@ mod dory { &prover_setup, ); + let vk = VerificationKey::<4>::new(&public_parameters); + let query_data = proof - .verify(non_existant_query.proof_expr(), &accessor, &verifier_setup) + .verify(non_existant_query.proof_expr(), &accessor, &vk.into_dory()) .unwrap(); let query_commitments = proof_of_sql_verifier::compute_query_commitments(&non_existant_query, &accessor); @@ -201,7 +214,7 @@ mod dory { non_existant_query.proof_expr(), &query_commitments, &query_data, - &verifier_setup, + &vk, ); assert!(result.is_ok()); @@ -212,9 +225,7 @@ mod dory { // Initialize setup let public_parameters = PublicParameters::rand(4, &mut test_rng()); let ps = ProverSetup::from(&public_parameters); - let vs = VerifierSetup::from(&public_parameters); let prover_setup = DoryProverPublicSetup::new(&ps, 4); - let verifier_setup = DoryVerifierPublicSetup::new(&vs, 4); // Build table accessor and query let accessor = build_accessor::(prover_setup); @@ -228,8 +239,9 @@ mod dory { ); // Get query data and commitments + let vk = VerificationKey::<4>::new(&public_parameters); let query_data = proof - .verify(query.proof_expr(), &accessor, &verifier_setup) + .verify(query.proof_expr(), &accessor, &vk.into_dory()) .unwrap(); let no_commitments = QueryCommitments::new(); @@ -238,7 +250,7 @@ mod dory { query.proof_expr(), &no_commitments, &query_data, - &verifier_setup, + &vk, ); assert!(result.is_err()); @@ -249,9 +261,7 @@ mod dory { // Initialize setup let public_parameters = PublicParameters::rand(4, &mut test_rng()); let ps = ProverSetup::from(&public_parameters); - let vs = VerifierSetup::from(&public_parameters); let prover_setup = DoryProverPublicSetup::new(&ps, 4); - let verifier_setup = DoryVerifierPublicSetup::new(&vs, 4); // Build table accessor and query let accessor = build_accessor::(prover_setup); @@ -265,8 +275,9 @@ mod dory { ); // Get query data and commitments + let vk = VerificationKey::<4>::new(&public_parameters); let query_data = proof - .verify(query.proof_expr(), &accessor, &verifier_setup) + .verify(query.proof_expr(), &accessor, &vk.into_dory()) .unwrap(); // Alter the data @@ -281,7 +292,7 @@ mod dory { query.proof_expr(), &altered_query_commitments, &query_data, - &verifier_setup, + &vk, ); assert!(result.is_err()); @@ -292,9 +303,7 @@ mod dory { // Initialize setup let public_parameters = PublicParameters::rand(4, &mut test_rng()); let ps = ProverSetup::from(&public_parameters); - let vs = VerifierSetup::from(&public_parameters); let prover_setup = DoryProverPublicSetup::new(&ps, 4); - let verifier_setup = DoryVerifierPublicSetup::new(&vs, 4); // Build table accessors and queries let accessor = build_accessor::(prover_setup); @@ -310,8 +319,9 @@ mod dory { ); // Get the result + let vk = VerificationKey::<4>::new(&public_parameters); let query_data = proof - .verify(query.proof_expr(), &accessor, &verifier_setup) + .verify(query.proof_expr(), &accessor, &vk.into_dory()) .unwrap(); // Compute query commitments for alien accessor @@ -323,7 +333,7 @@ mod dory { query.proof_expr(), &query_commitments, &query_data, - &verifier_setup, + &vk, ); assert!(result.is_err()); From 500b2ff1b0bd85b5d89792a349dc1d5f0e046fbe Mon Sep 17 00:00:00 2001 From: tarassh Date: Wed, 21 Aug 2024 09:23:15 -0700 Subject: [PATCH 11/19] group and wrap arguments into dedicated structures. --- Cargo.toml | 1 - src/client.rs | 31 --------------- src/dory.rs | 31 ++++++--------- src/{error.rs => errors.rs} | 7 ++-- src/lib.rs | 13 +++--- src/proof.rs | 46 +++++++++++++++++++++ src/pubs.rs | 49 +++++++++++++++++++++++ src/verification_key.rs | 7 ++-- src/verify_generic.rs | 15 ++++--- tests/integration.rs | 79 +++++++++++++++++++------------------ 10 files changed, 169 insertions(+), 110 deletions(-) delete mode 100644 src/client.rs rename src/{error.rs => errors.rs} (80%) create mode 100644 src/proof.rs create mode 100644 src/pubs.rs diff --git a/Cargo.toml b/Cargo.toml index b28b821..0ff1aa9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,6 @@ edition = "2021" [dependencies] ark-serialize = { version = "0.4.0", default-features = false } bincode = "1" -serde = { version = "1", features = ["derive"] } blitzar = { version = "3.1.0", default-features = false, optional = true } curve25519-dalek = { version = "4", optional = true } proof-of-sql = { version = "0.15.0", default-features = false } diff --git a/src/client.rs b/src/client.rs deleted file mode 100644 index edee67a..0000000 --- a/src/client.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2024, The Horizen Foundation -// SPDX-License-Identifier: Apache-2.0 -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::QueryCommitments; -use proof_of_sql::{ - base::{ - commitment::{Commitment, QueryCommitmentsExt}, - database::{CommitmentAccessor, SchemaAccessor}, - }, - sql::{parse::QueryExpr, proof::ProofExpr}, -}; - -pub fn compute_query_commitments( - query_expr: &QueryExpr, - accessor: &(impl CommitmentAccessor + SchemaAccessor), -) -> QueryCommitments { - let columns = query_expr.proof_expr().get_column_references(); - QueryCommitments::from_accessor_with_max_bounds(columns, accessor) -} \ No newline at end of file diff --git a/src/dory.rs b/src/dory.rs index fd6c83d..ed5abd3 100644 --- a/src/dory.rs +++ b/src/dory.rs @@ -13,26 +13,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -use proof_of_sql::{ - base::commitment::QueryCommitments, - sql::{ - ast::ProofPlan, - proof::{QueryData, VerifiableQueryResult}, - }, -}; - -pub use proof_of_sql::proof_primitive::dory::{ - DoryCommitment, DoryEvaluationProof, DoryScalar, DoryVerifierPublicSetup, -}; - -use crate::{error::VerifyError, verify_generic::verify_proof, VerificationKey}; +use crate::{verify_generic::verify_proof, DoryProof, VerificationKey, VerifyError, DoryPublicInput}; pub fn verify_dory_proof( - proof: VerifiableQueryResult, - expr: &ProofPlan, - commitments: &QueryCommitments, - query_data: &QueryData, + proof: &DoryProof, + pubs: &DoryPublicInput, vk: &VerificationKey, ) -> Result<(), VerifyError> { - verify_proof(proof, expr, commitments, query_data, &vk.into_dory()) -} \ No newline at end of file + + verify_proof( + proof.clone().into(), + pubs.expr(), + pubs.commitments(), + pubs.query_data(), + &vk.into_dory(), + ) +} diff --git a/src/error.rs b/src/errors.rs similarity index 80% rename from src/error.rs rename to src/errors.rs index 1a787b6..5abaf6e 100644 --- a/src/error.rs +++ b/src/errors.rs @@ -13,14 +13,15 @@ // See the License for the specific language governing permissions and // limitations under the License. +/// This module defines errors used across the verification library. #[derive(Debug, PartialEq)] pub enum VerifyError { - /// Provided data has not valid public inputs. + /// Provided data has invalid public inputs. InvalidInput, - /// Provided data has not valid proof. + /// Provided data has invalid proof. InvalidProofData, /// Verify proof failed. - VerifyError, + VerificationFailed, // Renamed for clarity /// Provided an invalid verification key. InvalidVerificationKey, } diff --git a/src/lib.rs b/src/lib.rs index 97d76d1..764eea7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,17 +13,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -mod client; -mod error; - +mod errors; +mod proof; +mod pubs; mod verification_key; mod verify_generic; pub mod dory; pub use dory::*; -pub use client::*; -pub use error::*; +pub use errors::*; +pub use proof::*; +pub use pubs::*; pub use verification_key::*; pub use verify_generic::*; @@ -31,4 +32,4 @@ pub use verify_generic::*; pub mod inner_product; #[cfg(feature = "inner-product")] -pub use inner_product::*; \ No newline at end of file +pub use inner_product::*; diff --git a/src/proof.rs b/src/proof.rs new file mode 100644 index 0000000..4c9f319 --- /dev/null +++ b/src/proof.rs @@ -0,0 +1,46 @@ +// Copyright 2024, The Horizen Foundation +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use proof_of_sql::proof_primitive::dory::DoryEvaluationProof; +use proof_of_sql::sql::proof::VerifiableQueryResult; + +use crate::VerifyError; + +#[derive(Clone)] +pub struct DoryProof { + proof: VerifiableQueryResult, +} + +impl TryFrom<&[u8]> for DoryProof { + type Error = VerifyError; + + fn try_from(value: &[u8]) -> Result { + let proof = bincode::deserialize(value).map_err(|_| VerifyError::InvalidProofData)?; + + Ok(Self::new(proof)) + } +} + +impl Into> for DoryProof { + fn into(self) -> VerifiableQueryResult { + self.proof + } +} + +impl DoryProof { + pub fn new(proof: VerifiableQueryResult) -> Self { + Self { proof } + } +} diff --git a/src/pubs.rs b/src/pubs.rs new file mode 100644 index 0000000..274e7ba --- /dev/null +++ b/src/pubs.rs @@ -0,0 +1,49 @@ +// Copyright 2024, The Horizen Foundation +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use proof_of_sql::{base::commitment::QueryCommitments, proof_primitive::dory::{DoryCommitment, DoryScalar}, sql::{ast::ProofPlan, parse::QueryExpr, proof::QueryData}}; + + +pub struct DoryPublicInput<'a> { + expr: &'a ProofPlan, + commitments: QueryCommitments, + query_data: QueryData, +} + +impl<'a> DoryPublicInput<'a> { + pub fn new( + query_expr: &'a QueryExpr, + commitments: QueryCommitments, + query_data: QueryData, + ) -> Self { + Self { + expr: query_expr.proof_expr(), + commitments, + query_data, + } + } + + pub fn expr(&self) -> &ProofPlan { + &self.expr + } + + pub fn commitments(&self) -> &QueryCommitments { + &self.commitments + } + + pub fn query_data(&self) -> &QueryData { + &self.query_data + } +} \ No newline at end of file diff --git a/src/verification_key.rs b/src/verification_key.rs index e9026c8..82fd2d7 100644 --- a/src/verification_key.rs +++ b/src/verification_key.rs @@ -14,7 +14,9 @@ // limitations under the License. use ark_serialize::CanonicalDeserialize; -use proof_of_sql::proof_primitive::dory::{DoryVerifierPublicSetup, VerifierSetup, PublicParameters}; +use proof_of_sql::proof_primitive::dory::{ + DoryVerifierPublicSetup, PublicParameters, VerifierSetup, +}; use crate::VerifyError; @@ -48,7 +50,6 @@ impl VerificationKey { } } - fn slice_to_usize(slice: &[u8]) -> usize { let mut array = [0u8; std::mem::size_of::()]; let len = slice.len().min(std::mem::size_of::()); @@ -87,4 +88,4 @@ mod test { let verification_key = VerificationKey::<4>::try_from(&writer[..writer.len() - 1]); assert!(verification_key.is_err()); } -} \ No newline at end of file +} diff --git a/src/verify_generic.rs b/src/verify_generic.rs index b24e699..665c2c4 100644 --- a/src/verify_generic.rs +++ b/src/verify_generic.rs @@ -15,10 +15,7 @@ use proof_of_sql::base::commitment::CommitmentEvaluationProof; use proof_of_sql::sql::proof::ProofExpr; - -use crate::error::VerifyError; - -pub use proof_of_sql::{ +use proof_of_sql::{ base::commitment::QueryCommitments, sql::{ ast::ProofPlan, @@ -26,6 +23,8 @@ pub use proof_of_sql::{ }, }; +use crate::VerifyError; + pub fn verify_proof( proof: VerifiableQueryResult, expr: &ProofPlan, @@ -41,21 +40,21 @@ pub fn verify_proof( .get_metadata(&column.column_id()) { if metadata.column_type() != column.column_type() { - return Err(VerifyError::VerifyError); + return Err(VerifyError::InvalidInput); } } } else { - return Err(VerifyError::VerifyError); + return Err(VerifyError::InvalidInput); } } let result = proof .verify(expr, commitments, setup) - .map_err(|_| VerifyError::VerifyError)?; + .map_err(|_| VerifyError::VerificationFailed)?; if result.table != query_data.table || result.verification_hash != query_data.verification_hash { - Err(VerifyError::VerifyError) + Err(VerifyError::VerificationFailed) } else { Ok(()) } diff --git a/tests/integration.rs b/tests/integration.rs index e627305..a8071ff 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -13,16 +13,23 @@ // See the License for the specific language governing permissions and // limitations under the License. +use proof_of_sql::base::{commitment::QueryCommitments, database::CommitmentAccessor}; pub use proof_of_sql::{ base::{ - commitment::{Commitment, CommitmentEvaluationProof}, - database::{ - owned_table_utility::*, OwnedTableTestAccessor, SchemaAccessor, TestAccessor, - }, + commitment::{Commitment, CommitmentEvaluationProof, QueryCommitmentsExt}, + database::{owned_table_utility::*, OwnedTableTestAccessor, SchemaAccessor, TestAccessor}, }, - sql::{parse::QueryExpr, proof::VerifiableQueryResult}, + sql::{parse::QueryExpr, proof::ProofExpr, proof::VerifiableQueryResult}, }; +fn compute_query_commitments( + query_expr: &QueryExpr, + accessor: &(impl CommitmentAccessor + SchemaAccessor), +) -> QueryCommitments { + let columns = query_expr.proof_expr().get_column_references(); + QueryCommitments::from_accessor_with_max_bounds(columns, accessor) +} + fn build_accessor( setup: ::ProverPublicSetup<'_>, ) -> OwnedTableTestAccessor { @@ -86,9 +93,7 @@ fn build_alien_query(accessor: &impl SchemaAccessor) -> QueryExpr .unwrap() } -fn build_query_non_existant_record( - accessor: &impl SchemaAccessor, -) -> QueryExpr { +fn build_query_non_existant_record(accessor: &impl SchemaAccessor) -> QueryExpr { QueryExpr::try_new( "SELECT b FROM table WHERE a = 4".parse().unwrap(), "sxt".parse().unwrap(), @@ -122,7 +127,7 @@ mod inner_product { let query_data = proof .verify(query.proof_expr(), &accessor, &verifier_setup) .unwrap(); - let query_commitments = proof_of_sql_verifier::compute_query_commitments(&query, &accessor); + let query_commitments = compute_query_commitments(&query, &accessor); let result = proof_of_sql_verifier::verify_inner_product_proof( proof, @@ -140,12 +145,11 @@ mod dory { use super::*; use proof_of_sql::proof_primitive::dory::{ - test_rng, DoryEvaluationProof, DoryProverPublicSetup, ProverSetup, - PublicParameters, + test_rng, DoryEvaluationProof, DoryProverPublicSetup, ProverSetup, PublicParameters, }; use proof_of_sql::base::commitment::QueryCommitments; - use proof_of_sql_verifier::VerificationKey; + use proof_of_sql_verifier::{DoryProof, DoryPublicInput, VerificationKey}; #[test] fn generate_and_verify_proof() { @@ -170,14 +174,14 @@ mod dory { let query_data = proof .verify(query.proof_expr(), &accessor, &vk.into_dory()) .unwrap(); - let query_commitments = proof_of_sql_verifier::compute_query_commitments(&query, &accessor); + let query_commitments = compute_query_commitments(&query, &accessor); // Verify proof + let proof = DoryProof::new(proof); + let pubs = DoryPublicInput::new(&query, query_commitments, query_data); let result = proof_of_sql_verifier::verify_dory_proof( - proof, - query.proof_expr(), - &query_commitments, - &query_data, + &proof, + &pubs, &vk, ); @@ -206,14 +210,13 @@ mod dory { let query_data = proof .verify(non_existant_query.proof_expr(), &accessor, &vk.into_dory()) .unwrap(); - let query_commitments = - proof_of_sql_verifier::compute_query_commitments(&non_existant_query, &accessor); + let query_commitments = compute_query_commitments(&non_existant_query, &accessor); + let dory_proof = DoryProof::new(proof); + let pubs = DoryPublicInput::new(&non_existant_query, query_commitments, query_data); let result = proof_of_sql_verifier::verify_dory_proof( - proof, - non_existant_query.proof_expr(), - &query_commitments, - &query_data, + &dory_proof, + &pubs, &vk, ); @@ -245,11 +248,11 @@ mod dory { .unwrap(); let no_commitments = QueryCommitments::new(); + let proof = DoryProof::new(proof); + let pubs = DoryPublicInput::new(&query, no_commitments, query_data); let result = proof_of_sql_verifier::verify_dory_proof( - proof, - query.proof_expr(), - &no_commitments, - &query_data, + &proof, + &pubs, &vk, ); @@ -283,15 +286,14 @@ mod dory { // Alter the data let altered_accessor: OwnedTableTestAccessor = build_altered_accessor(prover_setup); - let altered_query_commitments = - proof_of_sql_verifier::compute_query_commitments(&query, &altered_accessor); + let altered_query_commitments = compute_query_commitments(&query, &altered_accessor); // Verify proof + let proof = DoryProof::new(proof); + let pubs = DoryPublicInput::new(&query, altered_query_commitments, query_data); let result = proof_of_sql_verifier::verify_dory_proof( - proof, - query.proof_expr(), - &altered_query_commitments, - &query_data, + &proof, + &pubs, &vk, ); @@ -325,14 +327,13 @@ mod dory { .unwrap(); // Compute query commitments for alien accessor - let query_commitments = - proof_of_sql_verifier::compute_query_commitments(&alient_query, &alien_accessor); + let query_commitments = compute_query_commitments(&alient_query, &alien_accessor); + let proof = DoryProof::new(proof); + let pubs = DoryPublicInput::new(&query, query_commitments, query_data); let result = proof_of_sql_verifier::verify_dory_proof( - proof, - query.proof_expr(), - &query_commitments, - &query_data, + &proof, + &pubs, &vk, ); From d26e12ed6f4220197d4cd9e0b45f794187adaeea Mon Sep 17 00:00:00 2001 From: tarassh Date: Wed, 21 Aug 2024 10:21:45 -0700 Subject: [PATCH 12/19] cargo fmt --- src/dory.rs | 5 +++-- src/proof.rs | 4 ++++ src/pubs.rs | 9 ++++++--- tests/integration.rs | 30 +++++------------------------- 4 files changed, 18 insertions(+), 30 deletions(-) diff --git a/src/dory.rs b/src/dory.rs index ed5abd3..3e04415 100644 --- a/src/dory.rs +++ b/src/dory.rs @@ -13,14 +13,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{verify_generic::verify_proof, DoryProof, VerificationKey, VerifyError, DoryPublicInput}; +use crate::{ + verify_generic::verify_proof, DoryProof, DoryPublicInput, VerificationKey, VerifyError, +}; pub fn verify_dory_proof( proof: &DoryProof, pubs: &DoryPublicInput, vk: &VerificationKey, ) -> Result<(), VerifyError> { - verify_proof( proof.clone().into(), pubs.expr(), diff --git a/src/proof.rs b/src/proof.rs index 4c9f319..b6554c4 100644 --- a/src/proof.rs +++ b/src/proof.rs @@ -43,4 +43,8 @@ impl DoryProof { pub fn new(proof: VerifiableQueryResult) -> Self { Self { proof } } + + pub fn into_bytes(self) -> Vec { + bincode::serialize(&self.proof).unwrap() + } } diff --git a/src/pubs.rs b/src/pubs.rs index 274e7ba..1f2d439 100644 --- a/src/pubs.rs +++ b/src/pubs.rs @@ -13,8 +13,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use proof_of_sql::{base::commitment::QueryCommitments, proof_primitive::dory::{DoryCommitment, DoryScalar}, sql::{ast::ProofPlan, parse::QueryExpr, proof::QueryData}}; - +use proof_of_sql::{ + base::commitment::QueryCommitments, + proof_primitive::dory::{DoryCommitment, DoryScalar}, + sql::{ast::ProofPlan, parse::QueryExpr, proof::QueryData}, +}; pub struct DoryPublicInput<'a> { expr: &'a ProofPlan, @@ -46,4 +49,4 @@ impl<'a> DoryPublicInput<'a> { pub fn query_data(&self) -> &QueryData { &self.query_data } -} \ No newline at end of file +} diff --git a/tests/integration.rs b/tests/integration.rs index a8071ff..9fd3c32 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -179,11 +179,7 @@ mod dory { // Verify proof let proof = DoryProof::new(proof); let pubs = DoryPublicInput::new(&query, query_commitments, query_data); - let result = proof_of_sql_verifier::verify_dory_proof( - &proof, - &pubs, - &vk, - ); + let result = proof_of_sql_verifier::verify_dory_proof(&proof, &pubs, &vk); assert!(result.is_ok()); } @@ -214,11 +210,7 @@ mod dory { let dory_proof = DoryProof::new(proof); let pubs = DoryPublicInput::new(&non_existant_query, query_commitments, query_data); - let result = proof_of_sql_verifier::verify_dory_proof( - &dory_proof, - &pubs, - &vk, - ); + let result = proof_of_sql_verifier::verify_dory_proof(&dory_proof, &pubs, &vk); assert!(result.is_ok()); } @@ -250,11 +242,7 @@ mod dory { let proof = DoryProof::new(proof); let pubs = DoryPublicInput::new(&query, no_commitments, query_data); - let result = proof_of_sql_verifier::verify_dory_proof( - &proof, - &pubs, - &vk, - ); + let result = proof_of_sql_verifier::verify_dory_proof(&proof, &pubs, &vk); assert!(result.is_err()); } @@ -291,11 +279,7 @@ mod dory { // Verify proof let proof = DoryProof::new(proof); let pubs = DoryPublicInput::new(&query, altered_query_commitments, query_data); - let result = proof_of_sql_verifier::verify_dory_proof( - &proof, - &pubs, - &vk, - ); + let result = proof_of_sql_verifier::verify_dory_proof(&proof, &pubs, &vk); assert!(result.is_err()); } @@ -331,11 +315,7 @@ mod dory { let proof = DoryProof::new(proof); let pubs = DoryPublicInput::new(&query, query_commitments, query_data); - let result = proof_of_sql_verifier::verify_dory_proof( - &proof, - &pubs, - &vk, - ); + let result = proof_of_sql_verifier::verify_dory_proof(&proof, &pubs, &vk); assert!(result.is_err()); } From 535b68a4a519277333ad46146a3bb9ecc7961854 Mon Sep 17 00:00:00 2001 From: tarassh Date: Wed, 21 Aug 2024 10:36:46 -0700 Subject: [PATCH 13/19] add coments --- src/dory.rs | 15 +++++++++++++++ src/inner_product.rs | 12 ++++++++++++ src/proof.rs | 32 ++++++++++++++++++++++++++++++++ src/pubs.rs | 23 +++++++++++++++++++++++ src/verification_key.rs | 40 ++++++++++++++++++++++++++++++++++++++++ src/verify_generic.rs | 17 +++++++++++++++++ tests/integration.rs | 16 +++++++++++++++- 7 files changed, 154 insertions(+), 1 deletion(-) diff --git a/src/dory.rs b/src/dory.rs index 3e04415..3d16e72 100644 --- a/src/dory.rs +++ b/src/dory.rs @@ -17,6 +17,21 @@ use crate::{ verify_generic::verify_proof, DoryProof, DoryPublicInput, VerificationKey, VerifyError, }; +/// Verifies a Dory proof against the provided public input and verification key. +/// +/// # Arguments +/// +/// * `proof` - The Dory proof to be verified. +/// * `pubs` - The public input for the proof. +/// * `vk` - The verification key used to verify the proof. +/// +/// # Type Parameters +/// +/// * `N` - A const generic parameter, likely related to the size of the verification key. +/// +/// # Returns +/// +/// * `Result<(), VerifyError>` - Ok(()) if the proof is valid, or an error if verification fails. pub fn verify_dory_proof( proof: &DoryProof, pubs: &DoryPublicInput, diff --git a/src/inner_product.rs b/src/inner_product.rs index f25ce78..3c07c46 100644 --- a/src/inner_product.rs +++ b/src/inner_product.rs @@ -27,6 +27,18 @@ pub use blitzar::proof::InnerProductProof; pub use curve25519_dalek::RistrettoPoint; pub use proof_of_sql::base::scalar::Curve25519Scalar; +/// Verifies an inner product proof against the provided expression, commitments, and query data. +/// +/// # Arguments +/// +/// * `proof` - The inner product proof to be verified, wrapped in a VerifiableQueryResult. +/// * `expr` - The proof plan expression. +/// * `commitments` - The query commitments. +/// * `query_data` - The query data. +/// +/// # Returns +/// +/// * `Result<(), VerifyError>` - Ok(()) if the proof is valid, or an error if verification fails. pub fn verify_inner_product_proof( proof: VerifiableQueryResult, expr: &ProofPlan, diff --git a/src/proof.rs b/src/proof.rs index b6554c4..d7a0cde 100644 --- a/src/proof.rs +++ b/src/proof.rs @@ -18,6 +18,14 @@ use proof_of_sql::sql::proof::VerifiableQueryResult; use crate::VerifyError; +/// Represents a Dory proof. +/// +/// `DoryProof` is a wrapper around a `VerifiableQueryResult`. +/// It provides methods for creating, serializing, and deserializing Dory proofs. +/// +/// # Fields +/// +/// * `proof` - A `VerifiableQueryResult` containing the actual proof data. #[derive(Clone)] pub struct DoryProof { proof: VerifiableQueryResult, @@ -26,6 +34,15 @@ pub struct DoryProof { impl TryFrom<&[u8]> for DoryProof { type Error = VerifyError; + /// Attempts to create a DoryProof from a byte slice. + /// + /// # Arguments + /// + /// * `value` - The byte slice containing the serialized proof. + /// + /// # Returns + /// + /// * `Result` - A DoryProof if deserialization succeeds, or a VerifyError if it fails. fn try_from(value: &[u8]) -> Result { let proof = bincode::deserialize(value).map_err(|_| VerifyError::InvalidProofData)?; @@ -34,16 +51,31 @@ impl TryFrom<&[u8]> for DoryProof { } impl Into> for DoryProof { + /// Converts the DoryProof into a VerifiableQueryResult. fn into(self) -> VerifiableQueryResult { self.proof } } impl DoryProof { + /// Creates a new DoryProof. + /// + /// # Arguments + /// + /// * `proof` - A VerifiableQueryResult containing a DoryEvaluationProof. + /// + /// # Returns + /// + /// * `Self` - A new DoryProof instance. pub fn new(proof: VerifiableQueryResult) -> Self { Self { proof } } + /// Converts the DoryProof into a byte vector. + /// + /// # Returns + /// + /// * `Vec` - The serialized proof as a byte vector. pub fn into_bytes(self) -> Vec { bincode::serialize(&self.proof).unwrap() } diff --git a/src/pubs.rs b/src/pubs.rs index 1f2d439..b7ca1c4 100644 --- a/src/pubs.rs +++ b/src/pubs.rs @@ -19,6 +19,15 @@ use proof_of_sql::{ sql::{ast::ProofPlan, parse::QueryExpr, proof::QueryData}, }; +/// Represents the public input for a Dory proof. +/// +/// This structure encapsulates the necessary public information required +/// for verifying a Dory proof, including the proof expression, commitments, +/// and query data. +/// +/// # Type Parameters +/// +/// * `'a` - The lifetime of the referenced `ProofPlan`. pub struct DoryPublicInput<'a> { expr: &'a ProofPlan, commitments: QueryCommitments, @@ -26,6 +35,17 @@ pub struct DoryPublicInput<'a> { } impl<'a> DoryPublicInput<'a> { + /// Creates a new `DoryPublicInput` instance. + /// + /// # Arguments + /// + /// * `query_expr` - A reference to the query expression. + /// * `commitments` - The query commitments. + /// * `query_data` - The query data. + /// + /// # Returns + /// + /// A new `DoryPublicInput` instance. pub fn new( query_expr: &'a QueryExpr, commitments: QueryCommitments, @@ -38,14 +58,17 @@ impl<'a> DoryPublicInput<'a> { } } + /// Returns a reference to the proof expression. pub fn expr(&self) -> &ProofPlan { &self.expr } + /// Returns a reference to the query commitments. pub fn commitments(&self) -> &QueryCommitments { &self.commitments } + /// Returns a reference to the query data. pub fn query_data(&self) -> &QueryData { &self.query_data } diff --git a/src/verification_key.rs b/src/verification_key.rs index 82fd2d7..cd5f980 100644 --- a/src/verification_key.rs +++ b/src/verification_key.rs @@ -20,11 +20,28 @@ use proof_of_sql::proof_primitive::dory::{ use crate::VerifyError; +/// Represents a verification key for Dory proofs. +/// +/// This structure wraps a `VerifierSetup` and provides methods for +/// creating, deserializing, and converting the verification key. +/// +/// # Type Parameters +/// +/// * `N` - A const generic parameter representing the size of the verification key. pub struct VerificationKey(VerifierSetup); impl TryFrom<&[u8]> for VerificationKey { type Error = VerifyError; + /// Attempts to create a VerificationKey from a byte slice. + /// + /// # Arguments + /// + /// * `value` - The byte slice containing the serialized verification key. + /// + /// # Returns + /// + /// * `Result` - A VerificationKey if deserialization succeeds, or a VerifyError if it fails. fn try_from(value: &[u8]) -> Result { let setup = VerifierSetup::deserialize_compressed(value) .map_err(|_| VerifyError::InvalidVerificationKey)?; @@ -41,15 +58,38 @@ impl TryFrom<&[u8]> for VerificationKey { } impl VerificationKey { + /// Creates a new VerificationKey from PublicParameters. + /// + /// # Arguments + /// + /// * `params` - A reference to PublicParameters. + /// + /// # Returns + /// + /// A new VerificationKey instance. pub fn new(params: &PublicParameters) -> Self { Self(VerifierSetup::from(params)) } + /// Converts the VerificationKey into a DoryVerifierPublicSetup. + /// + /// # Returns + /// + /// A DoryVerifierPublicSetup instance. pub fn into_dory(&self) -> DoryVerifierPublicSetup<'_> { DoryVerifierPublicSetup::new(&self.0, N) } } +/// Converts a byte slice to a usize. +/// +/// # Arguments +/// +/// * `slice` - The byte slice to convert. +/// +/// # Returns +/// +/// The usize value represented by the byte slice. fn slice_to_usize(slice: &[u8]) -> usize { let mut array = [0u8; std::mem::size_of::()]; let len = slice.len().min(std::mem::size_of::()); diff --git a/src/verify_generic.rs b/src/verify_generic.rs index 665c2c4..54bf5d0 100644 --- a/src/verify_generic.rs +++ b/src/verify_generic.rs @@ -25,6 +25,23 @@ use proof_of_sql::{ use crate::VerifyError; +/// Verifies a generic proof against the provided expression, commitments, and query data. +/// +/// # Type Parameters +/// +/// * `CP` - A type that implements `CommitmentEvaluationProof`. +/// +/// # Arguments +/// +/// * `proof` - The proof to be verified, wrapped in a `VerifiableQueryResult`. +/// * `expr` - The proof plan expression. +/// * `commitments` - The query commitments. +/// * `query_data` - The query data. +/// * `setup` - The verifier's public setup. +/// +/// # Returns +/// +/// * `Result<(), VerifyError>` - Ok(()) if the proof is valid, or an error if verification fails. pub fn verify_proof( proof: VerifiableQueryResult, expr: &ProofPlan, diff --git a/tests/integration.rs b/tests/integration.rs index 9fd3c32..0a5a0bc 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -22,6 +22,9 @@ pub use proof_of_sql::{ sql::{parse::QueryExpr, proof::ProofExpr, proof::VerifiableQueryResult}, }; +// Helper functions for setting up test data and queries + +/// Computes query commitments for a given query expression and accessor. fn compute_query_commitments( query_expr: &QueryExpr, accessor: &(impl CommitmentAccessor + SchemaAccessor), @@ -30,6 +33,7 @@ fn compute_query_commitments( QueryCommitments::from_accessor_with_max_bounds(columns, accessor) } +/// Builds a test accessor with sample data. fn build_accessor( setup: ::ProverPublicSetup<'_>, ) -> OwnedTableTestAccessor { @@ -45,6 +49,7 @@ fn build_accessor( accessor } +/// Builds a test accessor with altered sample data. fn build_altered_accessor( setup: ::ProverPublicSetup<'_>, ) -> OwnedTableTestAccessor { @@ -60,6 +65,7 @@ fn build_altered_accessor( accessor } +/// Builds a test accessor with different table and column names. fn build_alien_accessor( setup: ::ProverPublicSetup<'_>, ) -> OwnedTableTestAccessor { @@ -75,6 +81,7 @@ fn build_alien_accessor( accessor } +/// Builds a sample query for testing. fn build_query(accessor: &impl SchemaAccessor) -> QueryExpr { QueryExpr::try_new( "SELECT b FROM table WHERE a = 2".parse().unwrap(), @@ -84,6 +91,7 @@ fn build_query(accessor: &impl SchemaAccessor) -> QueryExpr { .unwrap() } +/// Builds a sample query for the "alien" accessor. fn build_alien_query(accessor: &impl SchemaAccessor) -> QueryExpr { QueryExpr::try_new( "SELECT d FROM table2 WHERE c = 2".parse().unwrap(), @@ -93,6 +101,7 @@ fn build_alien_query(accessor: &impl SchemaAccessor) -> QueryExpr .unwrap() } +/// Builds a query for a non-existent record. fn build_query_non_existant_record(accessor: &impl SchemaAccessor) -> QueryExpr { QueryExpr::try_new( "SELECT b FROM table WHERE a = 4".parse().unwrap(), @@ -108,6 +117,7 @@ mod inner_product { use blitzar::{self, proof::InnerProductProof}; + /// Tests the generation and verification of an inner product proof. #[test] fn generate_and_verify_proof() { blitzar::compute::init_backend(); @@ -141,7 +151,6 @@ mod inner_product { } mod dory { - use super::*; use proof_of_sql::proof_primitive::dory::{ @@ -151,6 +160,7 @@ mod dory { use proof_of_sql::base::commitment::QueryCommitments; use proof_of_sql_verifier::{DoryProof, DoryPublicInput, VerificationKey}; + /// Tests the generation and verification of a Dory proof. #[test] fn generate_and_verify_proof() { // Initialize setup @@ -184,6 +194,7 @@ mod dory { assert!(result.is_ok()); } + /// Tests the generation and verification of a Dory proof for a non-existent record. #[test] fn generate_and_verify_proof_for_non_existant_record() { // Initialize setup @@ -215,6 +226,7 @@ mod dory { assert!(result.is_ok()); } + /// Tests that verification fails when commitments are missing. #[test] fn generate_and_verify_proof_without_commitments() { // Initialize setup @@ -247,6 +259,7 @@ mod dory { assert!(result.is_err()); } + /// Tests that verification fails when the underlying data has been altered. #[test] fn generate_and_verify_proof_for_altered_data() { // Initialize setup @@ -284,6 +297,7 @@ mod dory { assert!(result.is_err()); } + /// Tests that verification fails when using commitments from a different accessor. #[test] fn generate_and_verify_proof_from_alien_accessor() { // Initialize setup From 773d52f00707af19b0a9aa572e7d61fda4096692 Mon Sep 17 00:00:00 2001 From: tarassh Date: Wed, 21 Aug 2024 10:38:51 -0700 Subject: [PATCH 14/19] update readme --- README.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3027570..1a5dc61 100644 --- a/README.md +++ b/README.md @@ -1 +1,17 @@ -# proof-of-sql-verifier \ No newline at end of file +# Proof of SQL Verifier + +Proof of SQL Verifier is a Rust library for verifying SQL query results using zero-knowledge proofs. + +## Features + +- Verification of Dory proofs +- Integration with the proof-of-sql library + +## Installation + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +proof-of-sql-verifier = "0.1.0" +``` From 47e714b9934e4a45819be12f7ca52050e20a0c41 Mon Sep 17 00:00:00 2001 From: tarassh Date: Wed, 21 Aug 2024 11:01:38 -0700 Subject: [PATCH 15/19] add header script --- scripts/add_header_if_missing.sh | 30 ++++++++++++++++++++++++++++++ src/dory.rs | 2 +- src/errors.rs | 2 +- src/inner_product.rs | 2 +- src/lib.rs | 2 +- src/proof.rs | 2 +- src/pubs.rs | 2 +- src/verification_key.rs | 2 +- src/verify_generic.rs | 2 +- 9 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 scripts/add_header_if_missing.sh diff --git a/scripts/add_header_if_missing.sh b/scripts/add_header_if_missing.sh new file mode 100644 index 0000000..13de210 --- /dev/null +++ b/scripts/add_header_if_missing.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# Check if at least two arguments are provided +if [ "$#" -lt 2 ]; then + echo "Usage: $0 " + exit 1 +fi + +# Read arguments +HEADER_FILE="$1" +FILE_PATTERN="$2" + +# Read the license header from the specified file +if [ ! -f "$HEADER_FILE" ]; then + echo "Header file not found: $HEADER_FILE" + exit 1 +fi + +LICENSE_HEADER=$(cat "$HEADER_FILE") + +# Loop through all Rust files matching the pattern +shopt -s globstar +for file in $FILE_PATTERN; do + if [[ -f "$file" && "$file" == *.rs ]]; then + if ! grep -q "Copyright 2024, Horizen Labs, Inc." "$file"; then + echo "Adding license header to $file" + echo -e "$LICENSE_HEADER\n$(cat $file)" > "$file" + fi + fi +done \ No newline at end of file diff --git a/src/dory.rs b/src/dory.rs index 3d16e72..c1501ae 100644 --- a/src/dory.rs +++ b/src/dory.rs @@ -1,4 +1,4 @@ -// Copyright 2024, The Horizen Foundation +// Copyright 2024, Horizen Labs, Inc. // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/errors.rs b/src/errors.rs index 5abaf6e..688448a 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,4 +1,4 @@ -// Copyright 2024, The Horizen Foundation +// Copyright 2024, Horizen Labs, Inc. // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/inner_product.rs b/src/inner_product.rs index 3c07c46..8dbc4db 100644 --- a/src/inner_product.rs +++ b/src/inner_product.rs @@ -1,4 +1,4 @@ -// Copyright 2024, The Horizen Foundation +// Copyright 2024, Horizen Labs, Inc. // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/lib.rs b/src/lib.rs index 764eea7..0fe699c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2024, The Horizen Foundation +// Copyright 2024, Horizen Labs, Inc. // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/proof.rs b/src/proof.rs index d7a0cde..cb2be2f 100644 --- a/src/proof.rs +++ b/src/proof.rs @@ -1,4 +1,4 @@ -// Copyright 2024, The Horizen Foundation +// Copyright 2024, Horizen Labs, Inc. // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/pubs.rs b/src/pubs.rs index b7ca1c4..4cd2bc0 100644 --- a/src/pubs.rs +++ b/src/pubs.rs @@ -1,4 +1,4 @@ -// Copyright 2024, The Horizen Foundation +// Copyright 2024, Horizen Labs, Inc. // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/verification_key.rs b/src/verification_key.rs index cd5f980..7f1e173 100644 --- a/src/verification_key.rs +++ b/src/verification_key.rs @@ -1,4 +1,4 @@ -// Copyright 2024, The Horizen Foundation +// Copyright 2024, Horizen Labs, Inc. // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/verify_generic.rs b/src/verify_generic.rs index 54bf5d0..8367b8a 100644 --- a/src/verify_generic.rs +++ b/src/verify_generic.rs @@ -1,4 +1,4 @@ -// Copyright 2024, The Horizen Foundation +// Copyright 2024, Horizen Labs, Inc. // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); From 5aa7b9948fe46c8d3a035db0944078c931876db2 Mon Sep 17 00:00:00 2001 From: tarassh Date: Wed, 21 Aug 2024 11:15:01 -0700 Subject: [PATCH 16/19] CI: embed script into make --- Makefile.toml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Makefile.toml b/Makefile.toml index 2ba8629..257c76d 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -41,7 +41,24 @@ command = "cargo" args = ["clippy", "--", "--deny", "warnings"] [tasks.header-add] -script = { file = "./scripts/add_header_if_missing.sh" } +script = [ + "if [ \"$#\" -lt 2 ]; then", + " echo 'Usage: $0 '", + " exit 1", + "fi", + "HEADER_FILE=\"$1\"", + "FILE_PATTERN=\"$2\"", + "LICENSE_HEADER=$(cat \"$HEADER_FILE\")", + "shopt -s globstar", + "for file in $FILE_PATTERN; do", + " if [[ -f \"$file\" && \"$file\" == *.rs ]]; then", + " if ! grep -q 'Copyright 2024, Horizen Labs, Inc.' \"$file\"; then", + " echo 'Adding license header to $file'", + " echo -e \"$LICENSE_HEADER\\n$(cat $file)\" > \"$file\"", + " fi", + " fi", + "done" +] args = ["HEADER-APACHE2", "./!(target)/**/*.rs"] [tasks.header-check] From 87f8b113ce447d14e6e0fa3a73631160d8b2a5fb Mon Sep 17 00:00:00 2001 From: tarassh Date: Wed, 21 Aug 2024 11:27:22 -0700 Subject: [PATCH 17/19] CI: fix using script --- Makefile.toml | 19 +-------- scripts/add_header_if_missing.sh | 71 ++++++++++++++++++++------------ 2 files changed, 45 insertions(+), 45 deletions(-) mode change 100644 => 100755 scripts/add_header_if_missing.sh diff --git a/Makefile.toml b/Makefile.toml index 257c76d..2ba8629 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -41,24 +41,7 @@ command = "cargo" args = ["clippy", "--", "--deny", "warnings"] [tasks.header-add] -script = [ - "if [ \"$#\" -lt 2 ]; then", - " echo 'Usage: $0 '", - " exit 1", - "fi", - "HEADER_FILE=\"$1\"", - "FILE_PATTERN=\"$2\"", - "LICENSE_HEADER=$(cat \"$HEADER_FILE\")", - "shopt -s globstar", - "for file in $FILE_PATTERN; do", - " if [[ -f \"$file\" && \"$file\" == *.rs ]]; then", - " if ! grep -q 'Copyright 2024, Horizen Labs, Inc.' \"$file\"; then", - " echo 'Adding license header to $file'", - " echo -e \"$LICENSE_HEADER\\n$(cat $file)\" > \"$file\"", - " fi", - " fi", - "done" -] +script = { file = "./scripts/add_header_if_missing.sh" } args = ["HEADER-APACHE2", "./!(target)/**/*.rs"] [tasks.header-check] diff --git a/scripts/add_header_if_missing.sh b/scripts/add_header_if_missing.sh old mode 100644 new mode 100755 index 13de210..ce378ec --- a/scripts/add_header_if_missing.sh +++ b/scripts/add_header_if_missing.sh @@ -1,30 +1,47 @@ #!/bin/bash -# Check if at least two arguments are provided -if [ "$#" -lt 2 ]; then - echo "Usage: $0 " - exit 1 -fi - -# Read arguments -HEADER_FILE="$1" -FILE_PATTERN="$2" - -# Read the license header from the specified file -if [ ! -f "$HEADER_FILE" ]; then - echo "Header file not found: $HEADER_FILE" - exit 1 -fi - -LICENSE_HEADER=$(cat "$HEADER_FILE") - -# Loop through all Rust files matching the pattern -shopt -s globstar -for file in $FILE_PATTERN; do - if [[ -f "$file" && "$file" == *.rs ]]; then - if ! grep -q "Copyright 2024, Horizen Labs, Inc." "$file"; then - echo "Adding license header to $file" - echo -e "$LICENSE_HEADER\n$(cat $file)" > "$file" +set -euo pipefail +shopt -s extglob + +HEADER=${1:-HEADER-APACHE2} +START_PATH=${2:-"./!(target)/**/*.rs"} +CHECK_DIRTY=${CHECK_DIRTY:="false"} +DRY_RUN=${DRY_RUN:-"false"} + +N=`wc -l "${HEADER}" | awk '{print $1}'` + +DIRTY=0 + +function add_header { + local path=$1; + local header=${2:-${HEADER}}; + + local tmp=`mktemp` + + # Add \n at the top + echo "" > "${tmp}" + # Copy original + cat "${path}" >> "${tmp}" + + if [ "${DRY_RUN}" == "true" ]; then + echo "Dry run... '${path}' - '${header}' - '${tmp}'"; + return; + fi + if [ "${CHECK_DIRTY}" == "true" ]; then + return; fi - fi -done \ No newline at end of file + # Mix them + cat "${header}" "${tmp}" > "${path}" +} + +for f in ${START_PATH}; do + if ! diff <(head -n "${N}" "${f}") <(cat "${HEADER}") > /dev/null ; then + echo "'${f}' Doesn't start with header from '${HEADER}': Add it"; + add_header "${f}" "${HEADER}" + DIRTY=1 + fi +done + +if [[ "${CHECK_DIRTY}" == "true" && ${DIRTY} == 1 ]]; then + exit 1; +fi \ No newline at end of file From 1db0ae104696a415ded8545de952b1d32b1ce4a0 Mon Sep 17 00:00:00 2001 From: tarassh Date: Wed, 21 Aug 2024 11:36:45 -0700 Subject: [PATCH 18/19] CI: fix --- Makefile.toml | 2 +- scripts/add_header_if_missing.sh | 2 +- tests/integration.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile.toml b/Makefile.toml index 2ba8629..92c31eb 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -42,7 +42,7 @@ args = ["clippy", "--", "--deny", "warnings"] [tasks.header-add] script = { file = "./scripts/add_header_if_missing.sh" } -args = ["HEADER-APACHE2", "./!(target)/**/*.rs"] +args = ["HEADER-APACHE2", "./**/*.rs"] [tasks.header-check] env = { CHECK_DIRTY = "true", DRY_RUN = "true" } diff --git a/scripts/add_header_if_missing.sh b/scripts/add_header_if_missing.sh index ce378ec..ac62562 100755 --- a/scripts/add_header_if_missing.sh +++ b/scripts/add_header_if_missing.sh @@ -4,7 +4,7 @@ set -euo pipefail shopt -s extglob HEADER=${1:-HEADER-APACHE2} -START_PATH=${2:-"./!(target)/**/*.rs"} +START_PATH=${2:-"./**/*.rs"} CHECK_DIRTY=${CHECK_DIRTY:="false"} DRY_RUN=${DRY_RUN:-"false"} diff --git a/tests/integration.rs b/tests/integration.rs index 0a5a0bc..628c4d5 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -1,4 +1,4 @@ -// Copyright 2024, The Horizen Foundation +// Copyright 2024, Horizen Labs, Inc. // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); From a9fd13930b9bc98a46aa2af1eb73ebef77d9b3a4 Mon Sep 17 00:00:00 2001 From: tarassh Date: Wed, 21 Aug 2024 11:50:44 -0700 Subject: [PATCH 19/19] C: make clippy happy --- src/dory.rs | 2 +- src/proof.rs | 16 +++++++++------- src/pubs.rs | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/dory.rs b/src/dory.rs index c1501ae..1855f54 100644 --- a/src/dory.rs +++ b/src/dory.rs @@ -38,7 +38,7 @@ pub fn verify_dory_proof( vk: &VerificationKey, ) -> Result<(), VerifyError> { verify_proof( - proof.clone().into(), + proof.clone().into_dory(), pubs.expr(), pubs.commitments(), pubs.query_data(), diff --git a/src/proof.rs b/src/proof.rs index cb2be2f..9a4cd3d 100644 --- a/src/proof.rs +++ b/src/proof.rs @@ -50,13 +50,6 @@ impl TryFrom<&[u8]> for DoryProof { } } -impl Into> for DoryProof { - /// Converts the DoryProof into a VerifiableQueryResult. - fn into(self) -> VerifiableQueryResult { - self.proof - } -} - impl DoryProof { /// Creates a new DoryProof. /// @@ -79,4 +72,13 @@ impl DoryProof { pub fn into_bytes(self) -> Vec { bincode::serialize(&self.proof).unwrap() } + + /// Converts the DoryProof into a VerifiableQueryResult. + /// + /// # Returns + /// + /// * `VerifiableQueryResult` - The proof data. + pub fn into_dory(self) -> VerifiableQueryResult { + self.proof + } } diff --git a/src/pubs.rs b/src/pubs.rs index 4cd2bc0..6fc96f2 100644 --- a/src/pubs.rs +++ b/src/pubs.rs @@ -60,7 +60,7 @@ impl<'a> DoryPublicInput<'a> { /// Returns a reference to the proof expression. pub fn expr(&self) -> &ProofPlan { - &self.expr + self.expr } /// Returns a reference to the query commitments.