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
new file mode 100644
index 0000000..32a86fc
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+/target
+Cargo.lock
+lcov.info
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..0ff1aa9
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "proof-of-sql-verifier"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+ark-serialize = { version = "0.4.0", default-features = false }
+bincode = "1"
+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 }
+proof-of-sql-parser = { version = "0.15.0" }
+
+[dev-dependencies]
+proof-of-sql = { version = "0.15.0", default-features = false, features = ["test"] }
+
+[features]
+inner-product = ["dep:blitzar", "dep:curve25519-dalek", "proof-of-sql/blitzar"]
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..92c31eb
--- /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", "./**/*.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
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"
+```
diff --git a/scripts/add_header_if_missing.sh b/scripts/add_header_if_missing.sh
new file mode 100755
index 0000000..ac62562
--- /dev/null
+++ b/scripts/add_header_if_missing.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+set -euo pipefail
+shopt -s extglob
+
+HEADER=${1:-HEADER-APACHE2}
+START_PATH=${2:-"./**/*.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
+ # 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
diff --git a/src/dory.rs b/src/dory.rs
new file mode 100644
index 0000000..1855f54
--- /dev/null
+++ b/src/dory.rs
@@ -0,0 +1,47 @@
+// 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.
+
+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,
+ vk: &VerificationKey,
+) -> Result<(), VerifyError> {
+ verify_proof(
+ proof.clone().into_dory(),
+ pubs.expr(),
+ pubs.commitments(),
+ pubs.query_data(),
+ &vk.into_dory(),
+ )
+}
diff --git a/src/errors.rs b/src/errors.rs
new file mode 100644
index 0000000..688448a
--- /dev/null
+++ b/src/errors.rs
@@ -0,0 +1,27 @@
+// 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.
+
+/// This module defines errors used across the verification library.
+#[derive(Debug, PartialEq)]
+pub enum VerifyError {
+ /// Provided data has invalid public inputs.
+ InvalidInput,
+ /// Provided data has invalid proof.
+ InvalidProofData,
+ /// Verify proof failed.
+ VerificationFailed, // Renamed for clarity
+ /// Provided an invalid verification key.
+ InvalidVerificationKey,
+}
diff --git a/src/inner_product.rs b/src/inner_product.rs
new file mode 100644
index 0000000..8dbc4db
--- /dev/null
+++ b/src/inner_product.rs
@@ -0,0 +1,49 @@
+// 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.
+
+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;
+
+/// 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,
+ 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..0fe699c
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,35 @@
+// 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.
+
+mod errors;
+mod proof;
+mod pubs;
+mod verification_key;
+mod verify_generic;
+
+pub mod dory;
+pub use dory::*;
+
+pub use errors::*;
+pub use proof::*;
+pub use pubs::*;
+pub use verification_key::*;
+pub use verify_generic::*;
+
+#[cfg(feature = "inner-product")]
+pub mod inner_product;
+
+#[cfg(feature = "inner-product")]
+pub use inner_product::*;
diff --git a/src/proof.rs b/src/proof.rs
new file mode 100644
index 0000000..9a4cd3d
--- /dev/null
+++ b/src/proof.rs
@@ -0,0 +1,84 @@
+// 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.
+
+use proof_of_sql::proof_primitive::dory::DoryEvaluationProof;
+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,
+}
+
+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)?;
+
+ Ok(Self::new(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()
+ }
+
+ /// 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
new file mode 100644
index 0000000..6fc96f2
--- /dev/null
+++ b/src/pubs.rs
@@ -0,0 +1,75 @@
+// 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.
+
+use proof_of_sql::{
+ base::commitment::QueryCommitments,
+ proof_primitive::dory::{DoryCommitment, DoryScalar},
+ 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,
+ query_data: QueryData,
+}
+
+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,
+ query_data: QueryData,
+ ) -> Self {
+ Self {
+ expr: query_expr.proof_expr(),
+ commitments,
+ query_data,
+ }
+ }
+
+ /// 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
new file mode 100644
index 0000000..7f1e173
--- /dev/null
+++ b/src/verification_key.rs
@@ -0,0 +1,131 @@
+// 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.
+
+use ark_serialize::CanonicalDeserialize;
+use proof_of_sql::proof_primitive::dory::{
+ DoryVerifierPublicSetup, PublicParameters, VerifierSetup,
+};
+
+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)?;
+
+ // 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);
+ }
+
+ Ok(Self(setup))
+ }
+}
+
+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::());
+ array[..len].copy_from_slice(&slice[..len]);
+
+ usize::from_le_bytes(array)
+}
+
+#[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();
+
+ 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());
+ }
+}
diff --git a/src/verify_generic.rs b/src/verify_generic.rs
new file mode 100644
index 0000000..8367b8a
--- /dev/null
+++ b/src/verify_generic.rs
@@ -0,0 +1,78 @@
+// 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.
+
+use proof_of_sql::base::commitment::CommitmentEvaluationProof;
+use proof_of_sql::sql::proof::ProofExpr;
+use proof_of_sql::{
+ base::commitment::QueryCommitments,
+ sql::{
+ ast::ProofPlan,
+ proof::{QueryData, VerifiableQueryResult},
+ },
+};
+
+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,
+ commitments: &QueryCommitments,
+ query_data: &QueryData,
+ setup: &CP::VerifierPublicSetup<'_>,
+) -> Result<(), 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::InvalidInput);
+ }
+ }
+ } else {
+ return Err(VerifyError::InvalidInput);
+ }
+ }
+
+ let result = proof
+ .verify(expr, commitments, setup)
+ .map_err(|_| VerifyError::VerificationFailed)?;
+
+ if result.table != query_data.table || result.verification_hash != query_data.verification_hash
+ {
+ Err(VerifyError::VerificationFailed)
+ } else {
+ Ok(())
+ }
+}
diff --git a/tests/integration.rs b/tests/integration.rs
new file mode 100644
index 0000000..628c4d5
--- /dev/null
+++ b/tests/integration.rs
@@ -0,0 +1,336 @@
+// 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.
+
+use proof_of_sql::base::{commitment::QueryCommitments, database::CommitmentAccessor};
+pub use proof_of_sql::{
+ base::{
+ commitment::{Commitment, CommitmentEvaluationProof, QueryCommitmentsExt},
+ database::{owned_table_utility::*, OwnedTableTestAccessor, SchemaAccessor, TestAccessor},
+ },
+ 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),
+) -> QueryCommitments {
+ let columns = query_expr.proof_expr().get_column_references();
+ QueryCommitments::from_accessor_with_max_bounds(columns, accessor)
+}
+
+/// Builds a test accessor with sample data.
+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
+}
+
+/// Builds a test accessor with altered sample data.
+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
+}
+
+/// Builds a test accessor with different table and column names.
+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
+}
+
+/// 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(),
+ "sxt".parse().unwrap(),
+ accessor,
+ )
+ .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(),
+ "sxt".parse().unwrap(),
+ accessor,
+ )
+ .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(),
+ "sxt".parse().unwrap(),
+ accessor,
+ )
+ .unwrap()
+}
+
+#[cfg(feature = "inner-product")]
+mod inner_product {
+ use super::*;
+
+ 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();
+
+ 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 = 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());
+ }
+}
+
+mod dory {
+ use super::*;
+
+ use proof_of_sql::proof_primitive::dory::{
+ test_rng, DoryEvaluationProof, DoryProverPublicSetup, ProverSetup, PublicParameters,
+ };
+
+ 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
+ let public_parameters = PublicParameters::rand(4, &mut test_rng());
+ let ps = ProverSetup::from(&public_parameters);
+ let prover_setup = DoryProverPublicSetup::new(&ps, 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 vk = VerificationKey::<4>::new(&public_parameters);
+ let query_data = proof
+ .verify(query.proof_expr(), &accessor, &vk.into_dory())
+ .unwrap();
+ 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, &pubs, &vk);
+
+ 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
+ let public_parameters = PublicParameters::rand(4, &mut test_rng());
+ let ps = ProverSetup::from(&public_parameters);
+ let prover_setup = DoryProverPublicSetup::new(&ps, 4);
+
+ // 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 vk = VerificationKey::<4>::new(&public_parameters);
+
+ let query_data = proof
+ .verify(non_existant_query.proof_expr(), &accessor, &vk.into_dory())
+ .unwrap();
+ 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(&dory_proof, &pubs, &vk);
+
+ assert!(result.is_ok());
+ }
+
+ /// Tests that verification fails when commitments are missing.
+ #[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 prover_setup = DoryProverPublicSetup::new(&ps, 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 vk = VerificationKey::<4>::new(&public_parameters);
+ let query_data = proof
+ .verify(query.proof_expr(), &accessor, &vk.into_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, &pubs, &vk);
+
+ 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
+ let public_parameters = PublicParameters::rand(4, &mut test_rng());
+ let ps = ProverSetup::from(&public_parameters);
+ let prover_setup = DoryProverPublicSetup::new(&ps, 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 vk = VerificationKey::<4>::new(&public_parameters);
+ let query_data = proof
+ .verify(query.proof_expr(), &accessor, &vk.into_dory())
+ .unwrap();
+
+ // Alter the data
+ let altered_accessor: OwnedTableTestAccessor =
+ build_altered_accessor(prover_setup);
+ 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, &pubs, &vk);
+
+ 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
+ let public_parameters = PublicParameters::rand(4, &mut test_rng());
+ let ps = ProverSetup::from(&public_parameters);
+ let prover_setup = DoryProverPublicSetup::new(&ps, 4);
+
+ // 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 vk = VerificationKey::<4>::new(&public_parameters);
+ let query_data = proof
+ .verify(query.proof_expr(), &accessor, &vk.into_dory())
+ .unwrap();
+
+ // Compute query commitments for 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, &pubs, &vk);
+
+ assert!(result.is_err());
+ }
+}